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