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

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

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