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