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