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

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Handler to set parameters for assessments
                      3: #
1.562   ! damieng     4: # $Id: lonparmset.pm,v 1.561 2016/07/15 18:03:52 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('_');
1.562   ! damieng  1068:             if (document.parmform.pres_type.value!='') {
        !          1069:                 if (typedef[0]=='date') {
        !          1070:                     eval('document.parmform.recent_'+
        !          1071:                         document.parmform.pres_type.value+
        !          1072:                         '.value=document.parmform.pres_value.value;');
        !          1073:                 } else {
        !          1074:                     eval('document.parmform.recent_'+typedef[0]+
        !          1075:                         '.value=document.parmform.pres_value.value;');
        !          1076:                 }
1.44      albertel 1077:             }
                   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.562   ! damieng  1651: # Extracts lots of information about all of the the course's resources into a variety of hashes, using lonnavmaps and lonnet::metadata.
        !          1652: # All the parameters are references and are filled by the sub.
        !          1653: #
        !          1654: # @param {array reference} $ids - resource ids
        !          1655: # @param {hash reference} $typep - hash resource id (from big hash) -> resource type (file extension)
        !          1656: # @param {hash reference} $keyp - hash resource id -> comma-separated list of parameter keys from lonnet::metadata
        !          1657: # @param {hash reference} $allparms - hash parameter name -> parameter title
        !          1658: # @param {hash reference} $allparts - hash parameter part -> part title (a parameter part can be problem part.'_'.response id for response parameters)
        !          1659: # @param {hash reference} $allmaps - hash map id (from big hash) -> map src
        !          1660: # @param {hash reference} $mapp - hash resource id -> enclosing map src
        !          1661: # @param {hash reference} $symbp - hash map id or resource id -> map src.'___(all)' for a map or resource symb for a resource
        !          1662: # @param {hash reference} $maptitles - hash map id or src -> map title (this should really be two separate hashes)
        !          1663: # @param {hash reference} $uris - hash resource id -> resource src
        !          1664: # @param {hash reference} $keyorder - hash parameter key -> appearance rank for this parameter when looking through every resource and every parameter, starting at 100 (integer)
        !          1665: # @param {hash reference} $defkeytype - hash parameter name -> parameter type
1.63      bowersj2 1666: sub extractResourceInformation {
                   1667:     my $ids = shift;
                   1668:     my $typep = shift;
                   1669:     my $keyp = shift;
                   1670:     my $allparms = shift;
                   1671:     my $allparts = shift;
                   1672:     my $allmaps = shift;
                   1673:     my $mapp = shift;
                   1674:     my $symbp = shift;
1.82      www      1675:     my $maptitles=shift;
1.196     www      1676:     my $uris=shift;
1.210     www      1677:     my $keyorder=shift;
1.211     www      1678:     my $defkeytype=shift;
1.196     www      1679: 
1.210     www      1680:     my $keyordercnt=100;
1.63      bowersj2 1681: 
1.196     www      1682:     my $navmap = Apache::lonnavmaps::navmap->new();
                   1683:     my @allres=$navmap->retrieveResources(undef,undef,1,undef,1);
                   1684:     foreach my $resource (@allres) {
1.480     amueller 1685:         my $id=$resource->id();
1.196     www      1686:         my ($mapid,$resid)=split(/\./,$id);
1.480     amueller 1687:         if ($mapid eq '0') { next; }
                   1688:         $$ids[$#$ids+1]=$id;
                   1689:         my $srcf=$resource->src();
                   1690:         $srcf=~/\.(\w+)$/;
                   1691:         $$typep{$id}=$1;
                   1692:         $$keyp{$id}='';
1.196     www      1693:         $$uris{$id}=$srcf;
1.512     foxr     1694: 
1.480     amueller 1695:         foreach my $key (split(/\,/,&Apache::lonnet::metadata($srcf,'allpossiblekeys'))) {
                   1696:             next if ($key!~/^parameter_/);
1.363     albertel 1697: 
1.209     www      1698: # Hidden parameters
1.480     amueller 1699:             next if (&Apache::lonnet::metadata($srcf,$key.'.hidden') eq 'parm');
1.209     www      1700: #
                   1701: # allparms is a hash of parameter names
                   1702: #
1.480     amueller 1703:             my $name=&Apache::lonnet::metadata($srcf,$key.'.name');
                   1704:             if (!exists($$allparms{$name}) || $$allparms{$name} =~ m/^\s*$/ ) {
                   1705:                 my ($display,$parmdis);
                   1706:                 $display = &standard_parameter_names($name);
                   1707:                 if ($display eq '') {
                   1708:                     $display= &Apache::lonnet::metadata($srcf,$key.'.display');
                   1709:                     $parmdis = $display;
                   1710:                     $parmdis =~ s/\s*\[Part.*$//g;
                   1711:                 } else {
                   1712:                     $parmdis = &mt($display);
                   1713:                 }
                   1714:                 $$allparms{$name}=$parmdis;
                   1715:                 if (ref($defkeytype)) {
                   1716:                     $$defkeytype{$name}=
                   1717:                     &Apache::lonnet::metadata($srcf,$key.'.type');
                   1718:                 }
                   1719:             }
1.363     albertel 1720: 
1.209     www      1721: #
                   1722: # allparts is a hash of all parts
                   1723: #
1.480     amueller 1724:             my $part= &Apache::lonnet::metadata($srcf,$key.'.part');
                   1725:             $$allparts{$part} = &mt('Part: [_1]',$part);
1.209     www      1726: #
                   1727: # Remember all keys going with this resource
                   1728: #
1.480     amueller 1729:             if ($$keyp{$id}) {
                   1730:                 $$keyp{$id}.=','.$key;
                   1731:             } else {
                   1732:                 $$keyp{$id}=$key;
                   1733:             }   
1.210     www      1734: #
                   1735: # Put in order
1.446     bisitz   1736: #
1.480     amueller 1737:             unless ($$keyorder{$key}) {
                   1738:                 $$keyorder{$key}=$keyordercnt;
                   1739:                 $keyordercnt++;
                   1740:             }
1.473     amueller 1741:         }
                   1742: 
                   1743: 
1.480     amueller 1744:         if (!exists($$mapp{$mapid})) {
                   1745:             $$mapp{$id}=
                   1746:             &Apache::lonnet::declutter($resource->enclosing_map_src());
                   1747:             $$mapp{$mapid}=$$mapp{$id};
                   1748:             $$allmaps{$mapid}=$$mapp{$id};
                   1749:             if ($mapid eq '1') {
1.532     raeburn  1750:                 $$maptitles{$mapid}=&mt('Main Content');
1.480     amueller 1751:             } else {
                   1752:                 $$maptitles{$mapid}=&Apache::lonnet::gettitle($$mapp{$id});
                   1753:             }
                   1754:             $$maptitles{$$mapp{$id}}=$$maptitles{$mapid};
1.556     raeburn  1755:             $$symbp{$mapid}=$$mapp{$id}.'___(all)';  # Added in rev. 1.57, but seems not to be used.
                   1756:                                                      # Lines 1038 and 1114 which use $symbp{$mapid}
                   1757:                                                      # are commented out in rev. 1.57
1.473     amueller 1758:         } else {
1.480     amueller 1759:             $$mapp{$id} = $$mapp{$mapid};
1.473     amueller 1760:         }
1.480     amueller 1761:         $$symbp{$id}=&Apache::lonnet::encode_symb($$mapp{$id},$resid,$srcf);
1.63      bowersj2 1762:     }
                   1763: }
                   1764: 
1.208     www      1765: 
1.562   ! damieng  1766: # Tells if a parameter type is a date.
        !          1767: #
        !          1768: # @param {string} type - parameter type
        !          1769: # @returns{boolean} - true if it is a date
1.213     www      1770: sub isdateparm {
                   1771:     my $type=shift;
                   1772:     return (($type=~/^date/) && (!($type eq 'date_interval')));
                   1773: }
                   1774: 
1.562   ! damieng  1775: # Prints the HTML and Javascript to select parameters, with various shortcuts.
        !          1776: # FIXME: remove unused parameters
1.468     amueller 1777: #
1.562   ! damieng  1778: # @param {Apache2::RequestRec} $r - the Apache request (unused)
        !          1779: # @param {hash reference} $allparms - hash parameter name -> parameter title
        !          1780: # @param {array reference} $pscat - list of selected parameter names (unused)
        !          1781: # @param {hash reference} $keyorder - hash parameter key -> appearance rank (unused)
1.208     www      1782: sub parmmenu {
1.211     www      1783:     my ($r,$allparms,$pscat,$keyorder)=@_;
1.208     www      1784:     my $tempkey;
                   1785:     $r->print(<<ENDSCRIPT);
                   1786: <script type="text/javascript">
1.454     bisitz   1787: // <![CDATA[
1.208     www      1788:     function checkall(value, checkName) {
1.453     schualex 1789: 
                   1790:         var li = "_li";
                   1791:         var displayOverview = "";
                   1792:         
                   1793:         if (value == false) {
                   1794:             displayOverview = "none"
                   1795:         }
                   1796: 
1.562   ! damieng  1797:         for (i=0; i<document.forms.parmform.elements.length; i++) {
1.208     www      1798:             ele = document.forms.parmform.elements[i];
                   1799:             if (ele.name == checkName) {
                   1800:                 document.forms.parmform.elements[i].checked=value;
                   1801:             }
                   1802:         }
                   1803:     }
1.210     www      1804: 
                   1805:     function checkthis(thisvalue, checkName) {
1.562   ! damieng  1806:         for (i=0; i<document.forms.parmform.elements.length; i++) {
1.210     www      1807:             ele = document.forms.parmform.elements[i];
                   1808:             if (ele.name == checkName) {
1.562   ! damieng  1809:                 if (ele.value == thisvalue) {
        !          1810:                     document.forms.parmform.elements[i].checked=true;
        !          1811:                 }
1.210     www      1812:             }
                   1813:         }
                   1814:     }
                   1815: 
                   1816:     function checkdates() {
1.562   ! damieng  1817:         checkthis('duedate','pscat');
        !          1818:         checkthis('opendate','pscat');
        !          1819:         checkthis('answerdate','pscat');
1.218     www      1820:     }
                   1821: 
                   1822:     function checkdisset() {
1.562   ! damieng  1823:         checkthis('discussend','pscat');
        !          1824:         checkthis('discusshide','pscat');
        !          1825:         checkthis('discussvote','pscat');
1.218     www      1826:     }
                   1827: 
                   1828:     function checkcontdates() {
1.562   ! damieng  1829:         checkthis('contentopen','pscat');
        !          1830:         checkthis('contentclose','pscat');
1.218     www      1831:     }
1.446     bisitz   1832: 
1.210     www      1833:     function checkvisi() {
1.562   ! damieng  1834:         checkthis('hiddenresource','pscat');
        !          1835:         checkthis('encrypturl','pscat');
        !          1836:         checkthis('problemstatus','pscat');
        !          1837:         checkthis('contentopen','pscat');
        !          1838:         checkthis('opendate','pscat');
1.210     www      1839:     }
                   1840: 
                   1841:     function checkparts() {
1.562   ! damieng  1842:         checkthis('hiddenparts','pscat');
        !          1843:         checkthis('display','pscat');
        !          1844:         checkthis('ordered','pscat');
1.210     www      1845:     }
                   1846: 
                   1847:     function checkstandard() {
                   1848:         checkall(false,'pscat');
1.562   ! damieng  1849:         checkdates();
        !          1850:         checkthis('weight','pscat');
        !          1851:         checkthis('maxtries','pscat');
        !          1852:         checkthis('type','pscat');
        !          1853:         checkthis('problemstatus','pscat');
1.210     www      1854:     }
                   1855: 
1.454     bisitz   1856: // ]]>
1.208     www      1857: </script>
                   1858: ENDSCRIPT
1.453     schualex 1859: 
1.491     bisitz   1860:     $r->print('<hr />');
1.453     schualex 1861:     &shortCuts($r,$allparms,$pscat,$keyorder);
1.491     bisitz   1862:     $r->print('<hr />');
1.453     schualex 1863: }
1.562   ! damieng  1864: 
        !          1865: # Returns parameter categories.
        !          1866: #
        !          1867: # @returns {hash} - category name -> title in English
1.465     amueller 1868: sub categories {
                   1869:     return ('time_settings' => 'Time Settings',
                   1870:     'grading' => 'Grading',
                   1871:     'tries' => 'Tries',
                   1872:     'problem_appearance' => 'Problem Appearance',
                   1873:     'behaviour_of_input_fields' => 'Behaviour of Input Fields',
                   1874:     'hiding' => 'Hiding',
                   1875:     'high_level_randomization' => 'High Level Randomization',
                   1876:     'slots' => 'Slots',
                   1877:     'file_submission' => 'File Submission',
                   1878:     'misc' => 'Miscellaneous' ); 
                   1879: }
                   1880: 
1.562   ! damieng  1881: # Returns the category for each parameter.
        !          1882: #
        !          1883: # @returns {hash} - parameter name -> category name
1.465     amueller 1884: sub lookUpTableParameter {
                   1885:  
                   1886:     return ( 
                   1887:         'opendate' => 'time_settings',
                   1888:         'duedate' => 'time_settings',
                   1889:         'answerdate' => 'time_settings',
                   1890:         'interval' => 'time_settings',
                   1891:         'contentopen' => 'time_settings',
                   1892:         'contentclose' => 'time_settings',
                   1893:         'discussend' => 'time_settings',
1.560     damieng  1894:         'printstartdate' => 'time_settings',
                   1895:         'printenddate' => 'time_settings',
1.465     amueller 1896:         'weight' => 'grading',
                   1897:         'handgrade' => 'grading',
                   1898:         'maxtries' => 'tries',
                   1899:         'hinttries' => 'tries',
1.503     raeburn  1900:         'randomizeontries' => 'tries',
1.465     amueller 1901:         'type' => 'problem_appearance',
                   1902:         'problemstatus' => 'problem_appearance',
                   1903:         'display' => 'problem_appearance',
                   1904:         'ordered' => 'problem_appearance',
                   1905:         'numbubbles' => 'problem_appearance',
                   1906:         'tol' => 'behaviour_of_input_fields',
                   1907:         'sig' => 'behaviour_of_input_fields',
                   1908:         'turnoffunit' => 'behaviour_of_input_fields',
                   1909:         'hiddenresource' => 'hiding',
                   1910:         'hiddenparts' => 'hiding',
                   1911:         'discusshide' => 'hiding',
                   1912:         'buttonshide' => 'hiding',
                   1913:         'turnoffeditor' => 'hiding',
                   1914:         'encrypturl' => 'hiding',
                   1915:         'randomorder' => 'high_level_randomization',
                   1916:         'randompick' => 'high_level_randomization',
                   1917:         'available' => 'slots',
                   1918:         'useslots' => 'slots',
                   1919:         'availablestudent' => 'slots',
                   1920:         'uploadedfiletypes' => 'file_submission',
                   1921:         'maxfilesize' => 'file_submission',
                   1922:         'cssfile' => 'misc',
                   1923:         'mapalias' => 'misc',
                   1924:         'acc' => 'misc',
                   1925:         'maxcollaborators' => 'misc',
                   1926:         'scoreformat' => 'misc',
1.514     raeburn  1927:         'lenient' => 'grading',
1.519     raeburn  1928:         'retrypartial' => 'tries',
1.521     raeburn  1929:         'discussvote'  => 'misc',
1.533     raeburn  1930:         'examcode' => 'high_level_randomization', 
1.465     amueller 1931:     );    
                   1932: }
                   1933: 
1.562   ! damieng  1934: # Adds the given parameter name to an array of arrays listing all parameters for each category.
        !          1935: #
        !          1936: # @param {string} $name - parameter name
        !          1937: # @param {array reference} $catList - array reference category name -> array reference of parameter names
1.465     amueller 1938: sub whatIsMyCategory {
                   1939:     my $name = shift;
                   1940:     my $catList = shift;
                   1941:     my @list;
                   1942:     my %lookUpList = &lookUpTableParameter; #Initilize the lookupList
                   1943:     my $cat = $lookUpList{$name};
                   1944:     if (defined($cat)) {
                   1945:         if (!defined($$catList{$cat})){
                   1946:             push @list, ($name);
                   1947:             $$catList{$cat} = \@list;
                   1948:         } else {
                   1949:             push @{${$catList}{$cat}}, ($name);     
                   1950:         }
                   1951:     } else {
                   1952:         if (!defined($$catList{'misc'})){
                   1953:             push @list, ($name);
                   1954:             $$catList{'misc'} = \@list;
                   1955:         } else {
                   1956:             push @{${$catList}{'misc'}}, ($name);     
                   1957:         }
                   1958:     }        
                   1959: }
                   1960: 
1.562   ! damieng  1961: # Sorts parameter names based on appearance order.
        !          1962: #
        !          1963: # @param {array reference} name - array reference of parameter names
        !          1964: # @param {hash reference} $keyorder - hash parameter key -> appearance rank
        !          1965: # @returns {Array} - array of parameter names
1.465     amueller 1966: sub keysindisplayorderCategory {
                   1967:     my ($name,$keyorder)=@_;
                   1968:     return sort {
1.473     amueller 1969:         $$keyorder{'parameter_0_'.$a} <=> $$keyorder{'parameter_0_'.$b}; 
1.465     amueller 1970:     } ( @{$name});
                   1971: }
                   1972: 
1.562   ! damieng  1973: # Returns a hash category name -> order, starting at 1 (integer)
        !          1974: #
        !          1975: # @returns {hash}
1.467     amueller 1976: sub category_order {
                   1977:     return (
                   1978:         'time_settings' => 1,
                   1979:         'grading' => 2,
                   1980:         'tries' => 3,
                   1981:         'problem_appearance' => 4,
                   1982:         'hiding' => 5,
                   1983:         'behaviour_of_input_fields' => 6,
                   1984:         'high_level_randomization'  => 7,
                   1985:         'slots' => 8,
                   1986:         'file_submission' => 9,
                   1987:         'misc' => 10
                   1988:     );
                   1989: 
                   1990: }
1.453     schualex 1991: 
1.562   ! damieng  1992: # Prints HTML to let the user select parameters, from a list of all parameters organized by category.
        !          1993: #
        !          1994: # @param {Apache2::RequestRec} $r - the Apache request
        !          1995: # @param {hash reference} $allparms - hash parameter name -> parameter title
        !          1996: # @param {array reference} $pscat - list of selected parameter names
        !          1997: # @param {hash reference} $keyorder - hash parameter key -> appearance rank
1.453     schualex 1998: sub parmboxes {
                   1999:     my ($r,$allparms,$pscat,$keyorder)=@_;
1.548     raeburn  2000:     my %categories = &categories();
1.467     amueller 2001:     my %category_order = &category_order();
1.465     amueller 2002:     my %categoryList = (
                   2003:         'time_settings' => [],
                   2004:         'grading' => [],
                   2005:         'tries' => [],
                   2006:         'problem_appearance' => [],
                   2007:         'behaviour_of_input_fields' => [],
                   2008:         'hiding' => [],
                   2009:         'high_level_randomization' => [],
                   2010:         'slots' => [],
                   2011:         'file_submission' => [],
                   2012:         'misc' => [],
1.489     bisitz   2013:     );
1.510     www      2014: 
1.548     raeburn  2015:     foreach my $tempparameter (keys(%$allparms)) {
1.465     amueller 2016:         &whatIsMyCategory($tempparameter, \%categoryList);
                   2017:     }
1.453     schualex 2018:     #part to print the parm-list
1.536     raeburn  2019:     foreach my $key (sort { $category_order{$a} <=> $category_order{$b} } keys(%categoryList)) {
                   2020:         next if (@{$categoryList{$key}} == 0);
                   2021:         next if ($key eq '');
                   2022:         $r->print('<div class="LC_Box LC_400Box">'
                   2023:                  .'<h4 class="LC_hcell">'.&mt($categories{$key}).'</h4>'."\n");
                   2024:         foreach my $tempkey (&keysindisplayorderCategory($categoryList{$key},$keyorder)) {
                   2025:             $r->print('<span class="LC_nobreak">'
                   2026:                      .'<label><input type="checkbox" name="pscat" '
                   2027:                      .'value="'.$tempkey.'" ');
                   2028:             if ($$pscat[0] eq "all" || grep $_ eq $tempkey, @{$pscat}) {
                   2029:                 $r->print( ' checked="checked"');
                   2030:             }
                   2031:             $r->print(' />'.($$allparms{$tempkey}=~/\S/ ? $$allparms{$tempkey}
1.465     amueller 2032:                                                       : $tempkey)
1.536     raeburn  2033:                      .'</label></span><br />'."\n");
1.465     amueller 2034:         }
1.536     raeburn  2035:         $r->print('</div>');
1.465     amueller 2036:     }
1.536     raeburn  2037:     $r->print("\n");
1.453     schualex 2038: }
1.562   ! damieng  2039: 
        !          2040: # Prints HTML with shortcuts to select groups of parameters in one click, or deselect all.
        !          2041: # FIXME: remove unused parameters
1.468     amueller 2042: #
1.562   ! damieng  2043: # @param {Apache2::RequestRec} $r - the Apache request
        !          2044: # @param {hash reference} $allparms - hash parameter name -> parameter title (unused)
        !          2045: # @param {array reference} $pscat - list of selected parameter names (unused)
        !          2046: # @param {hash reference} $keyorder - hash parameter key -> appearance rank (unused)
1.453     schualex 2047: sub shortCuts {
                   2048:     my ($r,$allparms,$pscat,$keyorder)=@_;
                   2049: 
1.491     bisitz   2050:     # Parameter Selection
                   2051:     $r->print(
                   2052:         &Apache::lonhtmlcommon::start_funclist(&mt('Parameter Selection'))
                   2053:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2054:             '<a href="javascript:checkall(true, \'pscat\')">'.&mt('Select All').'</a>')
                   2055:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2056:             '<a href="javascript:checkstandard()">'.&mt('Select Common Only').'</a>')
                   2057:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2058:             '<a href="javascript:checkall(false, \'pscat\')">'.&mt('Unselect All').'</a>')
                   2059:        .&Apache::lonhtmlcommon::end_funclist()
                   2060:     );
                   2061: 
                   2062:     # Add Selection for...
                   2063:     $r->print(
                   2064:         &Apache::lonhtmlcommon::start_funclist(&mt('Add Selection for...'))
                   2065:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2066:             '<a href="javascript:checkdates()">'.&mt('Problem Dates').'</a>')
                   2067:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2068:             '<a href="javascript:checkcontdates()">'.&mt('Content Dates').'</a>')
                   2069:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2070:             '<a href="javascript:checkdisset()">'.&mt('Discussion Settings').'</a>')
                   2071:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2072:             '<a href="javascript:checkvisi()">'.&mt('Visibilities').'</a>')
                   2073:        .&Apache::lonhtmlcommon::add_item_funclist(
                   2074:             '<a href="javascript:checkparts()">'.&mt('Part Parameters').'</a>')
                   2075:        .&Apache::lonhtmlcommon::end_funclist()
                   2076:     );
1.208     www      2077: }
                   2078: 
1.562   ! damieng  2079: # Prints HTML to select parts to view (except for the title).
        !          2080: # Used by table and overview modes.
        !          2081: #
        !          2082: # @param {Apache2::RequestRec} $r - the Apache request
        !          2083: # @param {hash reference} $allparts - hash parameter part -> part title
        !          2084: # @param {array reference} $psprt - list of selected parameter parts
1.209     www      2085: sub partmenu {
1.446     bisitz   2086:     my ($r,$allparts,$psprt)=@_;
1.523     raeburn  2087:     my $selsize = 1+scalar(keys(%{$allparts}));
                   2088:     if ($selsize > 8) {
                   2089:         $selsize = 8;
                   2090:     }
1.446     bisitz   2091: 
1.523     raeburn  2092:     $r->print('<select multiple="multiple" name="psprt" size="'.$selsize.'">');
1.208     www      2093:     $r->print('<option value="all"');
1.562   ! damieng  2094:     $r->print(' selected="selected"') unless (@{$psprt}); # useless, the array is never empty
1.208     www      2095:     $r->print('>'.&mt('All Parts').'</option>');
                   2096:     my %temphash=();
                   2097:     foreach (@{$psprt}) { $temphash{$_}=1; }
1.234     albertel 2098:     foreach my $tempkey (sort {
1.560     damieng  2099:                 if ($a==$b) { return ($a cmp $b) } else { return ($a <=> $b); }
                   2100:             } keys(%{$allparts})) {
                   2101:         unless ($tempkey =~ /\./) {
                   2102:             $r->print('<option value="'.$tempkey.'"');
                   2103:             if ($$psprt[0] eq "all" ||  $temphash{$tempkey}) {
                   2104:                 $r->print(' selected="selected"');
                   2105:             }
                   2106:             $r->print('>'.$$allparts{$tempkey}.'</option>');
1.473     amueller 2107:         }
1.208     www      2108:     }
1.446     bisitz   2109:     $r->print('</select>');
1.209     www      2110: }
                   2111: 
1.562   ! damieng  2112: # Prints HTML to select a user and/or a group.
        !          2113: # Used by table mode.
        !          2114: #
        !          2115: # @param {Apache2::RequestRec} $r - the Apache request
        !          2116: # @param {string} $uname - selected user name
        !          2117: # @param {string} $id - selected Student/Employee ID
        !          2118: # @param {string} $udom - selected user domain
        !          2119: # @param {string} $csec - selected section name
        !          2120: # @param {string} $cgroup - selected group name
        !          2121: # @param {string} $parmlev - parameter level (Resource:'full', Map:'map', Course:'general')
        !          2122: # @param {array reference} $usersgroups - list of groups the user belongs to, if any
        !          2123: # @param {string} $pssymb - resource symb (when a single resource is selected)
1.209     www      2124: sub usermenu {
1.553     raeburn  2125:     my ($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,$usersgroups,$pssymb)=@_;
1.209     www      2126:     my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '.
                   2127:         &Apache::loncommon::selectstudent_link('parmform','uname','udom');
                   2128:     my $selscript=&Apache::loncommon::studentbrowser_javascript();
1.412     bisitz   2129: 
1.209     www      2130:     my $sections='';
1.300     albertel 2131:     my %sectionhash = &Apache::loncommon::get_sections();
                   2132: 
1.269     raeburn  2133:     my $groups;
1.553     raeburn  2134:     my %grouphash;
                   2135:     if (($pssymb) || &Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
                   2136:         %grouphash = &Apache::longroup::coursegroups();
                   2137:     } elsif ($env{'request.course.groups'} ne '') {
                   2138:         map { $grouphash{$_} = 1; } split(/,/,$env{'request.course.groups'});
                   2139:     }
1.299     albertel 2140: 
1.412     bisitz   2141:     my $g_s_header='';
                   2142:     my $g_s_footer='';
1.446     bisitz   2143: 
1.552     raeburn  2144:     my $currsec = $env{'request.course.sec'};
                   2145:     if ($currsec) {
                   2146:         $sections=&mt('Section:').' '.$currsec;
                   2147:         if (%grouphash) {
                   2148:             $sections .= ';'.('&nbsp;' x2);
                   2149:         }
                   2150:     } elsif (%sectionhash && $currsec eq '') {
1.412     bisitz   2151:         $sections=&mt('Section:').' <select name="csec"';
1.299     albertel 2152:         if (%grouphash && $parmlev ne 'full') {
1.269     raeburn  2153:             $sections .= qq| onchange="group_or_section('csec')" |;
                   2154:         }
                   2155:         $sections .= '>';
1.548     raeburn  2156:     foreach my $section ('',sort(keys(%sectionhash))) {
1.473     amueller 2157:         $sections.='<option value="'.$section.'" '.
                   2158:         ($section eq $csec?'selected="selected"':'').'>'.$section.
1.275     raeburn  2159:                                                               '</option>';
1.209     www      2160:         }
                   2161:         $sections.='</select>';
1.269     raeburn  2162:     }
1.412     bisitz   2163: 
1.552     raeburn  2164:     if (%sectionhash && %grouphash && $parmlev ne 'full' && $currsec eq '') {
1.412     bisitz   2165:         $sections .= '&nbsp;'.&mt('or').'&nbsp;';
1.269     raeburn  2166:         $sections .= qq|
                   2167: <script type="text/javascript">
1.454     bisitz   2168: // <![CDATA[
1.269     raeburn  2169: function group_or_section(caller) {
                   2170:    if (caller == "cgroup") {
                   2171:        if (document.parmform.cgroup.selectedIndex != 0) {
                   2172:            document.parmform.csec.selectedIndex = 0;
                   2173:        }
                   2174:    } else {
                   2175:        if (document.parmform.csec.selectedIndex != 0) {
                   2176:            document.parmform.cgroup.selectedIndex = 0;
                   2177:        }
                   2178:    }
                   2179: }
1.454     bisitz   2180: // ]]>
1.269     raeburn  2181: </script>
                   2182: |;
1.554     raeburn  2183:     } else {
1.269     raeburn  2184:         $sections .= qq|
                   2185: <script type="text/javascript">
1.454     bisitz   2186: // <![CDATA[
1.269     raeburn  2187: function group_or_section(caller) {
                   2188:     return;
                   2189: }
1.454     bisitz   2190: // ]]>
1.269     raeburn  2191: </script>
                   2192: |;
1.446     bisitz   2193:     }
1.299     albertel 2194: 
                   2195:     if (%grouphash) {
1.412     bisitz   2196:         $groups=&mt('Group:').' <select name="cgroup"';
1.552     raeburn  2197:         if (%sectionhash && $env{'form.action'} eq 'settable' && $currsec eq '') {
1.269     raeburn  2198:             $groups .= qq| onchange="group_or_section('cgroup')" |;
                   2199:         }
                   2200:         $groups .= '>';
1.548     raeburn  2201:         foreach my $grp ('',sort(keys(%grouphash))) {
1.275     raeburn  2202:             $groups.='<option value="'.$grp.'" ';
                   2203:             if ($grp eq $cgroup) {
                   2204:                 unless ((defined($uname)) && ($grp eq '')) {
                   2205:                     $groups .=  'selected="selected" ';
                   2206:                 }
                   2207:             } elsif (!defined($cgroup)) {
                   2208:                 if (@{$usersgroups} == 1) {
                   2209:                     if ($grp eq $$usersgroups[0]) {
                   2210:                         $groups .=  'selected="selected" ';
                   2211:                     }
                   2212:                 }
                   2213:             }
                   2214:             $groups .= '>'.$grp.'</option>';
1.269     raeburn  2215:         }
                   2216:         $groups.='</select>';
                   2217:     }
1.412     bisitz   2218: 
1.445     neumanie 2219:     if (%sectionhash || %grouphash) {
1.446     bisitz   2220:         $r->print(&Apache::lonhtmlcommon::row_title(&mt('Group/Section')));
                   2221:         $r->print($sections.$groups);
1.448     bisitz   2222:         $r->print(&Apache::lonhtmlcommon::row_closure());
1.554     raeburn  2223:     } else {
                   2224:         $r->print($sections); 
1.445     neumanie 2225:     }
1.446     bisitz   2226: 
                   2227:     $r->print(&Apache::lonhtmlcommon::row_title(&mt('User')));
1.443     neumanie 2228:     $r->print(&mt('For User [_1] or Student/Employee ID [_2] at Domain [_3]'
1.412     bisitz   2229:                  ,'<input type="text" value="'.$uname.'" size="12" name="uname" />'
                   2230:                  ,'<input type="text" value="'.$id.'" size="12" name="id" /> '
1.446     bisitz   2231:                  ,$chooseopt));
1.209     www      2232: }
                   2233: 
1.562   ! damieng  2234: # Prints HTML to select parameters from a list of all parameters.
        !          2235: # Uses parmmenu and parmboxes.
        !          2236: # Used by table and overview modes.
1.468     amueller 2237: #
1.562   ! damieng  2238: # @param {Apache2::RequestRec} $r - the Apache request
        !          2239: # @param {hash reference} $allparms - hash parameter name -> parameter title
        !          2240: # @param {array reference} $pscat - list of selected parameter names
        !          2241: # @param {array reference} $psprt - list of selected parameter parts (unused)
        !          2242: # @param {hash reference} $keyorder - hash parameter key -> appearance rank
        !          2243: # @param {string} [$divid] - name used to give an id to the HTML element for the scroll box
1.209     www      2244: sub displaymenu {
1.536     raeburn  2245:     my ($r,$allparms,$pscat,$psprt,$keyorder,$divid)=@_;
1.510     www      2246: 
1.445     neumanie 2247:     $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.510     www      2248:     $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parameters to View')));
                   2249: 
1.562   ! damieng  2250:     &parmmenu($r,$allparms,$pscat,$keyorder); # only $allparms is used by parmmenu
1.536     raeburn  2251:     $r->print(&Apache::loncommon::start_scrollbox('480px','440px','200px',$divid));
1.510     www      2252:     &parmboxes($r,$allparms,$pscat,$keyorder);
                   2253:     $r->print(&Apache::loncommon::end_scrollbox());
                   2254: 
                   2255:     $r->print(&Apache::lonhtmlcommon::row_closure(1));
1.453     schualex 2256:     $r->print(&Apache::lonhtmlcommon::end_pick_box());
1.510     www      2257:  
1.209     www      2258: }
                   2259: 
1.562   ! damieng  2260: # Prints HTML to select a map.
        !          2261: # Used by table mode and overview mode.
        !          2262: #
        !          2263: # @param {Apache2::RequestRec} $r - the Apache request
        !          2264: # @param {hash reference} $allmaps - hash map id -> map src
        !          2265: # @param {string} $pschp - selected map id, or 'all'
        !          2266: # @param {hash reference} $maptitles - hash map id or src -> map title
        !          2267: # @param {hash reference} $symbp - hash map id or resource id -> map src.'___(all)' for a map or resource symb for a resource
1.445     neumanie 2268: sub mapmenu {
1.499     raeburn  2269:     my ($r,$allmaps,$pschp,$maptitles,$symbp)=@_;
1.468     amueller 2270:     my %allmaps_inverted = reverse %$allmaps;
1.461     neumanie 2271:     my $navmap = Apache::lonnavmaps::navmap->new();
                   2272:     my $tree=[];
                   2273:     my $treeinfo={};
                   2274:     if (defined($navmap)) {
1.499     raeburn  2275:         my $it=$navmap->getIterator(undef,undef,undef,1,1,undef);
1.461     neumanie 2276:         my $curRes;
                   2277:         my $depth = 0;
1.468     amueller 2278:         my %parent = ();
                   2279:         my $startcount = 5;
                   2280:         my $lastcontainer = $startcount;
                   2281: # preparing what is to show ...
1.461     neumanie 2282:         while ($curRes = $it->next()) {
                   2283:             if ($curRes == $it->BEGIN_MAP()) {
                   2284:                 $depth++;
1.468     amueller 2285:                 $parent{$depth}= $lastcontainer;
1.461     neumanie 2286:             }
                   2287:             if ($curRes == $it->END_MAP()) {
                   2288:                 $depth--;
1.468     amueller 2289:                 $lastcontainer = $parent{$depth};
1.461     neumanie 2290:             }
                   2291:             if (ref($curRes)) {
1.468     amueller 2292:                 my $symb = $curRes->symb();
                   2293:                 my $ressymb = $symb;
1.461     neumanie 2294:                 if (($curRes->is_sequence()) || ($curRes->is_page())) {
                   2295:                     my $type = 'sequence';
                   2296:                     if ($curRes->is_page()) {
                   2297:                         $type = 'page';
                   2298:                     }
                   2299:                     my $id= $curRes->id();
1.468     amueller 2300:                     my $srcf = $curRes->src();
                   2301:                     my $resource_name = &Apache::lonnet::gettitle($srcf);
                   2302:                     if(!exists($treeinfo->{$id})) {
                   2303:                         push(@$tree,$id);
1.473     amueller 2304:                         my $enclosing_map_folder = &Apache::lonnet::declutter($curRes->enclosing_map_src());        
1.468     amueller 2305:                         $treeinfo->{$id} = {
1.461     neumanie 2306:                                     depth => $depth,
                   2307:                                     type  => $type,
1.468     amueller 2308:                                     name  => $resource_name,
                   2309:                                     enclosing_map_folder => $enclosing_map_folder,
1.461     neumanie 2310:                                     };
1.462     neumanie 2311:                     }
1.461     neumanie 2312:                 }
                   2313:             }
                   2314:         }
1.462     neumanie 2315:     }
1.473     amueller 2316: # Show it ...    
1.484     amueller 2317:     $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Enclosing Map or Folder'),'','',' id="mapmenu"'));
1.461     neumanie 2318:     if ((ref($tree) eq 'ARRAY') && (ref($treeinfo) eq 'HASH')) {
                   2319:         my $icon = '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" />';
1.497     bisitz   2320:         my $whitespace =
                   2321:             '<img src="'
                   2322:            .&Apache::loncommon::lonhttpdurl('/adm/lonIcons/whitespace_21.gif')
                   2323:            .'" alt="" />';
                   2324: 
1.498     bisitz   2325:         # Info about selectable folders/maps
                   2326:         $r->print(
                   2327:             '<div class="LC_info">'
1.508     www      2328:            .&mt('You can only select maps and folders which have modifiable settings.')
                   2329:            .' '.&Apache::loncommon::help_open_topic('Parameter_Set_Folder') 
1.498     bisitz   2330:            .'</div>'
                   2331:         );
                   2332: 
1.536     raeburn  2333:         $r->print(&Apache::loncommon::start_scrollbox('700px','680px','400px','mapmenuscroll'));
1.523     raeburn  2334:         $r->print(&Apache::loncommon::start_data_table(undef,'mapmenuinner'));
1.497     bisitz   2335: 
1.498     bisitz   2336:         # Display row: "All Maps or Folders"
                   2337:         $r->print(
1.523     raeburn  2338:             &Apache::loncommon::start_data_table_row(undef,'picklevel')
1.498     bisitz   2339:            .'<td>'
                   2340:            .'<label>'
                   2341:            .'<input type="radio" name="pschp"'
1.497     bisitz   2342:         );
                   2343:         $r->print(' checked="checked"') if ($pschp eq 'all' || !$pschp);
1.498     bisitz   2344:         $r->print(
                   2345:             ' value="all" />&nbsp;'.$icon.'&nbsp;'
                   2346:            .&mt('All Maps or Folders')
                   2347:            .'</label>'
                   2348:            .'<hr /></td>'
                   2349:            .&Apache::loncommon::end_data_table_row()
1.463     bisitz   2350:         );
1.497     bisitz   2351: 
1.532     raeburn  2352:         # Display row: "Main Content"
1.468     amueller 2353:         if (exists($$allmaps{1})) {
1.498     bisitz   2354:             $r->print(
                   2355:                 &Apache::loncommon::start_data_table_row()
                   2356:                .'<td>'
                   2357:                .'<label>'
                   2358:                .'<input type="radio" name="pschp" value="1"'
1.468     amueller 2359:             );
1.497     bisitz   2360:             $r->print(' checked="checked"') if ($pschp eq '1');
1.498     bisitz   2361:             $r->print(
                   2362:                 '/>&nbsp;'.$icon.'&nbsp;'
                   2363:                .$$maptitles{1}
                   2364:                .($$allmaps{1} !~/^uploaded/?' ['.$$allmaps{1}.']':'')
                   2365:                .'</label>'
                   2366:                .'</td>'
                   2367:                .&Apache::loncommon::end_data_table_row()
1.468     amueller 2368:             );
                   2369:         }
1.497     bisitz   2370: 
                   2371:         # Display rows for all course maps and folders
1.468     amueller 2372:         foreach my $id (@{$tree}) {
                   2373:             my ($mapid,$resid)=split(/\./,$id);
1.464     bisitz   2374:             # Indentation
1.468     amueller 2375:             my $depth = $treeinfo->{$id}->{'depth'};
1.464     bisitz   2376:             my $indent;
                   2377:             for (my $i = 0; $i < $depth; $i++) {
                   2378:                 $indent.= $whitespace;
                   2379:             }
1.461     neumanie 2380:             $icon =  '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" />';
1.468     amueller 2381:             if ($treeinfo->{$id}->{'type'} eq 'page') {
1.461     neumanie 2382:                 $icon = '<img src="/adm/lonIcons/navmap.page.open.gif" alt="" />';
                   2383:             }
1.468     amueller 2384:             my $symb_name = $$symbp{$id};
                   2385:             my ($front, $tail) = split (/___${resid}___/, $symb_name);
                   2386:             $symb_name = $tail;
1.498     bisitz   2387:             $r->print(
                   2388:                 &Apache::loncommon::start_data_table_row()
                   2389:                .'<td>'
                   2390:                .'<label>'
1.463     bisitz   2391:             );
1.498     bisitz   2392:             # Only offer radio button for folders/maps which can be parameterized
                   2393:             if ($allmaps_inverted{$symb_name}) {
                   2394:                 $r->print(
                   2395:                     '<input type ="radio" name="pschp"'
                   2396:                    .' value="'.$allmaps_inverted{$symb_name}.'"'
                   2397:                 );
                   2398:                 $r->print(' checked="checked"') if ($allmaps_inverted{$symb_name} eq $pschp);
                   2399:                 $r->print('/>');
                   2400:             } else {
                   2401:                 $r->print($whitespace);
1.461     neumanie 2402:             }
1.498     bisitz   2403:             $r->print(
                   2404:                 $indent.$icon.'&nbsp;'
                   2405:                .$treeinfo->{$id}->{name}
                   2406:                .($$allmaps{$mapid}!~/^uploaded/?' ['.$$allmaps{$mapid}.']':'')
                   2407:                .'</label>'
                   2408:                .'</td>'
                   2409:                .&Apache::loncommon::end_data_table_row()
1.463     bisitz   2410:             );
1.461     neumanie 2411:         }
1.497     bisitz   2412: 
1.523     raeburn  2413:         $r->print(&Apache::loncommon::end_data_table().
                   2414:                   '<br style="line-height:2px;" />'.
                   2415:                   &Apache::loncommon::end_scrollbox());
1.209     www      2416:     }
                   2417: }
                   2418: 
1.482     amueller 2419: # Build up the select Box to choose if your parameter specification should work for the resource, map/folder or the course level
                   2420: # 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      2421: sub levelmenu {
1.446     bisitz   2422:     my ($r,$alllevs,$parmlev)=@_;
                   2423: 
1.548     raeburn  2424:     $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parameter Level').
                   2425:                                                 &Apache::loncommon::help_open_topic('Course_Parameter_Levels')));
1.474     amueller 2426:     $r->print('<select id="parmlev" name="parmlev" onchange="showHide_courseContent()">');
1.548     raeburn  2427:     foreach my $lev (reverse(sort(keys(%{$alllevs})))) {
                   2428:         $r->print('<option value="'.$$alllevs{$lev}.'"');
                   2429:         if ($parmlev eq $$alllevs{$lev}) {
                   2430:             $r->print(' selected="selected"');
                   2431:         }
                   2432:         $r->print('>'.&mt($lev).'</option>');
1.208     www      2433:     }
1.446     bisitz   2434:     $r->print("</select>");
1.208     www      2435: }
                   2436: 
1.211     www      2437: 
                   2438: sub sectionmenu {
1.553     raeburn  2439:     my ($selectedsections)=@_;
1.300     albertel 2440:     my %sectionhash = &Apache::loncommon::get_sections();
1.553     raeburn  2441:     return '' if (!%sectionhash);
1.300     albertel 2442: 
1.552     raeburn  2443:     my (@possibles,$disabled);
                   2444:     if ($env{'request.course.sec'} ne '') {
                   2445:         @possibles = ($env{'request.course.sec'});
                   2446:         $selectedsections = [$env{'request.course.sec'}];
                   2447:         $disabled = ' disabled="disabled"';
                   2448:     } else {
                   2449:         @possibles = ('all',sort(keys(%sectionhash)));
                   2450:     }
1.553     raeburn  2451:     my $output = '<select name="Section" multiple="multiple" size="8"'.$disabled.'>';
1.552     raeburn  2452:     foreach my $s (@possibles) {
1.553     raeburn  2453:         $output .= '    <option value="'.$s.'"';
                   2454:         if ((@{$selectedsections}) && (grep(/^\Q$s\E$/,@{$selectedsections}))) {  
                   2455:             $output .= ' selected="selected"';
1.473     amueller 2456:         }
1.553     raeburn  2457:         $output .= '>'."$s</option>\n";
1.300     albertel 2458:     }
1.553     raeburn  2459:     $output .= "</select>\n";
                   2460:     return $output;
1.269     raeburn  2461: }
                   2462: 
                   2463: sub groupmenu {
1.553     raeburn  2464:     my ($selectedgroups)=@_;
                   2465:     my %grouphash;
                   2466:     if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
                   2467:         %grouphash = &Apache::longroup::coursegroups();
                   2468:     } elsif ($env{'request.course.groups'} ne '') {
                   2469:          map { $grouphash{$_} = 1; } split(/,/,$env{'request.course.groups'});
                   2470:     }
                   2471:     return '' if (!%grouphash);
1.299     albertel 2472: 
1.553     raeburn  2473:     my $output = '<select name="Group" multiple="multiple" size="8">';
1.299     albertel 2474:     foreach my $group (sort(keys(%grouphash))) {
1.553     raeburn  2475:         $output .= '    <option value="'.$group.'"';
                   2476:         if ((@{$selectedgroups}) && (grep(/^\Q$group\E$/,\@{$selectedgroups}))) {
                   2477:             $output .=  ' selected="selected"';
1.473     amueller 2478:         }
1.553     raeburn  2479:         $output .= '>'."$group</option>\n";
1.211     www      2480:     }
1.553     raeburn  2481:     $output .= "</select>\n";
                   2482:     return $output;
1.211     www      2483: }
                   2484: 
1.210     www      2485: sub keysplit {
                   2486:     my $keyp=shift;
                   2487:     return (split(/\,/,$keyp));
                   2488: }
                   2489: 
                   2490: sub keysinorder {
                   2491:     my ($name,$keyorder)=@_;
                   2492:     return sort {
1.560     damieng  2493:         $$keyorder{$a} <=> $$keyorder{$b};
1.548     raeburn  2494:     } (keys(%{$name}));
1.210     www      2495: }
                   2496: 
1.236     albertel 2497: sub keysinorder_bytype {
                   2498:     my ($name,$keyorder)=@_;
                   2499:     return sort {
1.560     damieng  2500:         my $ta=(split('_',$a))[-1];
                   2501:         my $tb=(split('_',$b))[-1];
                   2502:         if ($$keyorder{'parameter_0_'.$ta} == $$keyorder{'parameter_0_'.$tb}) {
                   2503:             return ($a cmp $b);
                   2504:         }
                   2505:         $$keyorder{'parameter_0_'.$ta} <=> $$keyorder{'parameter_0_'.$tb};
1.548     raeburn  2506:     } (keys(%{$name}));
1.236     albertel 2507: }
                   2508: 
1.211     www      2509: sub keysindisplayorder {
                   2510:     my ($name,$keyorder)=@_;
                   2511:     return sort {
1.560     damieng  2512:         $$keyorder{'parameter_0_'.$a} <=> $$keyorder{'parameter_0_'.$b};
1.548     raeburn  2513:     } (keys(%{$name}));
1.211     www      2514: }
                   2515: 
1.214     www      2516: sub sortmenu {
                   2517:     my ($r,$sortorder)=@_;
1.236     albertel 2518:     $r->print('<br /><label><input type="radio" name="sortorder" value="realmstudent"');
1.214     www      2519:     if ($sortorder eq 'realmstudent') {
1.422     bisitz   2520:        $r->print(' checked="checked"');
1.214     www      2521:     }
                   2522:     $r->print(' />'.&mt('Sort by realm first, then student (group/section)'));
1.236     albertel 2523:     $r->print('</label><br /><label><input type="radio" name="sortorder" value="studentrealm"');
1.214     www      2524:     if ($sortorder eq 'studentrealm') {
1.422     bisitz   2525:        $r->print(' checked="checked"');
1.214     www      2526:     }
1.236     albertel 2527:     $r->print(' />'.&mt('Sort by student (group/section) first, then realm').
1.473     amueller 2528:           '</label>');
1.214     www      2529: }
                   2530: 
1.211     www      2531: sub standardkeyorder {
                   2532:     return ('parameter_0_opendate' => 1,
1.473     amueller 2533:         'parameter_0_duedate' => 2,
                   2534:         'parameter_0_answerdate' => 3,
                   2535:         'parameter_0_interval' => 4,
                   2536:         'parameter_0_weight' => 5,
                   2537:         'parameter_0_maxtries' => 6,
                   2538:         'parameter_0_hinttries' => 7,
                   2539:         'parameter_0_contentopen' => 8,
                   2540:         'parameter_0_contentclose' => 9,
                   2541:         'parameter_0_type' => 10,
                   2542:         'parameter_0_problemstatus' => 11,
                   2543:         'parameter_0_hiddenresource' => 12,
                   2544:         'parameter_0_hiddenparts' => 13,
                   2545:         'parameter_0_display' => 14,
                   2546:         'parameter_0_ordered' => 15,
                   2547:         'parameter_0_tol' => 16,
                   2548:         'parameter_0_sig' => 17,
                   2549:         'parameter_0_turnoffunit' => 18,
1.521     raeburn  2550:         'parameter_0_discussend' => 19,
                   2551:         'parameter_0_discusshide' => 20,
                   2552:         'parameter_0_discussvote' => 21,
1.560     damieng  2553:         'parameter_0_printstartdate'  =>  22,
                   2554:         'parameter_0_printenddate' =>  23);
1.211     www      2555: }
                   2556: 
1.59      matthew  2557: 
1.560     damieng  2558: # Table mode UI.
1.30      www      2559: sub assessparms {
1.1       www      2560: 
1.43      albertel 2561:     my $r=shift;
1.201     www      2562: 
1.512     foxr     2563: 
                   2564: # -------------------------------------------------------- Variable declaration
1.201     www      2565:     my @ids=();
                   2566:     my %symbp=();
                   2567:     my %mapp=();
                   2568:     my %typep=();
                   2569:     my %keyp=();
                   2570:     my %uris=();
                   2571:     my %maptitles=();
1.129     www      2572:     my %allmaps=();
                   2573:     my %alllevs=();
1.57      albertel 2574: 
1.187     www      2575:     my $uname;
                   2576:     my $udom;
                   2577:     my $uhome;
                   2578:     my $csec;
1.269     raeburn  2579:     my $cgroup;
1.275     raeburn  2580:     my @usersgroups = ();
1.446     bisitz   2581: 
1.190     albertel 2582:     my $coursename=$env{'course.'.$env{'request.course.id'}.'.description'};
1.187     www      2583: 
1.57      albertel 2584:     $alllevs{'Resource Level'}='full';
1.215     www      2585:     $alllevs{'Map/Folder Level'}='map';
1.57      albertel 2586:     $alllevs{'Course Level'}='general';
                   2587: 
                   2588:     my %allparms;
                   2589:     my %allparts;
1.512     foxr     2590: # ------------------------------------------------------------------------------
                   2591: 
1.210     www      2592: #
                   2593: # Order in which these parameters will be displayed
                   2594: #
1.211     www      2595:     my %keyorder=&standardkeyorder();
                   2596: 
1.512     foxr     2597: #    @ids=();
                   2598: #    %symbp=();       # These seem defined above already.
                   2599: #    %typep=();
1.43      albertel 2600: 
                   2601:     my $message='';
                   2602: 
1.190     albertel 2603:     $csec=$env{'form.csec'};
1.552     raeburn  2604:     if ($env{'request.course.sec'} ne '') {
                   2605:         $csec = $env{'request.course.sec'};    
                   2606:     }
                   2607: 
1.553     raeburn  2608: # Check group privs.
1.269     raeburn  2609:     $cgroup=$env{'form.cgroup'};
1.553     raeburn  2610:     my $noeditgrp; 
                   2611:     if ($cgroup ne '') {
                   2612:         unless (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
                   2613:             if (($env{'request.course.groups'} eq '') || 
                   2614:                 (!grep(/^\Q$cgroup\E$/,split(/,/,$env{'request.course.groups'})))) {
                   2615:                 $noeditgrp = 1;
                   2616:             }
                   2617:         }
                   2618:     }
1.188     www      2619: 
1.190     albertel 2620:     if      ($udom=$env{'form.udom'}) {
                   2621:     } elsif ($udom=$env{'request.role.domain'}) {
                   2622:     } elsif ($udom=$env{'user.domain'}) {
1.172     albertel 2623:     } else {
1.473     amueller 2624:         $udom=$r->dir_config('lonDefDomain');
1.172     albertel 2625:     }
1.468     amueller 2626:     
1.43      albertel 2627: 
1.134     albertel 2628:     my @pscat=&Apache::loncommon::get_env_multiple('form.pscat');
1.190     albertel 2629:     my $pschp=$env{'form.pschp'};
1.506     www      2630: 
                   2631: 
1.134     albertel 2632:     my @psprt=&Apache::loncommon::get_env_multiple('form.psprt');
1.516     www      2633:     if (!@psprt) { $psprt[0]='all'; }
1.506     www      2634:     if (($env{'form.part'}) && ($psprt[0] ne 'all')) { $psprt[0]=$env{'form.part'}; }
1.57      albertel 2635: 
1.43      albertel 2636:     my $pssymb='';
1.57      albertel 2637:     my $parmlev='';
1.446     bisitz   2638: 
1.190     albertel 2639:     unless ($env{'form.parmlev'}) {
1.57      albertel 2640:         $parmlev = 'map';
                   2641:     } else {
1.190     albertel 2642:         $parmlev = $env{'form.parmlev'};
1.57      albertel 2643:     }
1.26      www      2644: 
1.29      www      2645: # ----------------------------------------------- Was this started from grades?
                   2646: 
1.560     damieng  2647:     if (($env{'form.command'} eq 'set') && ($env{'form.url'}) &&
                   2648:             (!$env{'form.dis'})) {
1.473     amueller 2649:         my $url=$env{'form.url'};
                   2650:         $url=~s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
                   2651:         $pssymb=&Apache::lonnet::symbread($url);
                   2652:         if (!@pscat) { @pscat=('all'); }
                   2653:         $pschp='';
1.57      albertel 2654:         $parmlev = 'full';
1.190     albertel 2655:     } elsif ($env{'form.symb'}) {
1.473     amueller 2656:         $pssymb=$env{'form.symb'};
                   2657:         if (!@pscat) { @pscat=('all'); }
                   2658:         $pschp='';
1.57      albertel 2659:         $parmlev = 'full';
1.43      albertel 2660:     } else {
1.473     amueller 2661:         $env{'form.url'}='';
1.43      albertel 2662:     }
                   2663: 
1.190     albertel 2664:     my $id=$env{'form.id'};
1.43      albertel 2665:     if (($id) && ($udom)) {
1.555     raeburn  2666:         $uname=(&Apache::lonnet::idget($udom,[$id],'ids'))[1];
1.473     amueller 2667:         if ($uname) {
                   2668:             $id='';
                   2669:         } else {
                   2670:             $message=
1.540     bisitz   2671:                 '<p class="LC_warning">'.
                   2672:                 &mt('Unknown ID [_1] at domain [_2]',
                   2673:                     "'".$id."'","'".$udom."'").
                   2674:                 '</p>';
1.473     amueller 2675:         }
1.43      albertel 2676:     } else {
1.473     amueller 2677:         $uname=$env{'form.uname'};
1.43      albertel 2678:     }
                   2679:     unless ($udom) { $uname=''; }
                   2680:     $uhome='';
                   2681:     if ($uname) {
1.473     amueller 2682:         $uhome=&Apache::lonnet::homeserver($uname,$udom);
1.43      albertel 2683:         if ($uhome eq 'no_host') {
1.473     amueller 2684:             $message=
1.540     bisitz   2685:                 '<p class="LC_warning">'.
                   2686:                 &mt('Unknown user [_1] at domain [_2]',
                   2687:                     "'".$uname."'","'".$udom."'").
                   2688:                 '</p>';
1.473     amueller 2689:             $uname='';
1.12      www      2690:         } else {
1.473     amueller 2691:             $csec=&Apache::lonnet::getsection($udom,$uname,
                   2692:                           $env{'request.course.id'});
                   2693:             if ($csec eq '-1') {
1.540     bisitz   2694:                 $message=
                   2695:                     '<p class="LC_warning">'.
                   2696:                     &mt('User [_1] at domain [_2] not in this course',
                   2697:                         "'".$uname."'","'".$udom."'").
                   2698:                     '</p>';
1.473     amueller 2699:                 $uname='';
                   2700:                 $csec=$env{'form.csec'};
1.269     raeburn  2701:                 $cgroup=$env{'form.cgroup'};
1.473     amueller 2702:             } else {
                   2703:                 my %name=&Apache::lonnet::userenvironment($udom,$uname,
                   2704:                   ('firstname','middlename','lastname','generation','id'));
                   2705:                 $message="\n<p>\n".&mt("Full Name").": ".
                   2706:                 $name{'firstname'}.' '.$name{'middlename'}.' '
                   2707:                 .$name{'lastname'}.' '.$name{'generation'}.
1.501     bisitz   2708:                 "<br />\n".&mt('Student/Employee ID').": ".$name{'id'}.'<p>';
1.473     amueller 2709:             }
1.297     raeburn  2710:             @usersgroups = &Apache::lonnet::get_users_groups(
1.275     raeburn  2711:                                        $udom,$uname,$env{'request.course.id'});
1.297     raeburn  2712:             if (@usersgroups > 0) {
1.306     albertel 2713:                 unless (grep(/^\Q$cgroup\E$/,@usersgroups)) {
1.275     raeburn  2714:                     $cgroup = $usersgroups[0];
1.297     raeburn  2715:                 }
1.269     raeburn  2716:             }
1.12      www      2717:         }
1.43      albertel 2718:     }
1.2       www      2719: 
1.43      albertel 2720:     unless ($csec) { $csec=''; }
1.269     raeburn  2721:     unless ($cgroup) { $cgroup=''; }
1.12      www      2722: 
1.14      www      2723: # --------------------------------------------------------- Get all assessments
1.446     bisitz   2724:     &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
1.473     amueller 2725:                 \%mapp, \%symbp,\%maptitles,\%uris,
                   2726:                 \%keyorder);
1.63      bowersj2 2727: 
1.57      albertel 2728:     $mapp{'0.0'} = '';
                   2729:     $symbp{'0.0'} = '';
1.99      albertel 2730: 
1.14      www      2731: # ---------------------------------------------------------- Anything to store?
1.190     albertel 2732:     if ($env{'form.pres_marker'}) {
1.205     www      2733:         my @markers=split(/\&\&\&/,$env{'form.pres_marker'});
                   2734:         my @values=split(/\&\&\&/,$env{'form.pres_value'});
                   2735:         my @types=split(/\&\&\&/,$env{'form.pres_type'});
1.500     raeburn  2736:         my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   2737:         my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.504     raeburn  2738:         my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};
                   2739:         my ($got_chostname,$chostname,$cmajor,$cminor);
                   2740:         my $totalstored = 0;
1.546     raeburn  2741:         my $now = time;
1.473     amueller 2742:         for (my $i=0;$i<=$#markers;$i++) {
1.557     raeburn  2743:             my ($needsrelease,$needsnewer,$name,$namematch);
1.556     raeburn  2744:             if (($env{'request.course.sec'} ne '') && ($markers[$i] =~ /\&(9|10|11|12)$/)) {
1.552     raeburn  2745:                 next if ($csec ne $env{'request.course.sec'});
                   2746:             }
1.556     raeburn  2747:             if ($markers[$i] =~ /\&(8|7|6|5)$/) {
1.553     raeburn  2748:                 next if ($noeditgrp);
1.557     raeburn  2749:             }
                   2750:             if ($markers[$i] =~ /\&(17|11|7|3)$/) {
                   2751:                 $namematch = 'maplevelrecurse';
                   2752:             }
1.556     raeburn  2753:             if ($markers[$i] =~ /^[\d.]+\&0_availablestudent\&(1|2|3|4)$/) {
1.437     raeburn  2754:                 my (@ok_slots,@fail_slots,@del_slots);
                   2755:                 my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
                   2756:                 my ($level,@all) =
                   2757:                     &parmval_by_symb('0.availablestudent',$pssymb,'',$uname,$udom,
                   2758:                                      $csec,$cgroup,$courseopt);
                   2759:                 foreach my $slot_name (split(/:/,$values[$i])) {
                   2760:                     next if ($slot_name eq '');
                   2761:                     if (&update_slots($slot_name,$cdom,$cnum,$pssymb,$uname,$udom) eq 'ok') {
                   2762:                         push(@ok_slots,$slot_name);
                   2763: 
                   2764:                     } else {
                   2765:                         push(@fail_slots,$slot_name);
                   2766:                     }
                   2767:                 }
                   2768:                 if (@ok_slots) {
                   2769:                     $values[$i] = join(':',@ok_slots);
                   2770:                 } else {
                   2771:                     $values[$i] = '';
                   2772:                 }
                   2773:                 if ($all[$level] ne '') {
                   2774:                     my @existing = split(/:/,$all[$level]);
                   2775:                     foreach my $slot_name (@existing) {
                   2776:                         if (!grep(/^\Q$slot_name\E$/,split(/:/,$values[$i]))) {
                   2777:                             if (&delete_slots($slot_name,$cdom,$cnum,$uname,$udom,$pssymb) eq 'ok') {
                   2778:                                 push(@del_slots,$slot_name);
                   2779:                             }
                   2780:                         }
                   2781:                     }
                   2782:                 }
1.554     raeburn  2783:             } elsif ($markers[$i] =~ /_(type|lenient|retrypartial|discussvote|examcode|printstartdate|printenddate|acc|interval)\&\d+$/) {
1.514     raeburn  2784:                 $name = $1;
1.533     raeburn  2785:                 my $val = $values[$i];
1.549     raeburn  2786:                 my $valmatch = '';
1.533     raeburn  2787:                 if ($name eq 'examcode') {
1.544     raeburn  2788:                     if (&Apache::lonnet::validCODE($values[$i])) {
                   2789:                         $val = 'valid';
                   2790:                     }
1.546     raeburn  2791:                 } elsif ($name eq 'printstartdate') {
                   2792:                     if ($val =~ /^\d+$/) {
                   2793:                         if ($val > $now) {
                   2794:                             $val = 'future';
                   2795:                         }
                   2796:                     } 
                   2797:                 } elsif ($name eq 'printenddate') {
                   2798:                     if ($val =~ /^\d+$/) {
                   2799:                         if ($val < $now) {
                   2800:                             $val = 'past';
                   2801:                         }
                   2802:                     }
1.549     raeburn  2803:                 } elsif (($name eq 'lenient') || ($name eq 'acc')) {
                   2804:                     my $stringtype = &get_stringtype($name);
                   2805:                     my $stringmatch = &standard_string_matches($stringtype);
                   2806:                     if (ref($stringmatch) eq 'ARRAY') {
                   2807:                         foreach my $item (@{$stringmatch}) {
                   2808:                             if (ref($item) eq 'ARRAY') {
                   2809:                                 my ($regexpname,$pattern) = @{$item};
                   2810:                                 if ($pattern ne '') {
                   2811:                                     if ($val =~ /$pattern/) {
                   2812:                                         $valmatch = $regexpname;
                   2813:                                         $val = '';
                   2814:                                         last;
                   2815:                                     }
                   2816:                                 }
                   2817:                             }
                   2818:                         }
                   2819:                     }
1.554     raeburn  2820:                 } elsif ($name eq 'interval') {
                   2821:                     my $intervaltype = &get_intervaltype($name);
                   2822:                     my $intervalmatch = &standard_interval_matches($intervaltype);
                   2823:                     if (ref($intervalmatch) eq 'ARRAY') {
                   2824:                         foreach my $item (@{$intervalmatch}) {
                   2825:                             if (ref($item) eq 'ARRAY') {
                   2826:                                 my ($regexpname,$pattern) = @{$item};
                   2827:                                 if ($pattern ne '') {
                   2828:                                     if ($val =~ /$pattern/) {
                   2829:                                         $valmatch = $regexpname;
                   2830:                                         $val = '';
                   2831:                                         last;
                   2832:                                     }
                   2833:                                 }
                   2834:                             }
                   2835:                         }
                   2836:                     }
1.533     raeburn  2837:                 }
1.504     raeburn  2838:                 $needsrelease =
1.557     raeburn  2839:                     $Apache::lonnet::needsrelease{"parameter:$name:$val:$valmatch:"};
1.504     raeburn  2840:                 if ($needsrelease) {
1.505     raeburn  2841:                     unless ($got_chostname) {
1.514     raeburn  2842:                         ($chostname,$cmajor,$cminor) = &parameter_release_vars();
1.504     raeburn  2843:                         $got_chostname = 1;
1.546     raeburn  2844:                     } 
1.557     raeburn  2845:                     $needsnewer = &parameter_releasecheck($name,$val,$valmatch,undef,
1.514     raeburn  2846:                                                           $needsrelease,
                   2847:                                                           $cmajor,$cminor);
1.500     raeburn  2848:                 }
1.437     raeburn  2849:             }
1.504     raeburn  2850:             if ($needsnewer) {
1.557     raeburn  2851:                 undef($namematch);
                   2852:             } else {
                   2853:                 my $currneeded;
                   2854:                 if ($needsrelease) {
                   2855:                     $currneeded = $needsrelease;
                   2856:                 }
                   2857:                 if ($namematch) {
                   2858:                     $needsrelease =
                   2859:                         $Apache::lonnet::needsrelease{"parameter::::$namematch"};
                   2860:                     if (($needsrelease) && (($currneeded eq '') || ($needsrelease < $currneeded))) {
                   2861:                         unless ($got_chostname) {
                   2862:                             ($chostname,$cmajor,$cminor) = &parameter_release_vars();
                   2863:                             $got_chostname = 1;
                   2864:                         }
                   2865:                         $needsnewer = &parameter_releasecheck(undef,undef,undef,$namematch,
                   2866:                                                               $needsrelease,
                   2867:                                                               $cmajor,$cminor);
                   2868:                     } else {
                   2869:                         undef($namematch);
                   2870:                     }
                   2871:                 }
                   2872:             }
                   2873:             if ($needsnewer) {
                   2874:                 $message .= &oldversion_warning($name,$namematch,$values[$i],$chostname,$cmajor,
1.504     raeburn  2875:                                                 $cminor,$needsrelease);
                   2876:             } else {
                   2877:                 $message.=&storeparm(split(/\&/,$markers[$i]),
                   2878:                                      $values[$i],
                   2879:                                      $types[$i],
                   2880:                                      $uname,$udom,$csec,$cgroup);
                   2881:                 $totalstored ++;
                   2882:             }
1.473     amueller 2883:         }
1.68      www      2884: # ---------------------------------------------------------------- Done storing
1.504     raeburn  2885:         if ($totalstored) {
                   2886:             $message.='<p class="LC_warning">'
                   2887:                      .&mt('Changes can take up to 10 minutes before being active for all students.')
                   2888:                      .&Apache::loncommon::help_open_topic('Caching')
                   2889:                      .'</p>';
                   2890:         }
1.68      www      2891:     }
1.57      albertel 2892: #----------------------------------------------- if all selected, fill in array
1.548     raeburn  2893:     if ($pscat[0] eq "all") {@pscat = (keys(%allparms));}
1.501     bisitz   2894:     if (!@pscat) { @pscat=('duedate','opendate','answerdate','weight','maxtries','type','problemstatus') };
1.548     raeburn  2895:     if ($psprt[0] eq "all" || !@psprt) {@psprt = (keys(%allparts));}
1.2       www      2896: # ------------------------------------------------------------------ Start page
1.63      bowersj2 2897: 
1.531     raeburn  2898:     my $crstype = &Apache::loncommon::course_type();
                   2899:     &startpage($r,$pssymb,$crstype);
1.57      albertel 2900: 
1.548     raeburn  2901:     foreach my $item ('tolerance','date_default','date_start','date_end',
1.473     amueller 2902:         'date_interval','int','float','string') {
                   2903:         $r->print('<input type="hidden" value="'.
1.548     raeburn  2904:           &HTML::Entities::encode($env{'form.recent_'.$item},'"&<>').
                   2905:           '" name="recent_'.$item.'" />');
1.44      albertel 2906:     }
1.446     bisitz   2907: 
1.459     bisitz   2908:     # ----- Start Parameter Selection
                   2909: 
                   2910:     # Hide parm selection?
                   2911:     $r->print(<<ENDPARMSELSCRIPT);
                   2912: <script type="text/javascript">
                   2913: // <![CDATA[
                   2914: function parmsel_show() {
1.562   ! damieng  2915:     document.getElementById('parmsel').style.display = "";
        !          2916:     document.getElementById('parmsellink').style.display = "none";
1.459     bisitz   2917: }
                   2918: // ]]>
                   2919: </script>
                   2920: ENDPARMSELSCRIPT
1.474     amueller 2921:     
1.445     neumanie 2922:     if (!$pssymb) {
1.486     www      2923:         my $parmselhiddenstyle=' style="display:none"';
                   2924:         if($env{'form.hideparmsel'} eq 'hidden') {
                   2925:            $r->print('<div id="parmsel"'.$parmselhiddenstyle.'>');
                   2926:         } else  {
                   2927:            $r->print('<div id="parmsel">');
                   2928:         }
                   2929: 
1.491     bisitz   2930:         # Step 1
1.523     raeburn  2931:         $r->print(&Apache::lonhtmlcommon::topic_bar(1,&mt('Resource Specification'),'parmstep1'));
                   2932:         $r->print('
1.474     amueller 2933: <script type="text/javascript">
1.523     raeburn  2934: // <![CDATA['.
                   2935:                  &showhide_js().'
1.474     amueller 2936: // ]]>
                   2937: </script>
1.523     raeburn  2938: ');
                   2939:         $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel'));
1.209     www      2940:         &levelmenu($r,\%alllevs,$parmlev);
1.491     bisitz   2941:         $r->print(&Apache::lonhtmlcommon::row_closure());
1.474     amueller 2942:         &mapmenu($r,\%allmaps,$pschp,\%maptitles, \%symbp);
1.491     bisitz   2943:         $r->print(&Apache::lonhtmlcommon::row_closure());
                   2944:         $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View')));
                   2945:         &partmenu($r,\%allparts,\@psprt);
1.474     amueller 2946:         $r->print(&Apache::lonhtmlcommon::row_closure(1));
                   2947:         $r->print(&Apache::lonhtmlcommon::end_pick_box());
1.491     bisitz   2948: 
                   2949:         # Step 2
1.523     raeburn  2950:         $r->print(&Apache::lonhtmlcommon::topic_bar(2,&mt('Parameter Specification'),'parmstep2'));
1.536     raeburn  2951:         &displaymenu($r,\%allparms,\@pscat,\@psprt,\%keyorder,'parmmenuscroll');
1.491     bisitz   2952: 
                   2953:         # Step 3
1.523     raeburn  2954:         $r->print(&Apache::lonhtmlcommon::topic_bar(3,&mt('User Specification (optional)'),'parmstep3'));
1.486     www      2955:         $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.553     raeburn  2956:         &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups,$pssymb);
1.486     www      2957:         $r->print(&Apache::lonhtmlcommon::row_closure(1));
                   2958:         $r->print(&Apache::lonhtmlcommon::end_pick_box());
1.491     bisitz   2959: 
                   2960:         # Update Display Button
1.486     www      2961:         $r->print('<p>'
                   2962:              .'<input type="submit" name="dis"'
1.511     www      2963:              .' value="'.&mt('Update Display').'" />'
1.486     www      2964:              .'<input type="hidden" name="hideparmsel" value="hidden" />'
                   2965:              .'</p>');
                   2966:         $r->print('</div>');
1.491     bisitz   2967: 
1.486     www      2968:         # Offer link to display parameter selection again
                   2969:         $r->print('<p id="parmsellink"');
                   2970:         if ($env{'form.hideparmsel'} ne 'hidden') {
                   2971:            $r->print($parmselhiddenstyle);
                   2972:         }
                   2973:         $r->print('>'
                   2974:              .'<a href="javascript:parmsel_show()">'
                   2975:              .&mt('Change Parameter Selection')
                   2976:              .'</a>'
                   2977:              .'</p>');
1.44      albertel 2978:     } else {
1.478     amueller 2979:         # parameter screen for a single resource. 
1.486     www      2980:         my ($map,$iid,$resource)=&Apache::lonnet::decode_symb($pssymb);
1.473     amueller 2981:         my $title = &Apache::lonnet::gettitle($pssymb);
1.501     bisitz   2982:         $r->print(&mt('Specific Resource: [_1] ([_2])',
                   2983:                          $title,'<span class="LC_filename">'.$resource.'</span>').
1.472     amueller 2984:                 '<input type="hidden" value="'.$pssymb.'" name="symb" />'.
1.486     www      2985:                   '<br />');
                   2986:         $r->print(&Apache::lonhtmlcommon::topic_bar('',&mt('Additional Display Specification (optional)')));
                   2987:         $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.553     raeburn  2988:         &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups,$pssymb);
1.486     www      2989:         $r->print(&Apache::lonhtmlcommon::row_closure(1));
                   2990:         $r->print(&Apache::lonhtmlcommon::end_pick_box());
                   2991:         $r->print('<p>'
1.459     bisitz   2992:              .'<input type="submit" name="dis"'
1.511     www      2993:              .' value="'.&mt('Update Display').'" />'
1.459     bisitz   2994:              .'<input type="hidden" name="hideparmsel" value="hidden" />'
1.486     www      2995:              .'</p>');
1.459     bisitz   2996:     }
1.478     amueller 2997:     
1.486     www      2998:     # ----- End Parameter Selection
1.57      albertel 2999: 
1.459     bisitz   3000:     # Display Messages
                   3001:     $r->print('<div>'.$message.'</div>');
1.210     www      3002: 
1.57      albertel 3003: 
                   3004:     my @temp_pscat;
                   3005:     map {
                   3006:         my $cat = $_;
                   3007:         push(@temp_pscat, map { $_.'.'.$cat } @psprt);
                   3008:     } @pscat;
                   3009: 
                   3010:     @pscat = @temp_pscat;
                   3011: 
1.548     raeburn  3012: 
1.209     www      3013:     if (($env{'form.prevvisit'}) || ($pschp) || ($pssymb)) {
1.10      www      3014: # ----------------------------------------------------------------- Start Table
1.57      albertel 3015:         my @catmarker=map { tr|.|_|; 'parameter_'.$_; } @pscat;
1.190     albertel 3016:         my $csuname=$env{'user.name'};
                   3017:         my $csudom=$env{'user.domain'};
1.57      albertel 3018: 
1.203     www      3019:         if ($parmlev eq 'full') {
1.506     www      3020: #
                   3021: # This produces the cascading table output of parameters
                   3022: #
1.560     damieng  3023:             my $coursespan=$csec?10:6;
                   3024:             my $userspan=4;
                   3025:             if ($cgroup ne '') {
                   3026:                 $coursespan += 4;
                   3027:             }
1.473     amueller 3028: 
1.560     damieng  3029:             $r->print(&Apache::loncommon::start_data_table());
                   3030:             #
                   3031:             # This produces the headers
                   3032:             #
                   3033:             $r->print('<tr><td colspan="5"></td>');
                   3034:             $r->print('<th colspan="'.($coursespan).'">'.&mt('Any User').'</th>');
                   3035:             if ($uname) {
1.473     amueller 3036:                 if (@usersgroups > 1) {
1.560     damieng  3037:                     $userspan ++;
                   3038:                 }
                   3039:                 $r->print('<th colspan="'.$userspan.'" rowspan="2">');
                   3040:                 $r->print(&mt('User [_1] at Domain [_2]',"'".$uname."'","'".$udom."'").'</th>');
                   3041:             }
                   3042:             my %lt=&Apache::lonlocal::texthash(
1.473     amueller 3043:                 'pie'    => "Parameter in Effect",
                   3044:                 'csv'    => "Current Session Value",
1.472     amueller 3045:                 'rl'     => "Resource Level",
1.473     amueller 3046:                 'ic'     => 'in Course',
                   3047:                 'aut'    => "Assessment URL and Title",
                   3048:                 'type'   => 'Type',
                   3049:                 'emof'   => "Enclosing Map or Folder",
                   3050:                 'part'   => 'Part',
1.472     amueller 3051:                 'pn'     => 'Parameter Name',
1.473     amueller 3052:                 'def'    => 'default',
                   3053:                 'femof'  => 'from Enclosing Map or Folder',
                   3054:                 'gen'    => 'general',
                   3055:                 'foremf' => 'for Enclosing Map or Folder',
1.556     raeburn  3056:                 'formfr' => 'for Map or Folder (recursive)',
1.473     amueller 3057:                 'fr'     => 'for Resource'
                   3058:             );
1.560     damieng  3059:             $r->print(<<ENDTABLETWO);
1.419     bisitz   3060: <th rowspan="3">$lt{'pie'}</th>
1.501     bisitz   3061: <th rowspan="3">$lt{'csv'}<br />($csuname:$csudom)</th>
1.556     raeburn  3062: </tr><tr><td colspan="5"></td><th colspan="3">$lt{'ic'}</th><th colspan="2">$lt{'rl'}</th>
1.419     bisitz   3063: <th colspan="1">$lt{'ic'}</th>
1.182     albertel 3064: 
1.10      www      3065: ENDTABLETWO
1.560     damieng  3066:             if ($csec) {
                   3067:                 $r->print('<th colspan="4">'.
                   3068:                 &mt("in Section")." $csec</th>");
                   3069:             }
                   3070:             if ($cgroup) {
1.556     raeburn  3071:                 $r->print('<th colspan="4">'.
1.472     amueller 3072:                 &mt("in Group")." $cgroup</th>");
1.560     damieng  3073:             }
                   3074:             $r->print(<<ENDTABLEHEADFOUR);
1.133     www      3075: </tr><tr><th>$lt{'aut'}</th><th>$lt{'type'}</th>
                   3076: <th>$lt{'emof'}</th><th>$lt{'part'}</th><th>$lt{'pn'}</th>
1.556     raeburn  3077: <th>$lt{'gen'}</th><th>$lt{'formfr'}</th><th>$lt{'foremf'}</th>
1.192     albertel 3078: <th>$lt{'def'}</th><th>$lt{'femof'}</th><th>$lt{'fr'}</th>
1.10      www      3079: ENDTABLEHEADFOUR
1.57      albertel 3080: 
1.560     damieng  3081:             if ($csec) {
                   3082:                 $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'formfr'}.'</th><th>'.$lt{'foremf'}.'</th><th>'.$lt{'fr'}.'</th>');
                   3083:             }
1.473     amueller 3084: 
1.560     damieng  3085:             if ($cgroup) {
                   3086:                 $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'formfr'}.'</th><th>'.&mt('foremf').'</th><th>'.$lt{'fr'}.'</th>');
                   3087:             }
                   3088: 
                   3089:             if ($uname) {
                   3090:                 if (@usersgroups > 1) {
                   3091:                     $r->print('<th>'.&mt('Control by other group?').'</th>');
                   3092:                 }
                   3093:                 $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'formfr'}.'</th><th>'.$lt{'foremf'}.'</th><th>'.$lt{'fr'}.'</th>');
                   3094:             }
                   3095: 
                   3096:             $r->print('</tr>');
1.506     www      3097: #
                   3098: # Done with the headers
                   3099: # 
1.560     damieng  3100:             my $defbgone='';
                   3101:             my $defbgtwo='';
                   3102:             my $defbgthree = '';
1.57      albertel 3103: 
1.560     damieng  3104:             foreach my $rid (@ids) {
1.57      albertel 3105: 
                   3106:                 my ($inmapid)=($rid=~/\.(\d+)$/);
                   3107: 
1.446     bisitz   3108:                 if ((!$pssymb &&
1.560     damieng  3109:                         (($pschp eq 'all') || ($allmaps{$pschp} eq $mapp{$rid})))
                   3110:                         ||
                   3111:                         ($pssymb && $pssymb eq $symbp{$rid})) {
1.4       www      3112: # ------------------------------------------------------ Entry for one resource
1.473     amueller 3113:                     if ($defbgone eq '#E0E099') {
                   3114:                         $defbgone='#E0E0DD';
1.57      albertel 3115:                     } else {
1.419     bisitz   3116:                         $defbgone='#E0E099';
1.57      albertel 3117:                     }
1.419     bisitz   3118:                     if ($defbgtwo eq '#FFFF99') {
1.473     amueller 3119:                         $defbgtwo='#FFFFDD';
1.57      albertel 3120:                     } else {
1.473     amueller 3121:                         $defbgtwo='#FFFF99';
1.57      albertel 3122:                     }
1.419     bisitz   3123:                     if ($defbgthree eq '#FFBB99') {
                   3124:                         $defbgthree='#FFBBDD';
1.269     raeburn  3125:                     } else {
1.419     bisitz   3126:                         $defbgthree='#FFBB99';
1.269     raeburn  3127:                     }
                   3128: 
1.57      albertel 3129:                     my $thistitle='';
                   3130:                     my %name=   ();
                   3131:                     undef %name;
                   3132:                     my %part=   ();
                   3133:                     my %display=();
                   3134:                     my %type=   ();
                   3135:                     my %default=();
1.196     www      3136:                     my $uri=&Apache::lonnet::declutter($uris{$rid});
1.57      albertel 3137: 
1.506     www      3138:                     my $filter=$env{'form.filter'};
1.548     raeburn  3139:                     foreach my $tempkeyp (&keysplit($keyp{$rid})) {
1.57      albertel 3140:                         if (grep $_ eq $tempkeyp, @catmarker) {
1.560     damieng  3141:                             my $parmname=&Apache::lonnet::metadata($uri,$tempkeyp.'.name');
                   3142:     # We may only want certain parameters listed
                   3143:                             if ($filter) {
                   3144:                                 unless ($filter=~/\Q$parmname\E/) { next; }
                   3145:                             }
                   3146:                             $name{$tempkeyp}=$parmname;
                   3147:                             $part{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.part');
                   3148: 
                   3149:                             my $parmdis=&Apache::lonnet::metadata($uri,$tempkeyp.'.display');
                   3150:                             if ($allparms{$name{$tempkeyp}} ne '') {
                   3151:                                 my $identifier;
                   3152:                                 if ($parmdis =~ /(\s*\[Part.*)$/) {
                   3153:                                     $identifier = $1;
                   3154:                                 }
                   3155:                                 $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier;
                   3156:                             } else {
                   3157:                                 $display{$tempkeyp} = $parmdis;
                   3158:                             }
                   3159:                             unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
                   3160:                             $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
                   3161:                             $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp);
                   3162:                             $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.type');
                   3163:                             $thistitle=&Apache::lonnet::metadata($uri,$tempkeyp.'.title');
1.57      albertel 3164:                         }
                   3165:                     }
1.548     raeburn  3166:                     my $totalparms=scalar(keys(%name));
1.57      albertel 3167:                     if ($totalparms>0) {
1.560     damieng  3168:                         my $firstrow=1;
1.473     amueller 3169:                         my $title=&Apache::lonnet::gettitle($symbp{$rid});
1.419     bisitz   3170:                         $r->print('<tr><td style="background-color:'.$defbgone.';"'.
1.57      albertel 3171:                              ' rowspan='.$totalparms.
1.419     bisitz   3172:                              '><tt><font size="-1">'.
1.57      albertel 3173:                              join(' / ',split(/\//,$uri)).
                   3174:                              '</font></tt><p><b>'.
1.154     albertel 3175:                              "<a href=\"javascript:openWindow('".
1.473     amueller 3176:                           &Apache::lonnet::clutter($uri).'?symb='.
                   3177:                           &escape($symbp{$rid}).
1.336     albertel 3178:                              "', 'metadatafile', '450', '500', 'no', 'yes');\"".
                   3179:                              " target=\"_self\">$title");
1.57      albertel 3180: 
                   3181:                         if ($thistitle) {
1.473     amueller 3182:                             $r->print(' ('.$thistitle.')');
1.57      albertel 3183:                         }
                   3184:                         $r->print('</a></b></td>');
1.419     bisitz   3185:                         $r->print('<td style="background-color:'.$defbgtwo.';"'.
1.57      albertel 3186:                                       ' rowspan='.$totalparms.'>'.$typep{$rid}.
                   3187:                                       '</td>');
                   3188: 
1.419     bisitz   3189:                         $r->print('<td style="background-color:'.$defbgone.';"'.
1.57      albertel 3190:                                       ' rowspan='.$totalparms.
1.238     www      3191:                                       '>'.$maptitles{$mapp{$rid}}.'</td>');
1.548     raeburn  3192:                         foreach my $item (&keysinorder_bytype(\%name,\%keyorder)) {
1.57      albertel 3193:                             unless ($firstrow) {
                   3194:                                 $r->print('<tr>');
                   3195:                             } else {
                   3196:                                 undef $firstrow;
                   3197:                             }
1.548     raeburn  3198:                             &print_row($r,$item,\%part,\%name,\%symbp,$rid,\%default,
1.57      albertel 3199:                                        \%type,\%display,$defbgone,$defbgtwo,
1.269     raeburn  3200:                                        $defbgthree,$parmlev,$uname,$udom,$csec,
1.553     raeburn  3201:                                        $cgroup,\@usersgroups,$noeditgrp);
1.57      albertel 3202:                         }
                   3203:                     }
                   3204:                 }
                   3205:             } # end foreach ids
1.43      albertel 3206: # -------------------------------------------------- End entry for one resource
1.517     www      3207:             $r->print(&Apache::loncommon::end_data_table);
1.203     www      3208:         } # end of  full
1.57      albertel 3209: #--------------------------------------------------- Entry for parm level map
                   3210:         if ($parmlev eq 'map') {
1.419     bisitz   3211:             my $defbgone = '#E0E099';
                   3212:             my $defbgtwo = '#FFFF99';
                   3213:             my $defbgthree = '#FFBB99';
1.57      albertel 3214: 
                   3215:             my %maplist;
                   3216: 
                   3217:             if ($pschp eq 'all') {
1.446     bisitz   3218:                 %maplist = %allmaps;
1.57      albertel 3219:             } else {
                   3220:                 %maplist = ($pschp => $mapp{$pschp});
                   3221:             }
                   3222: 
                   3223: #-------------------------------------------- for each map, gather information
                   3224:             my $mapid;
1.560     damieng  3225:             foreach $mapid (sort {$maplist{$a} cmp $maplist{$b}} keys(%maplist)) {
1.60      albertel 3226:                 my $maptitle = $maplist{$mapid};
1.57      albertel 3227: 
                   3228: #-----------------------  loop through ids and get all parameter types for map
                   3229: #-----------------------------------------          and associated information
                   3230:                 my %name = ();
                   3231:                 my %part = ();
                   3232:                 my %display = ();
                   3233:                 my %type = ();
                   3234:                 my %default = ();
                   3235:                 my $map = 0;
                   3236: 
1.473     amueller 3237: #        $r->print("Catmarker: @catmarker<br />\n");
1.446     bisitz   3238: 
1.548     raeburn  3239:                 foreach my $id (@ids) {
                   3240:                     ($map)=($id =~ /([\d]*?)\./);
                   3241:                     my $rid = $id;
1.446     bisitz   3242: 
1.57      albertel 3243: #                  $r->print("$mapid:$map:   $rid <br /> \n");
                   3244: 
1.560     damieng  3245:                     if ($map eq $mapid) {
1.473     amueller 3246:                         my $uri=&Apache::lonnet::declutter($uris{$rid});
1.57      albertel 3247: #                    $r->print("Keys: $keyp{$rid} <br />\n");
                   3248: 
                   3249: #--------------------------------------------------------------------
                   3250: # @catmarker contains list of all possible parameters including part #s
                   3251: # $fullkeyp contains the full part/id # for the extraction of proper parameters
                   3252: # $tempkeyp contains part 0 only (no ids - ie, subparts)
                   3253: # When storing information, store as part 0
                   3254: # When requesting information, request from full part
                   3255: #-------------------------------------------------------------------
1.548     raeburn  3256:                         foreach my $fullkeyp (&keysplit($keyp{$rid})) {
                   3257:                             my $tempkeyp = $fullkeyp;
                   3258:                             $tempkeyp =~ s/_\w+_/_0_/;
1.473     amueller 3259: 
1.548     raeburn  3260:                             if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
1.473     amueller 3261:                                 $part{$tempkeyp}="0";
                   3262:                                 $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');
                   3263:                                 my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');
                   3264:                                 if ($allparms{$name{$tempkeyp}} ne '') {
                   3265:                                     my $identifier;
                   3266:                                     if ($parmdis =~ /(\s*\[Part.*)$/) {
                   3267:                                         $identifier = $1;
                   3268:                                     }
                   3269:                                     $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier;
                   3270:                                 } else {
                   3271:                                     $display{$tempkeyp} = $parmdis;
                   3272:                                 }
                   3273:                                 unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
                   3274:                                 $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
                   3275:                                 $display{$tempkeyp} =~ s/_\w+_/_0_/;
                   3276:                                 $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp);
                   3277:                                 $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');
                   3278:                               }
                   3279:                         } # end loop through keys
1.560     damieng  3280:                     }
1.57      albertel 3281:                 } # end loop through ids
1.446     bisitz   3282: 
1.57      albertel 3283: #---------------------------------------------------- print header information
1.133     www      3284:                 my $foldermap=&mt($maptitle=~/^uploaded/?'Folder':'Map');
1.82      www      3285:                 my $showtitle=$maptitles{$maptitle}.($maptitle!~/^uploaded/?' ['.$maptitle.']':'');
1.401     bisitz   3286:                 my $tmp="";
1.57      albertel 3287:                 if ($uname) {
1.473     amueller 3288:                     my $person=&Apache::loncommon::plainname($uname,$udom);
1.401     bisitz   3289:                     $tmp.=&mt("User")." <font color=\"red\"><i>$uname \($person\) </i></font> ".
                   3290:                         &mt('in')." \n";
1.57      albertel 3291:                 } else {
1.401     bisitz   3292:                     $tmp.="<font color=\"red\"><i>".&mt('all').'</i></font> '.&mt('users in')." \n";
1.57      albertel 3293:                 }
1.269     raeburn  3294:                 if ($cgroup) {
1.401     bisitz   3295:                     $tmp.=&mt("Group")." <font color=\"red\"><i>$cgroup".
                   3296:                               "</i></font> ".&mt('of')." \n";
1.269     raeburn  3297:                     $csec = '';
                   3298:                 } elsif ($csec) {
1.401     bisitz   3299:                     $tmp.=&mt("Section")." <font color=\"red\"><i>$csec".
                   3300:                               "</i></font> ".&mt('of')." \n";
1.269     raeburn  3301:                 }
1.401     bisitz   3302:                 $r->print('<div align="center"><h4>'
                   3303:                          .&mt('Set Defaults for All Resources in [_1]Specifically for [_2][_3]'
1.404     bisitz   3304:                              ,$foldermap.'<br /><font color="red"><i>'.$showtitle.'</i></font><br />'
1.401     bisitz   3305:                              ,$tmp
                   3306:                              ,'<font color="red"><i>'.$coursename.'</i></font>'
                   3307:                              )
                   3308:                          ."<br /></h4>\n"
1.422     bisitz   3309:                 );
1.57      albertel 3310: #---------------------------------------------------------------- print table
1.419     bisitz   3311:                 $r->print('<p>'.&Apache::loncommon::start_data_table()
                   3312:                          .&Apache::loncommon::start_data_table_header_row()
                   3313:                          .'<th>'.&mt('Parameter Name').'</th>'
1.556     raeburn  3314:                          .'<th>'.&mt('Recursive Value').'</th>'
                   3315:                          .'<th>'.&mt('Non-Recursive Value').'</th>'
1.419     bisitz   3316:                          .'<th>'.&mt('Parameter in Effect').'</th>'
                   3317:                          .&Apache::loncommon::end_data_table_header_row()
                   3318:                 );
1.57      albertel 3319: 
1.548     raeburn  3320:                 foreach my $item (&keysinorder(\%name,\%keyorder)) {
1.473     amueller 3321:                     $r->print(&Apache::loncommon::start_data_table_row());
1.548     raeburn  3322:                     &print_row($r,$item,\%part,\%name,\%symbp,$mapid,\%default,
1.269     raeburn  3323:                            \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
1.553     raeburn  3324:                            $parmlev,$uname,$udom,$csec,$cgroup,'',$noeditgrp);
1.57      albertel 3325:                 }
1.422     bisitz   3326:                 $r->print(&Apache::loncommon::end_data_table().'</p>'
                   3327:                          .'</div>'
                   3328:                 );
1.57      albertel 3329:             } # end each map
                   3330:         } # end of $parmlev eq map
                   3331: #--------------------------------- Entry for parm level general (Course level)
                   3332:         if ($parmlev eq 'general') {
1.473     amueller 3333:             my $defbgone = '#E0E099';
1.419     bisitz   3334:             my $defbgtwo = '#FFFF99';
                   3335:             my $defbgthree = '#FFBB99';
1.57      albertel 3336: 
                   3337: #-------------------------------------------- for each map, gather information
                   3338:             my $mapid="0.0";
                   3339: #-----------------------  loop through ids and get all parameter types for map
                   3340: #-----------------------------------------          and associated information
                   3341:             my %name = ();
                   3342:             my %part = ();
                   3343:             my %display = ();
                   3344:             my %type = ();
                   3345:             my %default = ();
1.446     bisitz   3346: 
1.548     raeburn  3347:             foreach $id (@ids) {
                   3348:                 my $rid = $id;
1.446     bisitz   3349: 
1.196     www      3350:                 my $uri=&Apache::lonnet::declutter($uris{$rid});
1.57      albertel 3351: 
                   3352: #--------------------------------------------------------------------
                   3353: # @catmarker contains list of all possible parameters including part #s
                   3354: # $fullkeyp contains the full part/id # for the extraction of proper parameters
                   3355: # $tempkeyp contains part 0 only (no ids - ie, subparts)
                   3356: # When storing information, store as part 0
                   3357: # When requesting information, request from full part
                   3358: #-------------------------------------------------------------------
1.548     raeburn  3359:                 foreach my $fullkeyp (&keysplit($keyp{$rid})) {
                   3360:                     my $tempkeyp = $fullkeyp;
                   3361:                     $tempkeyp =~ s/_\w+_/_0_/;
                   3362:                     if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
1.473     amueller 3363:                         $part{$tempkeyp}="0";
                   3364:                         $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name');
                   3365:                         my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display');
                   3366:                         if ($allparms{$name{$tempkeyp}} ne '') {
                   3367:                             my $identifier;
                   3368:                             if ($parmdis =~ /(\s*\[Part.*)$/) {
                   3369:                                 $identifier = $1;
                   3370:                             }
                   3371:                             $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier;
                   3372:                         } else {
                   3373:                             $display{$tempkeyp} = $parmdis;
                   3374:                         }
                   3375:                         unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
                   3376:                         $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
                   3377:                         $display{$tempkeyp} =~ s/_\w+_/_0_/;
                   3378:                         $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp);
                   3379:                         $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type');
1.560     damieng  3380:                     }
1.57      albertel 3381:                 } # end loop through keys
                   3382:             } # end loop through ids
1.446     bisitz   3383: 
1.57      albertel 3384: #---------------------------------------------------- print header information
1.473     amueller 3385:             my $setdef=&mt("Set Defaults for All Resources in Course");
1.57      albertel 3386:             $r->print(<<ENDMAPONE);
1.419     bisitz   3387: <center>
                   3388: <h4>$setdef
1.135     albertel 3389: <font color="red"><i>$coursename</i></font><br />
1.57      albertel 3390: ENDMAPONE
                   3391:             if ($uname) {
1.473     amueller 3392:                 my $person=&Apache::loncommon::plainname($uname,$udom);
1.135     albertel 3393:                 $r->print(" ".&mt("User")."<font color=\"red\"> <i>$uname \($person\) </i></font> \n");
1.57      albertel 3394:             } else {
1.135     albertel 3395:                 $r->print("<i><font color=\"red\"> ".&mt("ALL")."</i> ".&mt("USERS")."</font> \n");
1.57      albertel 3396:             }
1.446     bisitz   3397: 
1.135     albertel 3398:             if ($csec) {$r->print(&mt("Section")."<font color=\"red\"> <i>$csec</i></font>\n")};
1.306     albertel 3399:             if ($cgroup) {$r->print(&mt("Group")."<font color=\"red\"> <i>$cgroup</i></font>\n")};
1.135     albertel 3400:             $r->print("</h4>\n");
1.57      albertel 3401: #---------------------------------------------------------------- print table
1.419     bisitz   3402:             $r->print('<p>'.&Apache::loncommon::start_data_table()
                   3403:                      .&Apache::loncommon::start_data_table_header_row()
                   3404:                      .'<th>'.&mt('Parameter Name').'</th>'
                   3405:                      .'<th>'.&mt('Default Value').'</th>'
                   3406:                      .'<th>'.&mt('Parameter in Effect').'</th>'
                   3407:                      .&Apache::loncommon::end_data_table_header_row()
                   3408:             );
1.57      albertel 3409: 
1.548     raeburn  3410:             foreach my $item (&keysinorder(\%name,\%keyorder)) {
1.419     bisitz   3411:                 $r->print(&Apache::loncommon::start_data_table_row());
1.548     raeburn  3412:                 &print_row($r,$item,\%part,\%name,\%symbp,$mapid,\%default,
1.269     raeburn  3413:                        \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
1.553     raeburn  3414:                                    $parmlev,$uname,$udom,$csec,$cgroup,'',$noeditgrp);
1.57      albertel 3415:             }
1.419     bisitz   3416:             $r->print(&Apache::loncommon::end_data_table()
                   3417:                      .'</p>'
                   3418:                      .'</center>'
                   3419:             );
1.57      albertel 3420:         } # end of $parmlev eq general
1.43      albertel 3421:     }
1.507     www      3422:     $r->print('</form>');
                   3423:     &endSettingsScreen($r);
                   3424:     $r->print(&Apache::loncommon::end_page());
1.57      albertel 3425: } # end sub assessparms
1.30      www      3426: 
1.560     damieng  3427: 
                   3428: 
1.120     www      3429: ##################################################
1.560     damieng  3430: # OVERVIEW MODE
1.207     www      3431: ##################################################
1.124     www      3432: my $tableopen;
                   3433: 
                   3434: sub tablestart {
1.552     raeburn  3435:     my ($readonly) = @_;
1.124     www      3436:     if ($tableopen) {
1.552     raeburn  3437:         return '';
1.124     www      3438:     } else {
1.552     raeburn  3439:         $tableopen=1;
                   3440:         my $output = &Apache::loncommon::start_data_table().'<tr><th>'.&mt('Parameter').'</th>';
                   3441:         if ($readonly) {
                   3442:             $output .= '<th>'.&mt('Current value').'</th>';
                   3443:         } else {
                   3444:             $output .= '<th>'.&mt('Delete').'</th><th>'.&mt('Set to ...').'</th>';
                   3445:         }
                   3446:         $output .= '</tr>';
                   3447:         return $output;
1.124     www      3448:     }
                   3449: }
                   3450: 
                   3451: sub tableend {
                   3452:     if ($tableopen) {
1.560     damieng  3453:         $tableopen=0;
                   3454:         return &Apache::loncommon::end_data_table();
1.124     www      3455:     } else {
1.560     damieng  3456:         return'';
1.124     www      3457:     }
                   3458: }
                   3459: 
1.207     www      3460: sub readdata {
                   3461:     my ($crs,$dom)=@_;
                   3462: # Read coursedata
                   3463:     my $resourcedata=&Apache::lonnet::get_courseresdata($crs,$dom);
                   3464: # Read userdata
                   3465: 
                   3466:     my $classlist=&Apache::loncoursedata::get_classlist();
1.548     raeburn  3467:     foreach my $user (keys(%$classlist)) {
                   3468:         if ($user=~/^($match_username)\:($match_domain)$/) {
                   3469:             my ($tuname,$tudom)=($1,$2);
                   3470:             my $useropt=&Apache::lonnet::get_userresdata($tuname,$tudom);
                   3471:             foreach my $userkey (keys(%{$useropt})) {
                   3472:                 if ($userkey=~/^\Q$env{'request.course.id'}\E/) {
1.207     www      3473:                     my $newkey=$userkey;
1.548     raeburn  3474:                     $newkey=~s/^($env{'request.course.id'}\.)/$1\[useropt\:$tuname\:$tudom\]\./;
                   3475:                     $$resourcedata{$newkey}=$$useropt{$userkey};
                   3476:                 }
                   3477:             }
1.473     amueller 3478:         }
                   3479:     }
1.552     raeburn  3480:     if (wantarray) {
                   3481:         return ($resourcedata,$classlist);
                   3482:     } else {
                   3483:         return $resourcedata;
                   3484:     }
1.207     www      3485: }
                   3486: 
                   3487: 
1.124     www      3488: # Setting
1.208     www      3489: 
                   3490: sub storedata {
                   3491:     my ($r,$crs,$dom)=@_;
1.207     www      3492: # Set userlevel immediately
                   3493: # Do an intermediate store of course level
                   3494:     my $olddata=&readdata($crs,$dom);
1.124     www      3495:     my %newdata=();
                   3496:     undef %newdata;
                   3497:     my @deldata=();
                   3498:     undef @deldata;
1.504     raeburn  3499:     my ($got_chostname,$chostname,$cmajor,$cminor);
1.546     raeburn  3500:     my $now = time;
1.560     damieng  3501:     foreach my $key (keys(%env)) {
                   3502:         if ($key =~ /^form\.([a-z]+)\_(.+)$/) {
                   3503:             my $cmd=$1;
                   3504:             my $thiskey=$2;
                   3505:             next if ($cmd eq 'settext' || $cmd eq 'setipallow' || $cmd eq 'setipdeny');
                   3506:             my ($tuname,$tudom)=&extractuser($thiskey);
                   3507:             my $tkey=$thiskey;
1.473     amueller 3508:             if ($tuname) {
1.560     damieng  3509:                 $tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;
                   3510:             }
                   3511:             if ($cmd eq 'set' || $cmd eq 'datepointer' || $cmd eq 'dateinterval') {
                   3512:             my ($data, $typeof, $text, $name, $valchk, $valmatch, $namematch);
                   3513:             if ($cmd eq 'set') {
                   3514:                 $data=$env{$key};
                   3515:                 $valmatch = '';
                   3516:                 $valchk = $data;
                   3517:                 $typeof=$env{'form.typeof_'.$thiskey};
                   3518:                 $text = &mt('Saved modified parameter for');
                   3519:                 if ($typeof eq 'string_questiontype') {
                   3520:                     $name = 'type';
                   3521:                 } elsif ($typeof eq 'string_lenient') {
                   3522:                     $name = 'lenient';
                   3523:                     my $stringmatch = &standard_string_matches($typeof);
                   3524:                     if (ref($stringmatch) eq 'ARRAY') {
                   3525:                         foreach my $item (@{$stringmatch}) {
                   3526:                             if (ref($item) eq 'ARRAY') {
                   3527:                                 my ($regexpname,$pattern) = @{$item};
                   3528:                                 if ($pattern ne '') {
                   3529:                                     if ($data =~ /$pattern/) {
                   3530:                                         $valmatch = $regexpname;
                   3531:                                         $valchk = '';
                   3532:                                         last;
                   3533:                                     }
1.549     raeburn  3534:                                 }
                   3535:                             }
                   3536:                         }
                   3537:                     }
1.560     damieng  3538:                 } elsif ($typeof eq 'string_discussvote') {
                   3539:                     $name = 'discussvote';
                   3540:                 } elsif ($typeof eq 'string_examcode') {
                   3541:                     $name = 'examcode';
                   3542:                     if (&Apache::lonnet::validCODE($data)) {
                   3543:                         $valchk = 'valid';
                   3544:                     }
                   3545:                 } elsif ($typeof eq 'string_yesno') {
                   3546:                     if ($thiskey =~ /\.retrypartial$/) {
                   3547:                         $name = 'retrypartial';
                   3548:                     }
                   3549:                 }
                   3550:             } elsif ($cmd eq 'datepointer') {
                   3551:                 $data=&Apache::lonhtmlcommon::get_date_from_form($env{$key});
                   3552:                 $typeof=$env{'form.typeof_'.$thiskey};
                   3553:                 $text = &mt('Saved modified date for');
                   3554:                 if ($typeof eq 'date_start') {
                   3555:                     if ($thiskey =~ /\.printstartdate$/) {
                   3556:                         $name = 'printstartdate';
                   3557:                         if (($data) && ($data > $now)) {
                   3558:                             $valchk = 'future';
                   3559:                         }
                   3560:                     }
                   3561:                 } elsif ($typeof eq 'date_end') {
                   3562:                     if ($thiskey =~ /\.printenddate$/) {
                   3563:                         $name = 'printenddate';
                   3564:                         if (($data) && ($data < $now)) {
                   3565:                             $valchk = 'past';
                   3566:                         }
1.504     raeburn  3567:                     }
                   3568:                 }
1.560     damieng  3569:             } elsif ($cmd eq 'dateinterval') {
                   3570:                 $data=&get_date_interval_from_form($thiskey);
                   3571:                 if ($thiskey =~ /\.interval$/) {
                   3572:                     $name = 'interval';
                   3573:                     my $intervaltype = &get_intervaltype($name);
                   3574:                     my $intervalmatch = &standard_interval_matches($intervaltype);
                   3575:                     if (ref($intervalmatch) eq 'ARRAY') {
                   3576:                         foreach my $item (@{$intervalmatch}) {
                   3577:                             if (ref($item) eq 'ARRAY') {
                   3578:                                 my ($regexpname,$pattern) = @{$item};
                   3579:                                 if ($pattern ne '') {
                   3580:                                     if ($data =~ /$pattern/) {
                   3581:                                         $valmatch = $regexpname;
                   3582:                                         $valchk = '';
                   3583:                                         last;
                   3584:                                     }
1.554     raeburn  3585:                                 }
                   3586:                             }
                   3587:                         }
                   3588:                     }
                   3589:                 }
1.560     damieng  3590:                 $typeof=$env{'form.typeof_'.$thiskey};
                   3591:                 $text = &mt('Saved modified date for');
1.554     raeburn  3592:             }
1.560     damieng  3593:             if ($thiskey =~ m{\.(?:sequence|page)___\(rec\)}) {
                   3594:                 $namematch = 'maplevelrecurse';
1.557     raeburn  3595:             }
1.560     damieng  3596:             if (($name ne '') || ($namematch ne '')) {
                   3597:                 my ($needsrelease,$needsnewer);
                   3598:                 if ($name ne '') {
                   3599:                     $needsrelease = $Apache::lonnet::needsrelease{"parameter:$name:$valchk:$valmatch:"};
1.557     raeburn  3600:                     if ($needsrelease) {
                   3601:                         unless ($got_chostname) {
1.560     damieng  3602:                             ($chostname,$cmajor,$cminor)=&parameter_release_vars();
1.557     raeburn  3603:                             $got_chostname = 1;
                   3604:                         }
1.560     damieng  3605:                         $needsnewer = &parameter_releasecheck($name,$valchk,$valmatch,undef,
                   3606:                                                             $needsrelease,
                   3607:                                                             $cmajor,$cminor);
                   3608:                     }
                   3609:                 }
                   3610:                 if ($namematch ne '') {
                   3611:                     if ($needsnewer) {
                   3612:                         undef($namematch);
1.557     raeburn  3613:                     } else {
1.560     damieng  3614:                         my $currneeded;
                   3615:                         if ($needsrelease) {
                   3616:                             $currneeded = $needsrelease;
                   3617:                         }
                   3618:                         $needsrelease =
                   3619:                             $Apache::lonnet::needsrelease{"parameter::::$namematch"};
                   3620:                         if (($needsrelease) && (($currneeded eq '') || ($needsrelease < $currneeded))) {
                   3621:                             unless ($got_chostname) {
                   3622:                                 ($chostname,$cmajor,$cminor) = &parameter_release_vars();
                   3623:                                 $got_chostname = 1;
                   3624:                             }
                   3625:                             $needsnewer = &parameter_releasecheck(undef,$valchk,$valmatch,$namematch,
                   3626:                                                                 $needsrelease,$cmajor,$cminor);
                   3627:                         } else {
                   3628:                             undef($namematch);
                   3629:                         }
1.557     raeburn  3630:                     }
1.504     raeburn  3631:                 }
1.560     damieng  3632:                 if ($needsnewer) {
                   3633:                     $r->print('<br />'.&oldversion_warning($name,$namematch,$data,
                   3634:                                                         $chostname,$cmajor,
                   3635:                                                         $cminor,$needsrelease));
                   3636:                     next;
                   3637:                 }
1.504     raeburn  3638:             }
1.560     damieng  3639:             if (defined($data) and $$olddata{$thiskey} ne $data) {
                   3640:                 if ($tuname) {
                   3641:                     if (&Apache::lonnet::put('resourcedata',{$tkey=>$data,
                   3642:                                         $tkey.'.type' => $typeof},
                   3643:                                 $tudom,$tuname) eq 'ok') {
                   3644:                         &log_parmset({$tkey=>$data,$tkey.'.type' => $typeof},0,$tuname,$tudom);
                   3645:                         $r->print('<br />'.$text.' '.
                   3646:                             &Apache::loncommon::plainname($tuname,$tudom));
                   3647:                     } else {
                   3648:                         $r->print('<div class="LC_error">'.
                   3649:                             &mt('Error saving parameters').'</div>');
                   3650:                     }
                   3651:                     &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
                   3652:                 } else {
                   3653:                     $newdata{$thiskey}=$data;
                   3654:                     $newdata{$thiskey.'.type'}=$typeof;
                   3655:                 }
1.557     raeburn  3656:             }
1.560     damieng  3657:             } elsif ($cmd eq 'del') {
                   3658:                 if ($tuname) {
                   3659:                     if (&Apache::lonnet::del('resourcedata',[$tkey],$tudom,$tuname) eq 'ok') {
                   3660:                             &log_parmset({$tkey=>''},1,$tuname,$tudom);
                   3661:                         $r->print('<br />'.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));
                   3662:                     } else {
                   3663:                         $r->print('<div class="LC_error">'.
                   3664:                             &mt('Error deleting parameters').'</div>');
                   3665:                     }
                   3666:                     &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
                   3667:                 } else {
                   3668:                     push (@deldata,$thiskey,$thiskey.'.type');
                   3669:                 }
1.473     amueller 3670:             }
                   3671:         }
                   3672:     }
1.207     www      3673: # Store all course level
1.144     www      3674:     my $delentries=$#deldata+1;
1.548     raeburn  3675:     my @newdatakeys=keys(%newdata);
1.144     www      3676:     my $putentries=$#newdatakeys+1;
                   3677:     if ($delentries) {
1.560     damieng  3678:         if (&Apache::lonnet::del('resourcedata',\@deldata,$dom,$crs) eq 'ok') {
                   3679:             my %loghash=map { $_ => '' } @deldata;
                   3680:             &log_parmset(\%loghash,1);
                   3681:             $r->print('<h2>'.&mt('Deleted [quant,_1,parameter]',$delentries/2).'</h2>');
                   3682:         } else {
                   3683:             $r->print('<div class="LC_error">'.
                   3684:                 &mt('Error deleting parameters').'</div>');
                   3685:         }
                   3686:         &Apache::lonnet::devalidatecourseresdata($crs,$dom);
1.144     www      3687:     }
                   3688:     if ($putentries) {
1.560     damieng  3689:         if (&Apache::lonnet::put('resourcedata',\%newdata,$dom,$crs) eq 'ok') {
                   3690:                     &log_parmset(\%newdata,0);
                   3691:             $r->print('<h3>'.&mt('Saved [quant,_1,parameter]',$putentries/2).'</h3>');
                   3692:         } else {
                   3693:             $r->print('<div class="LC_error">'.
                   3694:                 &mt('Error saving parameters').'</div>');
                   3695:         }
                   3696:         &Apache::lonnet::devalidatecourseresdata($crs,$dom);
1.144     www      3697:     }
1.208     www      3698: }
1.207     www      3699: 
1.208     www      3700: sub extractuser {
                   3701:     my $key=shift;
1.350     albertel 3702:     return ($key=~/^$env{'request.course.id'}.\[useropt\:($match_username)\:($match_domain)\]\./);
1.208     www      3703: }
1.206     www      3704: 
1.381     albertel 3705: sub parse_listdata_key {
                   3706:     my ($key,$listdata) = @_;
                   3707:     # split into student/section affected, and
                   3708:     # the realm (folder/resource part and parameter
1.446     bisitz   3709:     my ($student,$realm) =
1.473     amueller 3710:     ($key=~/^\Q$env{'request.course.id'}\E\.\[([^\.]+)\]\.(.+)$/);
1.381     albertel 3711:     # if course wide student would be undefined
                   3712:     if (!defined($student)) {
1.560     damieng  3713:         ($realm)=($key=~/^\Q$env{'request.course.id'}\E\.(.+)$/);
1.381     albertel 3714:     }
                   3715:     # strip off the .type if it's not the Question type parameter
                   3716:     if ($realm=~/\.type$/ && !exists($listdata->{$key.'.type'})) {
1.560     damieng  3717:         $realm=~s/\.type//;
1.381     albertel 3718:     }
                   3719:     # split into resource+part and parameter name
1.388     albertel 3720:     my ($res,    $parm) = ($realm=~/^(.*)\.(.*)$/);
                   3721:        ($res, my $part) = ($res  =~/^(.*)\.(.*)$/);
1.381     albertel 3722:     return ($student,$res,$part,$parm);
                   3723: }
                   3724: 
1.560     damieng  3725: # Displays forms for the given data in overview mode (newoverview or overview).
1.208     www      3726: sub listdata {
1.552     raeburn  3727:     my ($r,$resourcedata,$listdata,$sortorder,$caller,$classlist)=@_;
                   3728:     
1.207     www      3729: # Start list output
1.206     www      3730: 
1.122     www      3731:     my $oldsection='';
                   3732:     my $oldrealm='';
                   3733:     my $oldpart='';
1.123     www      3734:     my $pointer=0;
1.124     www      3735:     $tableopen=0;
1.145     www      3736:     my $foundkeys=0;
1.248     albertel 3737:     my %keyorder=&standardkeyorder();
1.381     albertel 3738: 
1.552     raeburn  3739:     my ($secidx,%grouphash);
                   3740:     if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
                   3741:         $secidx = &Apache::loncoursedata::CL_SECTION();
1.553     raeburn  3742:         if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
                   3743:             %grouphash = &Apache::longroup::coursegroups();
                   3744:         } elsif ($env{'request.course.groups'} ne '') {
                   3745:             map { $grouphash{$_} = 1; } split(/,/,$env{'request.course.groups'});
                   3746:         }
1.552     raeburn  3747:     }
                   3748: 
1.214     www      3749:     foreach my $thiskey (sort {
1.560     damieng  3750:         my ($astudent,$ares,$apart,$aparm) = &parse_listdata_key($a,$listdata);
                   3751:         my ($bstudent,$bres,$bpart,$bparm) = &parse_listdata_key($b,$listdata);
1.381     albertel 3752: 
1.560     damieng  3753:         # get the numerical order for the param
                   3754:         $aparm=$keyorder{'parameter_0_'.$aparm};
                   3755:         $bparm=$keyorder{'parameter_0_'.$bparm};
1.381     albertel 3756: 
1.560     damieng  3757:         my $result=0;
1.381     albertel 3758: 
1.560     damieng  3759:         if ($sortorder eq 'realmstudent') {
1.381     albertel 3760:             if ($ares     ne $bres    ) {
1.560     damieng  3761:                 $result = ($ares     cmp $bres);
1.446     bisitz   3762:             } elsif ($astudent ne $bstudent) {
1.560     damieng  3763:                 $result = ($astudent cmp $bstudent);
                   3764:             } elsif ($apart    ne $bpart   ) {
                   3765:                 $result = ($apart    cmp $bpart);
                   3766:             }
                   3767:         } else {
                   3768:             if      ($astudent ne $bstudent) {
                   3769:                 $result = ($astudent cmp $bstudent);
                   3770:             } elsif ($ares     ne $bres    ) {
                   3771:                 $result = ($ares     cmp $bres);
                   3772:             } elsif ($apart    ne $bpart   ) {
                   3773:                 $result = ($apart    cmp $bpart);
                   3774:             }
1.473     amueller 3775:         }
1.446     bisitz   3776: 
1.560     damieng  3777:         if (!$result) {
1.381     albertel 3778:             if (defined($aparm) && defined($bparm)) {
1.560     damieng  3779:                 $result = ($aparm <=> $bparm);
1.381     albertel 3780:             } elsif (defined($aparm)) {
1.560     damieng  3781:                 $result = -1;
1.381     albertel 3782:             } elsif (defined($bparm)) {
1.560     damieng  3783:                 $result = 1;
                   3784:             }
1.473     amueller 3785:         }
1.381     albertel 3786: 
1.560     damieng  3787:         $result;
                   3788:         
                   3789:     } keys(%{$listdata})) { # foreach my $thiskey
1.381     albertel 3790: 
1.560     damieng  3791:         my $readonly;
                   3792:         if ($$listdata{$thiskey.'.type'}) {
                   3793:             my $thistype=$$listdata{$thiskey.'.type'};
                   3794:             if ($$resourcedata{$thiskey.'.type'}) {
                   3795:                 $thistype=$$resourcedata{$thiskey.'.type'};
                   3796:             }
                   3797:             my ($middle,$part,$name)=
                   3798:                 ($thiskey=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
                   3799:             my $section=&mt('All Students');
                   3800:             if ($middle=~/^\[(.*)\]/) {
                   3801:                 my $issection=$1;
                   3802:                 if ($issection=~/^useropt\:($match_username)\:($match_domain)/) {
                   3803:                     my ($stuname,$studom) = ($1,$2);
                   3804:                     if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
                   3805:                         if (ref($classlist) eq 'HASH') {
                   3806:                             if (ref($classlist->{$stuname.':'.$studom}) eq 'ARRAY') {
                   3807:                                 next unless ($classlist->{$stuname.':'.$studom}->[$secidx] eq $env{'request.course.sec'}); 
                   3808:                             }
                   3809:                         }
                   3810:                     }
                   3811:                     $section=&mt('User').": ".&Apache::loncommon::plainname($stuname,$studom);
                   3812:                 } else {
                   3813:                     if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
                   3814:                         if (exists($grouphash{$issection})) {
                   3815:                             $section=&mt('Group').': '.$issection;
                   3816:                         } elsif ($issection eq $env{'request.course.sec'}) {
                   3817:                             $section = &mt('Section').': '.$issection;
                   3818:                         } else {
                   3819:                             next; 
1.552     raeburn  3820:                         }
1.560     damieng  3821:                     } else {
                   3822:                         $section=&mt('Group/Section').': '.$issection;
1.552     raeburn  3823:                     }
                   3824:                 }
1.560     damieng  3825:                 $middle=~s/^\[(.*)\]//;
                   3826:             } elsif (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
                   3827:                 $readonly = 1;
                   3828:             }
                   3829:             $middle=~s/\.+$//;
                   3830:             $middle=~s/^\.+//;
                   3831:             my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
                   3832:             if ($middle=~/^(.+)\_\_\_\((all|rec)\)$/) {
                   3833:                 my $mapurl = $1;
                   3834:                 my $maplevel = $2;
                   3835:                 my $leveltitle = &mt('Folder/Map');
                   3836:                 if ($maplevel eq 'rec') {
                   3837:                     $leveltitle = &mt('Recursive');
                   3838:                 }
                   3839:                 $realm='<span class="LC_parm_scope_folder">'.$leveltitle.': '.&Apache::lonnet::gettitle($mapurl).' <br /><span class="LC_parm_folder">('.$mapurl.')</span></span>';
                   3840:             } elsif ($middle) {
                   3841:                 my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
                   3842:                 $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').
                   3843:                     ': '.&Apache::lonnet::gettitle($middle).
                   3844:                     ' <br /><span class="LC_parm_symb">('.$url.' in '.$map.' id: '.
                   3845:                     $id.')</span></span>';
                   3846:             }
                   3847:             if ($sortorder eq 'realmstudent') {
                   3848:                 if ($realm ne $oldrealm) {
                   3849:                     $r->print(&tableend()."\n<hr /><h1>$realm</h1>");
                   3850:                     $oldrealm=$realm;
                   3851:                     $oldsection='';
                   3852:                 }
                   3853:                 if ($section ne $oldsection) {
                   3854:                     $r->print(&tableend()."\n<h2>$section</h2>");
                   3855:                     $oldsection=$section;
                   3856:                     $oldpart='';
                   3857:                 }
1.552     raeburn  3858:             } else {
1.560     damieng  3859:                 if ($section ne $oldsection) {
                   3860:                     $r->print(&tableend()."\n<hr /><h1>$section</h1>");
                   3861:                     $oldsection=$section;
                   3862:                     $oldrealm='';
                   3863:                 }
                   3864:                 if ($realm ne $oldrealm) {
                   3865:                     $r->print(&tableend()."\n<h2>$realm</h2>");
                   3866:                     $oldrealm=$realm;
                   3867:                     $oldpart='';
1.552     raeburn  3868:                 }
                   3869:             }
1.560     damieng  3870:             if ($part ne $oldpart) {
                   3871:                 $r->print(&tableend().
                   3872:                     "\n".'<span class="LC_parm_part">'.&mt('Part').": $part</span>");
                   3873:                 $oldpart=$part;
1.556     raeburn  3874:             }
1.560     damieng  3875:     #
                   3876:     # Ready to print
                   3877:     #
1.470     raeburn  3878:             my $parmitem = &standard_parameter_names($name);
1.560     damieng  3879:             $r->print(&tablestart($readonly).
                   3880:                 &Apache::loncommon::start_data_table_row().
                   3881:                 '<td><b>'.&mt($parmitem).
                   3882:                 '</b></td>');
                   3883:             unless ($readonly) {
                   3884:                 $r->print('<td><input type="checkbox" name="del_'.
                   3885:                         $thiskey.'" /></td>');
                   3886:             }
                   3887:             $r->print('<td>');
                   3888:             $foundkeys++;
                   3889:             if (&isdateparm($thistype)) {
                   3890:                 my $jskey='key_'.$pointer;
                   3891:                 my $state;
                   3892:                 $pointer++;
                   3893:                 if ($readonly) {
                   3894:                     $state = 'disabled';
                   3895:                 }
                   3896:                 $r->print(
                   3897:                     &Apache::lonhtmlcommon::date_setter('parmform',
                   3898:                                                         $jskey,
                   3899:                                                         $$resourcedata{$thiskey},
                   3900:                                                         '',1,$state));
                   3901:                 unless  ($readonly) {
                   3902:                     $r->print(
                   3903:     '<input type="hidden" name="datepointer_'.$thiskey.'" value="'.$jskey.'" />'.
                   3904:     (($$resourcedata{$thiskey}!=0)?'<span class="LC_nobreak"><a href="/adm/parmset?&action=dateshift1&timebase='.$$resourcedata{$thiskey}.'">'.
                   3905:     &mt('Shift all dates based on this date').'</a></span>':'').
                   3906:     &date_sanity_info($$resourcedata{$thiskey})
                   3907:                     );
                   3908:                 }
                   3909:             } elsif ($thistype eq 'date_interval') {
                   3910:                 $r->print(&date_interval_selector($thiskey,$name,
                   3911:                         $$resourcedata{$thiskey},$readonly));
                   3912:             } elsif ($thistype =~ m/^string/) {
                   3913:                 $r->print(&string_selector($thistype,$thiskey,
                   3914:                         $$resourcedata{$thiskey},$name,$readonly));
                   3915:             } else {
                   3916:                 $r->print(&default_selector($thiskey,$$resourcedata{$thiskey},$readonly));
1.552     raeburn  3917:             }
1.560     damieng  3918:             unless ($readonly) {
                   3919:                 $r->print('<input type="hidden" name="typeof_'.$thiskey.'" value="'.
                   3920:                         $thistype.'" />');
1.552     raeburn  3921:             }
1.560     damieng  3922:             $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.473     amueller 3923:         }
1.121     www      3924:     }
1.208     www      3925:     return $foundkeys;
                   3926: }
                   3927: 
1.385     albertel 3928: sub get_date_interval_from_form {
                   3929:     my ($key) = @_;
                   3930:     my $seconds = 0;
                   3931:     foreach my $which (['days', 86400],
1.473     amueller 3932:                ['hours', 3600],
                   3933:                ['minutes', 60],
                   3934:                ['seconds',  1]) {
1.560     damieng  3935:         my ($name, $factor) = @{ $which };
                   3936:         if (defined($env{'form.'.$name.'_'.$key})) {
                   3937:             $seconds += $env{'form.'.$name.'_'.$key} * $factor;
                   3938:         }
1.473     amueller 3939:     }
1.560     damieng  3940:     if (($key =~ /\.interval$/) &&
                   3941:             (($env{'form.done_'.$key} eq '_done') || ($env{'form.done_'.$key} eq '_done_proctor'))) {
1.559     raeburn  3942:         if ($env{'form.done_'.$key.'_buttontext'}) {
                   3943:             $env{'form.done_'.$key.'_buttontext'} =~ s/\://g;
                   3944:             $seconds .= '_done:'.$env{'form.done_'.$key.'_buttontext'}.':';
                   3945:             if ($env{'form.done_'.$key} eq '_done_proctor') {
                   3946:                 $seconds .= '_proctor';
                   3947:             }
                   3948:         } else {
                   3949:             $seconds .= $env{'form.done_'.$key}; 
                   3950:         }
                   3951:         if (($env{'form.done_'.$key} eq '_done_proctor') && 
1.560     damieng  3952:                 ($env{'form.done_'.$key.'_proctorkey'})) {
1.558     raeburn  3953:             $seconds .= '_'.$env{'form.done_'.$key.'_proctorkey'};
                   3954:         }
1.554     raeburn  3955:     }
1.385     albertel 3956:     return $seconds;
                   3957: }
                   3958: 
                   3959: 
1.383     albertel 3960: sub default_selector {
1.552     raeburn  3961:     my ($thiskey, $showval, $readonly) = @_;
                   3962:     my $disabled;
                   3963:     if ($readonly) {
                   3964:         $disabled = ' disabled="disabled"';
                   3965:     }
                   3966:     return '<input type="text" name="set_'.$thiskey.'" value="'.$showval.'"'.$disabled.' />';
1.383     albertel 3967: }
                   3968: 
1.549     raeburn  3969: sub string_ip_selector {
1.552     raeburn  3970:     my ($thiskey, $showval, $readonly) = @_;
1.549     raeburn  3971:     my %access = (
                   3972:                    allow => [],
                   3973:                    deny  => [],
                   3974:                  );
                   3975:     if ($showval ne '') {
                   3976:         my @current;
                   3977:         if ($showval =~ /,/) {
                   3978:             @current = split(/,/,$showval);
                   3979:         } else {
                   3980:             @current = ($showval);
                   3981:         }
                   3982:         foreach my $item (@current) {
                   3983:             if ($item =~ /^\!([\[\]a-zA-Z\.\d\*\-]+)$/) {
                   3984:                 push(@{$access{'deny'}},$1);
                   3985:             } elsif ($item =~ /^([\[\]a-zA-Z\.\d\*\-]+)$/) {
                   3986:                 push(@{$access{'allow'}},$item);
                   3987:             }
                   3988:         }
                   3989:     }
                   3990:     if (!@{$access{'allow'}}) {
                   3991:         @{$access{'allow'}} = ('');
                   3992:     }
                   3993:     if (!@{$access{'deny'}}) {
                   3994:         @{$access{'deny'}} = ('');
                   3995:     }
1.552     raeburn  3996:     my ($disabled,$addmore);
                   3997:     if ($disabled) {
                   3998:         $disabled=' disabled="disabled"';
                   3999:     } else {
                   4000:         $addmore = "\n".'<button class="LC_add_ipacc_button">'.&mt('Add more').'</button>';
                   4001:     }
1.549     raeburn  4002:     my $output = '<input type="hidden" name="set_'.$thiskey.'" />
                   4003: <table><tr><th>'.&mt('Allow from').'</th><th>'.&mt('Deny from').'</th></tr><tr>';
                   4004:     foreach my $acctype ('allow','deny') {
                   4005:         $output .= '
                   4006: <td valign="top">
                   4007: <div class="LC_string_ipacc_wrap" id="LC_string_ipacc_'.$acctype.'_'.$thiskey.'">
                   4008:   <div class="LC_string_ipacc_inner">'."\n";
                   4009:         my $num = 0;
                   4010:         foreach my $curr (@{$access{$acctype}}) {
1.552     raeburn  4011:             $output .= '<div><input type="text" name="setip'.$acctype.'_'.$thiskey.'" value="'.$curr.'"'.$disabled.' />';
1.549     raeburn  4012:             if ($num > 0) {
                   4013:                 $output .= '<a href="#" class="LC_remove_ipacc">'.&mt('Remove').'</a>'; 
                   4014:             }
                   4015:             $output .= '</div>'."\n";
                   4016:             $num ++;
                   4017:         }
                   4018:         $output .= '
1.552     raeburn  4019:   </div>'.$addmore.'
1.549     raeburn  4020: </div>
                   4021: </td>';
                   4022:    }
                   4023:    $output .= '
                   4024: </tr>
                   4025: </table>'."\n";
                   4026:     return $output;
                   4027: }
                   4028: 
1.560     damieng  4029: 
                   4030: { # block using some constants related to parameter types (overview mode)
                   4031: 
1.446     bisitz   4032: my %strings =
1.383     albertel 4033:     (
                   4034:      'string_yesno'
                   4035:              => [[ 'yes', 'Yes' ],
1.560     damieng  4036:                  [ 'no', 'No' ]],
1.383     albertel 4037:      'string_problemstatus'
                   4038:              => [[ 'yes', 'Yes' ],
1.473     amueller 4039:          [ 'answer', 'Yes, and show correct answer if they exceed the maximum number of tries.' ],
                   4040:          [ 'no', 'No, don\'t show correct/incorrect feedback.' ],
                   4041:          [ 'no_feedback_ever', 'No, show no feedback at all.' ]],
1.504     raeburn  4042:      'string_questiontype'
                   4043:              => [[ 'problem', 'Standard Problem'],
                   4044:                  [ 'survey', 'Survey'],
                   4045:                  [ 'anonsurveycred', 'Anonymous Survey (credit for submission)'],
1.530     bisitz   4046:                  [ 'exam', 'Bubblesheet Exam'],
1.504     raeburn  4047:                  [ 'anonsurvey', 'Anonymous Survey'],
                   4048:                  [ 'randomizetry', 'New Randomization Each N Tries (default N=1)'],
                   4049:                  [ 'practice', 'Practice'],
                   4050:                  [ 'surveycred', 'Survey (credit for submission)']],
1.514     raeburn  4051:      'string_lenient'
                   4052:              => [['yes', 'Yes' ],
                   4053:                  [ 'no', 'No' ],
1.549     raeburn  4054:                  [ 'default', 'Default - only bubblesheet grading is lenient' ],
                   4055:                  [ 'weighted', 'Yes, weighted (optionresponse in checkbox mode)' ]],
1.521     raeburn  4056:      'string_discussvote'
                   4057:              => [['yes','Yes'],
                   4058:                  ['notended','Yes, unless discussion ended'],
                   4059:                  ['no','No']],
1.549     raeburn  4060:      'string_ip'
                   4061:              => [['_allowfrom_','Hostname(s), or IP(s) from which access is allowed'],
                   4062:                  ['_denyfrom_',], 'Hostname(s) or IP(s) from which access is disallowed'], 
1.383     albertel 4063:      );
                   4064: 
1.549     raeburn  4065: my %stringmatches = (
                   4066:          'string_lenient'
                   4067:               => [['weighted','^\-?[.\d]+,\-?[.\d]+,\-?[.\d]+,\-?[.\d]+$'],],
                   4068:          'string_ip'
                   4069:               => [['_allowfrom_','[^\!]+'],
                   4070:                   ['_denyfrom_','\!']],
                   4071:     );
                   4072: 
                   4073: my %stringtypes = (
                   4074:                     type         => 'string_questiontype',
                   4075:                     lenient      => 'string_lenient',
                   4076:                     retrypartial => 'string_yesno',
                   4077:                     discussvote  => 'string_discussvote',
                   4078:                     examcode     => 'string_examcode',
                   4079:                     acc          => 'string_ip',
                   4080:                   );
                   4081: 
1.505     raeburn  4082: sub standard_string_options {
                   4083:     my ($string_type) = @_;
                   4084:     if (ref($strings{$string_type}) eq 'ARRAY') {
                   4085:         return $strings{$string_type};
                   4086:     }
                   4087:     return;
                   4088: }
1.383     albertel 4089: 
1.549     raeburn  4090: sub standard_string_matches {
                   4091:     my ($string_type) = @_;
                   4092:     if (ref($stringmatches{$string_type}) eq 'ARRAY') {
                   4093:         return $stringmatches{$string_type};
                   4094:     }
                   4095:     return;
                   4096: }
                   4097: 
                   4098: sub get_stringtype {
                   4099:     my ($name) = @_;
                   4100:     if (exists($stringtypes{$name})) {
                   4101:         return $stringtypes{$name};
                   4102:     }
                   4103:     return;
                   4104: }
                   4105: 
1.383     albertel 4106: sub string_selector {
1.552     raeburn  4107:     my ($thistype, $thiskey, $showval, $name, $readonly) = @_;
1.446     bisitz   4108: 
1.383     albertel 4109:     if (!exists($strings{$thistype})) {
1.552     raeburn  4110:         return &default_selector($thiskey,$showval,$readonly);
1.383     albertel 4111:     }
                   4112: 
1.504     raeburn  4113:     my %skiptype;
1.514     raeburn  4114:     if (($thistype eq 'string_questiontype') || 
1.560     damieng  4115:             ($thistype eq 'string_lenient') ||
                   4116:             ($thistype eq 'string_discussvote') ||
                   4117:             ($thistype eq 'string_ip') ||
                   4118:             ($name eq 'retrypartial')) {
1.504     raeburn  4119:         my ($got_chostname,$chostname,$cmajor,$cminor); 
                   4120:         foreach my $possibilities (@{ $strings{$thistype} }) {
                   4121:             next unless (ref($possibilities) eq 'ARRAY');
1.514     raeburn  4122:             my ($parmval, $description) = @{ $possibilities };
1.549     raeburn  4123:             my $parmmatch;
                   4124:             if (ref($stringmatches{$thistype}) eq 'ARRAY') {
                   4125:                 foreach my $item (@{$stringmatches{$thistype}}) {
                   4126:                     if (ref($item) eq 'ARRAY') {
                   4127:                         if ($parmval eq $item->[0]) {
                   4128:                             $parmmatch = $parmval;
                   4129:                             $parmval = '';
                   4130:                             last;
                   4131:                         }
                   4132:                     }
                   4133:                 }
                   4134:             }
                   4135:             my $needsrelease=$Apache::lonnet::needsrelease{"parameter:$name:$parmval:$parmmatch"}; 
1.504     raeburn  4136:             if ($needsrelease) {
                   4137:                 unless ($got_chostname) {
1.514     raeburn  4138:                     ($chostname,$cmajor,$cminor)=&parameter_release_vars();
1.504     raeburn  4139:                     $got_chostname = 1;
                   4140:                 }
1.557     raeburn  4141:                 my $needsnewer=&parameter_releasecheck($name,$parmval,$parmmatch,undef,
1.549     raeburn  4142:                                                        $needsrelease,$cmajor,$cminor);
1.504     raeburn  4143:                 if ($needsnewer) {
1.549     raeburn  4144:                     if ($parmmatch ne '') {
                   4145:                         $skiptype{$parmmatch} = 1;
                   4146:                     } elsif ($parmval ne '') {
                   4147:                         $skiptype{$parmval} = 1;
                   4148:                     }
1.504     raeburn  4149:                 }
                   4150:             }
                   4151:         }
                   4152:     }
1.549     raeburn  4153: 
                   4154:     if ($thistype eq 'string_ip') {
1.552     raeburn  4155:         return &string_ip_selector($thiskey,$showval,$readonly); 
1.549     raeburn  4156:     }
1.504     raeburn  4157: 
1.552     raeburn  4158:     my ($result,$disabled);
                   4159: 
                   4160:     if ($readonly) {
                   4161:         $disabled = ' disabled="disabled"';
                   4162:     }
1.504     raeburn  4163:     my $numinrow = 3;
                   4164:     if ($thistype eq 'string_problemstatus') {
                   4165:         $numinrow = 2;
                   4166:     } elsif ($thistype eq 'string_questiontype') {
                   4167:         if (keys(%skiptype) > 0) {
                   4168:              $numinrow = 4;
                   4169:         }
                   4170:     }
                   4171:     my $rem;
                   4172:     if (ref($strings{$thistype}) eq 'ARRAY') {
                   4173:         my $i=0;
                   4174:         foreach my $possibilities (@{ $strings{$thistype} }) {
                   4175:             next unless (ref($possibilities) eq 'ARRAY');
                   4176:             my ($name, $description) = @{ $possibilities };
1.549     raeburn  4177:             next if ($skiptype{$name});
1.504     raeburn  4178:             $rem = $i%($numinrow);
                   4179:             if ($rem == 0) {
                   4180:                 if ($i > 0) {
                   4181:                     $result .= '</tr>';
                   4182:                 }
                   4183:                 $result .= '<tr>';
                   4184:             }
1.549     raeburn  4185:             my $colspan;
                   4186:             if ($i == @{ $strings{$thistype} }-1) {
                   4187:                 $rem = @{ $strings{$thistype} }%($numinrow);
                   4188:                 if ($rem) {
                   4189:                     my $colsleft = $numinrow - $rem;
                   4190:                     if ($colsleft) {
                   4191:                         $colspan = $colsleft+1;
                   4192:                         $colspan = ' colspan="'.$colspan.'"';
                   4193:                     }
                   4194:                 }
                   4195:             }
                   4196:             my ($add,$onchange,$css_class);
                   4197:             if ($thistype eq 'string_lenient') {
                   4198:                 if ($name eq 'weighted') {
                   4199:                     my $display;
                   4200:                     my %relatives = &Apache::lonlocal::texthash(
                   4201:                                         corrchkd     => 'Correct (checked)',
                   4202:                                         corrunchkd   => 'Correct (unchecked)',
                   4203:                                         incorrchkd   => 'Incorrect (checked)',
                   4204:                                         incorrunchkd => 'Incorrect (unchecked)',
                   4205:                     );
                   4206:                     my %textval = (
                   4207:                                     corrchkd     => '1.0',
                   4208:                                     corrunchkd   => '1.0',
                   4209:                                     incorrchkd   => '0.0',
                   4210:                                     incorrunchkd => '0.0',
                   4211:                     );
                   4212:                     if ($showval =~ /^([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)$/) {
                   4213:                         $textval{'corrchkd'} = $1;
                   4214:                         $textval{'corrunchkd'} = $2;
                   4215:                         $textval{'incorrchkd'} = $3;
                   4216:                         $textval{'incorrunchkd'} = $4;
                   4217:                         $display = 'inline';
                   4218:                         $showval = $name;
                   4219:                     } else {
                   4220:                         $display = 'none';
                   4221:                     }
                   4222:                     $add = ' <div id="LC_parmtext_'.$thiskey.'" style="display:'.$display.'"><table>'.
                   4223:                            '<tr><th colspan="2">'.&mt("Foil's submission status").'</th><th>'.&mt('Points').'</th></tr>';  
                   4224:                     foreach my $reltype ('corrchkd','corrunchkd','incorrchkd','incorrunchkd') {
                   4225:                         $add .= '<tr><td>&nbsp;</td><td>'.$relatives{$reltype}.'</td>'."\n".
                   4226:                                 '<td><input type="text" name="settext_'.$thiskey.'"'.
1.552     raeburn  4227:                                 ' value="'.$textval{$reltype}.'" size="3"'.$disabled.' />'.
1.549     raeburn  4228:                                 '</td></tr>';
                   4229:                     }
                   4230:                     $add .= '</table></div>'."\n";
                   4231:                 }
                   4232:                 $onchange = ' onclick="javascript:toggleParmTextbox(this.form,'."'$thiskey'".');"';
                   4233:                 $css_class = ' class="LC_lenient_radio"';
                   4234:             }
                   4235:             $result .= '<td class="LC_left_item"'.$colspan.'>'.
1.504     raeburn  4236:                        '<span class="LC_nobreak"><label>'.
                   4237:                        '<input type="radio" name="set_'.$thiskey.
1.552     raeburn  4238:                        '" value="'.$name.'"'.$onchange.$css_class.$disabled;
1.504     raeburn  4239:             if ($showval eq $name) {
                   4240:                 $result .= ' checked="checked"';
                   4241:             }
1.549     raeburn  4242:             $result .= ' />'.&mt($description).'</label>'.$add.'</span></td>';
1.504     raeburn  4243:             $i++;
                   4244:         }
                   4245:         $result .= '</tr>';
1.473     amueller 4246:     }
1.504     raeburn  4247:     if ($result) {
                   4248:         $result = '<table border="0">'.$result.'</table>';
1.383     albertel 4249:     }
                   4250:     return $result;
                   4251: }
                   4252: 
1.554     raeburn  4253: my %intervals =
                   4254:     (
                   4255:      'date_interval'
                   4256:              => [[ 'done', 'Yes' ],
1.558     raeburn  4257:                  [ 'done_proctor', 'Yes, with proctor key'],                  
1.554     raeburn  4258:                  [ '', 'No' ]],
                   4259:     );
                   4260: 
                   4261: my %intervalmatches = (
                   4262:          'date_interval'
1.559     raeburn  4263:               => [['done','\d+_done(|\:[^\:]+\:)$'],
                   4264:                   ['done_proctor','\d+_done(|\:[^\:]+\:)_proctor_']],
1.554     raeburn  4265:     );
                   4266: 
                   4267: my %intervaltypes = (
                   4268:                       interval => 'date_interval',
                   4269:     );
                   4270: 
                   4271: sub standard_interval_matches {
                   4272:     my ($interval_type) = @_;
                   4273:     if (ref($intervalmatches{$interval_type}) eq 'ARRAY') {
                   4274:         return $intervalmatches{$interval_type};
                   4275:     }
                   4276:     return;
                   4277: }
                   4278: 
                   4279: sub get_intervaltype {
                   4280:     my ($name) = @_;
                   4281:     if (exists($intervaltypes{$name})) {
                   4282:         return $intervaltypes{$name};
                   4283:     }
                   4284:     return;
                   4285: }
                   4286: 
                   4287: sub standard_interval_options {
                   4288:     my ($interval_type) = @_;
                   4289:     if (ref($intervals{$interval_type}) eq 'ARRAY') {
                   4290:         return $intervals{$interval_type};
                   4291:     }
                   4292:     return;
                   4293: }
                   4294: 
                   4295: sub date_interval_selector {
                   4296:     my ($thiskey, $name, $showval, $readonly) = @_;
                   4297:     my ($result,%skipval);
                   4298:     if ($name eq 'interval') {
                   4299:         my $intervaltype = &get_intervaltype($name);
                   4300:         my ($got_chostname,$chostname,$cmajor,$cminor);
                   4301:         foreach my $possibilities (@{ $intervals{$intervaltype} }) {
                   4302:             next unless (ref($possibilities) eq 'ARRAY');
                   4303:             my ($parmval, $description) = @{ $possibilities };
                   4304:             my $parmmatch;
                   4305:             if (ref($intervalmatches{$intervaltype}) eq 'ARRAY') {
                   4306:                 foreach my $item (@{$intervalmatches{$intervaltype}}) {
                   4307:                     if (ref($item) eq 'ARRAY') {
                   4308:                         if ($parmval eq $item->[0]) {
                   4309:                             $parmmatch = $parmval;
                   4310:                             $parmval = '';
                   4311:                             last;
                   4312:                         }
                   4313:                     }
                   4314:                 }
                   4315:             }
                   4316:             my $needsrelease=$Apache::lonnet::needsrelease{"parameter:$name:$parmval:$parmmatch"};
                   4317:             if ($needsrelease) {
                   4318:                 unless ($got_chostname) {
                   4319:                     ($chostname,$cmajor,$cminor)=&parameter_release_vars();
                   4320:                     $got_chostname = 1;
                   4321:                 }
1.557     raeburn  4322:                 my $needsnewer=&parameter_releasecheck($name,$parmval,$parmmatch,undef,
1.554     raeburn  4323:                                                        $needsrelease,$cmajor,$cminor);
                   4324:                 if ($needsnewer) {
                   4325:                     if ($parmmatch ne '') {
                   4326:                         $skipval{$parmmatch} = 1;
                   4327:                     } elsif ($parmval ne '') {
                   4328:                         $skipval{$parmval} = 1;
                   4329:                     }
                   4330:                 }
                   4331:             }
                   4332:         }
                   4333:     }
                   4334: 
                   4335:     my $currval = $showval;
                   4336:     foreach my $which (['days', 86400, 31],
                   4337:                ['hours', 3600, 23],
                   4338:                ['minutes', 60, 59],
                   4339:                ['seconds',  1, 59]) {
1.560     damieng  4340:         my ($name, $factor, $max) = @{ $which };
                   4341:         my $amount = int($showval/$factor);
                   4342:         $showval  %= $factor;
                   4343:         my %select = ((map {$_ => $_} (0..$max)),
                   4344:                 'select_form_order' => [0..$max]);
                   4345:         $result .= &Apache::loncommon::select_form($amount,$name.'_'.$thiskey,
                   4346:                             \%select,'',$readonly);
                   4347:         $result .= ' '.&mt($name);
1.554     raeburn  4348:     }
                   4349:     if ($name eq 'interval') {
                   4350:         unless ($skipval{'done'}) {
                   4351:             my $checkedon = '';
1.558     raeburn  4352:             my $checkedproc = '';
                   4353:             my $currproctorkey = '';
                   4354:             my $currprocdisplay = 'hidden';
1.559     raeburn  4355:             my $currdonetext = &mt('Done');
1.554     raeburn  4356:             my $checkedoff = ' checked="checked"';
1.559     raeburn  4357:             if ($currval =~ /^(?:\d+)_done$/) {
                   4358:                 $checkedon = ' checked="checked"';
                   4359:                 $checkedoff = '';
                   4360:             } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:$/) {
                   4361:                 $currdonetext = $1;
1.554     raeburn  4362:                 $checkedon = ' checked="checked"';
                   4363:                 $checkedoff = '';
1.558     raeburn  4364:             } elsif ($currval =~ /^(?:\d+)_done_proctor_(.+)$/) {
                   4365:                 $currproctorkey = $1;
                   4366:                 $checkedproc = ' checked="checked"';
                   4367:                 $checkedoff = '';
                   4368:                 $currprocdisplay = 'text';
1.559     raeburn  4369:             } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:_proctor_(.+)$/) {
                   4370:                 $currdonetext = $1;
                   4371:                 $currproctorkey = $2;
                   4372:                 $checkedproc = ' checked="checked"';
                   4373:                 $checkedoff = '';
                   4374:                 $currprocdisplay = 'text';
1.554     raeburn  4375:             }
1.558     raeburn  4376:             my $onclick = ' onclick="toggleSecret(this.form,'."'done_','$thiskey'".');"';
                   4377:             $result .= '<br /><span class="LC_nobreak">'.&mt('Include "done" button').
                   4378:                        '<label><input type="radio" value="" name="done_'.$thiskey.'"'.$checkedoff.$onclick.' />'.
                   4379:                        &mt('No').'</label>'.('&nbsp;'x2).
                   4380:                        '<label><input type="radio" value="_done" name="done_'.$thiskey.'"'.$checkedon.$onclick.' />'.
                   4381:                        &mt('Yes').'</label>'.('&nbsp;'x2).
                   4382:                        '<label><input type="radio" value="_done_proctor" name="done_'.$thiskey.'"'.$checkedproc.$onclick.' />'.
                   4383:                        &mt('Yes, with proctor key').'</label>'.
                   4384:                        '<input type="'.$currprocdisplay.'" id="done_'.$thiskey.'_proctorkey" '.
1.559     raeburn  4385:                        'name="done_'.$thiskey.'_proctorkey" value="'.&HTML::Entities::encode($currproctorkey,'"<>&').'" /></span><br />'.
                   4386:                        '<span class="LC_nobreak">'.&mt('Button text').': '.
                   4387:                        '<input type="text" name="done_'.$thiskey.'_buttontext" value="'.&HTML::Entities::encode($currdonetext,'"<>&').'" /></span>';
1.554     raeburn  4388:         }
                   4389:     }
                   4390:     unless ($readonly) {
                   4391:         $result .= '<input type="hidden" name="dateinterval_'.$thiskey.'" />';
                   4392:     }
                   4393:     return $result;
                   4394: }
                   4395: 
1.549     raeburn  4396: sub oldversion_warning {
1.557     raeburn  4397:     my ($name,$namematch,$value,$chostname,$cmajor,$cminor,$needsrelease) = @_;
                   4398:     my $standard_name = &standard_parameter_names($name);
                   4399:     if ($namematch) {
                   4400:         my $level = &standard_parameter_levels($namematch);
                   4401:         my $msg = '';
                   4402:         if ($level) {
                   4403:             $msg = &mt('[_1] was [_2]not[_3] set at the level of: [_4].',
                   4404:                        $standard_name,'<b>','</b>','"'.$level.'"');
                   4405:         } else {
                   4406:             $msg = &mt('[_1] was [_2]not[_3] set.',
                   4407:                       $standard_name,'<b>','</b>');
                   4408:         }
                   4409:         return '<p class="LC_warning">'.$msg.'<br />'.
                   4410:                &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',
                   4411:                    $cmajor.'.'.$cminor,$chostname,
                   4412:                    $needsrelease).
                   4413:                    '</p>';
                   4414:     }
1.549     raeburn  4415:     my $desc;
                   4416:     my $stringtype = &get_stringtype($name);
                   4417:     if ($stringtype ne '') {
                   4418:         if ($name eq 'examcode') {
                   4419:             $desc = $value;
                   4420:         } elsif (ref($strings{$stringtypes{$name}}) eq 'ARRAY') {
                   4421:             foreach my $possibilities (@{ $strings{$stringtypes{$name}} }) {
                   4422:                 next unless (ref($possibilities) eq 'ARRAY');
                   4423:                 my ($parmval, $description) = @{ $possibilities };
                   4424:                 my $parmmatch;
                   4425:                 if (ref($stringmatches{$stringtypes{$name}}) eq 'ARRAY') {
                   4426:                     foreach my $item (@{$stringmatches{$stringtypes{$name}}}) {
                   4427:                         if (ref($item) eq 'ARRAY') {
                   4428:                             my ($regexpname,$pattern) = @{$item};
                   4429:                             if ($parmval eq $regexpname) {
                   4430:                                 if ($value =~ /$pattern/) {
                   4431:                                     $desc = $description; 
                   4432:                                     $parmmatch = 1;
                   4433:                                     last;
                   4434:                                 }
                   4435:                             }
                   4436:                         }
                   4437:                     }
                   4438:                     last if ($parmmatch);
                   4439:                 } elsif ($parmval eq $value) {
                   4440:                     $desc = $description;
                   4441:                     last;
                   4442:                 }
                   4443:             }
                   4444:         }
                   4445:     } elsif (($name eq 'printstartdate') || ($name eq 'printenddate')) {
                   4446:         my $now = time;
                   4447:         if ($value =~ /^\d+$/) {
                   4448:             if ($name eq 'printstartdate') {
                   4449:                 if ($value > $now) {
                   4450:                     $desc = &Apache::lonlocal::locallocaltime($value);
                   4451:                 }
                   4452:             } elsif ($name eq 'printenddate') {
                   4453:                 if ($value < $now) {
                   4454:                     $desc = &Apache::lonlocal::locallocaltime($value);
                   4455:                 }
                   4456:             }
                   4457:         }
                   4458:     }
                   4459:     return '<p class="LC_warning">'.
1.557     raeburn  4460:        &mt('[_1] was [_2]not[_3] set to [_4].',
                   4461:            $standard_name,'<b>','</b>','"'.$desc.'"').'<br />'.
                   4462:        &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',
                   4463:        $cmajor.'.'.$cminor,$chostname,
                   4464:        $needsrelease).
                   4465:        '</p>';
1.549     raeburn  4466: }
                   4467: 
1.560     damieng  4468: } # end of block using some constants related to parameter types
                   4469: 
1.549     raeburn  4470: 
1.389     www      4471: #
                   4472: # Shift all start and end dates by $shift
                   4473: #
                   4474: 
                   4475: sub dateshift {
                   4476:     my ($shift)=@_;
                   4477:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   4478:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
                   4479:     my %data=&Apache::lonnet::dump('resourcedata',$dom,$crs);
                   4480: # ugly retro fix for broken version of types
1.548     raeburn  4481:     foreach my $key (keys(%data)) {
1.389     www      4482:         if ($key=~/\wtype$/) {
                   4483:             my $newkey=$key;
                   4484:             $newkey=~s/type$/\.type/;
                   4485:             $data{$newkey}=$data{$key};
                   4486:             delete $data{$key};
                   4487:         }
                   4488:     }
1.391     www      4489:     my %storecontent=();
1.389     www      4490: # go through all parameters and look for dates
1.548     raeburn  4491:     foreach my $key (keys(%data)) {
1.389     www      4492:        if ($data{$key.'.type'}=~/^date_(start|end)$/) {
                   4493:           my $newdate=$data{$key}+$shift;
1.391     www      4494:           $storecontent{$key}=$newdate;
1.389     www      4495:        }
                   4496:     }
1.391     www      4497:     my $reply=&Apache::lonnet::cput
                   4498:                 ('resourcedata',\%storecontent,$dom,$crs);
                   4499:     if ($reply eq 'ok') {
                   4500:        &log_parmset(\%storecontent);
                   4501:     }
                   4502:     &Apache::lonnet::devalidatecourseresdata($crs,$dom);
                   4503:     return $reply;
1.389     www      4504: }
                   4505: 
1.208     www      4506: sub newoverview {
1.280     albertel 4507:     my ($r) = @_;
                   4508: 
1.208     www      4509:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   4510:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531     raeburn  4511:     my $crstype =  $env{'course.'.$env{'request.course.id'}.'.type'};
1.414     droeschl 4512:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
1.473     amueller 4513:         text=>"Overview Mode"});
1.523     raeburn  4514: 
                   4515:     my %loaditems = (
1.549     raeburn  4516:                       'onload'   => "showHide_courseContent(); resize_scrollbox('mapmenuscroll','1','1'); showHideLenient();",
1.523     raeburn  4517:                     );
                   4518:     my $js = '
                   4519: <script type="text/javascript">
                   4520: // <![CDATA[
                   4521: '.
                   4522:             &Apache::lonhtmlcommon::resize_scrollbox_js('params')."\n".
                   4523:             &showhide_js()."\n".
1.549     raeburn  4524:             &toggleparmtextbox_js()."\n".
                   4525:             &validateparms_js()."\n".
                   4526:             &ipacc_boxes_js()."\n".
1.558     raeburn  4527:             &done_proctor_js()."\n".
1.523     raeburn  4528: '// ]]>
                   4529: </script>
                   4530: ';
1.549     raeburn  4531: 
1.523     raeburn  4532:     my $start_page = &Apache::loncommon::start_page('Set Parameters',$js,
                   4533:                                                     {'add_entries' => \%loaditems,});
1.298     albertel 4534:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
1.507     www      4535:     $r->print($start_page.$breadcrumbs);
1.531     raeburn  4536:     &startSettingsScreen($r,'parmset',$crstype);
1.208     www      4537:     $r->print(<<ENDOVER);
1.549     raeburn  4538: <form method="post" action="/adm/parmset?action=newoverview" name="parmform" onsubmit="return validateParms();">
1.208     www      4539: ENDOVER
1.211     www      4540:     my @ids=();
                   4541:     my %typep=();
                   4542:     my %keyp=();
                   4543:     my %allparms=();
                   4544:     my %allparts=();
                   4545:     my %allmaps=();
                   4546:     my %mapp=();
                   4547:     my %symbp=();
                   4548:     my %maptitles=();
                   4549:     my %uris=();
                   4550:     my %keyorder=&standardkeyorder();
                   4551:     my %defkeytype=();
                   4552: 
                   4553:     my %alllevs=();
                   4554:     $alllevs{'Resource Level'}='full';
1.215     www      4555:     $alllevs{'Map/Folder Level'}='map';
1.211     www      4556:     $alllevs{'Course Level'}='general';
                   4557: 
                   4558:     my $csec=$env{'form.csec'};
1.269     raeburn  4559:     my $cgroup=$env{'form.cgroup'};
1.211     www      4560: 
                   4561:     my @pscat=&Apache::loncommon::get_env_multiple('form.pscat');
                   4562:     my $pschp=$env{'form.pschp'};
1.506     www      4563: 
1.211     www      4564:     my @psprt=&Apache::loncommon::get_env_multiple('form.psprt');
1.516     www      4565:     if (!@psprt) { $psprt[0]='all'; }
1.211     www      4566: 
1.446     bisitz   4567:     my @selected_sections =
1.473     amueller 4568:     &Apache::loncommon::get_env_multiple('form.Section');
1.211     www      4569:     @selected_sections = ('all') if (! @selected_sections);
1.374     albertel 4570:     foreach my $sec (@selected_sections) {
                   4571:         if ($sec eq 'all') {
1.211     www      4572:             @selected_sections = ('all');
                   4573:         }
                   4574:     }
1.552     raeburn  4575:     if ($env{'request.course.sec'} ne '') {
                   4576:         @selected_sections = ($env{'request.course.sec'});
                   4577:     }
1.269     raeburn  4578:     my @selected_groups =
                   4579:         &Apache::loncommon::get_env_multiple('form.Group');
1.211     www      4580: 
                   4581:     my $pssymb='';
                   4582:     my $parmlev='';
1.446     bisitz   4583: 
1.211     www      4584:     unless ($env{'form.parmlev'}) {
                   4585:         $parmlev = 'map';
                   4586:     } else {
                   4587:         $parmlev = $env{'form.parmlev'};
                   4588:     }
                   4589: 
1.446     bisitz   4590:     &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
1.473     amueller 4591:                 \%mapp, \%symbp,\%maptitles,\%uris,
                   4592:                 \%keyorder,\%defkeytype);
1.211     www      4593: 
1.374     albertel 4594:     if (grep {$_ eq 'all'} (@psprt)) {
1.481     amueller 4595:         @psprt = keys(%allparts);
1.374     albertel 4596:     }
1.211     www      4597: # Menu to select levels, etc
                   4598: 
1.456     bisitz   4599:     $r->print('<div class="LC_Box">');
1.445     neumanie 4600:     #$r->print('<h2 class="LC_hcell">Step 1</h2>');
1.452     bisitz   4601:     $r->print('<div>');
1.523     raeburn  4602:     $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel'));
1.211     www      4603:     &levelmenu($r,\%alllevs,$parmlev);
                   4604:     if ($parmlev ne 'general') {
1.447     bisitz   4605:         $r->print(&Apache::lonhtmlcommon::row_closure());
1.483     amueller 4606:         &mapmenu($r,\%allmaps,$pschp,\%maptitles,\%symbp);
1.211     www      4607:     }
1.447     bisitz   4608:     $r->print(&Apache::lonhtmlcommon::row_closure(1));
1.445     neumanie 4609:     $r->print(&Apache::lonhtmlcommon::end_pick_box());
                   4610:     $r->print('</div></div>');
1.446     bisitz   4611: 
1.456     bisitz   4612:     $r->print('<div class="LC_Box">');
1.452     bisitz   4613:     $r->print('<div>');
1.562   ! damieng  4614:     &displaymenu($r,\%allparms,\@pscat,\%keyorder); # FIXME: wrong parameters, could make keysindisplayorderCategory crash because $keyorder is undefined
1.453     schualex 4615:     $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.446     bisitz   4616:     $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View')));
1.553     raeburn  4617:     my $sectionselector = &sectionmenu(\@selected_sections);
                   4618:     my $groupselector = &groupmenu(\@selected_groups);
1.481     amueller 4619:     $r->print('<table>'.
1.553     raeburn  4620:               '<tr><th>'.&mt('Parts').'</th>');
                   4621:     if ($sectionselector) {
                   4622:         $r->print('<th>'.&mt('Section(s)').'</th>');
                   4623:     }
                   4624:     if ($groupselector) {
                   4625:         $r->print('<th>'.&mt('Group(s)').'</th>');
                   4626:     }
                   4627:     $r->print('</tr><tr><td>');
1.211     www      4628:     &partmenu($r,\%allparts,\@psprt);
1.553     raeburn  4629:     $r->print('</td>');
                   4630:     if ($sectionselector) { 
                   4631:         $r->print('<td>'.$sectionselector.'</td>');
                   4632:     }
                   4633:     if ($groupselector) {
                   4634:         $r->print('<td>'.$groupselector.'</td>');
                   4635:     }
                   4636:     $r->print('</tr></table>');
1.447     bisitz   4637:     $r->print(&Apache::lonhtmlcommon::row_closure(1));
1.445     neumanie 4638:     $r->print(&Apache::lonhtmlcommon::end_pick_box());
                   4639:     $r->print('</div></div>');
                   4640: 
1.456     bisitz   4641:     $r->print('<div class="LC_Box">');
1.452     bisitz   4642:     $r->print('<div>');
1.214     www      4643:     my $sortorder=$env{'form.sortorder'};
                   4644:     unless ($sortorder) { $sortorder='realmstudent'; }
                   4645:     &sortmenu($r,$sortorder);
1.445     neumanie 4646:     $r->print('</div></div>');
1.446     bisitz   4647: 
1.214     www      4648:     $r->print('<p><input type="submit" name="dis" value="'.&mt('Display').'" /></p>');
1.446     bisitz   4649: 
1.211     www      4650: # Build the list data hash from the specified parms
                   4651: 
                   4652:     my $listdata;
                   4653:     %{$listdata}=();
                   4654: 
                   4655:     foreach my $cat (@pscat) {
1.269     raeburn  4656:         &secgroup_lister($cat,$pschp,$parmlev,$listdata,\@psprt,\@selected_sections,\%defkeytype,\%allmaps,\@ids,\%symbp);
                   4657:         &secgroup_lister($cat,$pschp,$parmlev,$listdata,\@psprt,\@selected_groups,\%defkeytype,\%allmaps,\@ids,\%symbp);
1.211     www      4658:     }
                   4659: 
1.212     www      4660:     if (($env{'form.store'}) || ($env{'form.dis'})) {
1.211     www      4661: 
1.481     amueller 4662:         if ($env{'form.store'}) { &storedata($r,$crs,$dom); }
1.211     www      4663: 
                   4664: # Read modified data
                   4665: 
1.481     amueller 4666:         my $resourcedata=&readdata($crs,$dom);
1.211     www      4667: 
                   4668: # List data
                   4669: 
1.552     raeburn  4670:         &listdata($r,$resourcedata,$listdata,$sortorder,'newoverview');
1.211     www      4671:     }
                   4672:     $r->print(&tableend().
1.473     amueller 4673:          ((($env{'form.store'}) || ($env{'form.dis'}))?'<p><input type="submit" name="store" value="'.&mt('Save').'" /></p>':'').
1.507     www      4674:           '</form>');
                   4675:     &endSettingsScreen($r);
                   4676:     $r->print(&Apache::loncommon::end_page());
1.208     www      4677: }
                   4678: 
1.269     raeburn  4679: sub secgroup_lister {
                   4680:     my ($cat,$pschp,$parmlev,$listdata,$psprt,$selections,$defkeytype,$allmaps,$ids,$symbp) = @_;
                   4681:     foreach my $item (@{$selections}) {
                   4682:         foreach my $part (@{$psprt}) {
                   4683:             my $rootparmkey=$env{'request.course.id'};
                   4684:             if (($item ne 'all') && ($item ne 'none') && ($item)) {
                   4685:                 $rootparmkey.='.['.$item.']';
                   4686:             }
                   4687:             if ($parmlev eq 'general') {
                   4688: # course-level parameter
                   4689:                 my $newparmkey=$rootparmkey.'.'.$part.'.'.$cat;
                   4690:                 $$listdata{$newparmkey}=1;
                   4691:                 $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
                   4692:             } elsif ($parmlev eq 'map') {
                   4693: # map-level parameter
1.548     raeburn  4694:                 foreach my $mapid (keys(%{$allmaps})) {
1.269     raeburn  4695:                     if (($pschp ne 'all') && ($pschp ne $mapid)) { next; }
                   4696:                     my $newparmkey=$rootparmkey.'.'.$$allmaps{$mapid}.'___(all).'.$part.'.'.$cat;
                   4697:                     $$listdata{$newparmkey}=1;
                   4698:                     $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
1.556     raeburn  4699:                     $newparmkey=$rootparmkey.'.'.$$allmaps{$mapid}.'___(rec).'.$part.'.'.$cat;
                   4700:                     $$listdata{$newparmkey}=1;
                   4701:                     $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
1.269     raeburn  4702:                 }
                   4703:             } else {
                   4704: # resource-level parameter
                   4705:                 foreach my $rid (@{$ids}) {
                   4706:                     my ($map,$resid,$url)=&Apache::lonnet::decode_symb($$symbp{$rid});
                   4707:                     if (($pschp ne 'all') && ($$allmaps{$pschp} ne $map)) { next; }
                   4708:                     my $newparmkey=$rootparmkey.'.'.$$symbp{$rid}.'.'.$part.'.'.$cat;
                   4709:                     $$listdata{$newparmkey}=1;
                   4710:                     $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
                   4711:                 }
                   4712:             }
                   4713:         }
                   4714:     }
                   4715: }
                   4716: 
1.560     damieng  4717: # Display all existing parameter settings.
1.208     www      4718: sub overview {
1.280     albertel 4719:     my ($r) = @_;
1.208     www      4720:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   4721:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531     raeburn  4722:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.549     raeburn  4723:     my $js = '<script type="text/javascript">'."\n".
                   4724:              '// <![CDATA['."\n".
                   4725:              &toggleparmtextbox_js()."\n".
                   4726:              &validateparms_js()."\n".
                   4727:              &ipacc_boxes_js()."\n".
1.558     raeburn  4728:              &done_proctor_js()."\n".
1.549     raeburn  4729:              '// ]]>'."\n".
                   4730:              '</script>'."\n";
1.414     droeschl 4731:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
1.473     amueller 4732:     text=>"Overview Mode"});
1.549     raeburn  4733:     my %loaditems = (
                   4734:                       'onload'   => "showHideLenient();",
                   4735:                     );
                   4736: 
                   4737:     my $start_page=&Apache::loncommon::start_page('Modify Parameters',$js,{'add_entries' => \%loaditems,});
1.298     albertel 4738:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
1.507     www      4739:     $r->print($start_page.$breadcrumbs);
1.531     raeburn  4740:     &startSettingsScreen($r,'parmset',$crstype);
1.549     raeburn  4741:     $r->print('<form method="post" action="/adm/parmset?action=setoverview" name="parmform" onsubmit="return validateParms();">');
1.507     www      4742: 
1.208     www      4743: # Store modified
                   4744: 
                   4745:     &storedata($r,$crs,$dom);
                   4746: 
                   4747: # Read modified data
                   4748: 
1.552     raeburn  4749:     my ($resourcedata,$classlist)=&readdata($crs,$dom);
1.208     www      4750: 
1.214     www      4751: 
                   4752:     my $sortorder=$env{'form.sortorder'};
                   4753:     unless ($sortorder) { $sortorder='realmstudent'; }
                   4754:     &sortmenu($r,$sortorder);
                   4755: 
1.208     www      4756: # List data
                   4757: 
1.552     raeburn  4758:     my $foundkeys=&listdata($r,$resourcedata,$resourcedata,$sortorder,'overview',$classlist);
1.145     www      4759:     $r->print(&tableend().'<p>'.
1.527     bisitz   4760:     ($foundkeys?'<input type="submit" value="'.&mt('Save').'" />':'<span class="LC_info">'.&mt('There are no parameters.').'</span>').'</p></form>'.
1.473     amueller 4761:           &Apache::loncommon::end_page());
1.120     www      4762: }
1.121     www      4763: 
1.560     damieng  4764: # Unused sub.
1.333     albertel 4765: sub clean_parameters {
                   4766:     my ($r) = @_;
                   4767:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   4768:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
                   4769: 
1.414     droeschl 4770:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=cleanparameters',
1.473     amueller 4771:         text=>"Clean Parameters"});
1.333     albertel 4772:     my $start_page=&Apache::loncommon::start_page('Clean Parameters');
                   4773:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Clean');
                   4774:     $r->print(<<ENDOVER);
                   4775: $start_page
                   4776: $breadcrumbs
                   4777: <form method="post" action="/adm/parmset?action=cleanparameters" name="parmform">
                   4778: ENDOVER
                   4779: # Store modified
                   4780: 
                   4781:     &storedata($r,$crs,$dom);
                   4782: 
                   4783: # Read modified data
                   4784: 
                   4785:     my $resourcedata=&readdata($crs,$dom);
                   4786: 
                   4787: # List data
                   4788: 
                   4789:     $r->print('<h3>'.
1.473     amueller 4790:           &mt('These parameters refer to resources that do not exist.').
                   4791:           '</h3>'.
                   4792:           '<input type="submit" value="'.&mt('Delete Selected').'" />'.'<br />'.
                   4793:           '<br />');
1.333     albertel 4794:     $r->print(&Apache::loncommon::start_data_table().
1.473     amueller 4795:           '<tr>'.
                   4796:           '<th>'.&mt('Delete').'</th>'.
                   4797:           '<th>'.&mt('Parameter').'</th>'.
                   4798:           '</tr>');
1.333     albertel 4799:     foreach my $thiskey (sort(keys(%{$resourcedata}))) {
1.560     damieng  4800:         next if (!exists($resourcedata->{$thiskey.'.type'})
                   4801:             && $thiskey=~/\.type$/);
                   4802:         my %data = &parse_key($thiskey);
                   4803:         if (1) { #exists($data{'realm_exists'})
                   4804:             #&& !$data{'realm_exists'}) {
                   4805:             $r->print(&Apache::loncommon::start_data_table_row().
                   4806:                 '<tr>'.
                   4807:                 '<td><input type="checkbox" name="del_'.$thiskey.'" /></td>'              );
                   4808: 
                   4809:             $r->print('<td>');
                   4810:             my $display_value = $resourcedata->{$thiskey};
                   4811:             if (&isdateparm($resourcedata->{$thiskey.'.type'})) {
                   4812:             $display_value =
                   4813:                 &Apache::lonlocal::locallocaltime($display_value);
                   4814:             }
1.470     raeburn  4815:             my $parmitem = &standard_parameter_names($data{'parameter_name'});
                   4816:             $parmitem = &mt($parmitem);
1.560     damieng  4817:             $r->print(&mt('Parameter: "[_1]" with value: "[_2]"',
                   4818:                 $parmitem,$resourcedata->{$thiskey}));
                   4819:             $r->print('<br />');
                   4820:             if ($data{'scope_type'} eq 'all') {
                   4821:                 $r->print(&mt('All users'));
                   4822:             } elsif ($data{'scope_type'} eq 'user') {
                   4823:                 $r->print(&mt('User: [_1]',join(':',@{$data{'scope'}})));
                   4824:             } elsif ($data{'scope_type'} eq 'section') {
                   4825:                 $r->print(&mt('Section: [_1]',$data{'scope'}));
                   4826:             } elsif ($data{'scope_type'} eq 'group') {
                   4827:                 $r->print(&mt('Group: [_1]',$data{'scope'}));
                   4828:             }
                   4829:             $r->print('<br />');
                   4830:             if ($data{'realm_type'} eq 'all') {
                   4831:                 $r->print(&mt('All Resources'));
                   4832:             } elsif ($data{'realm_type'} eq 'folder') {
                   4833:                 $r->print(&mt('Folder: [_1]'),$data{'realm'});
                   4834:             } elsif ($data{'realm_type'} eq 'symb') {
                   4835:             my ($map,$resid,$url) =
                   4836:                 &Apache::lonnet::decode_symb($data{'realm'});
                   4837:             $r->print(&mt('Resource: [_1]with ID: [_2]in folder [_3]',
                   4838:                         $url.' <br />&nbsp;&nbsp;&nbsp;',
                   4839:                         $resid.' <br />&nbsp;&nbsp;&nbsp;',$map));
                   4840:             }
                   4841:             $r->print(' <br />&nbsp;&nbsp;&nbsp;'.&mt('Part: [_1]',$data{'parameter_part'}));
                   4842:             $r->print('</td></tr>');
                   4843: 
1.473     amueller 4844:         }
1.333     albertel 4845:     }
                   4846:     $r->print(&Apache::loncommon::end_data_table().'<p>'.
1.473     amueller 4847:           '<input type="submit" value="'.&mt('Delete Selected').'" />'.
1.507     www      4848:           '</p></form>');
                   4849:     &endSettingsScreen($r);
                   4850:     $r->print(&Apache::loncommon::end_page());
1.333     albertel 4851: }
                   4852: 
1.560     damieng  4853: # Overview mode, UI to shift all dates.
1.390     www      4854: sub date_shift_one {
                   4855:     my ($r) = @_;
                   4856:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   4857:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531     raeburn  4858:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.390     www      4859: 
1.414     droeschl 4860:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
1.473     amueller 4861:         text=>"Shifting Dates"});
1.390     www      4862:     my $start_page=&Apache::loncommon::start_page('Shift Dates');
                   4863:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
1.507     www      4864:     $r->print($start_page.$breadcrumbs);
1.531     raeburn  4865:     &startSettingsScreen($r,'parmset',$crstype);
1.538     bisitz   4866:     $r->print('<form name="shiftform" method="post" action="">'.
1.390     www      4867:               '<table><tr><td>'.&mt('Currently set date:').'</td><td>'.
                   4868:               &Apache::lonlocal::locallocaltime($env{'form.timebase'}).'</td></tr>'.
                   4869:               '<tr><td>'.&mt('Shifted date:').'</td><td>'.
1.541     bisitz   4870:                     &Apache::lonhtmlcommon::date_setter('shiftform',
1.390     www      4871:                                                         'timeshifted',
                   4872:                                                         $env{'form.timebase'},,
                   4873:                                                         '').
                   4874:               '</td></tr></table>'.
                   4875:               '<input type="hidden" name="action" value="dateshift2" />'.
                   4876:               '<input type="hidden" name="timebase" value="'.$env{'form.timebase'}.'" />'.
                   4877:               '<input type="submit" value="'.&mt('Shift all dates accordingly').'" /></form>');
1.507     www      4878:     &endSettingsScreen($r);
1.390     www      4879:     $r->print(&Apache::loncommon::end_page());
                   4880: }
                   4881: 
1.560     damieng  4882: # Overview mode, UI to shift all dates (second form).
1.390     www      4883: sub date_shift_two {
                   4884:     my ($r) = @_;
                   4885:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   4886:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531     raeburn  4887:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.414     droeschl 4888:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
1.473     amueller 4889:         text=>"Shifting Dates"});
1.390     www      4890:     my $start_page=&Apache::loncommon::start_page('Shift Dates');
                   4891:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
1.507     www      4892:     $r->print($start_page.$breadcrumbs);
1.531     raeburn  4893:     &startSettingsScreen($r,'parmset',$crstype);
1.390     www      4894:     my $timeshifted=&Apache::lonhtmlcommon::get_date_from_form('timeshifted');
1.543     bisitz   4895:     $r->print('<h2>'.&mt('Shift Dates').'</h2>'.
                   4896:               '<p>'.&mt('Shifting all dates such that [_1] becomes [_2]',
1.390     www      4897:               &Apache::lonlocal::locallocaltime($env{'form.timebase'}),
1.543     bisitz   4898:               &Apache::lonlocal::locallocaltime($timeshifted)).'</p>');
1.390     www      4899:     my $delta=$timeshifted-$env{'form.timebase'};
                   4900:     &dateshift($delta);
1.543     bisitz   4901:     $r->print(
                   4902:         &Apache::lonhtmlcommon::confirm_success(&mt('Done')).
                   4903:         '<br /><br />'.
                   4904:         &Apache::lonhtmlcommon::actionbox(
                   4905:             ['<a href="/adm/parmset">'.&mt('Content and Problem Settings').'</a>']));
1.507     www      4906:     &endSettingsScreen($r);
1.390     www      4907:     $r->print(&Apache::loncommon::end_page());
                   4908: }
                   4909: 
1.333     albertel 4910: sub parse_key {
                   4911:     my ($key) = @_;
                   4912:     my %data;
                   4913:     my ($middle,$part,$name)=
1.473     amueller 4914:     ($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
1.333     albertel 4915:     $data{'scope_type'} = 'all';
                   4916:     if ($middle=~/^\[(.*)\]/) {
1.560     damieng  4917:         $data{'scope'} = $1;
                   4918:         if ($data{'scope'}=~/^useropt\:($match_username)\:($match_domain)/) {
                   4919:             $data{'scope_type'} = 'user';
                   4920:             $data{'scope'} = [$1,$2];
                   4921:         } else {
                   4922:             #FIXME check for group scope
                   4923:             $data{'scope_type'} = 'section';
                   4924:         }
                   4925:         $middle=~s/^\[(.*)\]//;
1.333     albertel 4926:     }
                   4927:     $middle=~s/\.+$//;
                   4928:     $middle=~s/^\.+//;
                   4929:     $data{'realm_type'}='all';
                   4930:     if ($middle=~/^(.+)\_\_\_\(all\)$/) {
1.560     damieng  4931:         $data{'realm'} = $1;
                   4932:         $data{'realm_type'} = 'folder';
                   4933:         $data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});
                   4934:         ($data{'realm_exists'}) = &Apache::lonnet::is_on_map($data{'realm'});
1.333     albertel 4935:     } elsif ($middle) {
1.560     damieng  4936:         $data{'realm'} = $middle;
                   4937:         $data{'realm_type'} = 'symb';
                   4938:         $data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});
                   4939:         my ($map,$resid,$url) = &Apache::lonnet::decode_symb($data{'realm'});
                   4940:         $data{'realm_exists'} = &Apache::lonnet::symbverify($data{'realm'},$url);
1.333     albertel 4941:     }
1.446     bisitz   4942: 
1.333     albertel 4943:     $data{'parameter_part'} = $part;
                   4944:     $data{'parameter_name'} = $name;
                   4945: 
                   4946:     return %data;
                   4947: }
                   4948: 
1.239     raeburn  4949: 
1.416     jms      4950: sub header {
1.507     www      4951:     return &Apache::loncommon::start_page('Settings');
1.416     jms      4952: }
1.193     albertel 4953: 
                   4954: 
                   4955: 
1.560     damieng  4956: ##################################################
                   4957: # MAIN MENU
                   4958: ##################################################
                   4959: 
1.193     albertel 4960: sub print_main_menu {
                   4961:     my ($r,$parm_permission)=@_;
                   4962:     #
1.414     droeschl 4963:     $r->print(&header());
1.507     www      4964:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Content and Problem Settings'));
1.531     raeburn  4965:     my $crstype = &Apache::loncommon::course_type();
                   4966:     my $lc_crstype = lc($crstype);
                   4967: 
                   4968:     &startSettingsScreen($r,'parmset',$crstype);
1.193     albertel 4969:     $r->print(<<ENDMAINFORMHEAD);
                   4970: <form method="post" enctype="multipart/form-data"
                   4971:       action="/adm/parmset" name="studentform">
                   4972: ENDMAINFORMHEAD
                   4973: #
1.195     albertel 4974:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   4975:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1.268     albertel 4976:     my $vgr  = &Apache::lonnet::allowed('vgr',$env{'request.course.id'});
1.366     albertel 4977:     my $mgr  = &Apache::lonnet::allowed('mgr',$env{'request.course.id'});
1.520     raeburn  4978:     my $dcm = &Apache::lonnet::allowed('dcm',$env{'request.course.id'});
                   4979:     if ((!$dcm) && ($env{'request.course.sec'} ne '')) {
                   4980:         $dcm = &Apache::lonnet::allowed('dcm',$env{'request.course.id'}.
                   4981:                                         '/'.$env{'request.course.sec'});
                   4982:     }
1.268     albertel 4983: 
1.193     albertel 4984:     my @menu =
1.507     www      4985:         ( { categorytitle=>"Content Settings for this $crstype",
1.473     amueller 4986:         items => [
                   4987:           { linktext => 'Portfolio Metadata',
                   4988:             url => '/adm/parmset?action=setrestrictmeta',
                   4989:             permission => $parm_permission,
1.477     raeburn  4990:             linktitle => "Restrict metadata for this $lc_crstype." ,
1.473     amueller 4991:             icon =>'contact-new.png'   ,
                   4992:             },
                   4993:           { linktext => 'Reset Student Access Times',
                   4994:             url => '/adm/helper/resettimes.helper',
                   4995:             permission => $mgr,
1.477     raeburn  4996:             linktitle => "Reset access times for folders/maps, resources or the $lc_crstype."  ,
1.473     amueller 4997:             icon => 'start-here.png'  ,
                   4998:             },
1.520     raeburn  4999:           { linktext => 'Blocking Communication/Resource Access',
                   5000:             url => '/adm/setblock',
                   5001:             permission => $dcm,
                   5002:             linktitle => 'Configure blocking of communication/collaboration and access to resources during an exam',
                   5003:             icon => 'comblock.png',
                   5004:             },
1.473     amueller 5005:           { linktext => 'Set Parameter Setting Default Actions',
                   5006:             url => '/adm/parmset?action=setdefaults',
                   5007:             permission => $parm_permission,
                   5008:             linktitle =>'Set default actions for parameters.'  ,
                   5009:             icon => 'folder-new.png'  ,
                   5010:             }]},
                   5011:       { categorytitle => 'New and Existing Parameter Settings for Resources',
                   5012:         items => [
                   5013:           { linktext => 'Edit Resource Parameters - Helper Mode',
                   5014:             url => '/adm/helper/parameter.helper',
                   5015:             permission => $parm_permission,
                   5016:             linktitle =>'Set/Modify resource parameters in helper mode.'  ,
                   5017:             icon => 'dialog-information.png'  ,
                   5018:             #help => 'Parameter_Helper',
                   5019:             },
                   5020:           { linktext => 'Edit Resource Parameters - Overview Mode',
                   5021:             url => '/adm/parmset?action=newoverview',
                   5022:             permission => $parm_permission,
                   5023:             linktitle =>'Set/Modify resource parameters in overview mode.'  ,
                   5024:             icon => 'edit-find.png'  ,
                   5025:             #help => 'Parameter_Overview',
                   5026:             },
                   5027:           { linktext => 'Edit Resource Parameters - Table Mode',
                   5028:             url => '/adm/parmset?action=settable',
                   5029:             permission => $parm_permission,
                   5030:             linktitle =>'Set/Modify resource parameters in table mode.'  ,
                   5031:             icon => 'edit-copy.png'  ,
                   5032:             #help => 'Table_Mode',
                   5033:             }]},
1.417     droeschl 5034:            { categorytitle => 'Existing Parameter Settings for Resources',
1.473     amueller 5035:          items => [
                   5036:           { linktext => 'Modify Resource Parameters - Overview Mode',
                   5037:             url => '/adm/parmset?action=setoverview',
                   5038:             permission => $parm_permission,
                   5039:             linktitle =>'Set/Modify existing resource parameters in overview mode.'  ,
                   5040:             icon => 'preferences-desktop-wallpaper.png'  ,
                   5041:             #help => 'Parameter_Overview',
                   5042:             },
                   5043:           { linktext => 'Change Log',
                   5044:             url => '/adm/parmset?action=parameterchangelog',
                   5045:             permission => $parm_permission,
1.477     raeburn  5046:             linktitle =>"View parameter and $lc_crstype blog posting/user notification change log."  ,
1.487     wenzelju 5047:             icon => 'document-properties.png',
1.473     amueller 5048:             }]}
1.193     albertel 5049:           );
1.414     droeschl 5050:     $r->print(&Apache::lonhtmlcommon::generate_menu(@menu));
1.539     raeburn  5051:     $r->print('</form>');
1.507     www      5052:     &endSettingsScreen($r);
1.539     raeburn  5053:     $r->print(&Apache::loncommon::end_page());
1.193     albertel 5054:     return;
                   5055: }
1.414     droeschl 5056: 
1.416     jms      5057: 
                   5058: 
1.560     damieng  5059: ##################################################
                   5060: # PORTFOLIO METADATA
                   5061: ##################################################
                   5062: 
1.252     banghart 5063: sub output_row {
1.347     banghart 5064:     my ($r, $field_name, $field_text, $added_flag) = @_;
1.252     banghart 5065:     my $output;
1.263     banghart 5066:     my $options=$env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.options'};
                   5067:     my $values=$env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.values'};
1.337     banghart 5068:     if (!defined($options)) {
1.254     banghart 5069:         $options = 'active,stuadd';
1.261     banghart 5070:         $values = '';
1.252     banghart 5071:     }
1.337     banghart 5072:     if (!($options =~ /deleted/)) {
                   5073:         my @options= ( ['active', 'Show to student'],
1.418     schafran 5074:                     ['stuadd', 'Provide text area for students to type metadata'],
1.351     banghart 5075:                     ['choices','Provide choices for students to select from']);
1.473     amueller 5076: #           ['onlyone','Student may select only one choice']);
1.337     banghart 5077:         if ($added_flag) {
                   5078:             push @options,['deleted', 'Delete Metadata Field'];
                   5079:         }
1.351     banghart 5080:        $output = &Apache::loncommon::start_data_table_row();
1.451     bisitz   5081:         $output .= '<td><strong>'.$field_text.':</strong></td>';
1.351     banghart 5082:         $output .= &Apache::loncommon::end_data_table_row();
1.337     banghart 5083:         foreach my $opt (@options) {
1.560     damieng  5084:             my $checked = ($options =~ m/$opt->[0]/) ? ' checked="checked" ' : '' ;
                   5085:             $output .= &Apache::loncommon::continue_data_table_row();
                   5086:             $output .= '<td>'.('&nbsp;' x 5).'<label>
                   5087:                     <input type="checkbox" name="'.
                   5088:                     $field_name.'_'.$opt->[0].'" value="yes"'.$checked.' />'.
                   5089:                     &mt($opt->[1]).'</label></td>';
                   5090:             $output .= &Apache::loncommon::end_data_table_row();
                   5091:         }
1.351     banghart 5092:         $output .= &Apache::loncommon::continue_data_table_row();
1.451     bisitz   5093:         $output .= '<td>'.('&nbsp;' x 10).'<input name="'.$field_name.'_values" type="text" value="'.$values.'" size="80" /></td>';
1.351     banghart 5094:         $output .= &Apache::loncommon::end_data_table_row();
                   5095:         my $multiple_checked;
                   5096:         my $single_checked;
                   5097:         if ($options =~ m/onlyone/) {
1.422     bisitz   5098:             $multiple_checked = '';
1.423     bisitz   5099:             $single_checked = ' checked="checked"';
1.351     banghart 5100:         } else {
1.423     bisitz   5101:             $multiple_checked = ' checked="checked"';
1.422     bisitz   5102:             $single_checked = '';
1.351     banghart 5103:         }
1.560     damieng  5104:         $output .= &Apache::loncommon::continue_data_table_row();
                   5105:         $output .= '<td>'.('&nbsp;' x 10).'
                   5106:                     <input type="radio" name="'.$field_name.'_onlyone" value="multiple"'.$multiple_checked .' />
                   5107:                     '.&mt('Student may select multiple choices from list').'</td>';
                   5108:         $output .= &Apache::loncommon::end_data_table_row();
                   5109:         $output .= &Apache::loncommon::continue_data_table_row();
                   5110:         $output .= '<td>'.('&nbsp;' x 10).'
                   5111:                     <input type="radio" name="'.$field_name.'_onlyone"  value="single"'.$single_checked.' />
                   5112:                     '.&mt('Student may select only one choice from list').'</td>';
                   5113:         $output .= &Apache::loncommon::end_data_table_row();
1.252     banghart 5114:     }
                   5115:     return ($output);
                   5116: }
1.416     jms      5117: 
                   5118: 
1.560     damieng  5119: # UI to order portfolio metadata fields.
1.340     banghart 5120: sub order_meta_fields {
                   5121:     my ($r)=@_;
                   5122:     my $idx = 1;
                   5123:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   5124:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531     raeburn  5125:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};;
1.341     banghart 5126:     $r->print(&Apache::loncommon::start_page('Order Metadata Fields'));
1.560     damieng  5127:     &Apache::lonhtmlcommon::add_breadcrumb(
                   5128:         {href=>'/adm/parmset?action=addmetadata',
1.473     amueller 5129:         text=>"Add Metadata Field"});
1.560     damieng  5130:     &Apache::lonhtmlcommon::add_breadcrumb(
                   5131:         {href=>"/adm/parmset?action=setrestrictmeta",
                   5132:         text=>"Restrict Metadata"},
                   5133:         {text=>"Order Metadata"});
1.345     banghart 5134:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Order Metadata'));
1.531     raeburn  5135:     &startSettingsScreen($r,'parmset',$crstype);
1.340     banghart 5136:     if ($env{'form.storeorder'}) {
                   5137:         my $newpos = $env{'form.newpos'} - 1;
                   5138:         my $currentpos = $env{'form.currentpos'} - 1;
                   5139:         my @neworder = ();
1.548     raeburn  5140:         my @oldorder = split(/,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'});
1.340     banghart 5141:         my $i;
1.341     banghart 5142:         if ($newpos > $currentpos) {
1.340     banghart 5143:         # moving stuff up
                   5144:             for ($i=0;$i<$currentpos;$i++) {
1.560     damieng  5145:                 $neworder[$i]=$oldorder[$i];
1.340     banghart 5146:             }
                   5147:             for ($i=$currentpos;$i<$newpos;$i++) {
1.560     damieng  5148:                 $neworder[$i]=$oldorder[$i+1];
1.340     banghart 5149:             }
                   5150:             $neworder[$newpos]=$oldorder[$currentpos];
                   5151:             for ($i=$newpos+1;$i<=$#oldorder;$i++) {
1.560     damieng  5152:                 $neworder[$i]=$oldorder[$i];
1.340     banghart 5153:             }
                   5154:         } else {
                   5155:         # moving stuff down
1.473     amueller 5156:             for ($i=0;$i<$newpos;$i++) {
                   5157:                 $neworder[$i]=$oldorder[$i];
                   5158:             }
                   5159:             $neworder[$newpos]=$oldorder[$currentpos];
                   5160:             for ($i=$newpos+1;$i<$currentpos+1;$i++) {
                   5161:                 $neworder[$i]=$oldorder[$i-1];
                   5162:             }
                   5163:             for ($i=$currentpos+1;$i<=$#oldorder;$i++) {
                   5164:                 $neworder[$i]=$oldorder[$i];
                   5165:             }
1.340     banghart 5166:         }
1.560     damieng  5167:         my $ordered_fields = join ",", @neworder;
1.343     banghart 5168:         my $put_result = &Apache::lonnet::put('environment',
1.560     damieng  5169:                         {'metadata.addedorder'=>$ordered_fields},$dom,$crs);
                   5170:         &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.metadata.addedorder' => $ordered_fields});
1.340     banghart 5171:     }
1.357     raeburn  5172:     my $fields = &get_added_meta_fieldnames($env{'request.course.id'});
1.341     banghart 5173:     my $ordered_fields;
1.548     raeburn  5174:     my @fields_in_order = split(/,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'});
1.340     banghart 5175:     if (!@fields_in_order) {
                   5176:         # no order found, pick sorted order then create metadata.addedorder key.
1.548     raeburn  5177:         foreach my $key (sort(keys(%$fields))) {
1.340     banghart 5178:             push @fields_in_order, $key;
1.341     banghart 5179:             $ordered_fields = join ",", @fields_in_order;
1.340     banghart 5180:         }
1.341     banghart 5181:         my $put_result = &Apache::lonnet::put('environment',
1.446     bisitz   5182:                             {'metadata.addedorder'=>$ordered_fields},$dom,$crs);
                   5183:     }
1.340     banghart 5184:     $r->print('<table>');
                   5185:     my $num_fields = scalar(@fields_in_order);
                   5186:     foreach my $key (@fields_in_order) {
                   5187:         $r->print('<tr><td>');
                   5188:         $r->print('<form method="post" action="">');
1.537     bisitz   5189:         $r->print('<select name="newpos" onchange="this.form.submit()">');
1.340     banghart 5190:         for (my $i = 1;$i le $num_fields;$i ++) {
                   5191:             if ($i eq $idx) {
                   5192:                 $r->print('<option value="'.$i.'"  SELECTED>('.$i.')</option>');
                   5193:             } else {
                   5194:                 $r->print('<option value="'.$i.'">'.$i.'</option>');
                   5195:             }
                   5196:         }
                   5197:         $r->print('</select></td><td>');
                   5198:         $r->print('<input type="hidden" name="currentpos" value="'.$idx.'" />');
                   5199:         $r->print('<input type="hidden" name="storeorder" value="true" />');
                   5200:         $r->print('</form>');
                   5201:         $r->print($$fields{$key}.'</td></tr>');
                   5202:         $idx ++;
                   5203:     }
                   5204:     $r->print('</table>');
1.507     www      5205:     &endSettingsScreen($r);
1.340     banghart 5206:     return 'ok';
                   5207: }
1.416     jms      5208: 
                   5209: 
1.359     banghart 5210: sub continue {
                   5211:     my $output;
                   5212:     $output .= '<form action="" method="post">';
                   5213:     $output .= '<input type="hidden" name="action" value="setrestrictmeta" />';
                   5214:     $output .= '<input type="submit" value="Continue" />';
                   5215:     return ($output);
                   5216: }
1.416     jms      5217: 
                   5218: 
1.334     banghart 5219: sub addmetafield {
                   5220:     my ($r)=@_;
1.414     droeschl 5221:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=addmetadata',
1.473     amueller 5222:         text=>"Add Metadata Field"});
1.334     banghart 5223:     $r->print(&Apache::loncommon::start_page('Add Metadata Field'));
                   5224:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Add Metadata Field'));
1.335     banghart 5225:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   5226:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531     raeburn  5227:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
                   5228:     &startSettingsScreen($r,'parmset',$crstype);
1.339     banghart 5229:     if (exists($env{'form.undelete'})) {
1.358     banghart 5230:         my @meta_fields = &Apache::loncommon::get_env_multiple('form.undeletefield');
1.339     banghart 5231:         foreach my $meta_field(@meta_fields) {
                   5232:             my $options = $env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.options'};
                   5233:             $options =~ s/deleted//;
                   5234:             $options =~ s/,,/,/;
                   5235:             my $put_result = &Apache::lonnet::put('environment',
                   5236:                                         {'metadata.'.$meta_field.'.options'=>$options},$dom,$crs);
1.446     bisitz   5237: 
1.339     banghart 5238:             $r->print('Undeleted Metadata Field <strong>'.$env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.added'}."</strong> with result ".$put_result.'<br />');
                   5239:         }
1.359     banghart 5240:         $r->print(&continue());
1.339     banghart 5241:     } elsif (exists($env{'form.fieldname'})) {
1.335     banghart 5242:         my $meta_field = $env{'form.fieldname'};
                   5243:         my $display_field = $env{'form.fieldname'};
                   5244:         $meta_field =~ s/\W/_/g;
1.338     banghart 5245:         $meta_field =~ tr/A-Z/a-z/;
1.335     banghart 5246:         my $put_result = &Apache::lonnet::put('environment',
                   5247:                             {'metadata.'.$meta_field.'.values'=>"",
                   5248:                              'metadata.'.$meta_field.'.added'=>"$display_field",
                   5249:                              'metadata.'.$meta_field.'.options'=>""},$dom,$crs);
1.359     banghart 5250:         $r->print('Added new Metadata Field <strong>'.$env{'form.fieldname'}."</strong> with result ".$put_result.'<br />');
                   5251:         $r->print(&continue());
1.335     banghart 5252:     } else {
1.357     raeburn  5253:         my $fields = &get_deleted_meta_fieldnames($env{'request.course.id'});
1.339     banghart 5254:         if ($fields) {
                   5255:             $r->print('You may undelete previously deleted fields.<br />Check those you wish to undelete and click Undelete.<br />');
                   5256:             $r->print('<form method="post" action="">');
                   5257:             foreach my $key(keys(%$fields)) {
1.358     banghart 5258:                 $r->print('<input type="checkbox" name="undeletefield" value="'.$key.'" />'.$$fields{$key}.'<br /');
1.339     banghart 5259:             }
                   5260:             $r->print('<input type="submit" name="undelete" value="Undelete" />');
                   5261:             $r->print('</form>');
                   5262:         }
                   5263:         $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 5264:         $r->print('<input type="text" name="fieldname" /><br />');
                   5265:         $r->print('<input type="submit" value="Add Metadata Field" />');
1.334     banghart 5266:     }
1.361     albertel 5267:     $r->print('</form>');
1.507     www      5268:     &endSettingsScreen($r);
1.334     banghart 5269: }
1.416     jms      5270: 
                   5271: 
                   5272: 
1.560     damieng  5273: # Display or save portfolio metadata.
1.259     banghart 5274: sub setrestrictmeta {
1.240     banghart 5275:     my ($r)=@_;
1.242     banghart 5276:     my $next_meta;
1.244     banghart 5277:     my $output;
1.245     banghart 5278:     my $item_num;
1.246     banghart 5279:     my $put_result;
1.414     droeschl 5280:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setrestrictmeta',
1.473     amueller 5281:         text=>"Restrict Metadata"});
1.280     albertel 5282:     $r->print(&Apache::loncommon::start_page('Restrict Metadata'));
1.298     albertel 5283:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Restrict Metadata'));
1.240     banghart 5284:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   5285:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531     raeburn  5286:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
                   5287:     &startSettingsScreen($r,'parmset',$crstype);
1.259     banghart 5288:     my $key_base = $env{'course.'.$env{'request.course.id'}.'.'};
1.252     banghart 5289:     my $save_field = '';
1.259     banghart 5290:     if ($env{'form.restrictmeta'}) {
1.254     banghart 5291:         foreach my $field (sort(keys(%env))) {
1.252     banghart 5292:             if ($field=~m/^form.(.+)_(.+)$/) {
1.254     banghart 5293:                 my $options;
1.252     banghart 5294:                 my $meta_field = $1;
                   5295:                 my $meta_key = $2;
1.253     banghart 5296:                 if ($save_field ne $meta_field) {
1.252     banghart 5297:                     $save_field = $meta_field;
1.473     amueller 5298:                     if ($env{'form.'.$meta_field.'_stuadd'}) {
                   5299:                         $options.='stuadd,';
                   5300:                     }
                   5301:                     if ($env{'form.'.$meta_field.'_choices'}) {
                   5302:                         $options.='choices,';
                   5303:                     }
                   5304:                     if ($env{'form.'.$meta_field.'_onlyone'} eq 'single') {
                   5305:                         $options.='onlyone,';
                   5306:                     }
                   5307:                     if ($env{'form.'.$meta_field.'_active'}) {
                   5308:                         $options.='active,';
                   5309:                     }
                   5310:                     if ($env{'form.'.$meta_field.'_deleted'}) {
                   5311:                         $options.='deleted,';
                   5312:                     }
1.259     banghart 5313:                     my $name = $save_field;
1.560     damieng  5314:                     $put_result = &Apache::lonnet::put('environment',
                   5315:                         {'metadata.'.$meta_field.'.options'=>$options,
                   5316:                         'metadata.'.$meta_field.'.values'=>$env{'form.'.$meta_field.'_values'},
                   5317:                         },$dom,$crs);
1.252     banghart 5318:                 }
                   5319:             }
                   5320:         }
                   5321:     }
1.296     albertel 5322:     &Apache::lonnet::coursedescription($env{'request.course.id'},
1.473     amueller 5323:                        {'freshen_cache' => 1});
1.335     banghart 5324:     # Get the default metadata fields
1.258     albertel 5325:     my %metadata_fields = &Apache::lonmeta::fieldnames('portfolio');
1.335     banghart 5326:     # Now get possible added metadata fields
1.357     raeburn  5327:     my $added_metadata_fields = &get_added_meta_fieldnames($env{'request.course.id'});
1.346     banghart 5328:     my $row_alt = 1;
1.347     banghart 5329:     $output .= &Apache::loncommon::start_data_table();
1.258     albertel 5330:     foreach my $field (sort(keys(%metadata_fields))) {
1.265     banghart 5331:         if ($field ne 'courserestricted') {
1.346     banghart 5332:             $row_alt = $row_alt ? 0 : 1;
1.560     damieng  5333:             $output.= &output_row($r, $field, $metadata_fields{$field});
                   5334:         }
1.255     banghart 5335:     }
1.351     banghart 5336:     my $buttons = (<<ENDButtons);
                   5337:         <input type="submit" name="restrictmeta" value="Save" />
                   5338:         </form><br />
                   5339:         <form method="post" action="/adm/parmset?action=addmetadata" name="form1">
                   5340:         <input type="submit" name="restrictmeta" value="Add a Metadata Field" />
                   5341:         </form>
                   5342:         <br />
                   5343:         <form method="post" action="/adm/parmset?action=ordermetadata" name="form2">
                   5344:         <input type="submit" name="restrictmeta" value="Order Metadata Fields" />
                   5345: ENDButtons
1.337     banghart 5346:     my $added_flag = 1;
1.335     banghart 5347:     foreach my $field (sort(keys(%$added_metadata_fields))) {
1.346     banghart 5348:         $row_alt = $row_alt ? 0 : 1;
                   5349:         $output.= &output_row($r, $field, $$added_metadata_fields{$field},$added_flag, $row_alt);
1.335     banghart 5350:     }
1.347     banghart 5351:     $output .= &Apache::loncommon::end_data_table();
1.446     bisitz   5352:     $r->print(<<ENDenv);
1.259     banghart 5353:         <form method="post" action="/adm/parmset?action=setrestrictmeta" name="form">
1.244     banghart 5354:         $output
1.351     banghart 5355:         $buttons
1.340     banghart 5356:         </form>
1.244     banghart 5357: ENDenv
1.507     www      5358:     &endSettingsScreen($r);
1.280     albertel 5359:     $r->print(&Apache::loncommon::end_page());
1.240     banghart 5360:     return 'ok';
                   5361: }
1.416     jms      5362: 
                   5363: 
1.335     banghart 5364: sub get_added_meta_fieldnames {
1.357     raeburn  5365:     my ($cid) = @_;
1.335     banghart 5366:     my %fields;
                   5367:     foreach my $key(%env) {
1.357     raeburn  5368:         if ($key =~ m/\Q$cid\E\.metadata\.(.+)\.added$/) {
1.335     banghart 5369:             my $field_name = $1;
                   5370:             my ($display_field_name) = $env{$key};
                   5371:             $fields{$field_name} = $display_field_name;
                   5372:         }
                   5373:     }
                   5374:     return \%fields;
                   5375: }
1.416     jms      5376: 
                   5377: 
1.339     banghart 5378: sub get_deleted_meta_fieldnames {
1.357     raeburn  5379:     my ($cid) = @_;
1.339     banghart 5380:     my %fields;
                   5381:     foreach my $key(%env) {
1.357     raeburn  5382:         if ($key =~ m/\Q$cid\E\.metadata\.(.+)\.added$/) {
1.339     banghart 5383:             my $field_name = $1;
                   5384:             if ($env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.options'} =~ m/deleted/) {
                   5385:                 my ($display_field_name) = $env{$key};
                   5386:                 $fields{$field_name} = $display_field_name;
                   5387:             }
                   5388:         }
                   5389:     }
                   5390:     return \%fields;
                   5391: }
1.560     damieng  5392: 
                   5393: 
                   5394: ##################################################
                   5395: # PARAMETER SETTINGS DEFAULT ACTIONS
                   5396: ##################################################
                   5397: 
                   5398: # UI to change parameter setting default actions
1.220     www      5399: sub defaultsetter {
1.280     albertel 5400:     my ($r) = @_;
                   5401: 
1.414     droeschl 5402:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setdefaults',
1.473     amueller 5403:         text=>"Set Defaults"});
1.531     raeburn  5404:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   5405:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   5406:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.446     bisitz   5407:     my $start_page =
1.531     raeburn  5408:         &Apache::loncommon::start_page('Parameter Setting Default Actions');
1.298     albertel 5409:     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Defaults');
1.507     www      5410:     $r->print($start_page.$breadcrumbs);
1.531     raeburn  5411:     &startSettingsScreen($r,'parmset',$crstype);
1.507     www      5412:     $r->print('<form method="post" action="/adm/parmset?action=setdefaults" name="defaultform">');
1.280     albertel 5413: 
1.221     www      5414:     my @ids=();
                   5415:     my %typep=();
                   5416:     my %keyp=();
                   5417:     my %allparms=();
                   5418:     my %allparts=();
                   5419:     my %allmaps=();
                   5420:     my %mapp=();
                   5421:     my %symbp=();
                   5422:     my %maptitles=();
                   5423:     my %uris=();
                   5424:     my %keyorder=&standardkeyorder();
                   5425:     my %defkeytype=();
                   5426: 
1.446     bisitz   5427:     &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
1.473     amueller 5428:                 \%mapp, \%symbp,\%maptitles,\%uris,
                   5429:                 \%keyorder,\%defkeytype);
1.224     www      5430:     if ($env{'form.storerules'}) {
1.560     damieng  5431:         my %newrules=();
                   5432:         my @delrules=();
                   5433:         my %triggers=();
                   5434:         foreach my $key (keys(%env)) {
1.225     albertel 5435:             if ($key=~/^form\.(\w+)\_action$/) {
1.560     damieng  5436:                 my $tempkey=$1;
                   5437:                 my $action=$env{$key};
1.226     www      5438:                 if ($action) {
1.560     damieng  5439:                     $newrules{$tempkey.'_action'}=$action;
                   5440:                     if ($action ne 'default') {
                   5441:                         my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);
                   5442:                         $triggers{$whichparm}.=$tempkey.':';
                   5443:                     }
                   5444:                     $newrules{$tempkey.'_type'}=$defkeytype{$tempkey};
                   5445:                     if (&isdateparm($defkeytype{$tempkey})) {
                   5446:                         $newrules{$tempkey.'_days'}=$env{'form.'.$tempkey.'_days'};
                   5447:                         $newrules{$tempkey.'_hours'}=$env{'form.'.$tempkey.'_hours'};
                   5448:                         $newrules{$tempkey.'_min'}=$env{'form.'.$tempkey.'_min'};
                   5449:                         $newrules{$tempkey.'_sec'}=$env{'form.'.$tempkey.'_sec'};
                   5450:                     } else {
                   5451:                         $newrules{$tempkey.'_value'}=$env{'form.'.$tempkey.'_value'};
                   5452:                         $newrules{$tempkey.'_triggervalue'}=$env{'form.'.$tempkey.'_triggervalue'};
                   5453:                     }
                   5454:                 } else {
                   5455:                     push(@delrules,$tempkey.'_action');
                   5456:                     push(@delrules,$tempkey.'_type');
                   5457:                     push(@delrules,$tempkey.'_hours');
                   5458:                     push(@delrules,$tempkey.'_min');
                   5459:                     push(@delrules,$tempkey.'_sec');
                   5460:                     push(@delrules,$tempkey.'_value');
                   5461:                 }
1.473     amueller 5462:             }
                   5463:         }
1.560     damieng  5464:         foreach my $key (keys(%allparms)) {
                   5465:             $newrules{$key.'_triggers'}=$triggers{$key};
1.473     amueller 5466:         }
1.560     damieng  5467:         &Apache::lonnet::put('parmdefactions',\%newrules,$cdom,$cnum);
                   5468:         &Apache::lonnet::del('parmdefactions',\@delrules,$cdom,$cnum);
                   5469:         &resetrulescache();
1.224     www      5470:     }
1.227     www      5471:     my %lt=&Apache::lonlocal::texthash('days' => 'Days',
1.473     amueller 5472:                        'hours' => 'Hours',
                   5473:                        'min' => 'Minutes',
                   5474:                        'sec' => 'Seconds',
                   5475:                        'yes' => 'Yes',
                   5476:                        'no' => 'No');
1.222     www      5477:     my @standardoptions=('','default');
                   5478:     my @standarddisplay=('',&mt('Default value when manually setting'));
                   5479:     my @dateoptions=('','default');
                   5480:     my @datedisplay=('',&mt('Default value when manually setting'));
                   5481:     foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
1.560     damieng  5482:         unless ($tempkey) { next; }
                   5483:         push @standardoptions,'when_setting_'.$tempkey;
                   5484:         push @standarddisplay,&mt('Automatically set when setting ').$tempkey;
                   5485:         if (&isdateparm($defkeytype{$tempkey})) {
                   5486:             push @dateoptions,'later_than_'.$tempkey;
                   5487:             push @datedisplay,&mt('Automatically set later than ').$tempkey;
                   5488:             push @dateoptions,'earlier_than_'.$tempkey;
                   5489:             push @datedisplay,&mt('Automatically set earlier than ').$tempkey;
                   5490:         }
1.222     www      5491:     }
1.231     www      5492: $r->print(&mt('Manual setting rules apply to all interfaces.').'<br />'.
1.473     amueller 5493:       &mt('Automatic setting rules apply to table mode interfaces only.'));
1.318     albertel 5494:     $r->print("\n".&Apache::loncommon::start_data_table().
1.473     amueller 5495:           &Apache::loncommon::start_data_table_header_row().
                   5496:           "<th>".&mt('Rule for parameter').'</th><th>'.
                   5497:           &mt('Action').'</th><th>'.&mt('Value').'</th>'.
                   5498:           &Apache::loncommon::end_data_table_header_row());
1.221     www      5499:     foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
1.560     damieng  5500:         unless ($tempkey) { next; }
                   5501:         $r->print("\n".&Apache::loncommon::start_data_table_row().
                   5502:             "<td>".$allparms{$tempkey}."\n<br />(".$tempkey.')</td><td>');
                   5503:         my $action=&rulescache($tempkey.'_action');
                   5504:         $r->print('<select name="'.$tempkey.'_action">');
                   5505:         if (&isdateparm($defkeytype{$tempkey})) {
                   5506:             for (my $i=0;$i<=$#dateoptions;$i++) {
                   5507:             if ($dateoptions[$i]=~/\_$tempkey$/) { next; }
                   5508:             $r->print("\n<option value='$dateoptions[$i]'".
                   5509:                 ($dateoptions[$i] eq $action?' selected="selected"':'').
                   5510:                 ">$datedisplay[$i]</option>");
                   5511:             }
                   5512:         } else {
                   5513:             for (my $i=0;$i<=$#standardoptions;$i++) {
                   5514:             if ($standardoptions[$i]=~/\_$tempkey$/) { next; }
                   5515:             $r->print("\n<option value='$standardoptions[$i]'".
                   5516:                 ($standardoptions[$i] eq $action?' selected="selected"':'').
                   5517:                 ">$standarddisplay[$i]</option>");
                   5518:             }
1.473     amueller 5519:         }
1.560     damieng  5520:         $r->print('</select>');
                   5521:         unless (&isdateparm($defkeytype{$tempkey})) {
                   5522:             $r->print("\n<br />".&mt('Triggering value(s) of other parameter (optional, comma-separated):').
                   5523:                 '<input type="text" size="20" name="'.$tempkey.'_triggervalue" value="'.&rulescache($tempkey.'_triggervalue').'" />');
1.473     amueller 5524:         }
1.560     damieng  5525:         $r->print("\n</td><td>\n");
1.222     www      5526: 
1.221     www      5527:         if (&isdateparm($defkeytype{$tempkey})) {
1.560     damieng  5528:             my $days=&rulescache($tempkey.'_days');
                   5529:             my $hours=&rulescache($tempkey.'_hours');
                   5530:             my $min=&rulescache($tempkey.'_min');
                   5531:             my $sec=&rulescache($tempkey.'_sec');
                   5532:             $r->print(<<ENDINPUTDATE);
                   5533:     <input name="$tempkey\_days" type="text" size="4" value="$days" />$lt{'days'}<br />
                   5534:     <input name="$tempkey\_hours" type="text" size="4" value="$hours" />$lt{'hours'}<br />
                   5535:     <input name="$tempkey\_min" type="text" size="4" value="$min" />$lt{'min'}<br />
                   5536:     <input name="$tempkey\_sec" type="text" size="4" value="$sec" />$lt{'sec'}
                   5537:     ENDINPUTDATE
                   5538:         } elsif ($defkeytype{$tempkey} eq 'string_yesno') {
                   5539:                 my $yeschecked='';
                   5540:                 my $nochecked='';
                   5541:                 if (&rulescache($tempkey.'_value') eq 'yes') { $yeschecked=' checked="checked"'; }
                   5542:                 if (&rulescache($tempkey.'_value') eq 'no') { $nochecked=' checked="checked"'; }
                   5543: 
                   5544:             $r->print(<<ENDYESNO);
                   5545:     <label><input type="radio" name="$tempkey\_value" value="yes"$yeschecked /> $lt{'yes'}</label><br />
                   5546:     <label><input type="radio" name="$tempkey\_value" value="no"$nochecked /> $lt{'no'}</label>
                   5547:     ENDYESNO
1.221     www      5548:         } else {
1.560     damieng  5549:             $r->print('<input type="text" size="20" name="'.$tempkey.'_value" value="'.&rulescache($tempkey.'_value').'" />');
                   5550:         }
1.318     albertel 5551:         $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.221     www      5552:     }
1.318     albertel 5553:     $r->print(&Apache::loncommon::end_data_table().
1.473     amueller 5554:           "\n".'<input type="submit" name="storerules" value="'.
1.507     www      5555:           &mt('Save').'" /></form>'."\n");
                   5556:     &endSettingsScreen($r);
                   5557:     $r->print(&Apache::loncommon::end_page());
1.220     www      5558:     return;
                   5559: }
1.193     albertel 5560: 
1.560     damieng  5561: ##################################################
                   5562: # PARAMETER CHANGES LOG
                   5563: ##################################################
                   5564: 
1.290     www      5565: sub components {
1.330     albertel 5566:     my ($key,$uname,$udom,$exeuser,$exedomain,$typeflag)=@_;
                   5567: 
                   5568:     if ($typeflag) {
1.560     damieng  5569:         $key=~s/\.type$//;
1.290     www      5570:     }
1.330     albertel 5571: 
                   5572:     my ($middle,$part,$name)=
1.560     damieng  5573:         ($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
1.291     www      5574:     my $issection;
1.330     albertel 5575: 
1.290     www      5576:     my $section=&mt('All Students');
                   5577:     if ($middle=~/^\[(.*)\]/) {
1.560     damieng  5578:         $issection=$1;
                   5579:         $section=&mt('Group/Section').': '.$issection;
                   5580:         $middle=~s/^\[(.*)\]//;
1.290     www      5581:     }
                   5582:     $middle=~s/\.+$//;
                   5583:     $middle=~s/^\.+//;
1.291     www      5584:     if ($uname) {
1.560     damieng  5585:         $section=&mt('User').": ".&Apache::loncommon::plainname($uname,$udom);
                   5586:         $issection='';
1.291     www      5587:     }
1.316     albertel 5588:     my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
1.446     bisitz   5589:     my $realmdescription=&mt('all resources');
1.556     raeburn  5590:     if ($middle=~/^(.+)\_\_\_\((all|rec)\)$/) {
                   5591:         my $mapurl = $1;
                   5592:         my $maplevel = $2;
                   5593:         my $leveltitle = &mt('Folder/Map');
                   5594:         if ($maplevel eq 'rec') {
                   5595:             $leveltitle = &mt('Recursive');
                   5596:         }
1.560     damieng  5597:         $realm='<span class="LC_parm_scope_folder">'.$leveltitle.
                   5598:             ': '.&Apache::lonnet::gettitle($mapurl).' <span class="LC_parm_folder"><br />('.
                   5599:             $mapurl.')</span></span>';
                   5600:         $realmdescription=&mt('folder').' '.&Apache::lonnet::gettitle($mapurl);
                   5601:     } elsif ($middle) {
                   5602:         my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
                   5603:         $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').
                   5604:             ': '.&Apache::lonnet::gettitle($middle).' <br /><span class="LC_parm_symb">('.$url.
                   5605:             ' in '.$map.' id: '.$id.')</span></span>';
                   5606:         $realmdescription=&mt('resource').' '.&Apache::lonnet::gettitle($middle);
1.290     www      5607:     }
1.291     www      5608:     my $what=$part.'.'.$name;
1.330     albertel 5609:     return ($realm,$section,$name,$part,
1.473     amueller 5610:         $what,$middle,$uname,$udom,$issection,$realmdescription);
1.290     www      5611: }
1.293     www      5612: 
1.328     albertel 5613: my %standard_parms;
1.469     raeburn  5614: my %standard_parms_types;
1.416     jms      5615: 
1.328     albertel 5616: sub load_parameter_names {
                   5617:     open(my $config,"<$Apache::lonnet::perlvar{'lonTabDir'}/packages.tab");
                   5618:     while (my $configline=<$config>) {
1.560     damieng  5619:         if ($configline !~ /\S/ || $configline=~/^\#/) { next; }
                   5620:         chomp($configline);
                   5621:         my ($short,$plain)=split(/:/,$configline);
                   5622:         my (undef,$name,$type)=split(/\&/,$short,3);
                   5623:         if ($type eq 'display') {
                   5624:             $standard_parms{$name} = $plain;
1.469     raeburn  5625:         } elsif ($type eq 'type') {
1.560     damieng  5626:                 $standard_parms_types{$name} = $plain;
1.469     raeburn  5627:         }
1.328     albertel 5628:     }
                   5629:     close($config);
                   5630:     $standard_parms{'int_pos'}      = 'Positive Integer';
                   5631:     $standard_parms{'int_zero_pos'} = 'Positive Integer or Zero';
                   5632: }
                   5633: 
1.292     www      5634: sub standard_parameter_names {
                   5635:     my ($name)=@_;
1.328     albertel 5636:     if (!%standard_parms) {
1.560     damieng  5637:         &load_parameter_names();
1.328     albertel 5638:     }
1.292     www      5639:     if ($standard_parms{$name}) {
1.560     damieng  5640:         return $standard_parms{$name};
1.446     bisitz   5641:     } else {
1.560     damieng  5642:         return $name;
1.292     www      5643:     }
                   5644: }
1.290     www      5645: 
1.469     raeburn  5646: sub standard_parameter_types {
                   5647:     my ($name)=@_;
                   5648:     if (!%standard_parms_types) {
                   5649:         &load_parameter_names();
                   5650:     }
                   5651:     if ($standard_parms_types{$name}) {
                   5652:         return $standard_parms_types{$name};
                   5653:     }
                   5654:     return;
                   5655: }
1.309     www      5656: 
1.557     raeburn  5657: sub standard_parameter_levels {
                   5658:     my ($name)=@_;
                   5659:     my %levels = (
                   5660:                     'resourcelevel'   => 'a single resource',
                   5661:                     'maplevel'        => 'the enclosing map/folder', 
                   5662:                     'maplevelrecurse' => 'the enclosing map/folder (recursive into sub-folders)',
                   5663:                     'courselevel'     => 'the general (course) level',
                   5664:                  );
                   5665:     if ($levels{$name}) {
                   5666:         return $levels{$name};
                   5667:     }
                   5668:     return;
                   5669: }
                   5670: 
1.560     damieng  5671: # Display log for parameter changes, blog postings, user notification changes.
1.285     albertel 5672: sub parm_change_log {
1.284     www      5673:     my ($r)=@_;
1.531     raeburn  5674:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   5675:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   5676:     my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'}
1.414     droeschl 5677:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',
1.473     amueller 5678:     text=>"Parameter Change Log"});
1.522     raeburn  5679:     my $js = '<script type="text/javascript">'."\n".
                   5680:              '// <![CDATA['."\n".
                   5681:              &Apache::loncommon::display_filter_js('parmslog')."\n".
                   5682:              '// ]]>'."\n".
                   5683:              '</script>'."\n";
                   5684:     $r->print(&Apache::loncommon::start_page('Parameter Change Log',$js));
1.327     albertel 5685:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Parameter Change Log'));
1.531     raeburn  5686:     &startSettingsScreen($r,'parmset',$crstype);
                   5687:     my %parmlog=&Apache::lonnet::dump('nohist_parameterlog',$cdom,$cnum);
1.311     albertel 5688: 
1.301     www      5689:     if ((keys(%parmlog))[0]=~/^error\:/) { undef(%parmlog); }
1.311     albertel 5690: 
1.522     raeburn  5691:     $r->print('<div class="LC_left_float">'.
                   5692:               '<fieldset><legend>'.&mt('Display of Changes').'</legend>'.
                   5693:               '<form action="/adm/parmset?action=parameterchangelog"
1.327     albertel 5694:                      method="post" name="parameterlog">');
1.446     bisitz   5695: 
1.311     albertel 5696:     my %saveable_parameters = ('show' => 'scalar',);
                   5697:     &Apache::loncommon::store_course_settings('parameter_log',
                   5698:                                               \%saveable_parameters);
                   5699:     &Apache::loncommon::restore_course_settings('parameter_log',
                   5700:                                                 \%saveable_parameters);
1.522     raeburn  5701:     $r->print(&Apache::loncommon::display_filter('parmslog').'&nbsp;'."\n".
                   5702:               '<input type="submit" value="'.&mt('Display').'" />'.
                   5703:               '</form></fieldset></div><br clear="all" />');
1.301     www      5704: 
1.531     raeburn  5705:     my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
1.301     www      5706:     $r->print(&Apache::loncommon::start_data_table().&Apache::loncommon::start_data_table_header_row().
1.473     amueller 5707:           '<th>'.&mt('Time').'</th><th>'.&mt('User').'</th><th>'.&mt('Extent').'</th><th>'.&mt('Users').'</th><th>'.
                   5708:           &mt('Parameter').'</th><th>'.&mt('Part').'</th><th>'.&mt('New Value').'</th><th>'.&mt('Announce').'</th>'.
                   5709:           &Apache::loncommon::end_data_table_header_row());
1.309     www      5710:     my $shown=0;
1.349     www      5711:     my $folder='';
                   5712:     if ($env{'form.displayfilter'} eq 'currentfolder') {
1.560     damieng  5713:         my $last='';
                   5714:         if (tie(my %hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db',
                   5715:                 &GDBM_READER(),0640)) {
                   5716:             $last=$hash{'last_known'};
                   5717:             untie(%hash);
                   5718:         }
                   5719:         if ($last) { ($folder) = &Apache::lonnet::decode_symb($last); }
                   5720:     }
                   5721:     foreach my $id (sort {
                   5722:                 if ($parmlog{$b}{'exe_time'} ne $parmlog{$a}{'exe_time'}) {
                   5723:                     return $parmlog{$b}{'exe_time'} <=>$parmlog{$a}{'exe_time'}
                   5724:                 }
                   5725:                 my $aid = (split('00000',$a))[-1];
                   5726:                 my $bid = (split('00000',$b))[-1];
                   5727:                 return $bid<=>$aid;
1.473     amueller 5728:             } (keys(%parmlog))) {
1.294     www      5729:         my @changes=keys(%{$parmlog{$id}{'logentry'}});
1.560     damieng  5730:         my $count = 0;
                   5731:         my $time =
                   5732:             &Apache::lonlocal::locallocaltime($parmlog{$id}{'exe_time'});
                   5733:         my $plainname =
                   5734:             &Apache::loncommon::plainname($parmlog{$id}{'exe_uname'},
                   5735:                         $parmlog{$id}{'exe_udom'});
                   5736:         my $about_me_link =
                   5737:             &Apache::loncommon::aboutmewrapper($plainname,
                   5738:                             $parmlog{$id}{'exe_uname'},
                   5739:                             $parmlog{$id}{'exe_udom'});
                   5740:         my $send_msg_link='';
                   5741:         if ((($parmlog{$id}{'exe_uname'} ne $env{'user.name'})
                   5742:             || ($parmlog{$id}{'exe_udom'} ne $env{'user.domain'}))) {
                   5743:             $send_msg_link ='<br />'.
                   5744:             &Apache::loncommon::messagewrapper(&mt('Send message'),
                   5745:                             $parmlog{$id}{'exe_uname'},
                   5746:                             $parmlog{$id}{'exe_udom'});
                   5747:         }
                   5748:         my $row_start=&Apache::loncommon::start_data_table_row();
                   5749:         my $makenewrow=0;
                   5750:         my %istype=();
                   5751:         my $output;
                   5752:         foreach my $changed (reverse(sort(@changes))) {
                   5753:                 my $value=$parmlog{$id}{'logentry'}{$changed};
                   5754:             my $typeflag = ($changed =~/\.type$/ &&
                   5755:                     !exists($parmlog{$id}{'logentry'}{$changed.'.type'}));
1.330     albertel 5756:             my ($realm,$section,$parmname,$part,$what,$middle,$uname,$udom,$issection,$realmdescription)=
1.560     damieng  5757:                 &components($changed,$parmlog{$id}{'uname'},$parmlog{$id}{'udom'},undef,undef,$typeflag);
                   5758:             if ($env{'request.course.sec'} ne '') {
                   5759:                 next if (($issection ne '') && ($issection ne $env{'request.course.sec'}));
                   5760:                 if ($uname ne '') {
                   5761:                     my $stusection = &Apache::lonnet::getsection($uname,$udom,$env{'request.course.id'});
                   5762:                     next if (($stusection ne '-1') && ($stusection ne $env{'request.course.sec'})); 
                   5763:                 }
                   5764:             }
                   5765:             if ($env{'form.displayfilter'} eq 'currentfolder') {
                   5766:                 if ($folder) {
                   5767:                     if ($middle!~/^\Q$folder\E/) { next; }
                   5768:                 }
                   5769:             }
                   5770:             if ($typeflag) {
                   5771:                 $istype{$parmname}=$value;
                   5772:                 if (!$env{'form.includetypes'}) { next; }
                   5773:             }
                   5774:             $count++;
                   5775:             if ($makenewrow) {
                   5776:                 $output .= $row_start;
                   5777:             } else {
                   5778:                 $makenewrow=1;
                   5779:             }
1.470     raeburn  5780:             my $parmitem = &standard_parameter_names($parmname);
1.560     damieng  5781:             $output .='<td>'.$realm.'</td><td>'.$section.'</td><td>'.
                   5782:                 &mt($parmitem).'</td><td>'.
                   5783:                 ($part?&mt('Part: [_1]',$part):&mt('All Parts')).'</td><td>';
                   5784:             my $stillactive=0;
                   5785:             if ($parmlog{$id}{'delflag'}) {
                   5786:                 $output .= &mt('Deleted');
                   5787:             } else {
                   5788:                 if ($typeflag) {
1.470     raeburn  5789:                     my $parmitem = &standard_parameter_names($value); 
                   5790:                     $parmitem = &mt($parmitem);
1.560     damieng  5791:                     $output .= &mt('Type: [_1]',$parmitem);
                   5792:                 } else {
                   5793:                     my ($level,@all)=&parmval_by_symb($what,$middle,
                   5794:                         &Apache::lonnet::metadata($middle,$what),
                   5795:                         $uname,$udom,$issection,$issection,$courseopt);
1.469     raeburn  5796:                     my $showvalue = $value;
                   5797:                     if ($istype{$parmname} eq '') {
                   5798:                         my $type = &standard_parameter_types($parmname);
                   5799:                         if ($type ne '') {
                   5800:                             if (&isdateparm($type)) {
                   5801:                                 $showvalue =
                   5802:                                     &Apache::lonlocal::locallocaltime($value);
                   5803:                             }
                   5804:                         }
                   5805:                     } else {
1.560     damieng  5806:                         if (&isdateparm($istype{$parmname})) {
                   5807:                             $showvalue = &Apache::lonlocal::locallocaltime($value);
                   5808:                         }
1.469     raeburn  5809:                     }
                   5810:                     $output .= $showvalue;
1.560     damieng  5811:                     if ($value ne $all[$level]) {
                   5812:                         $output .= '<br /><span class="LC_warning">'.&mt('Not active anymore').'</span>';
                   5813:                     } else {
                   5814:                         $stillactive=1;
                   5815:                     }
                   5816:                 }
1.473     amueller 5817:             }
1.560     damieng  5818:             $output .= '</td><td>';
                   5819:                 
                   5820:             if ($stillactive) {
1.470     raeburn  5821:                 my $parmitem = &standard_parameter_names($parmname);
                   5822:                 $parmitem = &mt($parmitem);
1.560     damieng  5823:                 my $title=&mt('Changed [_1]',$parmitem);
1.471     raeburn  5824:                 my $description=&mt('Changed [_1] for [_2] to [_3]',
1.560     damieng  5825:                     $parmitem,$realmdescription,
1.473     amueller 5826:                     (&isdateparm($istype{$parmname})?&Apache::lonlocal::locallocaltime($value):$value));
1.560     damieng  5827:                 if (($uname) && ($udom)) {
                   5828:                     $output .=
                   5829:                     &Apache::loncommon::messagewrapper('Notify User',
                   5830:                                     $uname,$udom,$title,
                   5831:                                     $description);
                   5832:                 } else {
                   5833:                     $output .=
                   5834:                     &Apache::lonrss::course_blog_link($id,$title,
                   5835:                                     $description);
                   5836:                 }
                   5837:             }
                   5838:             $output .= '</td>'.&Apache::loncommon::end_data_table_row();
1.473     amueller 5839:         }
1.560     damieng  5840:         if ($env{'form.displayfilter'} eq 'containing') {
                   5841:             my $wholeentry=$about_me_link.':'.
                   5842:             $parmlog{$id}{'exe_uname'}.':'.$parmlog{$id}{'exe_udom'}.':'.
                   5843:             $output;
                   5844:             if ($wholeentry!~/\Q$env{'form.containingphrase'}\E/i) { next; }
1.473     amueller 5845:         }
1.349     www      5846:         if ($count) {
1.560     damieng  5847:             $r->print($row_start.'<td rowspan="'.$count.'">'.$time.'</td>
                   5848:                         <td rowspan="'.$count.'">'.$about_me_link.
                   5849:             '<br /><tt>'.$parmlog{$id}{'exe_uname'}.
                   5850:                         ':'.$parmlog{$id}{'exe_udom'}.'</tt>'.
                   5851:             $send_msg_link.'</td>'.$output);
                   5852:             $shown++;
                   5853:         }
                   5854:         if (!($env{'form.show'} eq &mt('all')
                   5855:             || $shown<=$env{'form.show'})) { last; }
1.286     www      5856:     }
1.301     www      5857:     $r->print(&Apache::loncommon::end_data_table());
1.507     www      5858:     &endSettingsScreen($r);
1.284     www      5859:     $r->print(&Apache::loncommon::end_page());
                   5860: }
                   5861: 
1.560     damieng  5862: ##################################################
                   5863: # MISC !
                   5864: ##################################################
                   5865: 
                   5866: # Used by table UI
1.437     raeburn  5867: sub update_slots {
                   5868:     my ($slot_name,$cdom,$cnum,$symb,$uname,$udom) = @_;
                   5869:     my %slot=&Apache::lonnet::get_slot($slot_name);
                   5870:     if (!keys(%slot)) {
                   5871:         return 'error: slot does not exist';
                   5872:     }
                   5873:     my $max=$slot{'maxspace'};
                   5874:     if (!defined($max)) { $max=99999; }
                   5875: 
                   5876:     my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
                   5877:                                        "^$slot_name\0");
                   5878:     my ($tmp)=%consumed;
                   5879:     if ($tmp=~/^error: 2 / ) {
                   5880:         return 'error: unable to determine current slot status';
                   5881:     }
                   5882:     my $last=0;
                   5883:     foreach my $key (keys(%consumed)) {
                   5884:         my $num=(split('\0',$key))[1];
                   5885:         if ($num > $last) { $last=$num; }
                   5886:         if ($consumed{$key}->{'name'} eq $uname.':'.$udom) {
                   5887:             return 'ok';
                   5888:         }
                   5889:     }
                   5890: 
                   5891:     if (scalar(keys(%consumed)) >= $max) {
                   5892:         return 'error: no space left in slot';
                   5893:     }
                   5894:     my $wanted=$last+1;
                   5895: 
                   5896:     my %reservation=('name'      => $uname.':'.$udom,
                   5897:                      'timestamp' => time,
                   5898:                      'symb'      => $symb);
                   5899: 
                   5900:     my $success=&Apache::lonnet::newput('slot_reservations',
                   5901:                                         {"$slot_name\0$wanted" =>
                   5902:                                              \%reservation},
                   5903:                                         $cdom, $cnum);
1.438     raeburn  5904:     if ($success eq 'ok') {
                   5905:         my %storehash = (
                   5906:                           symb    => $symb,
                   5907:                           slot    => $slot_name,
                   5908:                           action  => 'reserve',
                   5909:                           context => 'parameter',
                   5910:                         );
1.526     raeburn  5911:         &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,
1.524     raeburn  5912:                                    '',$uname,$udom,$cnum,$cdom);
1.438     raeburn  5913: 
1.526     raeburn  5914:         &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash,
1.524     raeburn  5915:                                    '',$uname,$udom,$uname,$udom);
1.438     raeburn  5916:     }
1.437     raeburn  5917:     return $success;
                   5918: }
                   5919: 
1.560     damieng  5920: # Used by table UI
1.437     raeburn  5921: sub delete_slots {
                   5922:     my ($slot_name,$cdom,$cnum,$uname,$udom,$symb) = @_;
                   5923:     my $delresult;
                   5924:     my %consumed = &Apache::lonnet::dump('slot_reservations',$cdom,
                   5925:                                          $cnum, "^$slot_name\0");
                   5926:     if (&Apache::lonnet::error(%consumed)) {
                   5927:         return 'error: unable to determine current slot status';
                   5928:     }
                   5929:     my ($tmp)=%consumed;
                   5930:     if ($tmp=~/^error: 2 /) {
                   5931:         return 'error: unable to determine current slot status';
                   5932:     }
                   5933:     foreach my $key (keys(%consumed)) {
                   5934:         if ($consumed{$key}->{'name'} eq $uname.':'.$udom) {
                   5935:             my $num=(split('\0',$key))[1];
                   5936:             my $entry = $slot_name.'\0'.$num;
                   5937:             $delresult = &Apache::lonnet::del('slot_reservations',[$entry],
                   5938:                                               $cdom,$cnum);
                   5939:             if ($delresult eq 'ok') {
                   5940:                 my %storehash = (
                   5941:                                   symb    => $symb,
                   5942:                                   slot    => $slot_name,
                   5943:                                   action  => 'release',
                   5944:                                   context => 'parameter',
                   5945:                                 );
1.526     raeburn  5946:                 &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,
1.524     raeburn  5947:                                            1,$uname,$udom,$cnum,$cdom);
1.526     raeburn  5948:                 &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash,
1.524     raeburn  5949:                                            1,$uname,$udom,$uname,$udom);
1.437     raeburn  5950:             }
                   5951:         }
                   5952:     }
                   5953:     return $delresult;
                   5954: }
                   5955: 
1.560     damieng  5956: # Used by handler
1.355     albertel 5957: sub check_for_course_info {
                   5958:     my $navmap = Apache::lonnavmaps::navmap->new();
                   5959:     return 1 if ($navmap);
                   5960:     return 0;
                   5961: }
                   5962: 
1.514     raeburn  5963: sub parameter_release_vars { 
1.504     raeburn  5964:    my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   5965:    my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};
                   5966:    my $chostname = &Apache::lonnet::hostname($chome);
                   5967:    my ($cmajor,$cminor) = 
                   5968:        split(/\./,&Apache::lonnet::get_server_loncaparev($cdom,$chome));
                   5969:    return ($chostname,$cmajor,$cminor);
                   5970: }
                   5971: 
1.514     raeburn  5972: sub parameter_releasecheck {
1.557     raeburn  5973:     my ($name,$value,$valmatch,$namematch,$needsrelease,$cmajor,$cminor) = @_;
1.504     raeburn  5974:     my $needsnewer;
                   5975:     my ($needsmajor,$needsminor) = split(/\./,$needsrelease);
                   5976:     if (($cmajor < $needsmajor) || 
                   5977:         ($cmajor == $needsmajor && $cminor < $needsminor)) {
                   5978:         $needsnewer = 1;
1.557     raeburn  5979:     } elsif ($name) {
                   5980:         if ($valmatch) {
                   5981:             &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:'.$name.'::'.$valmatch.':'});
                   5982:         } elsif ($value) { 
                   5983:             &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:'.$name.':'.$value.'::'});
                   5984:         }
                   5985:     } elsif ($namematch) {
                   5986:         &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter::::'.$namematch});
1.504     raeburn  5987:     }
                   5988:     return $needsnewer;
                   5989: }
                   5990: 
1.560     damieng  5991: ##################################################
                   5992: # HANDLER
                   5993: ##################################################
                   5994: 
                   5995: # Main handler for lonparmset.
                   5996: # Sub called based on request parameters action and command:
                   5997: # no command or action: print_main_menu
                   5998: # command 'set': assessparms (direct access to table mode for a resource)
                   5999: #                (this can also be accessed simply with the symb parameter)
                   6000: # action 'setoverview': overview (display all existing parameter settings)
                   6001: # action 'addmetadata': addmetafield (called to add a portfolio metadata field)
                   6002: # action 'ordermetadata': order_meta_fields (called to order portfolio metadata fields)
                   6003: # action 'setrestrictmeta': setrestrictmeta (display or save portfolio metadata)
                   6004: # action 'newoverview': newoverview (overview mode)
                   6005: # action 'setdefaults': defaultsetter (UI to change parameter setting default actions)
                   6006: # action 'settable': assessparms (table mode)
                   6007: # action 'parameterchangelog': parm_change_log (display log for parameter changes,
                   6008: #                              blog postings, user notification changes)
                   6009: # action 'cleanparameters': clean_parameters (unused)
                   6010: # action 'dateshift1': date_shift_one (overview mode, shift all dates)
                   6011: # action 'dateshift2': date_shift_two (overview mode, shift all dates)
1.30      www      6012: sub handler {
1.43      albertel 6013:     my $r=shift;
1.30      www      6014: 
1.376     albertel 6015:     &reset_caches();
                   6016: 
1.414     droeschl 6017:     &Apache::loncommon::content_type($r,'text/html');
                   6018:     $r->send_http_header;
                   6019:     return OK if $r->header_only;
                   6020: 
1.193     albertel 6021:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.473     amueller 6022:                         ['action','state',
1.205     www      6023:                                              'pres_marker',
                   6024:                                              'pres_value',
1.206     www      6025:                                              'pres_type',
1.506     www      6026:                                              'filter','part',
1.390     www      6027:                                              'udom','uname','symb','serial','timebase']);
1.131     www      6028: 
1.83      bowersj2 6029: 
1.193     albertel 6030:     &Apache::lonhtmlcommon::clear_breadcrumbs();
1.194     albertel 6031:     &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/parmset",
1.507     www      6032:                         text=>"Content and Problem Settings",
1.473     amueller 6033:                         faq=>10,
                   6034:                         bug=>'Instructor Interface',
1.442     droeschl 6035:                                             help =>
                   6036:                                             'Parameter_Manager,Course_Environment,Parameter_Helper,Parameter_Overview,Table_Mode'});
1.203     www      6037: 
1.30      www      6038: # ----------------------------------------------------- Needs to be in a course
1.194     albertel 6039:     my $parm_permission =
1.473     amueller 6040:     (&Apache::lonnet::allowed('opa',$env{'request.course.id'}) ||
                   6041:      &Apache::lonnet::allowed('opa',$env{'request.course.id'}.'/'.
                   6042:                   $env{'request.course.sec'}));
1.355     albertel 6043:     my $exists = &check_for_course_info();
                   6044: 
                   6045:     if ($env{'request.course.id'} &&  $parm_permission && $exists) {
1.193     albertel 6046:         #
                   6047:         # Main switch on form.action and form.state, as appropriate
                   6048:         #
                   6049:         # Check first if coming from someone else headed directly for
                   6050:         #  the table mode
                   6051:         if ((($env{'form.command'} eq 'set') && ($env{'form.url'})
1.560     damieng  6052:                 && (!$env{'form.dis'})) || ($env{'form.symb'})) {
                   6053:             &assessparms($r);
1.193     albertel 6054:         } elsif (! exists($env{'form.action'})) {
                   6055:             &print_main_menu($r,$parm_permission);
1.414     droeschl 6056:         } elsif ($env{'form.action'} eq 'setoverview') {
1.560     damieng  6057:             &overview($r);
                   6058:         } elsif ($env{'form.action'} eq 'addmetadata') {
                   6059:             &addmetafield($r);
                   6060:         } elsif ($env{'form.action'} eq 'ordermetadata') {
                   6061:             &order_meta_fields($r);
1.414     droeschl 6062:         } elsif ($env{'form.action'} eq 'setrestrictmeta') {
1.560     damieng  6063:             &setrestrictmeta($r);
1.414     droeschl 6064:         } elsif ($env{'form.action'} eq 'newoverview') {
1.560     damieng  6065:             &newoverview($r);
1.414     droeschl 6066:         } elsif ($env{'form.action'} eq 'setdefaults') {
1.560     damieng  6067:             &defaultsetter($r);
                   6068:         } elsif ($env{'form.action'} eq 'settable') {
                   6069:             &assessparms($r);
1.414     droeschl 6070:         } elsif ($env{'form.action'} eq 'parameterchangelog') {
1.560     damieng  6071:             &parm_change_log($r);
1.414     droeschl 6072:         } elsif ($env{'form.action'} eq 'cleanparameters') {
1.560     damieng  6073:             &clean_parameters($r);
1.414     droeschl 6074:         } elsif ($env{'form.action'} eq 'dateshift1') {
1.390     www      6075:             &date_shift_one($r);
1.414     droeschl 6076:         } elsif ($env{'form.action'} eq 'dateshift2') {
1.390     www      6077:             &date_shift_two($r);
1.446     bisitz   6078:         }
1.43      albertel 6079:     } else {
1.1       www      6080: # ----------------------------- Not in a course, or not allowed to modify parms
1.560     damieng  6081:         if ($exists) {
                   6082:             $env{'user.error.msg'}=
                   6083:             "/adm/parmset:opa:0:0:Cannot modify assessment parameters";
                   6084:         } else {
                   6085:             $env{'user.error.msg'}=
                   6086:             "/adm/parmset::0:1:Course environment gone, reinitialize the course";
                   6087:         }
                   6088:         return HTTP_NOT_ACCEPTABLE;
1.43      albertel 6089:     }
1.376     albertel 6090:     &reset_caches();
                   6091: 
1.43      albertel 6092:     return OK;
1.1       www      6093: }
                   6094: 
                   6095: 1;
                   6096: __END__
                   6097: 
                   6098: 

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