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