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