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