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

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

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