Annotation of loncom/interface/lonparmset.pm, revision 1.577
1.1 www 1: # The LearningOnline Network with CAPA
2: # Handler to set parameters for assessments
3: #
1.577 ! raeburn 4: # $Id: lonparmset.pm,v 1.576 2017/07/10 13:55:36 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.577 ! raeburn 1569: my ($parmname)=((split(/\&/,$mprefix))[1]=~/\_([^\_]+)$/);
! 1570: $r->print(&valout($$outpar[$which],$$typeoutpar[$which],$parmname));
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.576 raeburn 3540: my ($readonly,$is_map) = @_;
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 {
1.576 raeburn 3549: $output .= '<th>'.&mt('Delete').'</th>'.
3550: '<th>'.&mt('Set to ...').'</th>';
3551: if ($is_map) {
3552: $output .= '<th>'.&mt('Recursive?').'</th>';
3553: }
1.552 raeburn 3554: }
3555: $output .= '</tr>';
3556: return $output;
1.124 www 3557: }
3558: }
3559:
1.563 damieng 3560: # Returns HTML with the HTML table end tag, unless the table is not opened.
3561: # @returns {string}
1.124 www 3562: sub tableend {
3563: if ($tableopen) {
1.560 damieng 3564: $tableopen=0;
3565: return &Apache::loncommon::end_data_table();
1.124 www 3566: } else {
1.560 damieng 3567: return'';
1.124 www 3568: }
3569: }
3570:
1.563 damieng 3571: # Reads course and user information.
3572: # 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).
3573: # The key for student data is modified with '[useropt:'.username.':'.userdomain.'].'.
3574: # If the context is looking for a list, returns a list with the scalar data and the class list.
3575: # @param {string} $crs - course number
3576: # @param {string} $dom - course domain
3577: # @returns {hash reference|Array}
1.207 www 3578: sub readdata {
3579: my ($crs,$dom)=@_;
3580: # Read coursedata
3581: my $resourcedata=&Apache::lonnet::get_courseresdata($crs,$dom);
3582: # Read userdata
3583:
3584: my $classlist=&Apache::loncoursedata::get_classlist();
1.548 raeburn 3585: foreach my $user (keys(%$classlist)) {
3586: if ($user=~/^($match_username)\:($match_domain)$/) {
3587: my ($tuname,$tudom)=($1,$2);
3588: my $useropt=&Apache::lonnet::get_userresdata($tuname,$tudom);
3589: foreach my $userkey (keys(%{$useropt})) {
3590: if ($userkey=~/^\Q$env{'request.course.id'}\E/) {
1.207 www 3591: my $newkey=$userkey;
1.548 raeburn 3592: $newkey=~s/^($env{'request.course.id'}\.)/$1\[useropt\:$tuname\:$tudom\]\./;
3593: $$resourcedata{$newkey}=$$useropt{$userkey};
3594: }
3595: }
1.473 amueller 3596: }
3597: }
1.552 raeburn 3598: if (wantarray) {
3599: return ($resourcedata,$classlist);
3600: } else {
3601: return $resourcedata;
3602: }
1.207 www 3603: }
3604:
3605:
1.563 damieng 3606: # Stores parameter data, using form parameters directly.
3607: #
3608: # Uses the following form parameters. The variable part in the names is a resourcedata key (except for a modification for user data).
3609: # set_* (except settext, setipallow, setipdeny) - set a parameter value
3610: # del_* - remove a parameter
3611: # datepointer_* - set a date parameter (value is key_* refering to a set of other form parameters)
3612: # dateinterval_* - set a date interval parameter (value refers to more form parameters)
3613: # key_* - date values
3614: # days_* - for date intervals
3615: # hours_* - for date intervals
3616: # minutes_* - for date intervals
3617: # seconds_* - for date intervals
3618: # done_* - for date intervals
3619: # typeof_* - parameter type
3620: #
3621: # @param {Apache2::RequestRec} $r - the Apache request
3622: # @param {string} $crs - course number
3623: # @param {string} $dom - course domain
1.208 www 3624: sub storedata {
3625: my ($r,$crs,$dom)=@_;
1.207 www 3626: # Set userlevel immediately
3627: # Do an intermediate store of course level
3628: my $olddata=&readdata($crs,$dom);
1.124 www 3629: my %newdata=();
3630: undef %newdata;
3631: my @deldata=();
1.576 raeburn 3632: my @delrec=();
3633: my @delnonrec=();
1.124 www 3634: undef @deldata;
1.504 raeburn 3635: my ($got_chostname,$chostname,$cmajor,$cminor);
1.546 raeburn 3636: my $now = time;
1.560 damieng 3637: foreach my $key (keys(%env)) {
3638: if ($key =~ /^form\.([a-z]+)\_(.+)$/) {
3639: my $cmd=$1;
3640: my $thiskey=$2;
1.576 raeburn 3641: my ($altkey,$recursive,$tkey,$tkeyrec,$tkeynonrec);
3642: next if ($cmd eq 'rec' || $cmd eq 'settext' || $cmd eq 'setipallow' || $cmd eq 'setipdeny');
3643: if ((($cmd eq 'set') || ($cmd eq 'datepointer') || ($cmd eq 'dateinterval') || ($cmd eq 'del')) &&
3644: ($thiskey =~ /(?:sequence|page)\Q___(all)\E/)) {
3645: unless ($thiskey =~ /(encrypturl|hiddenresource)$/) {
3646: $altkey = $thiskey;
3647: $altkey =~ s/\Q___(all)\E/___(rec)/;
3648: if ($env{'form.rec_'.$thiskey}) {
3649: $recursive = 1;
3650: }
3651: }
3652: }
1.560 damieng 3653: my ($tuname,$tudom)=&extractuser($thiskey);
1.473 amueller 3654: if ($tuname) {
1.576 raeburn 3655: $tkey=$thiskey;
1.560 damieng 3656: $tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;
1.576 raeburn 3657: if ($altkey) {
3658: $tkeynonrec = $tkey;
3659: $tkeyrec = $altkey;
3660: $tkeyrec=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;
3661: }
1.560 damieng 3662: }
3663: if ($cmd eq 'set' || $cmd eq 'datepointer' || $cmd eq 'dateinterval') {
1.563 damieng 3664: my ($data, $typeof, $text, $name, $valchk, $valmatch, $namematch);
3665: if ($cmd eq 'set') {
3666: $data=$env{$key};
3667: $valmatch = '';
3668: $valchk = $data;
3669: $typeof=$env{'form.typeof_'.$thiskey};
3670: $text = &mt('Saved modified parameter for');
3671: if ($typeof eq 'string_questiontype') {
3672: $name = 'type';
3673: } elsif ($typeof eq 'string_lenient') {
3674: $name = 'lenient';
3675: my $stringmatch = &standard_string_matches($typeof);
3676: if (ref($stringmatch) eq 'ARRAY') {
3677: foreach my $item (@{$stringmatch}) {
3678: if (ref($item) eq 'ARRAY') {
3679: my ($regexpname,$pattern) = @{$item};
3680: if ($pattern ne '') {
3681: if ($data =~ /$pattern/) {
3682: $valmatch = $regexpname;
3683: $valchk = '';
3684: last;
3685: }
1.560 damieng 3686: }
1.549 raeburn 3687: }
3688: }
3689: }
1.563 damieng 3690: } elsif ($typeof eq 'string_discussvote') {
3691: $name = 'discussvote';
3692: } elsif ($typeof eq 'string_examcode') {
3693: $name = 'examcode';
3694: if (&Apache::lonnet::validCODE($data)) {
3695: $valchk = 'valid';
3696: }
3697: } elsif ($typeof eq 'string_yesno') {
3698: if ($thiskey =~ /\.retrypartial$/) {
3699: $name = 'retrypartial';
3700: }
1.549 raeburn 3701: }
1.563 damieng 3702: } elsif ($cmd eq 'datepointer') {
3703: $data=&Apache::lonhtmlcommon::get_date_from_form($env{$key});
3704: $typeof=$env{'form.typeof_'.$thiskey};
3705: $text = &mt('Saved modified date for');
3706: if ($typeof eq 'date_start') {
3707: if ($thiskey =~ /\.printstartdate$/) {
3708: $name = 'printstartdate';
3709: if (($data) && ($data > $now)) {
3710: $valchk = 'future';
3711: }
1.560 damieng 3712: }
1.563 damieng 3713: } elsif ($typeof eq 'date_end') {
3714: if ($thiskey =~ /\.printenddate$/) {
3715: $name = 'printenddate';
3716: if (($data) && ($data < $now)) {
3717: $valchk = 'past';
3718: }
1.560 damieng 3719: }
1.504 raeburn 3720: }
1.563 damieng 3721: } elsif ($cmd eq 'dateinterval') {
3722: $data=&get_date_interval_from_form($thiskey);
3723: if ($thiskey =~ /\.interval$/) {
3724: $name = 'interval';
3725: my $intervaltype = &get_intervaltype($name);
3726: my $intervalmatch = &standard_interval_matches($intervaltype);
3727: if (ref($intervalmatch) eq 'ARRAY') {
3728: foreach my $item (@{$intervalmatch}) {
3729: if (ref($item) eq 'ARRAY') {
3730: my ($regexpname,$pattern) = @{$item};
3731: if ($pattern ne '') {
3732: if ($data =~ /$pattern/) {
3733: $valmatch = $regexpname;
3734: $valchk = '';
3735: last;
3736: }
1.560 damieng 3737: }
1.554 raeburn 3738: }
3739: }
3740: }
3741: }
1.563 damieng 3742: $typeof=$env{'form.typeof_'.$thiskey};
3743: $text = &mt('Saved modified date for');
1.554 raeburn 3744: }
1.576 raeburn 3745: if ($recursive) {
1.563 damieng 3746: $namematch = 'maplevelrecurse';
1.560 damieng 3747: }
1.563 damieng 3748: if (($name ne '') || ($namematch ne '')) {
3749: my ($needsrelease,$needsnewer);
3750: if ($name ne '') {
3751: $needsrelease = $Apache::lonnet::needsrelease{"parameter:$name:$valchk:$valmatch:"};
1.560 damieng 3752: if ($needsrelease) {
3753: unless ($got_chostname) {
1.563 damieng 3754: ($chostname,$cmajor,$cminor)=¶meter_release_vars();
1.560 damieng 3755: $got_chostname = 1;
3756: }
1.563 damieng 3757: $needsnewer = ¶meter_releasecheck($name,$valchk,$valmatch,undef,
3758: $needsrelease,
3759: $cmajor,$cminor);
3760: }
3761: }
3762: if ($namematch ne '') {
3763: if ($needsnewer) {
3764: undef($namematch);
1.560 damieng 3765: } else {
1.563 damieng 3766: my $currneeded;
3767: if ($needsrelease) {
3768: $currneeded = $needsrelease;
3769: }
3770: $needsrelease =
3771: $Apache::lonnet::needsrelease{"parameter::::$namematch"};
3772: if (($needsrelease) &&
3773: (($currneeded eq '') || ($needsrelease < $currneeded))) {
3774: unless ($got_chostname) {
3775: ($chostname,$cmajor,$cminor) = ¶meter_release_vars();
3776: $got_chostname = 1;
3777: }
3778: $needsnewer = ¶meter_releasecheck(undef,$valchk,$valmatch,
3779: $namematch, $needsrelease,$cmajor,$cminor);
3780: } else {
3781: undef($namematch);
3782: }
1.560 damieng 3783: }
1.557 raeburn 3784: }
1.563 damieng 3785: if ($needsnewer) {
3786: $r->print('<br />'.&oldversion_warning($name,$namematch,$data,
3787: $chostname,$cmajor,
3788: $cminor,$needsrelease));
3789: next;
3790: }
1.504 raeburn 3791: }
1.576 raeburn 3792: my ($reconlychg,$haschange,$storekey);
3793: if ($tuname) {
3794: my $ustorekey;
3795: if ($altkey) {
3796: if ($recursive) {
3797: if (exists($$olddata{$thiskey})) {
3798: if ($$olddata{$thiskey} eq $data) {
3799: $reconlychg = 1;
3800: }
3801: &Apache::lonnet::del('resourcedata',[$tkeynonrec,$tkeynonrec.'.type'],$tudom,$tuname);
3802: }
3803: if (exists($$olddata{$altkey})) {
3804: if (defined($data) && $$olddata{$altkey} ne $data) {
3805: $haschange = 1;
3806: }
3807: } elsif ((!$reconlychg) && ($data ne '')) {
3808: $haschange = 1;
3809: }
3810: $ustorekey = $tkeyrec;
3811: } else {
3812: if (exists($$olddata{$altkey})) {
3813: if ($$olddata{$altkey} eq $data) {
3814: $reconlychg = 1;
3815: }
3816: &Apache::lonnet::del('resourcedata',[$tkeyrec,$tkeyrec.'.type'],$tudom,$tuname);
3817: }
3818: if (exists($$olddata{$thiskey})) {
3819: if (defined($data) && $$olddata{$thiskey} ne $data) {
3820: $haschange = 1;
3821: }
3822: } elsif ((!$reconlychg) && ($data ne '')) {
3823: $haschange = 1;
3824: }
3825: $ustorekey = $tkeynonrec;
3826: }
3827: } else {
3828: if (exists($$olddata{$tkey})) {
3829: if (defined($data) && $$olddata{$tkey} ne $data) {
3830: $haschange = 1;
3831: }
3832: $ustorekey = $tkey;
3833: }
3834: }
3835: if ($haschange || $reconlychg) {
3836: unless ($env{'form.del_'.$thiskey}) {
3837: if (&Apache::lonnet::put('resourcedata',{$ustorekey=>$data,
3838: $ustorekey.'.type' => $typeof},
3839: $tudom,$tuname) eq 'ok') {
3840: &log_parmset({$ustorekey=>$data,$ustorekey.'.type' => $typeof},0,$tuname,$tudom);
3841: $r->print('<br />'.$text.' '.
3842: &Apache::loncommon::plainname($tuname,$tudom));
3843: } else {
3844: $r->print('<div class="LC_error">'.
3845: &mt('Error saving parameters').'</div>');
3846: }
3847: &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
3848: }
3849: }
3850: } else {
3851: if ($altkey) {
3852: if ($recursive) {
3853: if (exists($$olddata{$thiskey})) {
3854: if ($$olddata{$thiskey} eq $data) {
3855: $reconlychg = 1;
3856: }
3857: push(@delnonrec,($thiskey,$thiskey.'.type'));
3858: }
3859: if (exists($$olddata{$altkey})) {
3860: if (defined($data) && $$olddata{$altkey} ne $data) {
3861: $haschange = 1;
3862: }
3863: } elsif (($data ne '') && (!$reconlychg)) {
3864: $haschange = 1;
3865: }
3866: $storekey = $altkey;
1.563 damieng 3867: } else {
1.576 raeburn 3868: if (exists($$olddata{$altkey})) {
3869: if ($$olddata{$altkey} eq $data) {
3870: $reconlychg = 1;
3871: }
3872: push(@delrec,($altkey,$altkey.'.type'));
3873: }
3874: if (exists($$olddata{$thiskey})) {
3875: if (defined($data) && $$olddata{$thiskey} ne $data) {
3876: $haschange = 1;
3877: }
3878: } elsif (($data ne '') && (!$reconlychg)) {
3879: $haschange = 1;
3880: }
3881: $storekey = $thiskey;
1.563 damieng 3882: }
1.560 damieng 3883: } else {
1.576 raeburn 3884: if (defined($data) && $$olddata{$thiskey} ne $data) {
3885: $haschange = 1;
3886: $storekey = $thiskey;
3887: }
3888: }
3889: }
3890: if ($reconlychg || $haschange) {
3891: unless ($env{'form.del_'.$thiskey}) {
3892: $newdata{$storekey}=$data;
3893: $newdata{$storekey.'.type'}=$typeof;
1.560 damieng 3894: }
3895: }
3896: } elsif ($cmd eq 'del') {
3897: if ($tuname) {
1.576 raeburn 3898: my $error;
3899: if ($altkey) {
3900: if (exists($$olddata{$altkey})) {
3901: if (&Apache::lonnet::del('resourcedata',[$tkeyrec,$tkeyrec.'.type'],$tudom,$tuname) eq 'ok') {
3902: &log_parmset({$tkeyrec=>''},1,$tuname,$tudom);
3903: if ($recursive) {
3904: $r->print('<br />'.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));
3905: }
3906: } elsif ($recursive) {
3907: $error = 1;
3908: }
3909: }
3910: if (exists($$olddata{$thiskey})) {
3911: if (&Apache::lonnet::del('resourcedata',[$tkeynonrec,$tkeynonrec.'.type'],$tudom,$tuname) eq 'ok') {
3912: &log_parmset({$tkeynonrec=>''},1,$tuname,$tudom);
3913: unless ($recursive) {
3914: $r->print('<br />'.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));
3915: }
3916: } elsif (!$recursive) {
3917: $error = 1;
3918: }
3919: }
1.560 damieng 3920: } else {
1.576 raeburn 3921: if (exists($$olddata{$thiskey})) {
3922: if (&Apache::lonnet::del('resourcedata',[$tkey,$tkey.'.type'],$tudom,$tuname) eq 'ok') {
3923: &log_parmset({$tkey=>''},1,$tuname,$tudom);
3924: $r->print('<br />'.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));
3925: } else {
3926: $error = 1;
3927: }
3928: }
3929: }
3930: if ($error) {
1.560 damieng 3931: $r->print('<div class="LC_error">'.
3932: &mt('Error deleting parameters').'</div>');
3933: }
3934: &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
3935: } else {
1.576 raeburn 3936: if ($altkey) {
3937: if (exists($$olddata{$altkey})) {
3938: unless (grep(/^\Q$altkey\E$/,@delrec)) {
3939: push(@deldata,($altkey,$altkey.'.type'));
3940: }
3941: }
3942: if (exists($$olddata{$thiskey})) {
3943: unless (grep(/^\Q$thiskey\E$/,@delnonrec)) {
3944: push(@deldata,($thiskey,$thiskey.'.type'));
3945: }
3946: }
3947: } elsif (exists($$olddata{$thiskey})) {
3948: push(@deldata,($thiskey,$thiskey.'.type'));
3949: }
1.560 damieng 3950: }
1.473 amueller 3951: }
3952: }
3953: }
1.207 www 3954: # Store all course level
1.144 www 3955: my $delentries=$#deldata+1;
1.576 raeburn 3956: my @alldels;
3957: if (@delrec) {
3958: push(@alldels,@delrec);
3959: }
3960: if (@delnonrec) {
3961: push(@alldels,@delnonrec);
3962: }
3963: if (@deldata) {
3964: push(@alldels,@deldata);
3965: }
1.548 raeburn 3966: my @newdatakeys=keys(%newdata);
1.144 www 3967: my $putentries=$#newdatakeys+1;
1.576 raeburn 3968: my ($delresult,$devalidate);
3969: if (@alldels) {
3970: if (&Apache::lonnet::del('resourcedata',\@alldels,$dom,$crs) eq 'ok') {
3971: my %loghash=map { $_ => '' } @alldels;
1.560 damieng 3972: &log_parmset(\%loghash,1);
1.576 raeburn 3973: if ($delentries) {
3974: $r->print('<h2>'.&mt('Deleted [quant,_1,parameter]',$delentries/2).'</h2>');
3975: }
3976: } elsif ($delentries) {
1.560 damieng 3977: $r->print('<div class="LC_error">'.
3978: &mt('Error deleting parameters').'</div>');
3979: }
1.576 raeburn 3980: $devalidate = 1;
1.144 www 3981: }
3982: if ($putentries) {
1.560 damieng 3983: if (&Apache::lonnet::put('resourcedata',\%newdata,$dom,$crs) eq 'ok') {
3984: &log_parmset(\%newdata,0);
3985: $r->print('<h3>'.&mt('Saved [quant,_1,parameter]',$putentries/2).'</h3>');
3986: } else {
3987: $r->print('<div class="LC_error">'.
3988: &mt('Error saving parameters').'</div>');
3989: }
1.576 raeburn 3990: $devalidate = 1;
3991: }
3992: if ($devalidate) {
1.560 damieng 3993: &Apache::lonnet::devalidatecourseresdata($crs,$dom);
1.144 www 3994: }
1.208 www 3995: }
1.207 www 3996:
1.563 damieng 3997: # Returns the username and domain from a key created in readdata from a resourcedata key.
3998: #
3999: # @param {string} $key - the key
4000: # @returns {Array}
1.208 www 4001: sub extractuser {
4002: my $key=shift;
1.350 albertel 4003: return ($key=~/^$env{'request.course.id'}.\[useropt\:($match_username)\:($match_domain)\]\./);
1.208 www 4004: }
1.206 www 4005:
1.563 damieng 4006: # Parses a parameter key and returns the components.
4007: #
4008: # @param {string} $key -
4009: # @param {hash reference} $listdata -
4010: # @return {Array} - (student, resource, part, parameter)
1.381 albertel 4011: sub parse_listdata_key {
4012: my ($key,$listdata) = @_;
4013: # split into student/section affected, and
4014: # the realm (folder/resource part and parameter
1.446 bisitz 4015: my ($student,$realm) =
1.473 amueller 4016: ($key=~/^\Q$env{'request.course.id'}\E\.\[([^\.]+)\]\.(.+)$/);
1.381 albertel 4017: # if course wide student would be undefined
4018: if (!defined($student)) {
1.560 damieng 4019: ($realm)=($key=~/^\Q$env{'request.course.id'}\E\.(.+)$/);
1.381 albertel 4020: }
4021: # strip off the .type if it's not the Question type parameter
4022: if ($realm=~/\.type$/ && !exists($listdata->{$key.'.type'})) {
1.560 damieng 4023: $realm=~s/\.type//;
1.381 albertel 4024: }
4025: # split into resource+part and parameter name
1.388 albertel 4026: my ($res, $parm) = ($realm=~/^(.*)\.(.*)$/);
4027: ($res, my $part) = ($res =~/^(.*)\.(.*)$/);
1.381 albertel 4028: return ($student,$res,$part,$parm);
4029: }
4030:
1.563 damieng 4031: # Prints HTML with forms for the given parameter data in overview mode (newoverview or overview).
4032: #
4033: # @param {Apache2::RequestRec} $r - the Apache request
4034: # @param {hash reference} $resourcedata - parameter data returned by readdata
4035: # @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
4036: # @param {string} $sortorder - realmstudent|studentrealm
4037: # @param {string} $caller - name of the calling sub (overview|newoverview)
4038: # @param {hash reference} $classlist - from loncoursedata::get_classlist
1.568 raeburn 4039: # @param {boolean} $readonly - true if editing not allowed
1.563 damieng 4040: # @returns{integer} - number of $listdata parameters processed
1.208 www 4041: sub listdata {
1.568 raeburn 4042: my ($r,$resourcedata,$listdata,$sortorder,$caller,$classlist,$readonly)=@_;
1.552 raeburn 4043:
1.207 www 4044: # Start list output
1.206 www 4045:
1.122 www 4046: my $oldsection='';
4047: my $oldrealm='';
4048: my $oldpart='';
1.123 www 4049: my $pointer=0;
1.124 www 4050: $tableopen=0;
1.145 www 4051: my $foundkeys=0;
1.248 albertel 4052: my %keyorder=&standardkeyorder();
1.381 albertel 4053:
1.552 raeburn 4054: my ($secidx,%grouphash);
4055: if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
4056: $secidx = &Apache::loncoursedata::CL_SECTION();
1.553 raeburn 4057: if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
4058: %grouphash = &Apache::longroup::coursegroups();
4059: } elsif ($env{'request.course.groups'} ne '') {
4060: map { $grouphash{$_} = 1; } split(/,/,$env{'request.course.groups'});
4061: }
1.552 raeburn 4062: }
4063:
1.576 raeburn 4064: foreach my $key (sort {
1.560 damieng 4065: my ($astudent,$ares,$apart,$aparm) = &parse_listdata_key($a,$listdata);
4066: my ($bstudent,$bres,$bpart,$bparm) = &parse_listdata_key($b,$listdata);
1.381 albertel 4067:
1.560 damieng 4068: # get the numerical order for the param
4069: $aparm=$keyorder{'parameter_0_'.$aparm};
4070: $bparm=$keyorder{'parameter_0_'.$bparm};
1.381 albertel 4071:
1.560 damieng 4072: my $result=0;
1.381 albertel 4073:
1.560 damieng 4074: if ($sortorder eq 'realmstudent') {
1.381 albertel 4075: if ($ares ne $bres ) {
1.560 damieng 4076: $result = ($ares cmp $bres);
1.446 bisitz 4077: } elsif ($astudent ne $bstudent) {
1.560 damieng 4078: $result = ($astudent cmp $bstudent);
4079: } elsif ($apart ne $bpart ) {
4080: $result = ($apart cmp $bpart);
4081: }
4082: } else {
4083: if ($astudent ne $bstudent) {
4084: $result = ($astudent cmp $bstudent);
4085: } elsif ($ares ne $bres ) {
4086: $result = ($ares cmp $bres);
4087: } elsif ($apart ne $bpart ) {
4088: $result = ($apart cmp $bpart);
4089: }
1.473 amueller 4090: }
1.446 bisitz 4091:
1.560 damieng 4092: if (!$result) {
1.381 albertel 4093: if (defined($aparm) && defined($bparm)) {
1.560 damieng 4094: $result = ($aparm <=> $bparm);
1.381 albertel 4095: } elsif (defined($aparm)) {
1.560 damieng 4096: $result = -1;
1.381 albertel 4097: } elsif (defined($bparm)) {
1.560 damieng 4098: $result = 1;
4099: }
1.473 amueller 4100: }
1.381 albertel 4101:
1.560 damieng 4102: $result;
4103:
1.576 raeburn 4104: } keys(%{$listdata})) { # foreach my $key
4105: my $thiskey = $key;
1.560 damieng 4106: if ($$listdata{$thiskey.'.type'}) {
4107: my $thistype=$$listdata{$thiskey.'.type'};
4108: if ($$resourcedata{$thiskey.'.type'}) {
4109: $thistype=$$resourcedata{$thiskey.'.type'};
4110: }
4111: my ($middle,$part,$name)=
1.572 damieng 4112: ($thiskey=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s\-]+)\.(\w+)$/);
1.560 damieng 4113: my $section=&mt('All Students');
1.576 raeburn 4114: my $showval = $$resourcedata{$thiskey};
1.560 damieng 4115: if ($middle=~/^\[(.*)\]/) {
4116: my $issection=$1;
4117: if ($issection=~/^useropt\:($match_username)\:($match_domain)/) {
4118: my ($stuname,$studom) = ($1,$2);
4119: if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
4120: if (ref($classlist) eq 'HASH') {
4121: if (ref($classlist->{$stuname.':'.$studom}) eq 'ARRAY') {
4122: next unless ($classlist->{$stuname.':'.$studom}->[$secidx] eq $env{'request.course.sec'});
4123: }
4124: }
4125: }
4126: $section=&mt('User').": ".&Apache::loncommon::plainname($stuname,$studom);
4127: } else {
4128: if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
4129: if (exists($grouphash{$issection})) {
4130: $section=&mt('Group').': '.$issection;
4131: } elsif ($issection eq $env{'request.course.sec'}) {
4132: $section = &mt('Section').': '.$issection;
4133: } else {
4134: next;
1.552 raeburn 4135: }
1.560 damieng 4136: } else {
4137: $section=&mt('Group/Section').': '.$issection;
1.552 raeburn 4138: }
4139: }
1.560 damieng 4140: $middle=~s/^\[(.*)\]//;
4141: } elsif (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
4142: $readonly = 1;
4143: }
4144: $middle=~s/\.+$//;
4145: $middle=~s/^\.+//;
4146: my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
1.576 raeburn 4147: my ($is_map,$is_recursive,$mapurl,$maplevel);
4148: if ($caller eq 'overview') {
4149: if ($middle=~/^(.+)\_\_\_\((all|rec)\)$/) {
4150: $mapurl = $1;
4151: $maplevel = $2;
4152: $is_map = 1;
4153: }
4154: } elsif ($caller eq 'newoverview') {
4155: if ($middle=~/^(.+)\_\_\_\((all)\)$/) {
4156: $mapurl = $1;
4157: $maplevel = $2;
4158: $is_map = 1;
4159: }
4160: }
4161: if ($is_map) {
1.560 damieng 4162: my $leveltitle = &mt('Folder/Map');
1.576 raeburn 4163: unless (($name eq 'hiddenresource') || ($name eq 'encrypturl')) {
4164: if ($caller eq 'newoverview') {
4165: my $altkey = $thiskey;
4166: $altkey =~ s/\Q___(all)\E/___(rec)/;
4167: if ((exists($$resourcedata{$altkey})) & (!exists($$resourcedata{$thiskey}))) {
4168: $is_recursive = 1;
4169: if ($$resourcedata{$altkey.'.type'}) {
4170: $thistype=$$resourcedata{$altkey.'.type'};
4171: }
4172: $showval = $$resourcedata{$altkey};
4173: }
4174: } elsif (($caller eq 'overview') && ($maplevel eq 'rec')) {
4175: $thiskey =~ s/\Q___(rec)\E/___(all)/;
4176: $is_recursive = 1;
4177: }
1.560 damieng 4178: }
4179: $realm='<span class="LC_parm_scope_folder">'.$leveltitle.': '.&Apache::lonnet::gettitle($mapurl).' <br /><span class="LC_parm_folder">('.$mapurl.')</span></span>';
4180: } elsif ($middle) {
4181: my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
4182: $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').
4183: ': '.&Apache::lonnet::gettitle($middle).
4184: ' <br /><span class="LC_parm_symb">('.$url.' in '.$map.' id: '.
4185: $id.')</span></span>';
4186: }
4187: if ($sortorder eq 'realmstudent') {
4188: if ($realm ne $oldrealm) {
4189: $r->print(&tableend()."\n<hr /><h1>$realm</h1>");
4190: $oldrealm=$realm;
4191: $oldsection='';
4192: }
4193: if ($section ne $oldsection) {
4194: $r->print(&tableend()."\n<h2>$section</h2>");
4195: $oldsection=$section;
4196: $oldpart='';
4197: }
1.552 raeburn 4198: } else {
1.560 damieng 4199: if ($section ne $oldsection) {
4200: $r->print(&tableend()."\n<hr /><h1>$section</h1>");
4201: $oldsection=$section;
4202: $oldrealm='';
4203: }
4204: if ($realm ne $oldrealm) {
4205: $r->print(&tableend()."\n<h2>$realm</h2>");
4206: $oldrealm=$realm;
4207: $oldpart='';
1.552 raeburn 4208: }
4209: }
1.560 damieng 4210: if ($part ne $oldpart) {
4211: $r->print(&tableend().
4212: "\n".'<span class="LC_parm_part">'.&mt('Part').": $part</span>");
4213: $oldpart=$part;
1.556 raeburn 4214: }
1.560 damieng 4215: #
4216: # Ready to print
4217: #
1.470 raeburn 4218: my $parmitem = &standard_parameter_names($name);
1.576 raeburn 4219: $r->print(&tablestart($readonly,$is_map).
1.560 damieng 4220: &Apache::loncommon::start_data_table_row().
4221: '<td><b>'.&mt($parmitem).
4222: '</b></td>');
4223: unless ($readonly) {
4224: $r->print('<td><input type="checkbox" name="del_'.
4225: $thiskey.'" /></td>');
4226: }
4227: $r->print('<td>');
4228: $foundkeys++;
4229: if (&isdateparm($thistype)) {
4230: my $jskey='key_'.$pointer;
4231: my $state;
4232: $pointer++;
4233: if ($readonly) {
4234: $state = 'disabled';
4235: }
4236: $r->print(
4237: &Apache::lonhtmlcommon::date_setter('parmform',
4238: $jskey,
1.576 raeburn 4239: $showval,
1.560 damieng 4240: '',1,$state));
4241: unless ($readonly) {
4242: $r->print(
4243: '<input type="hidden" name="datepointer_'.$thiskey.'" value="'.$jskey.'" />'.
1.576 raeburn 4244: (($showval!=0)?'<span class="LC_nobreak"><a href="/adm/parmset?&action=dateshift1&timebase='.$showval.'">'.
1.560 damieng 4245: &mt('Shift all dates based on this date').'</a></span>':'').
1.576 raeburn 4246: &date_sanity_info($showval)
1.560 damieng 4247: );
4248: }
4249: } elsif ($thistype eq 'date_interval') {
4250: $r->print(&date_interval_selector($thiskey,$name,
1.576 raeburn 4251: $showval,$readonly));
1.560 damieng 4252: } elsif ($thistype =~ m/^string/) {
4253: $r->print(&string_selector($thistype,$thiskey,
1.576 raeburn 4254: $showval,$name,$readonly));
1.560 damieng 4255: } else {
1.576 raeburn 4256: $r->print(&default_selector($thiskey,$showval,$readonly));
1.552 raeburn 4257: }
1.560 damieng 4258: unless ($readonly) {
4259: $r->print('<input type="hidden" name="typeof_'.$thiskey.'" value="'.
4260: $thistype.'" />');
1.552 raeburn 4261: }
1.576 raeburn 4262: $r->print('</td>');
4263: if ($is_map) {
4264: if (($name eq 'encrypturl') || ($name eq 'hiddenresource')) {
4265: $r->print('<td><table><tr><td>'.&mt('Yes').'</td></tr></table></td>');
4266: } else {
4267: my ($disabled,$recon,$recoff);
4268: if ($readonly) {
4269: $disabled = ' disabled="disabled"';
4270: }
4271: if ($is_recursive) {
4272: $recon = ' checked="checked"';
4273: } else {
4274: $recoff = ' checked="checked"';
4275: }
4276: $r->print('<td><table><tr><td><label><input type="radio" name="rec_'.$thiskey.'" value="1"'.$recon.$disabled.' />'.&mt('Yes').'</label>'.
4277: '</td><td><label><input type="radio" name="rec_'.$thiskey.'" value="0"'.$recoff.$disabled.' />'.&mt('No').'</label></td></tr></table></td>');
4278: }
4279: }
4280: $r->print(&Apache::loncommon::end_data_table_row());
1.473 amueller 4281: }
1.121 www 4282: }
1.208 www 4283: return $foundkeys;
4284: }
4285:
1.563 damieng 4286: # Returns a string representing the interval, directly using form data matching the given key.
4287: # The returned string may also include information related to proctored exams.
4288: # Format: seconds['_done'[':'done button title':']['_proctor'['_'proctor key]]]
4289: #
4290: # @param {string} $key - suffix for form fields related to the interval
4291: # @returns {string}
1.385 albertel 4292: sub get_date_interval_from_form {
4293: my ($key) = @_;
4294: my $seconds = 0;
4295: foreach my $which (['days', 86400],
1.473 amueller 4296: ['hours', 3600],
4297: ['minutes', 60],
4298: ['seconds', 1]) {
1.560 damieng 4299: my ($name, $factor) = @{ $which };
4300: if (defined($env{'form.'.$name.'_'.$key})) {
4301: $seconds += $env{'form.'.$name.'_'.$key} * $factor;
4302: }
1.473 amueller 4303: }
1.560 damieng 4304: if (($key =~ /\.interval$/) &&
4305: (($env{'form.done_'.$key} eq '_done') || ($env{'form.done_'.$key} eq '_done_proctor'))) {
1.559 raeburn 4306: if ($env{'form.done_'.$key.'_buttontext'}) {
4307: $env{'form.done_'.$key.'_buttontext'} =~ s/\://g;
4308: $seconds .= '_done:'.$env{'form.done_'.$key.'_buttontext'}.':';
4309: if ($env{'form.done_'.$key} eq '_done_proctor') {
4310: $seconds .= '_proctor';
4311: }
4312: } else {
4313: $seconds .= $env{'form.done_'.$key};
4314: }
4315: if (($env{'form.done_'.$key} eq '_done_proctor') &&
1.560 damieng 4316: ($env{'form.done_'.$key.'_proctorkey'})) {
1.558 raeburn 4317: $seconds .= '_'.$env{'form.done_'.$key.'_proctorkey'};
4318: }
1.554 raeburn 4319: }
1.385 albertel 4320: return $seconds;
4321: }
4322:
4323:
1.563 damieng 4324: # Returns HTML to enter a text value for a parameter.
4325: #
4326: # @param {string} $thiskey - parameter key
4327: # @param {string} $showval - the current value
4328: # @param {boolean} $readonly - true if the field should not be made editable
4329: # @returns {string}
1.383 albertel 4330: sub default_selector {
1.552 raeburn 4331: my ($thiskey, $showval, $readonly) = @_;
4332: my $disabled;
4333: if ($readonly) {
4334: $disabled = ' disabled="disabled"';
4335: }
4336: return '<input type="text" name="set_'.$thiskey.'" value="'.$showval.'"'.$disabled.' />';
1.383 albertel 4337: }
4338:
1.563 damieng 4339: # Returns HTML to enter allow/deny rules related to IP addresses.
4340: #
4341: # @param {string} $thiskey - parameter key
4342: # @param {string} $showval - the current value
4343: # @param {boolean} $readonly - true if the fields should not be made editable
4344: # @returns {string}
1.549 raeburn 4345: sub string_ip_selector {
1.552 raeburn 4346: my ($thiskey, $showval, $readonly) = @_;
1.549 raeburn 4347: my %access = (
4348: allow => [],
4349: deny => [],
4350: );
4351: if ($showval ne '') {
4352: my @current;
4353: if ($showval =~ /,/) {
4354: @current = split(/,/,$showval);
4355: } else {
4356: @current = ($showval);
4357: }
4358: foreach my $item (@current) {
4359: if ($item =~ /^\!([\[\]a-zA-Z\.\d\*\-]+)$/) {
4360: push(@{$access{'deny'}},$1);
4361: } elsif ($item =~ /^([\[\]a-zA-Z\.\d\*\-]+)$/) {
4362: push(@{$access{'allow'}},$item);
4363: }
4364: }
4365: }
4366: if (!@{$access{'allow'}}) {
4367: @{$access{'allow'}} = ('');
4368: }
4369: if (!@{$access{'deny'}}) {
4370: @{$access{'deny'}} = ('');
4371: }
1.552 raeburn 4372: my ($disabled,$addmore);
1.567 raeburn 4373: if ($readonly) {
1.552 raeburn 4374: $disabled=' disabled="disabled"';
4375: } else {
4376: $addmore = "\n".'<button class="LC_add_ipacc_button">'.&mt('Add more').'</button>';
4377: }
1.549 raeburn 4378: my $output = '<input type="hidden" name="set_'.$thiskey.'" />
4379: <table><tr><th>'.&mt('Allow from').'</th><th>'.&mt('Deny from').'</th></tr><tr>';
4380: foreach my $acctype ('allow','deny') {
4381: $output .= '
4382: <td valign="top">
4383: <div class="LC_string_ipacc_wrap" id="LC_string_ipacc_'.$acctype.'_'.$thiskey.'">
4384: <div class="LC_string_ipacc_inner">'."\n";
4385: my $num = 0;
4386: foreach my $curr (@{$access{$acctype}}) {
1.552 raeburn 4387: $output .= '<div><input type="text" name="setip'.$acctype.'_'.$thiskey.'" value="'.$curr.'"'.$disabled.' />';
1.549 raeburn 4388: if ($num > 0) {
4389: $output .= '<a href="#" class="LC_remove_ipacc">'.&mt('Remove').'</a>';
4390: }
4391: $output .= '</div>'."\n";
4392: $num ++;
4393: }
4394: $output .= '
1.552 raeburn 4395: </div>'.$addmore.'
1.549 raeburn 4396: </div>
4397: </td>';
4398: }
4399: $output .= '
4400: </tr>
4401: </table>'."\n";
4402: return $output;
4403: }
4404:
1.560 damieng 4405:
4406: { # block using some constants related to parameter types (overview mode)
4407:
1.446 bisitz 4408: my %strings =
1.383 albertel 4409: (
4410: 'string_yesno'
4411: => [[ 'yes', 'Yes' ],
1.560 damieng 4412: [ 'no', 'No' ]],
1.383 albertel 4413: 'string_problemstatus'
4414: => [[ 'yes', 'Yes' ],
1.473 amueller 4415: [ 'answer', 'Yes, and show correct answer if they exceed the maximum number of tries.' ],
4416: [ 'no', 'No, don\'t show correct/incorrect feedback.' ],
4417: [ 'no_feedback_ever', 'No, show no feedback at all.' ]],
1.504 raeburn 4418: 'string_questiontype'
4419: => [[ 'problem', 'Standard Problem'],
4420: [ 'survey', 'Survey'],
4421: [ 'anonsurveycred', 'Anonymous Survey (credit for submission)'],
1.530 bisitz 4422: [ 'exam', 'Bubblesheet Exam'],
1.504 raeburn 4423: [ 'anonsurvey', 'Anonymous Survey'],
4424: [ 'randomizetry', 'New Randomization Each N Tries (default N=1)'],
4425: [ 'practice', 'Practice'],
4426: [ 'surveycred', 'Survey (credit for submission)']],
1.514 raeburn 4427: 'string_lenient'
4428: => [['yes', 'Yes' ],
4429: [ 'no', 'No' ],
1.549 raeburn 4430: [ 'default', 'Default - only bubblesheet grading is lenient' ],
4431: [ 'weighted', 'Yes, weighted (optionresponse in checkbox mode)' ]],
1.521 raeburn 4432: 'string_discussvote'
4433: => [['yes','Yes'],
4434: ['notended','Yes, unless discussion ended'],
4435: ['no','No']],
1.549 raeburn 4436: 'string_ip'
4437: => [['_allowfrom_','Hostname(s), or IP(s) from which access is allowed'],
4438: ['_denyfrom_',], 'Hostname(s) or IP(s) from which access is disallowed'],
1.383 albertel 4439: );
4440:
1.549 raeburn 4441: my %stringmatches = (
4442: 'string_lenient'
4443: => [['weighted','^\-?[.\d]+,\-?[.\d]+,\-?[.\d]+,\-?[.\d]+$'],],
4444: 'string_ip'
4445: => [['_allowfrom_','[^\!]+'],
4446: ['_denyfrom_','\!']],
4447: );
4448:
4449: my %stringtypes = (
4450: type => 'string_questiontype',
4451: lenient => 'string_lenient',
4452: retrypartial => 'string_yesno',
4453: discussvote => 'string_discussvote',
4454: examcode => 'string_examcode',
4455: acc => 'string_ip',
4456: );
4457:
1.563 damieng 4458: # Returns the possible values and titles for a given string type, or undef if there are none.
4459: # Used by courseprefs.
4460: #
4461: # @param {string} $string_type - a parameter type for strings
4462: # @returns {array reference} - 2D array, containing values and English titles
1.505 raeburn 4463: sub standard_string_options {
4464: my ($string_type) = @_;
4465: if (ref($strings{$string_type}) eq 'ARRAY') {
4466: return $strings{$string_type};
4467: }
4468: return;
4469: }
1.383 albertel 4470:
1.563 damieng 4471: # Returns regular expressions to match kinds of string types, or undef if there are none.
4472: #
4473: # @param {string} $string_type - a parameter type for strings
4474: # @returns {array reference} - 2D array, containing regular expression names and regular expressions
1.549 raeburn 4475: sub standard_string_matches {
4476: my ($string_type) = @_;
4477: if (ref($stringmatches{$string_type}) eq 'ARRAY') {
4478: return $stringmatches{$string_type};
4479: }
4480: return;
4481: }
4482:
1.563 damieng 4483: # Returns a parameter type for a given parameter with a string type, or undef if not known.
4484: #
4485: # @param {string} $name - parameter name
4486: # @returns {string}
1.549 raeburn 4487: sub get_stringtype {
4488: my ($name) = @_;
4489: if (exists($stringtypes{$name})) {
4490: return $stringtypes{$name};
4491: }
4492: return;
4493: }
4494:
1.563 damieng 4495: # Returns HTML to edit a string parameter.
4496: #
4497: # @param {string} $thistype - parameter type
4498: # @param {string} $thiskey - parameter key
4499: # @param {string} $showval - parameter current value
4500: # @param {string} $name - parameter name
4501: # @param {boolean} $readonly - true if the values should not be made editable
4502: # @returns {string}
1.383 albertel 4503: sub string_selector {
1.552 raeburn 4504: my ($thistype, $thiskey, $showval, $name, $readonly) = @_;
1.446 bisitz 4505:
1.383 albertel 4506: if (!exists($strings{$thistype})) {
1.552 raeburn 4507: return &default_selector($thiskey,$showval,$readonly);
1.383 albertel 4508: }
4509:
1.504 raeburn 4510: my %skiptype;
1.514 raeburn 4511: if (($thistype eq 'string_questiontype') ||
1.560 damieng 4512: ($thistype eq 'string_lenient') ||
4513: ($thistype eq 'string_discussvote') ||
4514: ($thistype eq 'string_ip') ||
4515: ($name eq 'retrypartial')) {
1.504 raeburn 4516: my ($got_chostname,$chostname,$cmajor,$cminor);
4517: foreach my $possibilities (@{ $strings{$thistype} }) {
4518: next unless (ref($possibilities) eq 'ARRAY');
1.514 raeburn 4519: my ($parmval, $description) = @{ $possibilities };
1.549 raeburn 4520: my $parmmatch;
4521: if (ref($stringmatches{$thistype}) eq 'ARRAY') {
4522: foreach my $item (@{$stringmatches{$thistype}}) {
4523: if (ref($item) eq 'ARRAY') {
4524: if ($parmval eq $item->[0]) {
4525: $parmmatch = $parmval;
4526: $parmval = '';
4527: last;
4528: }
4529: }
4530: }
4531: }
4532: my $needsrelease=$Apache::lonnet::needsrelease{"parameter:$name:$parmval:$parmmatch"};
1.504 raeburn 4533: if ($needsrelease) {
4534: unless ($got_chostname) {
1.514 raeburn 4535: ($chostname,$cmajor,$cminor)=¶meter_release_vars();
1.504 raeburn 4536: $got_chostname = 1;
4537: }
1.557 raeburn 4538: my $needsnewer=¶meter_releasecheck($name,$parmval,$parmmatch,undef,
1.549 raeburn 4539: $needsrelease,$cmajor,$cminor);
1.504 raeburn 4540: if ($needsnewer) {
1.549 raeburn 4541: if ($parmmatch ne '') {
4542: $skiptype{$parmmatch} = 1;
4543: } elsif ($parmval ne '') {
4544: $skiptype{$parmval} = 1;
4545: }
1.504 raeburn 4546: }
4547: }
4548: }
4549: }
1.549 raeburn 4550:
4551: if ($thistype eq 'string_ip') {
1.552 raeburn 4552: return &string_ip_selector($thiskey,$showval,$readonly);
1.549 raeburn 4553: }
1.504 raeburn 4554:
1.552 raeburn 4555: my ($result,$disabled);
4556:
4557: if ($readonly) {
4558: $disabled = ' disabled="disabled"';
4559: }
1.504 raeburn 4560: my $numinrow = 3;
4561: if ($thistype eq 'string_problemstatus') {
4562: $numinrow = 2;
4563: } elsif ($thistype eq 'string_questiontype') {
4564: if (keys(%skiptype) > 0) {
4565: $numinrow = 4;
4566: }
4567: }
4568: my $rem;
4569: if (ref($strings{$thistype}) eq 'ARRAY') {
4570: my $i=0;
4571: foreach my $possibilities (@{ $strings{$thistype} }) {
4572: next unless (ref($possibilities) eq 'ARRAY');
4573: my ($name, $description) = @{ $possibilities };
1.549 raeburn 4574: next if ($skiptype{$name});
1.504 raeburn 4575: $rem = $i%($numinrow);
4576: if ($rem == 0) {
4577: if ($i > 0) {
4578: $result .= '</tr>';
4579: }
4580: $result .= '<tr>';
4581: }
1.549 raeburn 4582: my $colspan;
4583: if ($i == @{ $strings{$thistype} }-1) {
4584: $rem = @{ $strings{$thistype} }%($numinrow);
4585: if ($rem) {
4586: my $colsleft = $numinrow - $rem;
4587: if ($colsleft) {
4588: $colspan = $colsleft+1;
4589: $colspan = ' colspan="'.$colspan.'"';
4590: }
4591: }
4592: }
4593: my ($add,$onchange,$css_class);
4594: if ($thistype eq 'string_lenient') {
4595: if ($name eq 'weighted') {
4596: my $display;
4597: my %relatives = &Apache::lonlocal::texthash(
4598: corrchkd => 'Correct (checked)',
4599: corrunchkd => 'Correct (unchecked)',
4600: incorrchkd => 'Incorrect (checked)',
4601: incorrunchkd => 'Incorrect (unchecked)',
4602: );
4603: my %textval = (
4604: corrchkd => '1.0',
4605: corrunchkd => '1.0',
4606: incorrchkd => '0.0',
4607: incorrunchkd => '0.0',
4608: );
4609: if ($showval =~ /^([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)$/) {
4610: $textval{'corrchkd'} = $1;
4611: $textval{'corrunchkd'} = $2;
4612: $textval{'incorrchkd'} = $3;
4613: $textval{'incorrunchkd'} = $4;
4614: $display = 'inline';
4615: $showval = $name;
4616: } else {
4617: $display = 'none';
4618: }
4619: $add = ' <div id="LC_parmtext_'.$thiskey.'" style="display:'.$display.'"><table>'.
4620: '<tr><th colspan="2">'.&mt("Foil's submission status").'</th><th>'.&mt('Points').'</th></tr>';
4621: foreach my $reltype ('corrchkd','corrunchkd','incorrchkd','incorrunchkd') {
4622: $add .= '<tr><td> </td><td>'.$relatives{$reltype}.'</td>'."\n".
4623: '<td><input type="text" name="settext_'.$thiskey.'"'.
1.552 raeburn 4624: ' value="'.$textval{$reltype}.'" size="3"'.$disabled.' />'.
1.549 raeburn 4625: '</td></tr>';
4626: }
4627: $add .= '</table></div>'."\n";
4628: }
4629: $onchange = ' onclick="javascript:toggleParmTextbox(this.form,'."'$thiskey'".');"';
4630: $css_class = ' class="LC_lenient_radio"';
4631: }
4632: $result .= '<td class="LC_left_item"'.$colspan.'>'.
1.504 raeburn 4633: '<span class="LC_nobreak"><label>'.
4634: '<input type="radio" name="set_'.$thiskey.
1.552 raeburn 4635: '" value="'.$name.'"'.$onchange.$css_class.$disabled;
1.504 raeburn 4636: if ($showval eq $name) {
4637: $result .= ' checked="checked"';
4638: }
1.549 raeburn 4639: $result .= ' />'.&mt($description).'</label>'.$add.'</span></td>';
1.504 raeburn 4640: $i++;
4641: }
4642: $result .= '</tr>';
1.473 amueller 4643: }
1.504 raeburn 4644: if ($result) {
4645: $result = '<table border="0">'.$result.'</table>';
1.383 albertel 4646: }
4647: return $result;
4648: }
4649:
1.554 raeburn 4650: my %intervals =
4651: (
4652: 'date_interval'
4653: => [[ 'done', 'Yes' ],
1.558 raeburn 4654: [ 'done_proctor', 'Yes, with proctor key'],
1.554 raeburn 4655: [ '', 'No' ]],
4656: );
4657:
4658: my %intervalmatches = (
4659: 'date_interval'
1.559 raeburn 4660: => [['done','\d+_done(|\:[^\:]+\:)$'],
4661: ['done_proctor','\d+_done(|\:[^\:]+\:)_proctor_']],
1.554 raeburn 4662: );
4663:
4664: my %intervaltypes = (
4665: interval => 'date_interval',
4666: );
4667:
1.563 damieng 4668: # Returns regular expressions to match kinds of interval type, or undef if there are none.
4669: #
4670: # @param {string} $interval_type - a parameter type for intervals
4671: # @returns {array reference} - 2D array, containing regular expression names and regular expressions
1.554 raeburn 4672: sub standard_interval_matches {
4673: my ($interval_type) = @_;
4674: if (ref($intervalmatches{$interval_type}) eq 'ARRAY') {
4675: return $intervalmatches{$interval_type};
4676: }
4677: return;
4678: }
4679:
1.563 damieng 4680: # Returns a parameter type for a given parameter with an interval type, or undef if not known.
4681: #
4682: # @param {string} $name - parameter name
4683: # @returns {string}
1.554 raeburn 4684: sub get_intervaltype {
4685: my ($name) = @_;
4686: if (exists($intervaltypes{$name})) {
4687: return $intervaltypes{$name};
4688: }
4689: return;
4690: }
4691:
1.563 damieng 4692: # Returns the possible values and titles for a given interval type, or undef if there are none.
4693: # Used by courseprefs.
4694: #
4695: # @param {string} $interval_type - a parameter type for intervals
4696: # @returns {array reference} - 2D array, containing values and English titles
1.554 raeburn 4697: sub standard_interval_options {
4698: my ($interval_type) = @_;
4699: if (ref($intervals{$interval_type}) eq 'ARRAY') {
4700: return $intervals{$interval_type};
4701: }
4702: return;
4703: }
4704:
1.563 damieng 4705: # Returns HTML to edit a date interval parameter.
4706: #
4707: # @param {string} $thiskey - parameter key
4708: # @param {string} $name - parameter name
4709: # @param {string} $showval - parameter current value
4710: # @param {boolean} $readonly - true if the values should not be made editable
4711: # @returns {string}
1.554 raeburn 4712: sub date_interval_selector {
4713: my ($thiskey, $name, $showval, $readonly) = @_;
4714: my ($result,%skipval);
4715: if ($name eq 'interval') {
4716: my $intervaltype = &get_intervaltype($name);
4717: my ($got_chostname,$chostname,$cmajor,$cminor);
4718: foreach my $possibilities (@{ $intervals{$intervaltype} }) {
4719: next unless (ref($possibilities) eq 'ARRAY');
4720: my ($parmval, $description) = @{ $possibilities };
4721: my $parmmatch;
4722: if (ref($intervalmatches{$intervaltype}) eq 'ARRAY') {
4723: foreach my $item (@{$intervalmatches{$intervaltype}}) {
4724: if (ref($item) eq 'ARRAY') {
4725: if ($parmval eq $item->[0]) {
4726: $parmmatch = $parmval;
4727: $parmval = '';
4728: last;
4729: }
4730: }
4731: }
4732: }
4733: my $needsrelease=$Apache::lonnet::needsrelease{"parameter:$name:$parmval:$parmmatch"};
4734: if ($needsrelease) {
4735: unless ($got_chostname) {
4736: ($chostname,$cmajor,$cminor)=¶meter_release_vars();
4737: $got_chostname = 1;
4738: }
1.557 raeburn 4739: my $needsnewer=¶meter_releasecheck($name,$parmval,$parmmatch,undef,
1.554 raeburn 4740: $needsrelease,$cmajor,$cminor);
4741: if ($needsnewer) {
4742: if ($parmmatch ne '') {
4743: $skipval{$parmmatch} = 1;
4744: } elsif ($parmval ne '') {
4745: $skipval{$parmval} = 1;
4746: }
4747: }
4748: }
4749: }
4750: }
4751:
4752: my $currval = $showval;
4753: foreach my $which (['days', 86400, 31],
4754: ['hours', 3600, 23],
4755: ['minutes', 60, 59],
4756: ['seconds', 1, 59]) {
1.560 damieng 4757: my ($name, $factor, $max) = @{ $which };
4758: my $amount = int($showval/$factor);
4759: $showval %= $factor;
4760: my %select = ((map {$_ => $_} (0..$max)),
4761: 'select_form_order' => [0..$max]);
4762: $result .= &Apache::loncommon::select_form($amount,$name.'_'.$thiskey,
4763: \%select,'',$readonly);
4764: $result .= ' '.&mt($name);
1.554 raeburn 4765: }
4766: if ($name eq 'interval') {
4767: unless ($skipval{'done'}) {
4768: my $checkedon = '';
1.558 raeburn 4769: my $checkedproc = '';
4770: my $currproctorkey = '';
4771: my $currprocdisplay = 'hidden';
1.559 raeburn 4772: my $currdonetext = &mt('Done');
1.554 raeburn 4773: my $checkedoff = ' checked="checked"';
1.559 raeburn 4774: if ($currval =~ /^(?:\d+)_done$/) {
4775: $checkedon = ' checked="checked"';
4776: $checkedoff = '';
4777: } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:$/) {
4778: $currdonetext = $1;
1.554 raeburn 4779: $checkedon = ' checked="checked"';
4780: $checkedoff = '';
1.558 raeburn 4781: } elsif ($currval =~ /^(?:\d+)_done_proctor_(.+)$/) {
4782: $currproctorkey = $1;
4783: $checkedproc = ' checked="checked"';
4784: $checkedoff = '';
4785: $currprocdisplay = 'text';
1.559 raeburn 4786: } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:_proctor_(.+)$/) {
4787: $currdonetext = $1;
4788: $currproctorkey = $2;
4789: $checkedproc = ' checked="checked"';
4790: $checkedoff = '';
4791: $currprocdisplay = 'text';
1.554 raeburn 4792: }
1.558 raeburn 4793: my $onclick = ' onclick="toggleSecret(this.form,'."'done_','$thiskey'".');"';
1.567 raeburn 4794: my $disabled;
4795: if ($readonly) {
4796: $disabled = ' disabled="disabled"';
4797: }
1.558 raeburn 4798: $result .= '<br /><span class="LC_nobreak">'.&mt('Include "done" button').
1.567 raeburn 4799: '<label><input type="radio" value="" name="done_'.$thiskey.'"'.$checkedoff.$onclick.$disabled.' />'.
1.558 raeburn 4800: &mt('No').'</label>'.(' 'x2).
1.567 raeburn 4801: '<label><input type="radio" value="_done" name="done_'.$thiskey.'"'.$checkedon.$onclick.$disabled.' />'.
1.558 raeburn 4802: &mt('Yes').'</label>'.(' 'x2).
1.567 raeburn 4803: '<label><input type="radio" value="_done_proctor" name="done_'.$thiskey.'"'.$checkedproc.$onclick.$disabled.' />'.
1.558 raeburn 4804: &mt('Yes, with proctor key').'</label>'.
4805: '<input type="'.$currprocdisplay.'" id="done_'.$thiskey.'_proctorkey" '.
1.567 raeburn 4806: 'name="done_'.$thiskey.'_proctorkey" value="'.&HTML::Entities::encode($currproctorkey,'"<>&').'"'.$disabled.' /></span><br />'.
1.559 raeburn 4807: '<span class="LC_nobreak">'.&mt('Button text').': '.
1.567 raeburn 4808: '<input type="text" name="done_'.$thiskey.'_buttontext" value="'.&HTML::Entities::encode($currdonetext,'"<>&').'"'.$disabled.' /></span>';
1.554 raeburn 4809: }
4810: }
4811: unless ($readonly) {
4812: $result .= '<input type="hidden" name="dateinterval_'.$thiskey.'" />';
4813: }
4814: return $result;
4815: }
4816:
1.563 damieng 4817: # Returns HTML with a warning if a parameter requires a more recent version of LON-CAPA.
4818: #
4819: # @param {string} $name - parameter name
4820: # @param {string} $namematch - parameter level name (recognized: resourcelevel|maplevel|maplevelrecurse|courselevel)
4821: # @param {string} $value - parameter value
4822: # @param {string} $chostname - course server name
4823: # @param {integer} $cmajor - major version number
4824: # @param {integer} $cminor - minor version number
4825: # @param {string} $needsrelease - release version needed (major.minor)
4826: # @returns {string}
1.549 raeburn 4827: sub oldversion_warning {
1.557 raeburn 4828: my ($name,$namematch,$value,$chostname,$cmajor,$cminor,$needsrelease) = @_;
4829: my $standard_name = &standard_parameter_names($name);
4830: if ($namematch) {
4831: my $level = &standard_parameter_levels($namematch);
4832: my $msg = '';
4833: if ($level) {
4834: $msg = &mt('[_1] was [_2]not[_3] set at the level of: [_4].',
4835: $standard_name,'<b>','</b>','"'.$level.'"');
4836: } else {
4837: $msg = &mt('[_1] was [_2]not[_3] set.',
4838: $standard_name,'<b>','</b>');
4839: }
4840: return '<p class="LC_warning">'.$msg.'<br />'.
4841: &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',
4842: $cmajor.'.'.$cminor,$chostname,
4843: $needsrelease).
4844: '</p>';
4845: }
1.549 raeburn 4846: my $desc;
4847: my $stringtype = &get_stringtype($name);
4848: if ($stringtype ne '') {
4849: if ($name eq 'examcode') {
4850: $desc = $value;
4851: } elsif (ref($strings{$stringtypes{$name}}) eq 'ARRAY') {
4852: foreach my $possibilities (@{ $strings{$stringtypes{$name}} }) {
4853: next unless (ref($possibilities) eq 'ARRAY');
4854: my ($parmval, $description) = @{ $possibilities };
4855: my $parmmatch;
4856: if (ref($stringmatches{$stringtypes{$name}}) eq 'ARRAY') {
4857: foreach my $item (@{$stringmatches{$stringtypes{$name}}}) {
4858: if (ref($item) eq 'ARRAY') {
4859: my ($regexpname,$pattern) = @{$item};
4860: if ($parmval eq $regexpname) {
4861: if ($value =~ /$pattern/) {
4862: $desc = $description;
4863: $parmmatch = 1;
4864: last;
4865: }
4866: }
4867: }
4868: }
4869: last if ($parmmatch);
4870: } elsif ($parmval eq $value) {
4871: $desc = $description;
4872: last;
4873: }
4874: }
4875: }
4876: } elsif (($name eq 'printstartdate') || ($name eq 'printenddate')) {
4877: my $now = time;
4878: if ($value =~ /^\d+$/) {
4879: if ($name eq 'printstartdate') {
4880: if ($value > $now) {
4881: $desc = &Apache::lonlocal::locallocaltime($value);
4882: }
4883: } elsif ($name eq 'printenddate') {
4884: if ($value < $now) {
4885: $desc = &Apache::lonlocal::locallocaltime($value);
4886: }
4887: }
4888: }
4889: }
4890: return '<p class="LC_warning">'.
1.557 raeburn 4891: &mt('[_1] was [_2]not[_3] set to [_4].',
4892: $standard_name,'<b>','</b>','"'.$desc.'"').'<br />'.
4893: &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',
4894: $cmajor.'.'.$cminor,$chostname,
4895: $needsrelease).
4896: '</p>';
1.549 raeburn 4897: }
4898:
1.560 damieng 4899: } # end of block using some constants related to parameter types
4900:
1.549 raeburn 4901:
1.563 damieng 4902:
4903: # Shifts all start and end dates in the current course by $shift.
1.389 www 4904: #
1.563 damieng 4905: # @param {integer} $shift - time to shift, in seconds
4906: # @returns {string} - error name or 'ok'
1.389 www 4907: sub dateshift {
4908: my ($shift)=@_;
4909: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
4910: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
4911: my %data=&Apache::lonnet::dump('resourcedata',$dom,$crs);
4912: # ugly retro fix for broken version of types
1.548 raeburn 4913: foreach my $key (keys(%data)) {
1.389 www 4914: if ($key=~/\wtype$/) {
4915: my $newkey=$key;
4916: $newkey=~s/type$/\.type/;
4917: $data{$newkey}=$data{$key};
4918: delete $data{$key};
4919: }
4920: }
1.391 www 4921: my %storecontent=();
1.389 www 4922: # go through all parameters and look for dates
1.548 raeburn 4923: foreach my $key (keys(%data)) {
1.389 www 4924: if ($data{$key.'.type'}=~/^date_(start|end)$/) {
4925: my $newdate=$data{$key}+$shift;
1.391 www 4926: $storecontent{$key}=$newdate;
1.389 www 4927: }
4928: }
1.391 www 4929: my $reply=&Apache::lonnet::cput
4930: ('resourcedata',\%storecontent,$dom,$crs);
4931: if ($reply eq 'ok') {
4932: &log_parmset(\%storecontent);
4933: }
4934: &Apache::lonnet::devalidatecourseresdata($crs,$dom);
4935: return $reply;
1.389 www 4936: }
4937:
1.563 damieng 4938: # Overview mode UI to edit course parameters.
4939: #
4940: # @param {Apache2::RequestRec} $r - the Apache request
1.208 www 4941: sub newoverview {
1.568 raeburn 4942: my ($r,$parm_permission) = @_;
1.280 albertel 4943:
1.208 www 4944: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
4945: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 4946: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.568 raeburn 4947: my $readonly = 1;
4948: if ($parm_permission->{'edit'}) {
4949: undef($readonly);
4950: }
1.414 droeschl 4951: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
1.473 amueller 4952: text=>"Overview Mode"});
1.523 raeburn 4953:
4954: my %loaditems = (
1.549 raeburn 4955: 'onload' => "showHide_courseContent(); resize_scrollbox('mapmenuscroll','1','1'); showHideLenient();",
1.523 raeburn 4956: );
4957: my $js = '
4958: <script type="text/javascript">
4959: // <![CDATA[
4960: '.
4961: &Apache::lonhtmlcommon::resize_scrollbox_js('params')."\n".
4962: &showhide_js()."\n".
1.549 raeburn 4963: &toggleparmtextbox_js()."\n".
4964: &validateparms_js()."\n".
4965: &ipacc_boxes_js()."\n".
1.558 raeburn 4966: &done_proctor_js()."\n".
1.523 raeburn 4967: '// ]]>
4968: </script>
4969: ';
1.549 raeburn 4970:
1.523 raeburn 4971: my $start_page = &Apache::loncommon::start_page('Set Parameters',$js,
4972: {'add_entries' => \%loaditems,});
1.298 albertel 4973: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
1.507 www 4974: $r->print($start_page.$breadcrumbs);
1.531 raeburn 4975: &startSettingsScreen($r,'parmset',$crstype);
1.208 www 4976: $r->print(<<ENDOVER);
1.549 raeburn 4977: <form method="post" action="/adm/parmset?action=newoverview" name="parmform" onsubmit="return validateParms();">
1.208 www 4978: ENDOVER
1.211 www 4979: my @ids=();
4980: my %typep=();
4981: my %keyp=();
4982: my %allparms=();
4983: my %allparts=();
4984: my %allmaps=();
4985: my %mapp=();
4986: my %symbp=();
4987: my %maptitles=();
4988: my %uris=();
4989: my %keyorder=&standardkeyorder();
4990: my %defkeytype=();
4991:
4992: my %alllevs=();
4993: $alllevs{'Resource Level'}='full';
1.215 www 4994: $alllevs{'Map/Folder Level'}='map';
1.211 www 4995: $alllevs{'Course Level'}='general';
4996:
4997: my $csec=$env{'form.csec'};
1.269 raeburn 4998: my $cgroup=$env{'form.cgroup'};
1.211 www 4999:
5000: my @pscat=&Apache::loncommon::get_env_multiple('form.pscat');
5001: my $pschp=$env{'form.pschp'};
1.506 www 5002:
1.211 www 5003: my @psprt=&Apache::loncommon::get_env_multiple('form.psprt');
1.516 www 5004: if (!@psprt) { $psprt[0]='all'; }
1.211 www 5005:
1.446 bisitz 5006: my @selected_sections =
1.473 amueller 5007: &Apache::loncommon::get_env_multiple('form.Section');
1.211 www 5008: @selected_sections = ('all') if (! @selected_sections);
1.374 albertel 5009: foreach my $sec (@selected_sections) {
5010: if ($sec eq 'all') {
1.211 www 5011: @selected_sections = ('all');
5012: }
5013: }
1.552 raeburn 5014: if ($env{'request.course.sec'} ne '') {
5015: @selected_sections = ($env{'request.course.sec'});
5016: }
1.269 raeburn 5017: my @selected_groups =
5018: &Apache::loncommon::get_env_multiple('form.Group');
1.211 www 5019:
5020: my $pssymb='';
5021: my $parmlev='';
1.446 bisitz 5022:
1.211 www 5023: unless ($env{'form.parmlev'}) {
5024: $parmlev = 'map';
5025: } else {
5026: $parmlev = $env{'form.parmlev'};
5027: }
5028:
1.446 bisitz 5029: &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
1.473 amueller 5030: \%mapp, \%symbp,\%maptitles,\%uris,
5031: \%keyorder,\%defkeytype);
1.211 www 5032:
1.374 albertel 5033: if (grep {$_ eq 'all'} (@psprt)) {
1.481 amueller 5034: @psprt = keys(%allparts);
1.374 albertel 5035: }
1.211 www 5036: # Menu to select levels, etc
5037:
1.456 bisitz 5038: $r->print('<div class="LC_Box">');
1.445 neumanie 5039: #$r->print('<h2 class="LC_hcell">Step 1</h2>');
1.452 bisitz 5040: $r->print('<div>');
1.523 raeburn 5041: $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel'));
1.211 www 5042: &levelmenu($r,\%alllevs,$parmlev);
5043: if ($parmlev ne 'general') {
1.447 bisitz 5044: $r->print(&Apache::lonhtmlcommon::row_closure());
1.483 amueller 5045: &mapmenu($r,\%allmaps,$pschp,\%maptitles,\%symbp);
1.211 www 5046: }
1.447 bisitz 5047: $r->print(&Apache::lonhtmlcommon::row_closure(1));
1.445 neumanie 5048: $r->print(&Apache::lonhtmlcommon::end_pick_box());
5049: $r->print('</div></div>');
1.446 bisitz 5050:
1.456 bisitz 5051: $r->print('<div class="LC_Box">');
1.452 bisitz 5052: $r->print('<div>');
1.562 damieng 5053: &displaymenu($r,\%allparms,\@pscat,\%keyorder); # FIXME: wrong parameters, could make keysindisplayorderCategory crash because $keyorder is undefined
1.453 schualex 5054: $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.446 bisitz 5055: $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View')));
1.553 raeburn 5056: my $sectionselector = §ionmenu(\@selected_sections);
5057: my $groupselector = &groupmenu(\@selected_groups);
1.481 amueller 5058: $r->print('<table>'.
1.553 raeburn 5059: '<tr><th>'.&mt('Parts').'</th>');
5060: if ($sectionselector) {
5061: $r->print('<th>'.&mt('Section(s)').'</th>');
5062: }
5063: if ($groupselector) {
5064: $r->print('<th>'.&mt('Group(s)').'</th>');
5065: }
5066: $r->print('</tr><tr><td>');
1.211 www 5067: &partmenu($r,\%allparts,\@psprt);
1.553 raeburn 5068: $r->print('</td>');
5069: if ($sectionselector) {
5070: $r->print('<td>'.$sectionselector.'</td>');
5071: }
5072: if ($groupselector) {
5073: $r->print('<td>'.$groupselector.'</td>');
5074: }
5075: $r->print('</tr></table>');
1.447 bisitz 5076: $r->print(&Apache::lonhtmlcommon::row_closure(1));
1.445 neumanie 5077: $r->print(&Apache::lonhtmlcommon::end_pick_box());
5078: $r->print('</div></div>');
5079:
1.456 bisitz 5080: $r->print('<div class="LC_Box">');
1.452 bisitz 5081: $r->print('<div>');
1.214 www 5082: my $sortorder=$env{'form.sortorder'};
5083: unless ($sortorder) { $sortorder='realmstudent'; }
5084: &sortmenu($r,$sortorder);
1.445 neumanie 5085: $r->print('</div></div>');
1.446 bisitz 5086:
1.214 www 5087: $r->print('<p><input type="submit" name="dis" value="'.&mt('Display').'" /></p>');
1.446 bisitz 5088:
1.211 www 5089: # Build the list data hash from the specified parms
5090:
5091: my $listdata;
5092: %{$listdata}=();
5093:
5094: foreach my $cat (@pscat) {
1.269 raeburn 5095: &secgroup_lister($cat,$pschp,$parmlev,$listdata,\@psprt,\@selected_sections,\%defkeytype,\%allmaps,\@ids,\%symbp);
5096: &secgroup_lister($cat,$pschp,$parmlev,$listdata,\@psprt,\@selected_groups,\%defkeytype,\%allmaps,\@ids,\%symbp);
1.211 www 5097: }
5098:
1.212 www 5099: if (($env{'form.store'}) || ($env{'form.dis'})) {
1.211 www 5100:
1.481 amueller 5101: if ($env{'form.store'}) { &storedata($r,$crs,$dom); }
1.211 www 5102:
5103: # Read modified data
5104:
1.481 amueller 5105: my $resourcedata=&readdata($crs,$dom);
1.211 www 5106:
5107: # List data
5108:
1.568 raeburn 5109: &listdata($r,$resourcedata,$listdata,$sortorder,'newoverview',undef,$readonly);
5110: }
5111: $r->print(&tableend());
5112: unless ($readonly) {
5113: $r->print( ((($env{'form.store'}) || ($env{'form.dis'}))?'<p><input type="submit" name="store" value="'.&mt('Save').'" /></p>':'') );
1.211 www 5114: }
1.568 raeburn 5115: $r->print('</form>');
1.507 www 5116: &endSettingsScreen($r);
5117: $r->print(&Apache::loncommon::end_page());
1.208 www 5118: }
5119:
1.563 damieng 5120: # Fills $listdata with parameter information.
5121: # Keys use the format course id.[section id].part.name and course id.[section id].part.name.type.
5122: # The non-type value is always 1.
5123: #
5124: # @param {string} $cat - parameter name
1.566 damieng 5125: # @param {string} $pschp - selected map pc, or 'all'
1.563 damieng 5126: # @param {string} $parmlev - selected level value (full|map|general), or ''
5127: # @param {hash reference} $listdata - the parameter data that will be modified
5128: # @param {array reference} $psprt - selected parts
5129: # @param {array reference} $selections - selected sections
5130: # @param {hash reference} $defkeytype - hash parameter name -> parameter type
1.566 damieng 5131: # @param {hash reference} $allmaps - hash map pc -> map src
5132: # @param {array reference} $ids - resource and map ids
5133: # @param {hash reference} $symbp - hash map pc or resource/map id -> map src.'___(all)' or resource symb
1.269 raeburn 5134: sub secgroup_lister {
5135: my ($cat,$pschp,$parmlev,$listdata,$psprt,$selections,$defkeytype,$allmaps,$ids,$symbp) = @_;
5136: foreach my $item (@{$selections}) {
5137: foreach my $part (@{$psprt}) {
5138: my $rootparmkey=$env{'request.course.id'};
5139: if (($item ne 'all') && ($item ne 'none') && ($item)) {
5140: $rootparmkey.='.['.$item.']';
5141: }
5142: if ($parmlev eq 'general') {
5143: # course-level parameter
5144: my $newparmkey=$rootparmkey.'.'.$part.'.'.$cat;
5145: $$listdata{$newparmkey}=1;
5146: $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
5147: } elsif ($parmlev eq 'map') {
5148: # map-level parameter
1.548 raeburn 5149: foreach my $mapid (keys(%{$allmaps})) {
1.269 raeburn 5150: if (($pschp ne 'all') && ($pschp ne $mapid)) { next; }
5151: my $newparmkey=$rootparmkey.'.'.$$allmaps{$mapid}.'___(all).'.$part.'.'.$cat;
5152: $$listdata{$newparmkey}=1;
5153: $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
5154: }
5155: } else {
5156: # resource-level parameter
5157: foreach my $rid (@{$ids}) {
5158: my ($map,$resid,$url)=&Apache::lonnet::decode_symb($$symbp{$rid});
5159: if (($pschp ne 'all') && ($$allmaps{$pschp} ne $map)) { next; }
5160: my $newparmkey=$rootparmkey.'.'.$$symbp{$rid}.'.'.$part.'.'.$cat;
5161: $$listdata{$newparmkey}=1;
5162: $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
5163: }
5164: }
5165: }
5166: }
5167: }
5168:
1.563 damieng 5169: # UI to edit parameter settings starting with a list of all existing parameters.
5170: # (called by setoverview action)
5171: #
5172: # @param {Apache2::RequestRec} $r - the Apache request
1.208 www 5173: sub overview {
1.568 raeburn 5174: my ($r,$parm_permission) = @_;
1.208 www 5175: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
5176: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 5177: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.568 raeburn 5178: my $readonly = 1;
5179: if ($parm_permission->{'edit'}) {
5180: undef($readonly);
5181: }
1.549 raeburn 5182: my $js = '<script type="text/javascript">'."\n".
5183: '// <![CDATA['."\n".
5184: &toggleparmtextbox_js()."\n".
5185: &validateparms_js()."\n".
5186: &ipacc_boxes_js()."\n".
1.558 raeburn 5187: &done_proctor_js()."\n".
1.549 raeburn 5188: '// ]]>'."\n".
5189: '</script>'."\n";
1.414 droeschl 5190: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
1.473 amueller 5191: text=>"Overview Mode"});
1.549 raeburn 5192: my %loaditems = (
5193: 'onload' => "showHideLenient();",
5194: );
5195:
5196: my $start_page=&Apache::loncommon::start_page('Modify Parameters',$js,{'add_entries' => \%loaditems,});
1.298 albertel 5197: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
1.507 www 5198: $r->print($start_page.$breadcrumbs);
1.531 raeburn 5199: &startSettingsScreen($r,'parmset',$crstype);
1.549 raeburn 5200: $r->print('<form method="post" action="/adm/parmset?action=setoverview" name="parmform" onsubmit="return validateParms();">');
1.507 www 5201:
1.208 www 5202: # Store modified
5203:
1.568 raeburn 5204: unless ($readonly) {
5205: &storedata($r,$crs,$dom);
5206: }
1.208 www 5207:
5208: # Read modified data
5209:
1.552 raeburn 5210: my ($resourcedata,$classlist)=&readdata($crs,$dom);
1.208 www 5211:
1.214 www 5212:
5213: my $sortorder=$env{'form.sortorder'};
5214: unless ($sortorder) { $sortorder='realmstudent'; }
5215: &sortmenu($r,$sortorder);
5216:
1.568 raeburn 5217: my $submitbutton = '<input type="submit" value="'.&mt('Save').'" />';
5218:
5219: if ($readonly) {
5220: $r->print('<p>'.$submitbutton.'</p>');
5221: }
5222:
1.208 www 5223: # List data
5224:
1.568 raeburn 5225: my $foundkeys=&listdata($r,$resourcedata,$resourcedata,$sortorder,'overview',$classlist,$readonly);
5226: $r->print(&tableend().'<p>');
5227: if ($foundkeys) {
5228: unless ($readonly) {
5229: $r->print('<p>'.$submitbutton.'</p>');
5230: }
5231: } else {
5232: $r->print('<p class="LC_info">'.&mt('There are no parameters.').'</p>');
5233: }
5234: $r->print('</form>'.&Apache::loncommon::end_page());
1.120 www 5235: }
1.121 www 5236:
1.560 damieng 5237: # Unused sub.
1.563 damieng 5238: #
5239: # @param {Apache2::RequestRec} $r - the Apache request
1.333 albertel 5240: sub clean_parameters {
5241: my ($r) = @_;
5242: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
5243: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
5244:
1.414 droeschl 5245: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=cleanparameters',
1.473 amueller 5246: text=>"Clean Parameters"});
1.333 albertel 5247: my $start_page=&Apache::loncommon::start_page('Clean Parameters');
5248: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Clean');
5249: $r->print(<<ENDOVER);
5250: $start_page
5251: $breadcrumbs
5252: <form method="post" action="/adm/parmset?action=cleanparameters" name="parmform">
5253: ENDOVER
5254: # Store modified
5255:
5256: &storedata($r,$crs,$dom);
5257:
5258: # Read modified data
5259:
5260: my $resourcedata=&readdata($crs,$dom);
5261:
5262: # List data
5263:
5264: $r->print('<h3>'.
1.473 amueller 5265: &mt('These parameters refer to resources that do not exist.').
5266: '</h3>'.
5267: '<input type="submit" value="'.&mt('Delete Selected').'" />'.'<br />'.
5268: '<br />');
1.333 albertel 5269: $r->print(&Apache::loncommon::start_data_table().
1.473 amueller 5270: '<tr>'.
5271: '<th>'.&mt('Delete').'</th>'.
5272: '<th>'.&mt('Parameter').'</th>'.
5273: '</tr>');
1.333 albertel 5274: foreach my $thiskey (sort(keys(%{$resourcedata}))) {
1.560 damieng 5275: next if (!exists($resourcedata->{$thiskey.'.type'})
5276: && $thiskey=~/\.type$/);
5277: my %data = &parse_key($thiskey);
5278: if (1) { #exists($data{'realm_exists'})
5279: #&& !$data{'realm_exists'}) {
5280: $r->print(&Apache::loncommon::start_data_table_row().
5281: '<tr>'.
5282: '<td><input type="checkbox" name="del_'.$thiskey.'" /></td>' );
5283:
5284: $r->print('<td>');
5285: my $display_value = $resourcedata->{$thiskey};
5286: if (&isdateparm($resourcedata->{$thiskey.'.type'})) {
5287: $display_value =
5288: &Apache::lonlocal::locallocaltime($display_value);
5289: }
1.470 raeburn 5290: my $parmitem = &standard_parameter_names($data{'parameter_name'});
5291: $parmitem = &mt($parmitem);
1.560 damieng 5292: $r->print(&mt('Parameter: "[_1]" with value: "[_2]"',
5293: $parmitem,$resourcedata->{$thiskey}));
5294: $r->print('<br />');
5295: if ($data{'scope_type'} eq 'all') {
5296: $r->print(&mt('All users'));
5297: } elsif ($data{'scope_type'} eq 'user') {
5298: $r->print(&mt('User: [_1]',join(':',@{$data{'scope'}})));
5299: } elsif ($data{'scope_type'} eq 'section') {
5300: $r->print(&mt('Section: [_1]',$data{'scope'}));
5301: } elsif ($data{'scope_type'} eq 'group') {
5302: $r->print(&mt('Group: [_1]',$data{'scope'}));
5303: }
5304: $r->print('<br />');
5305: if ($data{'realm_type'} eq 'all') {
5306: $r->print(&mt('All Resources'));
5307: } elsif ($data{'realm_type'} eq 'folder') {
5308: $r->print(&mt('Folder: [_1]'),$data{'realm'});
5309: } elsif ($data{'realm_type'} eq 'symb') {
5310: my ($map,$resid,$url) =
5311: &Apache::lonnet::decode_symb($data{'realm'});
5312: $r->print(&mt('Resource: [_1]with ID: [_2]in folder [_3]',
5313: $url.' <br /> ',
5314: $resid.' <br /> ',$map));
5315: }
5316: $r->print(' <br /> '.&mt('Part: [_1]',$data{'parameter_part'}));
5317: $r->print('</td></tr>');
5318:
1.473 amueller 5319: }
1.333 albertel 5320: }
5321: $r->print(&Apache::loncommon::end_data_table().'<p>'.
1.473 amueller 5322: '<input type="submit" value="'.&mt('Delete Selected').'" />'.
1.507 www 5323: '</p></form>');
5324: &endSettingsScreen($r);
5325: $r->print(&Apache::loncommon::end_page());
1.333 albertel 5326: }
5327:
1.563 damieng 5328: # UI to shift all dates (called by dateshift1 action).
5329: # Used by overview mode.
5330: #
5331: # @param {Apache2::RequestRec} $r - the Apache request
1.390 www 5332: sub date_shift_one {
5333: my ($r) = @_;
5334: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
5335: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 5336: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.390 www 5337:
1.414 droeschl 5338: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
1.473 amueller 5339: text=>"Shifting Dates"});
1.390 www 5340: my $start_page=&Apache::loncommon::start_page('Shift Dates');
5341: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
1.507 www 5342: $r->print($start_page.$breadcrumbs);
1.531 raeburn 5343: &startSettingsScreen($r,'parmset',$crstype);
1.538 bisitz 5344: $r->print('<form name="shiftform" method="post" action="">'.
1.390 www 5345: '<table><tr><td>'.&mt('Currently set date:').'</td><td>'.
5346: &Apache::lonlocal::locallocaltime($env{'form.timebase'}).'</td></tr>'.
5347: '<tr><td>'.&mt('Shifted date:').'</td><td>'.
1.541 bisitz 5348: &Apache::lonhtmlcommon::date_setter('shiftform',
1.390 www 5349: 'timeshifted',
5350: $env{'form.timebase'},,
5351: '').
5352: '</td></tr></table>'.
5353: '<input type="hidden" name="action" value="dateshift2" />'.
5354: '<input type="hidden" name="timebase" value="'.$env{'form.timebase'}.'" />'.
5355: '<input type="submit" value="'.&mt('Shift all dates accordingly').'" /></form>');
1.507 www 5356: &endSettingsScreen($r);
1.390 www 5357: $r->print(&Apache::loncommon::end_page());
5358: }
5359:
1.563 damieng 5360: # UI to shift all dates (second form).
5361: #
5362: # @param {Apache2::RequestRec} $r - the Apache request
1.390 www 5363: sub date_shift_two {
5364: my ($r) = @_;
5365: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
5366: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 5367: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.414 droeschl 5368: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
1.473 amueller 5369: text=>"Shifting Dates"});
1.390 www 5370: my $start_page=&Apache::loncommon::start_page('Shift Dates');
5371: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
1.507 www 5372: $r->print($start_page.$breadcrumbs);
1.531 raeburn 5373: &startSettingsScreen($r,'parmset',$crstype);
1.390 www 5374: my $timeshifted=&Apache::lonhtmlcommon::get_date_from_form('timeshifted');
1.543 bisitz 5375: $r->print('<h2>'.&mt('Shift Dates').'</h2>'.
5376: '<p>'.&mt('Shifting all dates such that [_1] becomes [_2]',
1.390 www 5377: &Apache::lonlocal::locallocaltime($env{'form.timebase'}),
1.543 bisitz 5378: &Apache::lonlocal::locallocaltime($timeshifted)).'</p>');
1.390 www 5379: my $delta=$timeshifted-$env{'form.timebase'};
5380: &dateshift($delta);
1.543 bisitz 5381: $r->print(
5382: &Apache::lonhtmlcommon::confirm_success(&mt('Done')).
5383: '<br /><br />'.
5384: &Apache::lonhtmlcommon::actionbox(
5385: ['<a href="/adm/parmset">'.&mt('Content and Problem Settings').'</a>']));
1.507 www 5386: &endSettingsScreen($r);
1.390 www 5387: $r->print(&Apache::loncommon::end_page());
5388: }
5389:
1.563 damieng 5390: # Returns the different components of a resourcedata key.
5391: # Keys: scope_type, scope, realm_type, realm, realm_title,
5392: # realm_exists, parameter_part, parameter_name.
5393: # Was used by clean_parameters (which is unused).
5394: #
5395: # @param {string} $key - the parameter key
5396: # @returns {hash}
1.333 albertel 5397: sub parse_key {
5398: my ($key) = @_;
5399: my %data;
5400: my ($middle,$part,$name)=
1.572 damieng 5401: ($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s\-]+)\.(\w+)$/);
1.333 albertel 5402: $data{'scope_type'} = 'all';
5403: if ($middle=~/^\[(.*)\]/) {
1.560 damieng 5404: $data{'scope'} = $1;
5405: if ($data{'scope'}=~/^useropt\:($match_username)\:($match_domain)/) {
5406: $data{'scope_type'} = 'user';
5407: $data{'scope'} = [$1,$2];
5408: } else {
5409: #FIXME check for group scope
5410: $data{'scope_type'} = 'section';
5411: }
5412: $middle=~s/^\[(.*)\]//;
1.333 albertel 5413: }
5414: $middle=~s/\.+$//;
5415: $middle=~s/^\.+//;
5416: $data{'realm_type'}='all';
5417: if ($middle=~/^(.+)\_\_\_\(all\)$/) {
1.560 damieng 5418: $data{'realm'} = $1;
5419: $data{'realm_type'} = 'folder';
5420: $data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});
5421: ($data{'realm_exists'}) = &Apache::lonnet::is_on_map($data{'realm'});
1.333 albertel 5422: } elsif ($middle) {
1.560 damieng 5423: $data{'realm'} = $middle;
5424: $data{'realm_type'} = 'symb';
5425: $data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});
5426: my ($map,$resid,$url) = &Apache::lonnet::decode_symb($data{'realm'});
5427: $data{'realm_exists'} = &Apache::lonnet::symbverify($data{'realm'},$url);
1.333 albertel 5428: }
1.446 bisitz 5429:
1.333 albertel 5430: $data{'parameter_part'} = $part;
5431: $data{'parameter_name'} = $name;
5432:
5433: return %data;
5434: }
5435:
1.239 raeburn 5436:
1.563 damieng 5437: # Calls loncommon::start_page with the "Settings" title.
1.416 jms 5438: sub header {
1.507 www 5439: return &Apache::loncommon::start_page('Settings');
1.416 jms 5440: }
1.193 albertel 5441:
5442:
5443:
1.560 damieng 5444: ##################################################
5445: # MAIN MENU
5446: ##################################################
5447:
1.563 damieng 5448: # Content and problem settings main menu.
5449: #
5450: # @param {Apache2::RequestRec} $r - the Apache request
5451: # @param {boolean} $parm_permission - true if the user has permission to edit the current course or section
1.193 albertel 5452: sub print_main_menu {
5453: my ($r,$parm_permission)=@_;
5454: #
1.414 droeschl 5455: $r->print(&header());
1.507 www 5456: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Content and Problem Settings'));
1.531 raeburn 5457: my $crstype = &Apache::loncommon::course_type();
5458: my $lc_crstype = lc($crstype);
5459:
5460: &startSettingsScreen($r,'parmset',$crstype);
1.193 albertel 5461: $r->print(<<ENDMAINFORMHEAD);
5462: <form method="post" enctype="multipart/form-data"
5463: action="/adm/parmset" name="studentform">
5464: ENDMAINFORMHEAD
5465: #
1.195 albertel 5466: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
5467: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1.268 albertel 5468: my $vgr = &Apache::lonnet::allowed('vgr',$env{'request.course.id'});
1.366 albertel 5469: my $mgr = &Apache::lonnet::allowed('mgr',$env{'request.course.id'});
1.520 raeburn 5470: my $dcm = &Apache::lonnet::allowed('dcm',$env{'request.course.id'});
1.568 raeburn 5471: my $vcb = &Apache::lonnet::allowed('vcb',$env{'request.course.id'});
5472: my $vpa = &Apache::lonnet::allowed('vpa',$env{'request.course.id'});
1.520 raeburn 5473: if ((!$dcm) && ($env{'request.course.sec'} ne '')) {
5474: $dcm = &Apache::lonnet::allowed('dcm',$env{'request.course.id'}.
5475: '/'.$env{'request.course.sec'});
5476: }
1.568 raeburn 5477: if ((!$vcb) && ($env{'request.course.sec'} ne '')) {
5478: $vcb = &Apache::lonnet::allowed('vcb',$env{'request.course.id'}.
5479: '/'.$env{'request.course.sec'});
5480: }
5481: my (%linktext,%linktitle,%url);
5482: if ($parm_permission->{'edit'}) {
5483: %linktext = (
5484: newoverview => 'Edit Resource Parameters - Overview Mode',
5485: settable => 'Edit Resource Parameters - Table Mode',
5486: setoverview => 'Modify Resource Parameters - Overview Mode',
5487: );
5488: %linktitle = (
5489: newoverview => 'Set/Modify resource parameters in overview mode.',
5490: settable => 'Set/Modify resource parameters in table mode.',
5491: setoverview => 'Set/Modify existing resource parameters in overview mode.',
5492: );
5493: } else {
5494: %linktext = (
5495: newoverview => 'View Resource Parameters - Overview Mode',
5496: settable => 'View Resource Parameters - Table Mode',
5497: setoverview => 'View Resource Parameters - Overview Mode',
5498: );
5499: %linktitle = (
5500: newoverview => 'Display resource parameters in overview mode.',
5501: settable => 'Display resource parameters in table mode.',
5502: setoverview => 'Display existing resource parameters in overview mode.',
5503: );
5504: }
5505: if ($mgr) {
5506: $linktext{'resettimes'} = 'Reset Student Access Times';
5507: $linktitle{'resettimes'} = "Reset access times for folders/maps, resources or the $lc_crstype.";
5508: $url{'resettimes'} = '/adm/helper/resettimes.helper';
5509: } elsif ($vgr) {
5510: $linktext{'resettimes'} = 'Display Student Access Times',
5511: $linktitle{'resettimes'} = "Display access times for folders/maps, resources or the $lc_crstype.",
5512: $url{'resettimes'} = '/adm/accesstimes';
5513: }
1.193 albertel 5514: my @menu =
1.507 www 5515: ( { categorytitle=>"Content Settings for this $crstype",
1.473 amueller 5516: items => [
5517: { linktext => 'Portfolio Metadata',
5518: url => '/adm/parmset?action=setrestrictmeta',
1.568 raeburn 5519: permission => $parm_permission->{'setrestrictmeta'},
1.477 raeburn 5520: linktitle => "Restrict metadata for this $lc_crstype." ,
1.473 amueller 5521: icon =>'contact-new.png' ,
5522: },
1.568 raeburn 5523: { linktext => $linktext{'resettimes'},
5524: url => $url{'resettimes'},
5525: permission => ($vgr || $mgr),
5526: linktitle => $linktitle{'resettimes'},
5527: icon => 'start-here.png',
1.473 amueller 5528: },
1.520 raeburn 5529: { linktext => 'Blocking Communication/Resource Access',
5530: url => '/adm/setblock',
1.568 raeburn 5531: permission => ($vcb || $dcm),
1.520 raeburn 5532: linktitle => 'Configure blocking of communication/collaboration and access to resources during an exam',
5533: icon => 'comblock.png',
5534: },
1.473 amueller 5535: { linktext => 'Set Parameter Setting Default Actions',
5536: url => '/adm/parmset?action=setdefaults',
1.568 raeburn 5537: permission => $parm_permission->{'setdefaults'},
1.473 amueller 5538: linktitle =>'Set default actions for parameters.' ,
5539: icon => 'folder-new.png' ,
5540: }]},
5541: { categorytitle => 'New and Existing Parameter Settings for Resources',
5542: items => [
5543: { linktext => 'Edit Resource Parameters - Helper Mode',
5544: url => '/adm/helper/parameter.helper',
1.568 raeburn 5545: permission => $parm_permission->{'helper'},
1.473 amueller 5546: linktitle =>'Set/Modify resource parameters in helper mode.' ,
5547: icon => 'dialog-information.png' ,
5548: #help => 'Parameter_Helper',
5549: },
1.568 raeburn 5550: { linktext => $linktext{'newoverview'},
1.473 amueller 5551: url => '/adm/parmset?action=newoverview',
1.568 raeburn 5552: permission => $parm_permission->{'newoverview'},
5553: linktitle => $linktitle{'newoverview'},
5554: icon => 'edit-find.png',
1.473 amueller 5555: #help => 'Parameter_Overview',
5556: },
1.568 raeburn 5557: { linktext => $linktext{'settable'},
1.473 amueller 5558: url => '/adm/parmset?action=settable',
1.568 raeburn 5559: permission => $parm_permission->{'settable'},
5560: linktitle => $linktitle{'settable'},
5561: icon => 'edit-copy.png',
1.473 amueller 5562: #help => 'Table_Mode',
5563: }]},
1.417 droeschl 5564: { categorytitle => 'Existing Parameter Settings for Resources',
1.473 amueller 5565: items => [
1.570 raeburn 5566: { linktext => $linktext{'setoverview'},
1.473 amueller 5567: url => '/adm/parmset?action=setoverview',
1.568 raeburn 5568: permission => $parm_permission->{'setoverview'},
5569: linktitle => $linktitle{'setoverview'},
5570: icon => 'preferences-desktop-wallpaper.png',
1.473 amueller 5571: #help => 'Parameter_Overview',
5572: },
5573: { linktext => 'Change Log',
5574: url => '/adm/parmset?action=parameterchangelog',
1.568 raeburn 5575: permission => $parm_permission->{'parameterchangelog'},
1.477 raeburn 5576: linktitle =>"View parameter and $lc_crstype blog posting/user notification change log." ,
1.487 wenzelju 5577: icon => 'document-properties.png',
1.473 amueller 5578: }]}
1.193 albertel 5579: );
1.414 droeschl 5580: $r->print(&Apache::lonhtmlcommon::generate_menu(@menu));
1.539 raeburn 5581: $r->print('</form>');
1.507 www 5582: &endSettingsScreen($r);
1.539 raeburn 5583: $r->print(&Apache::loncommon::end_page());
1.193 albertel 5584: return;
5585: }
1.414 droeschl 5586:
1.416 jms 5587:
5588:
1.560 damieng 5589: ##################################################
5590: # PORTFOLIO METADATA
5591: ##################################################
5592:
1.563 damieng 5593: # Prints HTML to edit an item of portfolio metadata. The HTML contains several td elements (no tr).
5594: # It looks like field titles are not localized.
5595: #
5596: # @param {Apache2::RequestRec} $r - the Apache request
5597: # @param {string} $field_name - metadata field name
5598: # @param {string} $field_text - metadata field title, in English unless manually added
5599: # @param {boolean} $added_flag - true if the field was manually added
1.252 banghart 5600: sub output_row {
1.347 banghart 5601: my ($r, $field_name, $field_text, $added_flag) = @_;
1.252 banghart 5602: my $output;
1.263 banghart 5603: my $options=$env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.options'};
5604: my $values=$env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.values'};
1.337 banghart 5605: if (!defined($options)) {
1.254 banghart 5606: $options = 'active,stuadd';
1.261 banghart 5607: $values = '';
1.252 banghart 5608: }
1.337 banghart 5609: if (!($options =~ /deleted/)) {
5610: my @options= ( ['active', 'Show to student'],
1.418 schafran 5611: ['stuadd', 'Provide text area for students to type metadata'],
1.351 banghart 5612: ['choices','Provide choices for students to select from']);
1.473 amueller 5613: # ['onlyone','Student may select only one choice']);
1.337 banghart 5614: if ($added_flag) {
5615: push @options,['deleted', 'Delete Metadata Field'];
5616: }
1.351 banghart 5617: $output = &Apache::loncommon::start_data_table_row();
1.451 bisitz 5618: $output .= '<td><strong>'.$field_text.':</strong></td>';
1.351 banghart 5619: $output .= &Apache::loncommon::end_data_table_row();
1.337 banghart 5620: foreach my $opt (@options) {
1.560 damieng 5621: my $checked = ($options =~ m/$opt->[0]/) ? ' checked="checked" ' : '' ;
5622: $output .= &Apache::loncommon::continue_data_table_row();
5623: $output .= '<td>'.(' ' x 5).'<label>
5624: <input type="checkbox" name="'.
5625: $field_name.'_'.$opt->[0].'" value="yes"'.$checked.' />'.
5626: &mt($opt->[1]).'</label></td>';
5627: $output .= &Apache::loncommon::end_data_table_row();
5628: }
1.351 banghart 5629: $output .= &Apache::loncommon::continue_data_table_row();
1.451 bisitz 5630: $output .= '<td>'.(' ' x 10).'<input name="'.$field_name.'_values" type="text" value="'.$values.'" size="80" /></td>';
1.351 banghart 5631: $output .= &Apache::loncommon::end_data_table_row();
5632: my $multiple_checked;
5633: my $single_checked;
5634: if ($options =~ m/onlyone/) {
1.422 bisitz 5635: $multiple_checked = '';
1.423 bisitz 5636: $single_checked = ' checked="checked"';
1.351 banghart 5637: } else {
1.423 bisitz 5638: $multiple_checked = ' checked="checked"';
1.422 bisitz 5639: $single_checked = '';
1.351 banghart 5640: }
1.560 damieng 5641: $output .= &Apache::loncommon::continue_data_table_row();
5642: $output .= '<td>'.(' ' x 10).'
5643: <input type="radio" name="'.$field_name.'_onlyone" value="multiple"'.$multiple_checked .' />
5644: '.&mt('Student may select multiple choices from list').'</td>';
5645: $output .= &Apache::loncommon::end_data_table_row();
5646: $output .= &Apache::loncommon::continue_data_table_row();
5647: $output .= '<td>'.(' ' x 10).'
5648: <input type="radio" name="'.$field_name.'_onlyone" value="single"'.$single_checked.' />
5649: '.&mt('Student may select only one choice from list').'</td>';
5650: $output .= &Apache::loncommon::end_data_table_row();
1.252 banghart 5651: }
5652: return ($output);
5653: }
1.416 jms 5654:
5655:
1.560 damieng 5656: # UI to order portfolio metadata fields.
1.563 damieng 5657: # Currently useless because addmetafield does not work.
5658: #
5659: # @param {Apache2::RequestRec} $r - the Apache request
1.340 banghart 5660: sub order_meta_fields {
5661: my ($r)=@_;
5662: my $idx = 1;
5663: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
5664: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 5665: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};;
1.341 banghart 5666: $r->print(&Apache::loncommon::start_page('Order Metadata Fields'));
1.560 damieng 5667: &Apache::lonhtmlcommon::add_breadcrumb(
5668: {href=>'/adm/parmset?action=addmetadata',
1.473 amueller 5669: text=>"Add Metadata Field"});
1.560 damieng 5670: &Apache::lonhtmlcommon::add_breadcrumb(
5671: {href=>"/adm/parmset?action=setrestrictmeta",
5672: text=>"Restrict Metadata"},
5673: {text=>"Order Metadata"});
1.345 banghart 5674: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Order Metadata'));
1.531 raeburn 5675: &startSettingsScreen($r,'parmset',$crstype);
1.340 banghart 5676: if ($env{'form.storeorder'}) {
5677: my $newpos = $env{'form.newpos'} - 1;
5678: my $currentpos = $env{'form.currentpos'} - 1;
5679: my @neworder = ();
1.548 raeburn 5680: my @oldorder = split(/,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'});
1.340 banghart 5681: my $i;
1.341 banghart 5682: if ($newpos > $currentpos) {
1.340 banghart 5683: # moving stuff up
5684: for ($i=0;$i<$currentpos;$i++) {
1.560 damieng 5685: $neworder[$i]=$oldorder[$i];
1.340 banghart 5686: }
5687: for ($i=$currentpos;$i<$newpos;$i++) {
1.560 damieng 5688: $neworder[$i]=$oldorder[$i+1];
1.340 banghart 5689: }
5690: $neworder[$newpos]=$oldorder[$currentpos];
5691: for ($i=$newpos+1;$i<=$#oldorder;$i++) {
1.560 damieng 5692: $neworder[$i]=$oldorder[$i];
1.340 banghart 5693: }
5694: } else {
5695: # moving stuff down
1.473 amueller 5696: for ($i=0;$i<$newpos;$i++) {
5697: $neworder[$i]=$oldorder[$i];
5698: }
5699: $neworder[$newpos]=$oldorder[$currentpos];
5700: for ($i=$newpos+1;$i<$currentpos+1;$i++) {
5701: $neworder[$i]=$oldorder[$i-1];
5702: }
5703: for ($i=$currentpos+1;$i<=$#oldorder;$i++) {
5704: $neworder[$i]=$oldorder[$i];
5705: }
1.340 banghart 5706: }
1.560 damieng 5707: my $ordered_fields = join ",", @neworder;
1.343 banghart 5708: my $put_result = &Apache::lonnet::put('environment',
1.560 damieng 5709: {'metadata.addedorder'=>$ordered_fields},$dom,$crs);
5710: &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.metadata.addedorder' => $ordered_fields});
1.340 banghart 5711: }
1.357 raeburn 5712: my $fields = &get_added_meta_fieldnames($env{'request.course.id'});
1.341 banghart 5713: my $ordered_fields;
1.548 raeburn 5714: my @fields_in_order = split(/,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'});
1.340 banghart 5715: if (!@fields_in_order) {
5716: # no order found, pick sorted order then create metadata.addedorder key.
1.548 raeburn 5717: foreach my $key (sort(keys(%$fields))) {
1.340 banghart 5718: push @fields_in_order, $key;
1.341 banghart 5719: $ordered_fields = join ",", @fields_in_order;
1.340 banghart 5720: }
1.341 banghart 5721: my $put_result = &Apache::lonnet::put('environment',
1.446 bisitz 5722: {'metadata.addedorder'=>$ordered_fields},$dom,$crs);
5723: }
1.340 banghart 5724: $r->print('<table>');
5725: my $num_fields = scalar(@fields_in_order);
5726: foreach my $key (@fields_in_order) {
5727: $r->print('<tr><td>');
5728: $r->print('<form method="post" action="">');
1.537 bisitz 5729: $r->print('<select name="newpos" onchange="this.form.submit()">');
1.340 banghart 5730: for (my $i = 1;$i le $num_fields;$i ++) {
5731: if ($i eq $idx) {
5732: $r->print('<option value="'.$i.'" SELECTED>('.$i.')</option>');
5733: } else {
5734: $r->print('<option value="'.$i.'">'.$i.'</option>');
5735: }
5736: }
5737: $r->print('</select></td><td>');
5738: $r->print('<input type="hidden" name="currentpos" value="'.$idx.'" />');
5739: $r->print('<input type="hidden" name="storeorder" value="true" />');
5740: $r->print('</form>');
5741: $r->print($$fields{$key}.'</td></tr>');
5742: $idx ++;
5743: }
5744: $r->print('</table>');
1.507 www 5745: &endSettingsScreen($r);
1.340 banghart 5746: return 'ok';
5747: }
1.416 jms 5748:
5749:
1.563 damieng 5750: # Returns HTML with a Continue button redirecting to the initial portfolio metadata screen.
5751: # @returns {string}
1.359 banghart 5752: sub continue {
5753: my $output;
5754: $output .= '<form action="" method="post">';
5755: $output .= '<input type="hidden" name="action" value="setrestrictmeta" />';
5756: $output .= '<input type="submit" value="Continue" />';
5757: return ($output);
5758: }
1.416 jms 5759:
5760:
1.563 damieng 5761: # UI to add a metadata field.
5762: # Currenly does not work because of an HTML error (the field is not visible).
5763: #
5764: # @param {Apache2::RequestRec} $r - the Apache request
1.334 banghart 5765: sub addmetafield {
5766: my ($r)=@_;
1.414 droeschl 5767: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=addmetadata',
1.473 amueller 5768: text=>"Add Metadata Field"});
1.334 banghart 5769: $r->print(&Apache::loncommon::start_page('Add Metadata Field'));
5770: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Add Metadata Field'));
1.335 banghart 5771: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
5772: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 5773: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
5774: &startSettingsScreen($r,'parmset',$crstype);
1.339 banghart 5775: if (exists($env{'form.undelete'})) {
1.358 banghart 5776: my @meta_fields = &Apache::loncommon::get_env_multiple('form.undeletefield');
1.339 banghart 5777: foreach my $meta_field(@meta_fields) {
5778: my $options = $env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.options'};
5779: $options =~ s/deleted//;
5780: $options =~ s/,,/,/;
5781: my $put_result = &Apache::lonnet::put('environment',
5782: {'metadata.'.$meta_field.'.options'=>$options},$dom,$crs);
1.446 bisitz 5783:
1.339 banghart 5784: $r->print('Undeleted Metadata Field <strong>'.$env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.added'}."</strong> with result ".$put_result.'<br />');
5785: }
1.359 banghart 5786: $r->print(&continue());
1.339 banghart 5787: } elsif (exists($env{'form.fieldname'})) {
1.335 banghart 5788: my $meta_field = $env{'form.fieldname'};
5789: my $display_field = $env{'form.fieldname'};
5790: $meta_field =~ s/\W/_/g;
1.338 banghart 5791: $meta_field =~ tr/A-Z/a-z/;
1.335 banghart 5792: my $put_result = &Apache::lonnet::put('environment',
5793: {'metadata.'.$meta_field.'.values'=>"",
5794: 'metadata.'.$meta_field.'.added'=>"$display_field",
5795: 'metadata.'.$meta_field.'.options'=>""},$dom,$crs);
1.359 banghart 5796: $r->print('Added new Metadata Field <strong>'.$env{'form.fieldname'}."</strong> with result ".$put_result.'<br />');
5797: $r->print(&continue());
1.335 banghart 5798: } else {
1.357 raeburn 5799: my $fields = &get_deleted_meta_fieldnames($env{'request.course.id'});
1.339 banghart 5800: if ($fields) {
5801: $r->print('You may undelete previously deleted fields.<br />Check those you wish to undelete and click Undelete.<br />');
5802: $r->print('<form method="post" action="">');
5803: foreach my $key(keys(%$fields)) {
1.358 banghart 5804: $r->print('<input type="checkbox" name="undeletefield" value="'.$key.'" />'.$$fields{$key}.'<br /');
1.339 banghart 5805: }
5806: $r->print('<input type="submit" name="undelete" value="Undelete" />');
5807: $r->print('</form>');
5808: }
1.571 damieng 5809: $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 5810: $r->print('<input type="text" name="fieldname" /><br />');
5811: $r->print('<input type="submit" value="Add Metadata Field" />');
1.334 banghart 5812: }
1.361 albertel 5813: $r->print('</form>');
1.507 www 5814: &endSettingsScreen($r);
1.334 banghart 5815: }
1.416 jms 5816:
5817:
5818:
1.560 damieng 5819: # Display or save portfolio metadata.
1.563 damieng 5820: #
5821: # @param {Apache2::RequestRec} $r - the Apache request
1.259 banghart 5822: sub setrestrictmeta {
1.240 banghart 5823: my ($r)=@_;
1.242 banghart 5824: my $next_meta;
1.244 banghart 5825: my $output;
1.245 banghart 5826: my $item_num;
1.246 banghart 5827: my $put_result;
1.414 droeschl 5828: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setrestrictmeta',
1.473 amueller 5829: text=>"Restrict Metadata"});
1.280 albertel 5830: $r->print(&Apache::loncommon::start_page('Restrict Metadata'));
1.298 albertel 5831: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Restrict Metadata'));
1.240 banghart 5832: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
5833: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 5834: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
5835: &startSettingsScreen($r,'parmset',$crstype);
1.259 banghart 5836: my $key_base = $env{'course.'.$env{'request.course.id'}.'.'};
1.252 banghart 5837: my $save_field = '';
1.259 banghart 5838: if ($env{'form.restrictmeta'}) {
1.254 banghart 5839: foreach my $field (sort(keys(%env))) {
1.252 banghart 5840: if ($field=~m/^form.(.+)_(.+)$/) {
1.254 banghart 5841: my $options;
1.252 banghart 5842: my $meta_field = $1;
5843: my $meta_key = $2;
1.253 banghart 5844: if ($save_field ne $meta_field) {
1.252 banghart 5845: $save_field = $meta_field;
1.473 amueller 5846: if ($env{'form.'.$meta_field.'_stuadd'}) {
5847: $options.='stuadd,';
5848: }
5849: if ($env{'form.'.$meta_field.'_choices'}) {
5850: $options.='choices,';
5851: }
5852: if ($env{'form.'.$meta_field.'_onlyone'} eq 'single') {
5853: $options.='onlyone,';
5854: }
5855: if ($env{'form.'.$meta_field.'_active'}) {
5856: $options.='active,';
5857: }
5858: if ($env{'form.'.$meta_field.'_deleted'}) {
5859: $options.='deleted,';
5860: }
1.259 banghart 5861: my $name = $save_field;
1.560 damieng 5862: $put_result = &Apache::lonnet::put('environment',
5863: {'metadata.'.$meta_field.'.options'=>$options,
5864: 'metadata.'.$meta_field.'.values'=>$env{'form.'.$meta_field.'_values'},
5865: },$dom,$crs);
1.252 banghart 5866: }
5867: }
5868: }
5869: }
1.296 albertel 5870: &Apache::lonnet::coursedescription($env{'request.course.id'},
1.473 amueller 5871: {'freshen_cache' => 1});
1.335 banghart 5872: # Get the default metadata fields
1.258 albertel 5873: my %metadata_fields = &Apache::lonmeta::fieldnames('portfolio');
1.335 banghart 5874: # Now get possible added metadata fields
1.357 raeburn 5875: my $added_metadata_fields = &get_added_meta_fieldnames($env{'request.course.id'});
1.346 banghart 5876: my $row_alt = 1;
1.347 banghart 5877: $output .= &Apache::loncommon::start_data_table();
1.258 albertel 5878: foreach my $field (sort(keys(%metadata_fields))) {
1.265 banghart 5879: if ($field ne 'courserestricted') {
1.346 banghart 5880: $row_alt = $row_alt ? 0 : 1;
1.560 damieng 5881: $output.= &output_row($r, $field, $metadata_fields{$field});
5882: }
1.255 banghart 5883: }
1.351 banghart 5884: my $buttons = (<<ENDButtons);
5885: <input type="submit" name="restrictmeta" value="Save" />
5886: </form><br />
5887: <form method="post" action="/adm/parmset?action=addmetadata" name="form1">
5888: <input type="submit" name="restrictmeta" value="Add a Metadata Field" />
5889: </form>
5890: <br />
5891: <form method="post" action="/adm/parmset?action=ordermetadata" name="form2">
5892: <input type="submit" name="restrictmeta" value="Order Metadata Fields" />
5893: ENDButtons
1.337 banghart 5894: my $added_flag = 1;
1.335 banghart 5895: foreach my $field (sort(keys(%$added_metadata_fields))) {
1.346 banghart 5896: $row_alt = $row_alt ? 0 : 1;
1.563 damieng 5897: $output.= &output_row($r, $field, $$added_metadata_fields{$field},$added_flag, $row_alt); # FIXME: wrong parameters
1.335 banghart 5898: }
1.347 banghart 5899: $output .= &Apache::loncommon::end_data_table();
1.446 bisitz 5900: $r->print(<<ENDenv);
1.259 banghart 5901: <form method="post" action="/adm/parmset?action=setrestrictmeta" name="form">
1.244 banghart 5902: $output
1.351 banghart 5903: $buttons
1.340 banghart 5904: </form>
1.244 banghart 5905: ENDenv
1.507 www 5906: &endSettingsScreen($r);
1.280 albertel 5907: $r->print(&Apache::loncommon::end_page());
1.240 banghart 5908: return 'ok';
5909: }
1.416 jms 5910:
5911:
1.563 damieng 5912: # Returns metadata fields that have been manually added.
5913: #
5914: # @param {string} $cid - course id
5915: # @returns {hash reference} - hash field name -> field title (not localized)
1.335 banghart 5916: sub get_added_meta_fieldnames {
1.357 raeburn 5917: my ($cid) = @_;
1.335 banghart 5918: my %fields;
5919: foreach my $key(%env) {
1.357 raeburn 5920: if ($key =~ m/\Q$cid\E\.metadata\.(.+)\.added$/) {
1.335 banghart 5921: my $field_name = $1;
5922: my ($display_field_name) = $env{$key};
5923: $fields{$field_name} = $display_field_name;
5924: }
5925: }
5926: return \%fields;
5927: }
1.416 jms 5928:
5929:
1.563 damieng 5930: # Returns metadata fields that have been manually added and deleted.
5931: #
5932: # @param {string} $cid - course id
5933: # @returns {hash reference} - hash field name -> field title (not localized)
1.339 banghart 5934: sub get_deleted_meta_fieldnames {
1.357 raeburn 5935: my ($cid) = @_;
1.339 banghart 5936: my %fields;
5937: foreach my $key(%env) {
1.357 raeburn 5938: if ($key =~ m/\Q$cid\E\.metadata\.(.+)\.added$/) {
1.339 banghart 5939: my $field_name = $1;
5940: if ($env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.options'} =~ m/deleted/) {
5941: my ($display_field_name) = $env{$key};
5942: $fields{$field_name} = $display_field_name;
5943: }
5944: }
5945: }
5946: return \%fields;
5947: }
1.560 damieng 5948:
5949:
5950: ##################################################
5951: # PARAMETER SETTINGS DEFAULT ACTIONS
5952: ##################################################
5953:
5954: # UI to change parameter setting default actions
1.563 damieng 5955: #
5956: # @param {Apache2::RequestRec} $r - the Apache request
1.220 www 5957: sub defaultsetter {
1.280 albertel 5958: my ($r) = @_;
5959:
1.414 droeschl 5960: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setdefaults',
1.473 amueller 5961: text=>"Set Defaults"});
1.531 raeburn 5962: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
5963: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
5964: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.446 bisitz 5965: my $start_page =
1.531 raeburn 5966: &Apache::loncommon::start_page('Parameter Setting Default Actions');
1.298 albertel 5967: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Defaults');
1.507 www 5968: $r->print($start_page.$breadcrumbs);
1.531 raeburn 5969: &startSettingsScreen($r,'parmset',$crstype);
1.507 www 5970: $r->print('<form method="post" action="/adm/parmset?action=setdefaults" name="defaultform">');
1.280 albertel 5971:
1.221 www 5972: my @ids=();
5973: my %typep=();
5974: my %keyp=();
5975: my %allparms=();
5976: my %allparts=();
5977: my %allmaps=();
5978: my %mapp=();
5979: my %symbp=();
5980: my %maptitles=();
5981: my %uris=();
5982: my %keyorder=&standardkeyorder();
5983: my %defkeytype=();
5984:
1.446 bisitz 5985: &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
1.473 amueller 5986: \%mapp, \%symbp,\%maptitles,\%uris,
5987: \%keyorder,\%defkeytype);
1.224 www 5988: if ($env{'form.storerules'}) {
1.560 damieng 5989: my %newrules=();
5990: my @delrules=();
5991: my %triggers=();
5992: foreach my $key (keys(%env)) {
1.225 albertel 5993: if ($key=~/^form\.(\w+)\_action$/) {
1.560 damieng 5994: my $tempkey=$1;
5995: my $action=$env{$key};
1.226 www 5996: if ($action) {
1.560 damieng 5997: $newrules{$tempkey.'_action'}=$action;
5998: if ($action ne 'default') {
5999: my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);
6000: $triggers{$whichparm}.=$tempkey.':';
6001: }
6002: $newrules{$tempkey.'_type'}=$defkeytype{$tempkey};
6003: if (&isdateparm($defkeytype{$tempkey})) {
6004: $newrules{$tempkey.'_days'}=$env{'form.'.$tempkey.'_days'};
6005: $newrules{$tempkey.'_hours'}=$env{'form.'.$tempkey.'_hours'};
6006: $newrules{$tempkey.'_min'}=$env{'form.'.$tempkey.'_min'};
6007: $newrules{$tempkey.'_sec'}=$env{'form.'.$tempkey.'_sec'};
6008: } else {
6009: $newrules{$tempkey.'_value'}=$env{'form.'.$tempkey.'_value'};
6010: $newrules{$tempkey.'_triggervalue'}=$env{'form.'.$tempkey.'_triggervalue'};
6011: }
6012: } else {
6013: push(@delrules,$tempkey.'_action');
6014: push(@delrules,$tempkey.'_type');
6015: push(@delrules,$tempkey.'_hours');
6016: push(@delrules,$tempkey.'_min');
6017: push(@delrules,$tempkey.'_sec');
6018: push(@delrules,$tempkey.'_value');
6019: }
1.473 amueller 6020: }
6021: }
1.560 damieng 6022: foreach my $key (keys(%allparms)) {
6023: $newrules{$key.'_triggers'}=$triggers{$key};
1.473 amueller 6024: }
1.560 damieng 6025: &Apache::lonnet::put('parmdefactions',\%newrules,$cdom,$cnum);
6026: &Apache::lonnet::del('parmdefactions',\@delrules,$cdom,$cnum);
6027: &resetrulescache();
1.224 www 6028: }
1.227 www 6029: my %lt=&Apache::lonlocal::texthash('days' => 'Days',
1.473 amueller 6030: 'hours' => 'Hours',
6031: 'min' => 'Minutes',
6032: 'sec' => 'Seconds',
6033: 'yes' => 'Yes',
6034: 'no' => 'No');
1.222 www 6035: my @standardoptions=('','default');
6036: my @standarddisplay=('',&mt('Default value when manually setting'));
6037: my @dateoptions=('','default');
6038: my @datedisplay=('',&mt('Default value when manually setting'));
6039: foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
1.560 damieng 6040: unless ($tempkey) { next; }
6041: push @standardoptions,'when_setting_'.$tempkey;
6042: push @standarddisplay,&mt('Automatically set when setting ').$tempkey;
6043: if (&isdateparm($defkeytype{$tempkey})) {
6044: push @dateoptions,'later_than_'.$tempkey;
6045: push @datedisplay,&mt('Automatically set later than ').$tempkey;
6046: push @dateoptions,'earlier_than_'.$tempkey;
6047: push @datedisplay,&mt('Automatically set earlier than ').$tempkey;
6048: }
1.222 www 6049: }
1.563 damieng 6050: $r->print(&mt('Manual setting rules apply to all interfaces.').'<br />'.
6051: &mt('Automatic setting rules apply to table mode interfaces only.'));
1.318 albertel 6052: $r->print("\n".&Apache::loncommon::start_data_table().
1.473 amueller 6053: &Apache::loncommon::start_data_table_header_row().
6054: "<th>".&mt('Rule for parameter').'</th><th>'.
6055: &mt('Action').'</th><th>'.&mt('Value').'</th>'.
6056: &Apache::loncommon::end_data_table_header_row());
1.221 www 6057: foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
1.560 damieng 6058: unless ($tempkey) { next; }
6059: $r->print("\n".&Apache::loncommon::start_data_table_row().
6060: "<td>".$allparms{$tempkey}."\n<br />(".$tempkey.')</td><td>');
6061: my $action=&rulescache($tempkey.'_action');
6062: $r->print('<select name="'.$tempkey.'_action">');
6063: if (&isdateparm($defkeytype{$tempkey})) {
6064: for (my $i=0;$i<=$#dateoptions;$i++) {
6065: if ($dateoptions[$i]=~/\_$tempkey$/) { next; }
6066: $r->print("\n<option value='$dateoptions[$i]'".
6067: ($dateoptions[$i] eq $action?' selected="selected"':'').
6068: ">$datedisplay[$i]</option>");
6069: }
6070: } else {
6071: for (my $i=0;$i<=$#standardoptions;$i++) {
6072: if ($standardoptions[$i]=~/\_$tempkey$/) { next; }
6073: $r->print("\n<option value='$standardoptions[$i]'".
6074: ($standardoptions[$i] eq $action?' selected="selected"':'').
6075: ">$standarddisplay[$i]</option>");
6076: }
1.473 amueller 6077: }
1.560 damieng 6078: $r->print('</select>');
6079: unless (&isdateparm($defkeytype{$tempkey})) {
6080: $r->print("\n<br />".&mt('Triggering value(s) of other parameter (optional, comma-separated):').
6081: '<input type="text" size="20" name="'.$tempkey.'_triggervalue" value="'.&rulescache($tempkey.'_triggervalue').'" />');
1.473 amueller 6082: }
1.560 damieng 6083: $r->print("\n</td><td>\n");
1.222 www 6084:
1.221 www 6085: if (&isdateparm($defkeytype{$tempkey})) {
1.560 damieng 6086: my $days=&rulescache($tempkey.'_days');
6087: my $hours=&rulescache($tempkey.'_hours');
6088: my $min=&rulescache($tempkey.'_min');
6089: my $sec=&rulescache($tempkey.'_sec');
6090: $r->print(<<ENDINPUTDATE);
6091: <input name="$tempkey\_days" type="text" size="4" value="$days" />$lt{'days'}<br />
6092: <input name="$tempkey\_hours" type="text" size="4" value="$hours" />$lt{'hours'}<br />
6093: <input name="$tempkey\_min" type="text" size="4" value="$min" />$lt{'min'}<br />
6094: <input name="$tempkey\_sec" type="text" size="4" value="$sec" />$lt{'sec'}
1.564 raeburn 6095: ENDINPUTDATE
1.560 damieng 6096: } elsif ($defkeytype{$tempkey} eq 'string_yesno') {
6097: my $yeschecked='';
6098: my $nochecked='';
6099: if (&rulescache($tempkey.'_value') eq 'yes') { $yeschecked=' checked="checked"'; }
6100: if (&rulescache($tempkey.'_value') eq 'no') { $nochecked=' checked="checked"'; }
6101:
6102: $r->print(<<ENDYESNO);
6103: <label><input type="radio" name="$tempkey\_value" value="yes"$yeschecked /> $lt{'yes'}</label><br />
6104: <label><input type="radio" name="$tempkey\_value" value="no"$nochecked /> $lt{'no'}</label>
1.564 raeburn 6105: ENDYESNO
1.221 www 6106: } else {
1.560 damieng 6107: $r->print('<input type="text" size="20" name="'.$tempkey.'_value" value="'.&rulescache($tempkey.'_value').'" />');
6108: }
1.318 albertel 6109: $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.221 www 6110: }
1.318 albertel 6111: $r->print(&Apache::loncommon::end_data_table().
1.473 amueller 6112: "\n".'<input type="submit" name="storerules" value="'.
1.507 www 6113: &mt('Save').'" /></form>'."\n");
6114: &endSettingsScreen($r);
6115: $r->print(&Apache::loncommon::end_page());
1.220 www 6116: return;
6117: }
1.193 albertel 6118:
1.560 damieng 6119: ##################################################
6120: # PARAMETER CHANGES LOG
6121: ##################################################
6122:
1.563 damieng 6123: # Returns some info for a parameter log entry.
6124: # Returned entries:
6125: # $realm - HTML title for the parameter level and resource
6126: # $section - parameter section
6127: # $name - parameter name
6128: # $part - parameter part
6129: # $what - $part.'.'.$name
6130: # $middle - resource symb ?
6131: # $uname - user name (same as given)
6132: # $udom - user domain (same as given)
6133: # $issection - section or group name
6134: # $realmdescription - title for the parameter level and resource (without using HTML)
6135: #
6136: # FIXME: remove unused fields.
6137: #
6138: # @param {string} $key - parameter log key
6139: # @param {string} $uname - user name
6140: # @param {string} $udom - user domain
6141: # @param {string} $exeuser - unused
6142: # @param {string} $exedomain - unused
6143: # @param {boolean} $typeflag - .type log entry
6144: # @returns {Array}
1.290 www 6145: sub components {
1.330 albertel 6146: my ($key,$uname,$udom,$exeuser,$exedomain,$typeflag)=@_;
6147:
6148: if ($typeflag) {
1.560 damieng 6149: $key=~s/\.type$//;
1.290 www 6150: }
1.330 albertel 6151:
6152: my ($middle,$part,$name)=
1.572 damieng 6153: ($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s\-]+)\.(\w+)$/);
1.291 www 6154: my $issection;
1.330 albertel 6155:
1.290 www 6156: my $section=&mt('All Students');
6157: if ($middle=~/^\[(.*)\]/) {
1.560 damieng 6158: $issection=$1;
6159: $section=&mt('Group/Section').': '.$issection;
6160: $middle=~s/^\[(.*)\]//;
1.290 www 6161: }
6162: $middle=~s/\.+$//;
6163: $middle=~s/^\.+//;
1.291 www 6164: if ($uname) {
1.560 damieng 6165: $section=&mt('User').": ".&Apache::loncommon::plainname($uname,$udom);
6166: $issection='';
1.291 www 6167: }
1.316 albertel 6168: my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
1.446 bisitz 6169: my $realmdescription=&mt('all resources');
1.556 raeburn 6170: if ($middle=~/^(.+)\_\_\_\((all|rec)\)$/) {
6171: my $mapurl = $1;
6172: my $maplevel = $2;
6173: my $leveltitle = &mt('Folder/Map');
6174: if ($maplevel eq 'rec') {
6175: $leveltitle = &mt('Recursive');
6176: }
1.560 damieng 6177: $realm='<span class="LC_parm_scope_folder">'.$leveltitle.
6178: ': '.&Apache::lonnet::gettitle($mapurl).' <span class="LC_parm_folder"><br />('.
6179: $mapurl.')</span></span>';
6180: $realmdescription=&mt('folder').' '.&Apache::lonnet::gettitle($mapurl);
6181: } elsif ($middle) {
6182: my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
6183: $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').
6184: ': '.&Apache::lonnet::gettitle($middle).' <br /><span class="LC_parm_symb">('.$url.
6185: ' in '.$map.' id: '.$id.')</span></span>';
6186: $realmdescription=&mt('resource').' '.&Apache::lonnet::gettitle($middle);
1.290 www 6187: }
1.291 www 6188: my $what=$part.'.'.$name;
1.330 albertel 6189: return ($realm,$section,$name,$part,
1.473 amueller 6190: $what,$middle,$uname,$udom,$issection,$realmdescription);
1.290 www 6191: }
1.293 www 6192:
1.563 damieng 6193: my %standard_parms; # hash parameter name -> parameter title (not localized)
6194: my %standard_parms_types; # hash parameter name -> parameter type
1.416 jms 6195:
1.563 damieng 6196: # Reads parameter info from packages.tab into %standard_parms.
1.328 albertel 6197: sub load_parameter_names {
6198: open(my $config,"<$Apache::lonnet::perlvar{'lonTabDir'}/packages.tab");
6199: while (my $configline=<$config>) {
1.560 damieng 6200: if ($configline !~ /\S/ || $configline=~/^\#/) { next; }
6201: chomp($configline);
6202: my ($short,$plain)=split(/:/,$configline);
6203: my (undef,$name,$type)=split(/\&/,$short,3);
6204: if ($type eq 'display') {
6205: $standard_parms{$name} = $plain;
1.469 raeburn 6206: } elsif ($type eq 'type') {
1.560 damieng 6207: $standard_parms_types{$name} = $plain;
1.469 raeburn 6208: }
1.328 albertel 6209: }
6210: close($config);
6211: $standard_parms{'int_pos'} = 'Positive Integer';
6212: $standard_parms{'int_zero_pos'} = 'Positive Integer or Zero';
1.575 raeburn 6213: $standard_parms{'scoreformat'} = 'Format for display of score';
1.328 albertel 6214: }
6215:
1.563 damieng 6216: # Returns a parameter title for standard parameters, the name for others.
6217: #
6218: # @param {string} $name - parameter name
6219: # @returns {string}
1.292 www 6220: sub standard_parameter_names {
6221: my ($name)=@_;
1.328 albertel 6222: if (!%standard_parms) {
1.560 damieng 6223: &load_parameter_names();
1.328 albertel 6224: }
1.292 www 6225: if ($standard_parms{$name}) {
1.560 damieng 6226: return $standard_parms{$name};
1.446 bisitz 6227: } else {
1.560 damieng 6228: return $name;
1.292 www 6229: }
6230: }
1.290 www 6231:
1.563 damieng 6232: # Returns a parameter type for standard parameters, undef for others.
6233: #
6234: # @param {string} $name - parameter name
6235: # @returns {string}
1.469 raeburn 6236: sub standard_parameter_types {
6237: my ($name)=@_;
6238: if (!%standard_parms_types) {
6239: &load_parameter_names();
6240: }
6241: if ($standard_parms_types{$name}) {
6242: return $standard_parms_types{$name};
6243: }
6244: return;
6245: }
1.309 www 6246:
1.563 damieng 6247: # Returns a parameter level title (not localized) from the parameter level name.
6248: #
6249: # @param {string} $name - parameter level name (recognized: resourcelevel|maplevel|maplevelrecurse|courselevel)
6250: # @returns {string}
1.557 raeburn 6251: sub standard_parameter_levels {
6252: my ($name)=@_;
6253: my %levels = (
6254: 'resourcelevel' => 'a single resource',
6255: 'maplevel' => 'the enclosing map/folder',
6256: 'maplevelrecurse' => 'the enclosing map/folder (recursive into sub-folders)',
6257: 'courselevel' => 'the general (course) level',
6258: );
6259: if ($levels{$name}) {
6260: return $levels{$name};
6261: }
6262: return;
6263: }
6264:
1.560 damieng 6265: # Display log for parameter changes, blog postings, user notification changes.
1.563 damieng 6266: #
6267: # @param {Apache2::RequestRec} $r - the Apache request
1.285 albertel 6268: sub parm_change_log {
1.568 raeburn 6269: my ($r,$parm_permission)=@_;
1.531 raeburn 6270: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
6271: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.569 raeburn 6272: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.414 droeschl 6273: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',
1.473 amueller 6274: text=>"Parameter Change Log"});
1.522 raeburn 6275: my $js = '<script type="text/javascript">'."\n".
6276: '// <![CDATA['."\n".
6277: &Apache::loncommon::display_filter_js('parmslog')."\n".
6278: '// ]]>'."\n".
6279: '</script>'."\n";
6280: $r->print(&Apache::loncommon::start_page('Parameter Change Log',$js));
1.327 albertel 6281: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Parameter Change Log'));
1.531 raeburn 6282: &startSettingsScreen($r,'parmset',$crstype);
6283: my %parmlog=&Apache::lonnet::dump('nohist_parameterlog',$cdom,$cnum);
1.311 albertel 6284:
1.301 www 6285: if ((keys(%parmlog))[0]=~/^error\:/) { undef(%parmlog); }
1.311 albertel 6286:
1.522 raeburn 6287: $r->print('<div class="LC_left_float">'.
6288: '<fieldset><legend>'.&mt('Display of Changes').'</legend>'.
6289: '<form action="/adm/parmset?action=parameterchangelog"
1.327 albertel 6290: method="post" name="parameterlog">');
1.446 bisitz 6291:
1.311 albertel 6292: my %saveable_parameters = ('show' => 'scalar',);
6293: &Apache::loncommon::store_course_settings('parameter_log',
6294: \%saveable_parameters);
6295: &Apache::loncommon::restore_course_settings('parameter_log',
6296: \%saveable_parameters);
1.522 raeburn 6297: $r->print(&Apache::loncommon::display_filter('parmslog').' '."\n".
6298: '<input type="submit" value="'.&mt('Display').'" />'.
6299: '</form></fieldset></div><br clear="all" />');
1.301 www 6300:
1.568 raeburn 6301: my $readonly = 1;
6302: if ($parm_permission->{'edit'}) {
6303: undef($readonly);
6304: }
1.531 raeburn 6305: my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
1.301 www 6306: $r->print(&Apache::loncommon::start_data_table().&Apache::loncommon::start_data_table_header_row().
1.473 amueller 6307: '<th>'.&mt('Time').'</th><th>'.&mt('User').'</th><th>'.&mt('Extent').'</th><th>'.&mt('Users').'</th><th>'.
1.568 raeburn 6308: &mt('Parameter').'</th><th>'.&mt('Part').'</th><th>'.&mt('New Value').'</th>');
6309: unless ($readonly) {
6310: $r->print('<th>'.&mt('Announce').'</th>');
6311: }
6312: $r->print(&Apache::loncommon::end_data_table_header_row());
1.309 www 6313: my $shown=0;
1.349 www 6314: my $folder='';
6315: if ($env{'form.displayfilter'} eq 'currentfolder') {
1.560 damieng 6316: my $last='';
6317: if (tie(my %hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db',
6318: &GDBM_READER(),0640)) {
6319: $last=$hash{'last_known'};
6320: untie(%hash);
6321: }
6322: if ($last) { ($folder) = &Apache::lonnet::decode_symb($last); }
6323: }
6324: foreach my $id (sort {
6325: if ($parmlog{$b}{'exe_time'} ne $parmlog{$a}{'exe_time'}) {
6326: return $parmlog{$b}{'exe_time'} <=>$parmlog{$a}{'exe_time'}
6327: }
6328: my $aid = (split('00000',$a))[-1];
6329: my $bid = (split('00000',$b))[-1];
6330: return $bid<=>$aid;
1.473 amueller 6331: } (keys(%parmlog))) {
1.294 www 6332: my @changes=keys(%{$parmlog{$id}{'logentry'}});
1.560 damieng 6333: my $count = 0;
6334: my $time =
6335: &Apache::lonlocal::locallocaltime($parmlog{$id}{'exe_time'});
6336: my $plainname =
6337: &Apache::loncommon::plainname($parmlog{$id}{'exe_uname'},
6338: $parmlog{$id}{'exe_udom'});
6339: my $about_me_link =
6340: &Apache::loncommon::aboutmewrapper($plainname,
6341: $parmlog{$id}{'exe_uname'},
6342: $parmlog{$id}{'exe_udom'});
6343: my $send_msg_link='';
1.568 raeburn 6344: if ((!$readonly) &&
6345: (($parmlog{$id}{'exe_uname'} ne $env{'user.name'})
1.560 damieng 6346: || ($parmlog{$id}{'exe_udom'} ne $env{'user.domain'}))) {
6347: $send_msg_link ='<br />'.
6348: &Apache::loncommon::messagewrapper(&mt('Send message'),
6349: $parmlog{$id}{'exe_uname'},
6350: $parmlog{$id}{'exe_udom'});
6351: }
6352: my $row_start=&Apache::loncommon::start_data_table_row();
6353: my $makenewrow=0;
6354: my %istype=();
6355: my $output;
6356: foreach my $changed (reverse(sort(@changes))) {
6357: my $value=$parmlog{$id}{'logentry'}{$changed};
6358: my $typeflag = ($changed =~/\.type$/ &&
6359: !exists($parmlog{$id}{'logentry'}{$changed.'.type'}));
1.330 albertel 6360: my ($realm,$section,$parmname,$part,$what,$middle,$uname,$udom,$issection,$realmdescription)=
1.560 damieng 6361: &components($changed,$parmlog{$id}{'uname'},$parmlog{$id}{'udom'},undef,undef,$typeflag);
6362: if ($env{'request.course.sec'} ne '') {
6363: next if (($issection ne '') && ($issection ne $env{'request.course.sec'}));
6364: if ($uname ne '') {
6365: my $stusection = &Apache::lonnet::getsection($uname,$udom,$env{'request.course.id'});
6366: next if (($stusection ne '-1') && ($stusection ne $env{'request.course.sec'}));
6367: }
6368: }
6369: if ($env{'form.displayfilter'} eq 'currentfolder') {
6370: if ($folder) {
6371: if ($middle!~/^\Q$folder\E/) { next; }
6372: }
6373: }
6374: if ($typeflag) {
6375: $istype{$parmname}=$value;
6376: if (!$env{'form.includetypes'}) { next; }
6377: }
6378: $count++;
6379: if ($makenewrow) {
6380: $output .= $row_start;
6381: } else {
6382: $makenewrow=1;
6383: }
1.470 raeburn 6384: my $parmitem = &standard_parameter_names($parmname);
1.560 damieng 6385: $output .='<td>'.$realm.'</td><td>'.$section.'</td><td>'.
6386: &mt($parmitem).'</td><td>'.
6387: ($part?&mt('Part: [_1]',$part):&mt('All Parts')).'</td><td>';
6388: my $stillactive=0;
6389: if ($parmlog{$id}{'delflag'}) {
6390: $output .= &mt('Deleted');
6391: } else {
6392: if ($typeflag) {
1.470 raeburn 6393: my $parmitem = &standard_parameter_names($value);
6394: $parmitem = &mt($parmitem);
1.560 damieng 6395: $output .= &mt('Type: [_1]',$parmitem);
6396: } else {
6397: my ($level,@all)=&parmval_by_symb($what,$middle,
6398: &Apache::lonnet::metadata($middle,$what),
6399: $uname,$udom,$issection,$issection,$courseopt);
1.469 raeburn 6400: my $showvalue = $value;
6401: if ($istype{$parmname} eq '') {
6402: my $type = &standard_parameter_types($parmname);
6403: if ($type ne '') {
6404: if (&isdateparm($type)) {
6405: $showvalue =
6406: &Apache::lonlocal::locallocaltime($value);
6407: }
6408: }
6409: } else {
1.560 damieng 6410: if (&isdateparm($istype{$parmname})) {
6411: $showvalue = &Apache::lonlocal::locallocaltime($value);
6412: }
1.469 raeburn 6413: }
6414: $output .= $showvalue;
1.560 damieng 6415: if ($value ne $all[$level]) {
6416: $output .= '<br /><span class="LC_warning">'.&mt('Not active anymore').'</span>';
6417: } else {
6418: $stillactive=1;
6419: }
6420: }
1.473 amueller 6421: }
1.568 raeburn 6422: $output .= '</td>';
6423:
6424: unless ($readonly) {
6425: $output .= '<td>';
6426: if ($stillactive) {
6427: my $parmitem = &standard_parameter_names($parmname);
6428: $parmitem = &mt($parmitem);
6429: my $title=&mt('Changed [_1]',$parmitem);
6430: my $description=&mt('Changed [_1] for [_2] to [_3]',
6431: $parmitem,$realmdescription,
6432: (&isdateparm($istype{$parmname})?&Apache::lonlocal::locallocaltime($value):$value));
6433: if (($uname) && ($udom)) {
6434: $output .=
6435: &Apache::loncommon::messagewrapper('Notify User',
6436: $uname,$udom,$title,
6437: $description);
6438: } else {
6439: $output .=
6440: &Apache::lonrss::course_blog_link($id,$title,
6441: $description);
6442: }
1.560 damieng 6443: }
1.568 raeburn 6444: $output .= '</td>';
1.560 damieng 6445: }
1.568 raeburn 6446: $output .= &Apache::loncommon::end_data_table_row();
1.473 amueller 6447: }
1.560 damieng 6448: if ($env{'form.displayfilter'} eq 'containing') {
6449: my $wholeentry=$about_me_link.':'.
6450: $parmlog{$id}{'exe_uname'}.':'.$parmlog{$id}{'exe_udom'}.':'.
6451: $output;
6452: if ($wholeentry!~/\Q$env{'form.containingphrase'}\E/i) { next; }
1.473 amueller 6453: }
1.349 www 6454: if ($count) {
1.560 damieng 6455: $r->print($row_start.'<td rowspan="'.$count.'">'.$time.'</td>
6456: <td rowspan="'.$count.'">'.$about_me_link.
6457: '<br /><tt>'.$parmlog{$id}{'exe_uname'}.
6458: ':'.$parmlog{$id}{'exe_udom'}.'</tt>'.
6459: $send_msg_link.'</td>'.$output);
6460: $shown++;
6461: }
6462: if (!($env{'form.show'} eq &mt('all')
6463: || $shown<=$env{'form.show'})) { last; }
1.286 www 6464: }
1.301 www 6465: $r->print(&Apache::loncommon::end_data_table());
1.507 www 6466: &endSettingsScreen($r);
1.284 www 6467: $r->print(&Apache::loncommon::end_page());
6468: }
6469:
1.560 damieng 6470: ##################################################
6471: # MISC !
6472: ##################################################
6473:
1.563 damieng 6474: # Stores slot information.
1.560 damieng 6475: # Used by table UI
1.563 damieng 6476: # FIXME: I don't understand how this can work when the symb is not defined (if only a map was selected)
6477: #
6478: # @param {string} $slot_name - slot name
6479: # @param {string} $cdom - course domain
6480: # @param {string} $cnum - course number
6481: # @param {string} $symb - resource symb
6482: # @param {string} $uname - user name
6483: # @param {string} $udom - user domain
6484: # @returns {string} - 'ok' or error name
1.437 raeburn 6485: sub update_slots {
6486: my ($slot_name,$cdom,$cnum,$symb,$uname,$udom) = @_;
6487: my %slot=&Apache::lonnet::get_slot($slot_name);
6488: if (!keys(%slot)) {
6489: return 'error: slot does not exist';
6490: }
6491: my $max=$slot{'maxspace'};
6492: if (!defined($max)) { $max=99999; }
6493:
6494: my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
6495: "^$slot_name\0");
6496: my ($tmp)=%consumed;
6497: if ($tmp=~/^error: 2 / ) {
6498: return 'error: unable to determine current slot status';
6499: }
6500: my $last=0;
6501: foreach my $key (keys(%consumed)) {
6502: my $num=(split('\0',$key))[1];
6503: if ($num > $last) { $last=$num; }
6504: if ($consumed{$key}->{'name'} eq $uname.':'.$udom) {
6505: return 'ok';
6506: }
6507: }
6508:
6509: if (scalar(keys(%consumed)) >= $max) {
6510: return 'error: no space left in slot';
6511: }
6512: my $wanted=$last+1;
6513:
6514: my %reservation=('name' => $uname.':'.$udom,
6515: 'timestamp' => time,
6516: 'symb' => $symb);
6517:
6518: my $success=&Apache::lonnet::newput('slot_reservations',
6519: {"$slot_name\0$wanted" =>
6520: \%reservation},
6521: $cdom, $cnum);
1.438 raeburn 6522: if ($success eq 'ok') {
6523: my %storehash = (
6524: symb => $symb,
6525: slot => $slot_name,
6526: action => 'reserve',
6527: context => 'parameter',
6528: );
1.526 raeburn 6529: &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,
1.524 raeburn 6530: '',$uname,$udom,$cnum,$cdom);
1.438 raeburn 6531:
1.526 raeburn 6532: &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash,
1.524 raeburn 6533: '',$uname,$udom,$uname,$udom);
1.438 raeburn 6534: }
1.437 raeburn 6535: return $success;
6536: }
6537:
1.563 damieng 6538: # Deletes a slot reservation.
1.560 damieng 6539: # Used by table UI
1.563 damieng 6540: # FIXME: I don't understand how this can work when the symb is not defined (if only a map was selected)
6541: #
6542: # @param {string} $slot_name - slot name
6543: # @param {string} $cdom - course domain
6544: # @param {string} $cnum - course number
6545: # @param {string} $uname - user name
6546: # @param {string} $udom - user domain
6547: # @param {string} $symb - resource symb
6548: # @returns {string} - 'ok' or error name
1.437 raeburn 6549: sub delete_slots {
6550: my ($slot_name,$cdom,$cnum,$uname,$udom,$symb) = @_;
6551: my $delresult;
6552: my %consumed = &Apache::lonnet::dump('slot_reservations',$cdom,
6553: $cnum, "^$slot_name\0");
6554: if (&Apache::lonnet::error(%consumed)) {
6555: return 'error: unable to determine current slot status';
6556: }
6557: my ($tmp)=%consumed;
6558: if ($tmp=~/^error: 2 /) {
6559: return 'error: unable to determine current slot status';
6560: }
6561: foreach my $key (keys(%consumed)) {
6562: if ($consumed{$key}->{'name'} eq $uname.':'.$udom) {
6563: my $num=(split('\0',$key))[1];
6564: my $entry = $slot_name.'\0'.$num;
6565: $delresult = &Apache::lonnet::del('slot_reservations',[$entry],
6566: $cdom,$cnum);
6567: if ($delresult eq 'ok') {
6568: my %storehash = (
6569: symb => $symb,
6570: slot => $slot_name,
6571: action => 'release',
6572: context => 'parameter',
6573: );
1.526 raeburn 6574: &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,
1.524 raeburn 6575: 1,$uname,$udom,$cnum,$cdom);
1.526 raeburn 6576: &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash,
1.524 raeburn 6577: 1,$uname,$udom,$uname,$udom);
1.437 raeburn 6578: }
6579: }
6580: }
6581: return $delresult;
6582: }
6583:
1.563 damieng 6584: # Returns true if there is a current course.
1.560 damieng 6585: # Used by handler
1.563 damieng 6586: #
6587: # @returns {boolean}
1.355 albertel 6588: sub check_for_course_info {
6589: my $navmap = Apache::lonnavmaps::navmap->new();
6590: return 1 if ($navmap);
6591: return 0;
6592: }
6593:
1.563 damieng 6594: # Returns the current course host and host LON-CAPA version.
6595: #
6596: # @returns {Array} - (course hostname, major version number, minor version number)
1.514 raeburn 6597: sub parameter_release_vars {
1.504 raeburn 6598: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
6599: my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};
6600: my $chostname = &Apache::lonnet::hostname($chome);
6601: my ($cmajor,$cminor) =
6602: split(/\./,&Apache::lonnet::get_server_loncaparev($cdom,$chome));
6603: return ($chostname,$cmajor,$cminor);
6604: }
6605:
1.563 damieng 6606: # Checks if the course host version can handle a parameter required version,
6607: # and if it does, stores the release needed for the course.
6608: #
6609: # @param {string} $name - parameter name
6610: # @param {string} $value - parameter value
6611: # @param {string} $valmatch - name of the test used for checking the value
6612: # @param {string} $namematch - name of the test used for checking the name
6613: # @param {string} $needsrelease - version needed by the parameter, major.minor
6614: # @param {integer} $cmajor - course major version number
6615: # @param {integer} $cminor - course minor version number
6616: # @returns {boolean} - true if a newer version is needed
1.514 raeburn 6617: sub parameter_releasecheck {
1.557 raeburn 6618: my ($name,$value,$valmatch,$namematch,$needsrelease,$cmajor,$cminor) = @_;
1.504 raeburn 6619: my $needsnewer;
6620: my ($needsmajor,$needsminor) = split(/\./,$needsrelease);
6621: if (($cmajor < $needsmajor) ||
6622: ($cmajor == $needsmajor && $cminor < $needsminor)) {
6623: $needsnewer = 1;
1.557 raeburn 6624: } elsif ($name) {
6625: if ($valmatch) {
6626: &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:'.$name.'::'.$valmatch.':'});
6627: } elsif ($value) {
6628: &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:'.$name.':'.$value.'::'});
6629: }
6630: } elsif ($namematch) {
6631: &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter::::'.$namematch});
1.504 raeburn 6632: }
6633: return $needsnewer;
6634: }
6635:
1.568 raeburn 6636: sub get_permission {
6637: my %permission;
6638: my $allowed = 0;
6639: return (\%permission,$allowed) unless ($env{'request.course.id'});
6640: if ((&Apache::lonnet::allowed('opa',$env{'request.course.id'})) ||
6641: (&Apache::lonnet::allowed('opa',$env{'request.course.id'}.'/'.
6642: $env{'request.course.sec'}))) {
6643: %permission= (
6644: 'edit' => 1,
6645: 'set' => 1,
6646: 'setoverview' => 1,
6647: 'addmetadata' => 1,
6648: 'ordermetadata' => 1,
6649: 'setrestrictmeta' => 1,
6650: 'newoverview' => 1,
6651: 'setdefaults' => 1,
6652: 'settable' => 1,
6653: 'parameterchangelog' => 1,
6654: 'cleanparameters' => 1,
6655: 'dateshift1' => 1,
6656: 'dateshift2' => 1,
6657: 'helper' => 1,
6658: );
6659: } elsif ((&Apache::lonnet::allowed('vpa',$env{'request.course.id'})) ||
6660: (&Apache::lonnet::allowed('vpa',$env{'request.course.id'}.'/'.
6661: $env{'request.course.sec'}))) {
6662: %permission = (
6663: 'set' => 1,
6664: 'settable' => 1,
6665: 'newoverview' => 1,
6666: 'setoverview' => 1,
6667: 'parameterchangelog' => 1,
6668: );
6669: }
6670: foreach my $perm (values(%permission)) {
6671: if ($perm) { $allowed=1; last; }
6672: }
6673: return (\%permission,$allowed);
6674: }
6675:
1.560 damieng 6676: ##################################################
6677: # HANDLER
6678: ##################################################
6679:
6680: # Main handler for lonparmset.
6681: # Sub called based on request parameters action and command:
6682: # no command or action: print_main_menu
6683: # command 'set': assessparms (direct access to table mode for a resource)
6684: # (this can also be accessed simply with the symb parameter)
6685: # action 'setoverview': overview (display all existing parameter settings)
6686: # action 'addmetadata': addmetafield (called to add a portfolio metadata field)
6687: # action 'ordermetadata': order_meta_fields (called to order portfolio metadata fields)
6688: # action 'setrestrictmeta': setrestrictmeta (display or save portfolio metadata)
6689: # action 'newoverview': newoverview (overview mode)
6690: # action 'setdefaults': defaultsetter (UI to change parameter setting default actions)
6691: # action 'settable': assessparms (table mode)
6692: # action 'parameterchangelog': parm_change_log (display log for parameter changes,
6693: # blog postings, user notification changes)
6694: # action 'cleanparameters': clean_parameters (unused)
6695: # action 'dateshift1': date_shift_one (overview mode, shift all dates)
6696: # action 'dateshift2': date_shift_two (overview mode, shift all dates)
1.30 www 6697: sub handler {
1.43 albertel 6698: my $r=shift;
1.30 www 6699:
1.376 albertel 6700: &reset_caches();
6701:
1.414 droeschl 6702: &Apache::loncommon::content_type($r,'text/html');
6703: $r->send_http_header;
6704: return OK if $r->header_only;
6705:
1.193 albertel 6706: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.473 amueller 6707: ['action','state',
1.205 www 6708: 'pres_marker',
6709: 'pres_value',
1.206 www 6710: 'pres_type',
1.506 www 6711: 'filter','part',
1.390 www 6712: 'udom','uname','symb','serial','timebase']);
1.131 www 6713:
1.83 bowersj2 6714:
1.193 albertel 6715: &Apache::lonhtmlcommon::clear_breadcrumbs();
1.194 albertel 6716: &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/parmset",
1.507 www 6717: text=>"Content and Problem Settings",
1.473 amueller 6718: faq=>10,
6719: bug=>'Instructor Interface',
1.442 droeschl 6720: help =>
6721: 'Parameter_Manager,Course_Environment,Parameter_Helper,Parameter_Overview,Table_Mode'});
1.203 www 6722:
1.30 www 6723: # ----------------------------------------------------- Needs to be in a course
1.568 raeburn 6724: my ($parm_permission,$allowed) = &get_permission();
1.355 albertel 6725: my $exists = &check_for_course_info();
6726:
1.568 raeburn 6727: if ($env{'request.course.id'} && $allowed && $exists) {
1.193 albertel 6728: #
6729: # Main switch on form.action and form.state, as appropriate
6730: #
6731: # Check first if coming from someone else headed directly for
6732: # the table mode
1.568 raeburn 6733: if (($parm_permission->{'set'}) &&
6734: ((($env{'form.command'} eq 'set') && ($env{'form.url'})
6735: && (!$env{'form.dis'})) || ($env{'form.symb'}))) {
6736: &assessparms($r,$parm_permission);
1.193 albertel 6737: } elsif (! exists($env{'form.action'})) {
6738: &print_main_menu($r,$parm_permission);
1.568 raeburn 6739: } elsif (!$parm_permission->{$env{'form.action'}}) {
6740: &print_main_menu($r,$parm_permission);
1.414 droeschl 6741: } elsif ($env{'form.action'} eq 'setoverview') {
1.568 raeburn 6742: &overview($r,$parm_permission);
1.560 damieng 6743: } elsif ($env{'form.action'} eq 'addmetadata') {
6744: &addmetafield($r);
6745: } elsif ($env{'form.action'} eq 'ordermetadata') {
6746: &order_meta_fields($r);
1.414 droeschl 6747: } elsif ($env{'form.action'} eq 'setrestrictmeta') {
1.560 damieng 6748: &setrestrictmeta($r);
1.414 droeschl 6749: } elsif ($env{'form.action'} eq 'newoverview') {
1.568 raeburn 6750: &newoverview($r,$parm_permission);
1.414 droeschl 6751: } elsif ($env{'form.action'} eq 'setdefaults') {
1.560 damieng 6752: &defaultsetter($r);
6753: } elsif ($env{'form.action'} eq 'settable') {
1.568 raeburn 6754: &assessparms($r,$parm_permission);
1.414 droeschl 6755: } elsif ($env{'form.action'} eq 'parameterchangelog') {
1.568 raeburn 6756: &parm_change_log($r,$parm_permission);
1.414 droeschl 6757: } elsif ($env{'form.action'} eq 'cleanparameters') {
1.560 damieng 6758: &clean_parameters($r);
1.414 droeschl 6759: } elsif ($env{'form.action'} eq 'dateshift1') {
1.390 www 6760: &date_shift_one($r);
1.414 droeschl 6761: } elsif ($env{'form.action'} eq 'dateshift2') {
1.390 www 6762: &date_shift_two($r);
1.446 bisitz 6763: }
1.43 albertel 6764: } else {
1.1 www 6765: # ----------------------------- Not in a course, or not allowed to modify parms
1.560 damieng 6766: if ($exists) {
6767: $env{'user.error.msg'}=
6768: "/adm/parmset:opa:0:0:Cannot modify assessment parameters";
6769: } else {
6770: $env{'user.error.msg'}=
6771: "/adm/parmset::0:1:Course environment gone, reinitialize the course";
6772: }
6773: return HTTP_NOT_ACCEPTABLE;
1.43 albertel 6774: }
1.376 albertel 6775: &reset_caches();
6776:
1.43 albertel 6777: return OK;
1.1 www 6778: }
6779:
6780: 1;
6781: __END__
6782:
6783:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>