Annotation of loncom/interface/lonparmset.pm, revision 1.588
1.1 www 1: # The LearningOnline Network with CAPA
2: # Handler to set parameters for assessments
3: #
1.588 ! raeburn 4: # $Id: lonparmset.pm,v 1.587 2018/11/13 03:59:00 raeburn Exp $
1.40 albertel 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
1.59 matthew 28: ###################################################################
29: ###################################################################
30:
31: =pod
32:
33: =head1 NAME
34:
35: lonparmset - Handler to set parameters for assessments and course
36:
37: =head1 SYNOPSIS
38:
1.579 raeburn 39: lonparmset provides an interface to setting content parameters in a
40: course.
1.560 damieng 41:
42: It contains all the code for the "Content and Problem Settings" UI, except
43: for the helpers parameter.helper and resettimes.helper, and lonhelper.pm,
44: and lonblockingmenu.pm.
1.59 matthew 45:
46: =head1 DESCRIPTION
47:
48: This module sets coursewide and assessment parameters.
49:
50: =head1 INTERNAL SUBROUTINES
51:
1.416 jms 52: =over
1.59 matthew 53:
1.416 jms 54: =item parmval()
1.59 matthew 55:
56: Figure out a cascading parameter.
57:
1.71 albertel 58: Inputs: $what - a parameter spec (incluse part info and name I.E. 0.weight)
1.162 albertel 59: $id - a bighash Id number
1.71 albertel 60: $def - the resource's default value 'stupid emacs
61:
1.556 raeburn 62: Returns: A list, the first item is the index into the remaining list of items of parm values that is the active one, the list consists of parm values at the 18 possible levels
1.71 albertel 63:
1.556 raeburn 64: 18 - General Course
65: 17 - Map or Folder level in course (recursive)
66: 16 - Map or Folder level in course (non-recursive)
67: 15 - resource default
68: 14 - map default
69: 13 - resource level in course
70: 12 - General for section
71: 11 - Map or Folder level for section (recursive)
72: 10 - Map or Folder level for section (non-recursive)
73: 9 - resource level in section
74: 8 - General for group
75: 7 - Map or Folder level for group (recursive)
76: 6 - Map or Folder level for group (non-recursive)
77: 5 - resource level in group
78: 4 - General for specific student
79: 3 - Map or Folder level for specific student (recursive)
80: 2 - Map or Folder level for specific student (non-recursive)
1.71 albertel 81: 1 - resource level for specific student
1.2 www 82:
1.416 jms 83: =item parmval_by_symb()
84:
85: =item reset_caches()
86:
87: =item cacheparmhash()
88:
89: =item parmhash()
90:
91: =item symbcache()
92:
93: =item preset_defaults()
94:
95: =item date_sanity_info()
96:
97: =item storeparm()
98:
99: Store a parameter by symb
100:
101: Takes
102: - symb
103: - name of parameter
104: - level
105: - new value
106: - new type
107: - username
108: - userdomain
109:
110: =item log_parmset()
111:
112: =item storeparm_by_symb_inner()
113:
114: =item valout()
115:
116: Format a value for output.
117:
118: Inputs: $value, $type, $editable
119:
120: Returns: $value, formatted for output. If $type indicates it is a date,
121: localtime($value) is returned.
122: $editable will return an icon to click on
123:
124: =item plink()
125:
126: Produces a link anchor.
127:
128: Inputs: $type,$dis,$value,$marker,$return,$call
129:
130: Returns: scalar with html code for a link which will envoke the
131: javascript function 'pjump'.
132:
133: =item page_js()
134:
135: =item startpage()
136:
137: =item print_row()
138:
139: =item print_td()
140:
1.580 raeburn 141: =item check_other_groups()
1.416 jms 142:
143: =item parm_control_group()
144:
145: =item extractResourceInformation() :
146:
1.512 foxr 147: extractResourceInformation extracts lots of information about all of the the course's resources into a variety of hashes.
1.416 jms 148:
1.542 raeburn 149: Input: See list below
150:
151: =over 4
1.416 jms 152:
1.512 foxr 153: =item * B<env{'user.name'}> : Current username
1.416 jms 154:
1.512 foxr 155: =item * B<env{'user.domain'}> : Domain of current user.
1.416 jms 156:
1.542 raeburn 157: =item * B<env{"request.course.fn"}> : Course
158:
159: =back
1.416 jms 160:
1.512 foxr 161: Outputs: See list below:
1.416 jms 162:
1.542 raeburn 163: =over 4
164:
1.512 foxr 165: =item * B<ids> (out) : An array that will contain all of the ids in the course.
1.416 jms 166:
1.512 foxr 167: =item * B<typep>(out) : hash, id->type, where "type" contains the extension of the file, thus, I<problem exam quiz assess survey form>.
1.416 jms 168:
1.512 foxr 169: =item * B<keyp> (out) : hash, id->key list, will contain a comma separated list of the meta-data keys available for the given id
1.416 jms 170:
1.512 foxr 171: =item * B<allparms> (out) : hash, name of parameter->display value (what is the display value?)
1.416 jms 172:
1.512 foxr 173: =item * B<allparts> (out) : hash, part identification->text representation of part, where the text representation is "[Part $part]"
174:
175: =item * B<allmaps> (out) : hash, ???
1.416 jms 176:
177: =item * B<mapp> : ??
178:
179: =item * B<symbp> : hash, id->full sym?
180:
1.512 foxr 181: =item * B<maptitles>
182:
183: =item * B<uris>
1.416 jms 184:
1.512 foxr 185: =item * B<keyorder>
186:
187: =item * B<defkeytype>
1.416 jms 188:
1.542 raeburn 189: =back
190:
1.416 jms 191: =item isdateparm()
192:
193: =item parmmenu()
194:
195: =item partmenu()
196:
197: =item usermenu()
198:
199: =item displaymenu()
200:
201: =item mapmenu()
202:
203: =item levelmenu()
204:
205: =item sectionmenu()
206:
207: =item keysplit()
208:
209: =item keysinorder()
210:
211: =item keysinorder_bytype()
212:
213: =item keysindisplayorder()
214:
215: =item standardkeyorder()
216:
217: =item assessparms() :
218:
219: Show assessment data and parameters. This is a large routine that should
220: be simplified and shortened... someday.
221:
1.513 foxr 222: Inputs: $r - the Apache request object.
223:
1.416 jms 224: Returns: nothing
225:
226: Variables used (guessed by Jeremy):
227:
1.542 raeburn 228: =over
229:
1.416 jms 230: =item * B<pscat>: ParameterS CATegories? ends up a list of the types of parameters that exist, e.g., tol, weight, acc, opendate, duedate, answerdate, sig, maxtries, type.
231:
232: =item * B<psprt>: ParameterS PaRTs? a list of the parts of a problem that we are displaying? Used to display only selected parts?
233:
234: =item * B<@catmarker> contains list of all possible parameters including part #s
235:
236: =item * B<$fullkeyp> contains the full part/id # for the extraction of proper parameters
237:
238: =item * B<$tempkeyp> contains part 0 only (no ids - ie, subparts)
239: When storing information, store as part 0
240: When requesting information, request from full part
241:
1.542 raeburn 242: =back
243:
1.416 jms 244: =item tablestart()
245:
246: =item tableend()
247:
248: =item extractuser()
249:
250: =item parse_listdata_key()
251:
252: =item listdata()
253:
254: =item date_interval_selector()
255:
256: =item get_date_interval_from_form()
257:
258: =item default_selector()
259:
260: =item string_selector()
261:
262: =item dateshift()
263:
264: =item newoverview()
265:
266: =item secgroup_lister()
267:
268: =item overview()
269:
270: =item clean_parameters()
271:
272: =item date_shift_one()
273:
274: =item date_shift_two()
275:
276: =item parse_key()
277:
278: =item header()
279:
280: Output html header for page
281:
282: =item print_main_menu()
283:
284: =item output_row()
285:
286: Set portfolio metadata
287:
288: =item order_meta_fields()
289:
290: =item addmetafield()
291:
292: =item setrestrictmeta()
293:
294: =item get_added_meta_fieldnames()
295:
296: =item get_deleted_meta_fieldnames()
297:
298: =item defaultsetter()
299:
300: =item components()
301:
302: =item load_parameter_names()
303:
304: =item parm_change_log()
305:
306: =item handler() :
307:
1.450 raeburn 308: Main handler. Calls &assessparms subroutine.
1.416 jms 309:
310: =back
311:
1.59 matthew 312: =cut
313:
1.416 jms 314: ###################################################################
315: ###################################################################
316:
317: package Apache::lonparmset;
318:
319: use strict;
320: use Apache::lonnet;
321: use Apache::Constants qw(:common :http REDIRECT);
322: use Apache::lonhtmlcommon();
323: use Apache::loncommon;
324: use GDBM_File;
325: use Apache::lonhomework;
326: use Apache::lonxml;
327: use Apache::lonlocal;
328: use Apache::lonnavmaps;
329: use Apache::longroup;
330: use Apache::lonrss;
1.506 www 331: use HTML::Entities;
1.416 jms 332: use LONCAPA qw(:DEFAULT :match);
333:
334:
1.560 damieng 335: ##################################################
336: # CONTENT AND PROBLEM SETTINGS HTML PAGE HEADER/FOOTER
337: ##################################################
338:
339: # Page header
1.561 damieng 340: #
341: # @param {Apache2::RequestRec} $r - Apache request object
342: # @param {string} $mode - selected tab, 'parmset' for course and problem settings, or 'coursepref' for course settings
343: # @param {string} $crstype - course type ('Community' for community settings)
1.507 www 344: sub startSettingsScreen {
1.531 raeburn 345: my ($r,$mode,$crstype)=@_;
1.507 www 346:
1.531 raeburn 347: my $tabtext = &mt('Course Settings');
348: if ($crstype eq 'Community') {
349: $tabtext = &mt('Community Settings');
350: }
1.507 www 351: $r->print("\n".'<ul class="LC_TabContentBigger" id="main">');
352: $r->print("\n".'<li'.($mode eq 'coursepref'?' class="active"':'').'><a href="/adm/courseprefs"><b> '.
1.531 raeburn 353: $tabtext.
1.507 www 354: ' </b></a></li>');
355:
1.523 raeburn 356: $r->print("\n".'<li'.($mode eq 'parmset'?' class="active"':'').' id="tabbededitor"><a href="/adm/parmset"><b>'.
1.507 www 357: &mt('Content and Problem Settings').'</b></a></li>');
358: $r->print("\n".'</ul>'."\n");
1.523 raeburn 359: $r->print('<div class="LC_Box" style="clear:both;margin:0;" id="parameditor"><div id="maincoursedoc" style="margin:0 0;padding:0 0;"><div class="LC_ContentBox" id="mainCourseDocuments" style="display: block;">');
1.507 www 360: }
361:
1.560 damieng 362: # Page footer
1.507 www 363: sub endSettingsScreen {
364: my ($r)=@_;
365: $r->print('</div></div></div>');
366: }
367:
368:
369:
1.560 damieng 370: ##################################################
1.563 damieng 371: # (mostly) TABLE MODE
1.560 damieng 372: # (parmval is also used for the log of parameter changes)
373: ##################################################
374:
1.566 damieng 375: # Calls parmval_by_symb, getting the symb from $id with &symbcache.
1.561 damieng 376: #
377: # @param {string} $what - part info and parameter name separated by a dot, e.g. '0.weight'
1.566 damieng 378: # @param {string} $id - resource id or map pc
1.561 damieng 379: # @param {string} $def - the resource's default value for this parameter
380: # @param {string} $uname - user name
381: # @param {string} $udom - user domain
382: # @param {string} $csec - section name
383: # @param {string} $cgroup - group name
384: # @param {hash reference} $courseopt - course parameters hash (result of lonnet::get_courseresdata, dump of course's resourcedata.db)
385: # @returns {Array}
1.2 www 386: sub parmval {
1.275 raeburn 387: my ($what,$id,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;
388: return &parmval_by_symb($what,&symbcache($id),$def,$uname,$udom,$csec,
389: $cgroup,$courseopt);
1.201 www 390: }
391:
1.561 damieng 392: # Returns an array containing
393: # - the most specific level that is defined for that parameter (integer)
394: # - an array with the level as index and the parameter value as value (when defined)
395: # (level 1 is the most specific and will have precedence)
396: #
397: # @param {string} $what - part info and parameter name separated by a dot, e.g. '0.weight'
1.566 damieng 398: # @param {string} $symb - resource symb or map src
1.561 damieng 399: # @param {string} $def - the resource's default value for this parameter
400: # @param {string} $uname - user name
401: # @param {string} $udom - user domain
402: # @param {string} $csec - section name
403: # @param {string} $cgroup - group name
404: # @param {hash reference} $courseopt - course parameters hash (result of lonnet::get_courseresdata, dump of course's resourcedata.db)
405: # @returns {Array}
1.201 www 406: sub parmval_by_symb {
1.275 raeburn 407: my ($what,$symb,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;
1.200 www 408:
1.352 albertel 409: my $useropt;
410: if ($uname ne '' && $udom ne '') {
1.561 damieng 411: $useropt = &Apache::lonnet::get_userresdata($uname,$udom);
1.352 albertel 412: }
1.200 www 413:
1.8 www 414: my $result='';
1.44 albertel 415: my @outpar=();
1.2 www 416: # ----------------------------------------------------- Cascading lookup scheme
1.446 bisitz 417: my $map=(&Apache::lonnet::decode_symb($symb))[0];
1.305 albertel 418: $map = &Apache::lonnet::deversion($map);
1.561 damieng 419:
420: # NOTE: some of that code looks redondant with code in lonnavmaps::parmval_real,
421: # any change should be reflected there.
422:
1.201 www 423: my $symbparm=$symb.'.'.$what;
1.556 raeburn 424: my $recurseparm=$map.'___(rec).'.$what;
1.201 www 425: my $mapparm=$map.'___(all).'.$what;
1.10 www 426:
1.269 raeburn 427: my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$what;
428: my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;
1.556 raeburn 429: my $grpleveli=$env{'request.course.id'}.'.['.$cgroup.'].'.$recurseparm;
1.269 raeburn 430: my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;
431:
1.190 albertel 432: my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$what;
433: my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;
1.556 raeburn 434: my $secleveli=$env{'request.course.id'}.'.['.$csec.'].'.$recurseparm;
1.190 albertel 435: my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;
436:
437: my $courselevel=$env{'request.course.id'}.'.'.$what;
438: my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;
1.556 raeburn 439: my $courseleveli=$env{'request.course.id'}.'.'.$recurseparm;
1.190 albertel 440: my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;
1.2 www 441:
1.11 www 442:
1.182 albertel 443: # --------------------------------------------------------- first, check course
1.11 www 444:
1.561 damieng 445: # 18 - General Course
1.200 www 446: if (defined($$courseopt{$courselevel})) {
1.556 raeburn 447: $outpar[18]=$$courseopt{$courselevel};
448: $result=18;
449: }
450:
1.561 damieng 451: # 17 - Map or Folder level in course (recursive)
1.556 raeburn 452: if (defined($$courseopt{$courseleveli})) {
453: $outpar[17]=$$courseopt{$courseleveli};
454: $result=17;
1.43 albertel 455: }
1.11 www 456:
1.561 damieng 457: # 16 - Map or Folder level in course (non-recursive)
1.200 www 458: if (defined($$courseopt{$courselevelm})) {
1.556 raeburn 459: $outpar[16]=$$courseopt{$courselevelm};
460: $result=16;
1.43 albertel 461: }
1.11 www 462:
1.182 albertel 463: # ------------------------------------------------------- second, check default
464:
1.561 damieng 465: # 15 - resource default
1.556 raeburn 466: if (defined($def)) { $outpar[15]=$def; $result=15; }
1.182 albertel 467:
468: # ------------------------------------------------------ third, check map parms
469:
1.556 raeburn 470:
1.561 damieng 471: # 14 - map default
1.376 albertel 472: my $thisparm=&parmhash($symbparm);
1.556 raeburn 473: if (defined($thisparm)) { $outpar[14]=$thisparm; $result=14; }
1.182 albertel 474:
1.561 damieng 475: # 13 - resource level in course
1.200 www 476: if (defined($$courseopt{$courselevelr})) {
1.556 raeburn 477: $outpar[13]=$$courseopt{$courselevelr};
478: $result=13;
1.43 albertel 479: }
1.11 www 480:
1.182 albertel 481: # ------------------------------------------------------ fourth, back to course
1.352 albertel 482: if ($csec ne '') {
1.561 damieng 483: # 12 - General for section
1.200 www 484: if (defined($$courseopt{$seclevel})) {
1.556 raeburn 485: $outpar[12]=$$courseopt{$seclevel};
486: $result=12;
487: }
1.561 damieng 488: # 11 - Map or Folder level for section (recursive)
1.556 raeburn 489: if (defined($$courseopt{$secleveli})) {
490: $outpar[11]=$$courseopt{$secleveli};
491: $result=11;
492: }
1.561 damieng 493: # 10 - Map or Folder level for section (non-recursive)
1.200 www 494: if (defined($$courseopt{$seclevelm})) {
1.556 raeburn 495: $outpar[10]=$$courseopt{$seclevelm};
496: $result=10;
497: }
1.561 damieng 498: # 9 - resource level in section
1.200 www 499: if (defined($$courseopt{$seclevelr})) {
1.556 raeburn 500: $outpar[9]=$$courseopt{$seclevelr};
501: $result=9;
502: }
1.43 albertel 503: }
1.275 raeburn 504: # ------------------------------------------------------ fifth, check course group
1.352 albertel 505: if ($cgroup ne '') {
1.561 damieng 506: # 8 - General for group
1.269 raeburn 507: if (defined($$courseopt{$grplevel})) {
1.556 raeburn 508: $outpar[8]=$$courseopt{$grplevel};
509: $result=8;
510: }
1.561 damieng 511: # 7 - Map or Folder level for group (recursive)
1.556 raeburn 512: if (defined($$courseopt{$grpleveli})) {
513: $outpar[7]=$$courseopt{$grpleveli};
514: $result=7;
1.269 raeburn 515: }
1.561 damieng 516: # 6 - Map or Folder level for group (non-recursive)
1.269 raeburn 517: if (defined($$courseopt{$grplevelm})) {
1.556 raeburn 518: $outpar[6]=$$courseopt{$grplevelm};
519: $result=6;
1.269 raeburn 520: }
1.561 damieng 521: # 5 - resource level in group
1.269 raeburn 522: if (defined($$courseopt{$grplevelr})) {
1.556 raeburn 523: $outpar[5]=$$courseopt{$grplevelr};
524: $result=5;
1.269 raeburn 525: }
526: }
1.11 www 527:
1.556 raeburn 528: # ---------------------------------------------------------- sixth, check user
1.11 www 529:
1.352 albertel 530: if ($uname ne '') {
1.561 damieng 531: # 4 - General for specific student
532: if (defined($$useropt{$courselevel})) {
533: $outpar[4]=$$useropt{$courselevel};
534: $result=4;
535: }
1.556 raeburn 536:
1.561 damieng 537: # 3 - Map or Folder level for specific student (recursive)
538: if (defined($$useropt{$courseleveli})) {
539: $outpar[3]=$$useropt{$courseleveli};
540: $result=3;
541: }
1.473 amueller 542:
1.561 damieng 543: # 2 - Map or Folder level for specific student (non-recursive)
544: if (defined($$useropt{$courselevelm})) {
545: $outpar[2]=$$useropt{$courselevelm};
546: $result=2;
547: }
1.473 amueller 548:
1.561 damieng 549: # 1 - resource level for specific student
550: if (defined($$useropt{$courselevelr})) {
551: $outpar[1]=$$useropt{$courselevelr};
552: $result=1;
553: }
1.43 albertel 554: }
1.44 albertel 555: return ($result,@outpar);
1.2 www 556: }
557:
1.198 www 558:
559:
1.376 albertel 560: # --- Caches local to lonparmset
561:
1.446 bisitz 562:
1.561 damieng 563: # Reset lonparmset caches (called at the beginning and end of the handler).
1.376 albertel 564: sub reset_caches {
565: &resetparmhash();
566: &resetsymbcache();
567: &resetrulescache();
1.203 www 568: }
569:
1.561 damieng 570: # cache for map parameters, stored temporarily in $env{'request.course.fn'}_parms.db
571: # (these parameters come from param elements in .sequence files created with the advanced RAT)
1.376 albertel 572: {
1.561 damieng 573: my $parmhashid; # course identifier, to initialize the cache only once for a course
574: my %parmhash; # the parameter cache
575: # reset map parameter hash
1.376 albertel 576: sub resetparmhash {
1.560 damieng 577: undef($parmhashid);
578: undef(%parmhash);
1.376 albertel 579: }
1.446 bisitz 580:
1.561 damieng 581: # dump the _parms.db database into %parmhash
1.376 albertel 582: sub cacheparmhash {
1.560 damieng 583: if ($parmhashid eq $env{'request.course.fn'}) { return; }
584: my %parmhashfile;
585: if (tie(%parmhashfile,'GDBM_File',
586: $env{'request.course.fn'}.'_parms.db',&GDBM_READER(),0640)) {
587: %parmhash=%parmhashfile;
588: untie(%parmhashfile);
589: $parmhashid=$env{'request.course.fn'};
590: }
1.201 www 591: }
1.446 bisitz 592:
1.561 damieng 593: # returns a parameter value for an identifier symb.parts.parameter, using the map parameter cache
1.376 albertel 594: sub parmhash {
1.560 damieng 595: my ($id) = @_;
596: &cacheparmhash();
597: return $parmhash{$id};
1.376 albertel 598: }
1.560 damieng 599: }
1.376 albertel 600:
1.566 damieng 601: # cache resource id or map pc -> resource symb or map src, using lonnavmaps to find association
1.446 bisitz 602: {
1.561 damieng 603: my $symbsid; # course identifier, to initialize the cache only once for a course
604: my %symbs; # hash id->symb
605: # reset the id->symb cache
1.376 albertel 606: sub resetsymbcache {
1.560 damieng 607: undef($symbsid);
608: undef(%symbs);
1.376 albertel 609: }
1.446 bisitz 610:
1.566 damieng 611: # returns the resource symb or map src corresponding to a resource id or map pc
612: # (using lonnavmaps and a cache)
1.376 albertel 613: sub symbcache {
1.560 damieng 614: my $id=shift;
615: if ($symbsid ne $env{'request.course.id'}) {
616: undef(%symbs);
617: }
618: if (!$symbs{$id}) {
619: my $navmap = Apache::lonnavmaps::navmap->new();
620: if ($id=~/\./) {
621: my $resource=$navmap->getById($id);
622: $symbs{$id}=$resource->symb();
623: } else {
624: my $resource=$navmap->getByMapPc($id);
625: $symbs{$id}=&Apache::lonnet::declutter($resource->src());
626: }
627: $symbsid=$env{'request.course.id'};
1.473 amueller 628: }
1.560 damieng 629: return $symbs{$id};
1.473 amueller 630: }
1.560 damieng 631: }
1.201 www 632:
1.561 damieng 633: # cache for parameter default actions (stored in parmdefactions.db)
1.446 bisitz 634: {
1.561 damieng 635: my $rulesid; # course identifier, to initialize the cache only once for a course
636: my %rules; # parameter default actions hash
1.376 albertel 637: sub resetrulescache {
1.560 damieng 638: undef($rulesid);
639: undef(%rules);
1.376 albertel 640: }
1.446 bisitz 641:
1.561 damieng 642: # returns the value for a given key in the parameter default action hash
1.376 albertel 643: sub rulescache {
1.560 damieng 644: my $id=shift;
645: if ($rulesid ne $env{'request.course.id'}
646: && !defined($rules{$id})) {
647: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
648: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
649: %rules=&Apache::lonnet::dump('parmdefactions',$dom,$crs);
650: $rulesid=$env{'request.course.id'};
651: }
652: return $rules{$id};
1.221 www 653: }
654: }
655:
1.416 jms 656:
1.561 damieng 657: # Returns the values of the parameter type default action
658: # "default value when manually setting".
659: # If none is defined, ('','','','','') is returned.
660: #
661: # @param {string} $type - parameter type
662: # @returns {Array<string>} - (hours, min, sec, value)
1.229 www 663: sub preset_defaults {
664: my $type=shift;
665: if (&rulescache($type.'_action') eq 'default') {
1.560 damieng 666: # yes, there is something
667: return (&rulescache($type.'_hours'),
668: &rulescache($type.'_min'),
669: &rulescache($type.'_sec'),
670: &rulescache($type.'_value'));
1.229 www 671: } else {
1.560 damieng 672: # nothing there or something else
673: return ('','','','','');
1.229 www 674: }
675: }
676:
1.416 jms 677:
1.561 damieng 678: # Checks that a date is after enrollment start date and before
679: # enrollment end date.
680: # Returns HTML with a warning if it is not, or the empty string otherwise.
681: # This is used by both overview and table modes.
682: #
683: # @param {integer} $checkdate - the date to check.
684: # @returns {string} - HTML possibly containing a localized warning message.
1.277 www 685: sub date_sanity_info {
686: my $checkdate=shift;
687: unless ($checkdate) { return ''; }
688: my $result='';
689: my $crsprefix='course.'.$env{'request.course.id'}.'.';
690: if ($env{$crsprefix.'default_enrollment_end_date'}) {
691: if ($checkdate>$env{$crsprefix.'default_enrollment_end_date'}) {
1.413 bisitz 692: $result.='<div class="LC_warning">'
693: .&mt('After course enrollment end!')
694: .'</div>';
1.277 www 695: }
696: }
697: if ($env{$crsprefix.'default_enrollment_start_date'}) {
698: if ($checkdate<$env{$crsprefix.'default_enrollment_start_date'}) {
1.413 bisitz 699: $result.='<div class="LC_warning">'
700: .&mt('Before course enrollment start!')
701: .'</div>';
1.277 www 702: }
703: }
1.413 bisitz 704: # Preparation for additional warnings about dates in the past/future.
705: # An improved, more context sensitive version is recommended,
706: # e.g. warn for due and answer dates which are defined before the corresponding open date, etc.
707: # if ($checkdate<time) {
708: # $result.='<div class="LC_info">'
709: # .'('.&mt('in the past').')'
710: # .'</div>';
711: # }
712: # if ($checkdate>time) {
713: # $result.='<div class="LC_info">'
714: # .'('.&mt('in the future').')'
715: # .'</div>';
716: # }
1.277 www 717: return $result;
718: }
1.561 damieng 719:
720:
721: # Store a parameter value and type by ID, also triggering more parameter changes based on parameter default actions.
1.186 www 722: #
1.566 damieng 723: # @param {string} $sresid - resource id or map pc
1.565 damieng 724: # @param {string} $spnam - part info and parameter name separated by a dot or underscore, e.g. '0.weight'
1.561 damieng 725: # @param {integer} $snum - level
726: # @param {string} $nval - new value
727: # @param {string} $ntype - new type
728: # @param {string} $uname - username
729: # @param {string} $udom - userdomain
730: # @param {string} $csec - section name
731: # @param {string} $cgroup - group name
1.186 www 732: sub storeparm {
1.269 raeburn 733: my ($sresid,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;
1.275 raeburn 734: &storeparm_by_symb(&symbcache($sresid),$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,'',$cgroup);
1.197 www 735: }
736:
1.561 damieng 737: my %recstack; # hash parameter name -> 1 when a parameter was used before in a recursive call to storeparm_by_symb
738:
739: # Store a parameter value and type by symb, also triggering more parameter changes based on parameter default actions.
740: # Uses storeparm_by_symb_inner to actually store the parameter, ignoring any returned error.
741: #
1.566 damieng 742: # @param {string} $symb - resource symb or map src
1.565 damieng 743: # @param {string} $spnam - part info and parameter name separated by a dot or underscore, e.g. '0.weight'
1.561 damieng 744: # @param {integer} $snum - level
745: # @param {string} $nval - new value
746: # @param {string} $ntype - new type
747: # @param {string} $uname - username
748: # @param {string} $udom - userdomain
749: # @param {string} $csec - section name
750: # @param {boolean} $recflag - should be true for recursive calls to storeparm_by_symb, false otherwise
751: # @param {string} $cgroup - group name
1.197 www 752: sub storeparm_by_symb {
1.275 raeburn 753: my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$recflag,$cgroup)=@_;
1.226 www 754: unless ($recflag) {
1.560 damieng 755: # first time call
756: %recstack=();
757: $recflag=1;
1.226 www 758: }
1.560 damieng 759: # store parameter
1.226 www 760: &storeparm_by_symb_inner
1.473 amueller 761: ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup);
1.560 damieng 762: # don't do anything if parameter was reset
1.266 www 763: unless ($nval) { return; }
1.226 www 764: my ($prefix,$parm)=($spnam=~/^(.*[\_\.])([^\_\.]+)$/);
1.560 damieng 765: # remember that this was set
1.226 www 766: $recstack{$parm}=1;
1.560 damieng 767: # what does this trigger?
1.226 www 768: foreach my $triggered (split(/\:/,&rulescache($parm.'_triggers'))) {
1.560 damieng 769: # don't backfire
770: unless ((!$triggered) || ($recstack{$triggered})) {
771: my $action=&rulescache($triggered.'_action');
772: my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);
773: # set triggered parameter on same level
774: my $newspnam=$prefix.$triggered;
775: my $newvalue='';
776: my $active=1;
777: if ($action=~/^when\_setting/) {
778: # are there restrictions?
779: if (&rulescache($triggered.'_triggervalue')=~/\w/) {
780: $active=0;
1.565 damieng 781: foreach my $possiblevalue (split(/\s*\,\s*/,&rulescache($triggered.'_triggervalue'))) {
1.560 damieng 782: if (lc($possiblevalue) eq lc($nval)) { $active=1; }
783: }
784: }
785: $newvalue=&rulescache($triggered.'_value');
786: } else {
787: my $totalsecs=((&rulescache($triggered.'_days')*24+&rulescache($triggered.'_hours'))*60+&rulescache($triggered.'_min'))*60+&rulescache($triggered.'_sec');
788: if ($action=~/^later\_than/) {
789: $newvalue=$nval+$totalsecs;
790: } else {
791: $newvalue=$nval-$totalsecs;
792: }
793: }
794: if ($active) {
795: &storeparm_by_symb($symb,$newspnam,$snum,$newvalue,&rulescache($triggered.'_type'),
796: $uname,$udom,$csec,$recflag,$cgroup);
797: }
798: }
1.226 www 799: }
800: return '';
801: }
802:
1.561 damieng 803: # Adds all given arguments to the course parameter log.
804: # @returns {string} - the answer to the lonnet query.
1.293 www 805: sub log_parmset {
1.525 raeburn 806: return &Apache::lonnet::write_log('course','parameterlog',@_);
1.284 www 807: }
808:
1.561 damieng 809: # Store a parameter value and type by symb, without using the parameter default actions.
810: # Expire related sheets.
811: #
1.566 damieng 812: # @param {string} $symb - resource symb or map src
1.561 damieng 813: # @param {string} $spnam - part info and parameter name separated by a dot, e.g. '0.weight'
814: # @param {integer} $snum - level
815: # @param {string} $nval - new value
816: # @param {string} $ntype - new type
817: # @param {string} $uname - username
818: # @param {string} $udom - userdomain
819: # @param {string} $csec - section name
820: # @param {string} $cgroup - group name
821: # @returns {string} - HTML code with an error message if the parameter could not be stored.
1.226 www 822: sub storeparm_by_symb_inner {
1.197 www 823: # ---------------------------------------------------------- Get symb, map, etc
1.269 raeburn 824: my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;
1.197 www 825: # ---------------------------------------------------------- Construct prefixes
1.186 www 826: $spnam=~s/\_([^\_]+)$/\.$1/;
1.446 bisitz 827: my $map=(&Apache::lonnet::decode_symb($symb))[0];
1.305 albertel 828: $map = &Apache::lonnet::deversion($map);
829:
1.197 www 830: my $symbparm=$symb.'.'.$spnam;
1.556 raeburn 831: my $recurseparm=$map.'___(rec).'.$spnam;
1.197 www 832: my $mapparm=$map.'___(all).'.$spnam;
833:
1.269 raeburn 834: my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$spnam;
835: my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;
1.556 raeburn 836: my $grpleveli=$env{'request.course.id'}.'.['.$cgroup.'].'.$recurseparm;
1.269 raeburn 837: my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;
838:
1.190 albertel 839: my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$spnam;
840: my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;
1.556 raeburn 841: my $secleveli=$env{'request.course.id'}.'.['.$csec.'].'.$recurseparm;
1.190 albertel 842: my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;
1.446 bisitz 843:
1.190 albertel 844: my $courselevel=$env{'request.course.id'}.'.'.$spnam;
845: my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;
1.556 raeburn 846: my $courseleveli=$env{'request.course.id'}.'.'.$recurseparm;
1.190 albertel 847: my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;
1.446 bisitz 848:
1.186 www 849: my $storeunder='';
1.578 raeburn 850: my $possreplace='';
1.556 raeburn 851: if (($snum==18) || ($snum==4)) { $storeunder=$courselevel; }
1.578 raeburn 852: if (($snum==17) || ($snum==3)) {
853: $storeunder=$courseleveli;
854: $possreplace=$courselevelm;
855: }
856: if (($snum==16) || ($snum==2)) {
857: $storeunder=$courselevelm;
858: $possreplace=$courseleveli;
859: }
1.556 raeburn 860: if (($snum==13) || ($snum==1)) { $storeunder=$courselevelr; }
861: if ($snum==12) { $storeunder=$seclevel; }
1.578 raeburn 862: if ($snum==11) {
863: $storeunder=$secleveli;
864: $possreplace=$seclevelm;
865: }
866: if ($snum==10) {
867: $storeunder=$seclevelm;
868: $possreplace=$secleveli;
869: }
1.556 raeburn 870: if ($snum==9) { $storeunder=$seclevelr; }
871: if ($snum==8) { $storeunder=$grplevel; }
1.578 raeburn 872: if ($snum==7) {
873: $storeunder=$grpleveli;
874: $possreplace=$grplevelm;
875: }
876: if ($snum==6) {
877: $storeunder=$grplevelm;
878: $possreplace=$grpleveli;
879: }
1.556 raeburn 880: if ($snum==5) { $storeunder=$grplevelr; }
1.269 raeburn 881:
1.446 bisitz 882:
1.186 www 883: my $delete;
884: if ($nval eq '') { $delete=1;}
885: my %storecontent = ($storeunder => $nval,
1.473 amueller 886: $storeunder.'.type' => $ntype);
1.186 www 887: my $reply='';
1.560 damieng 888:
1.556 raeburn 889: if ($snum>4) {
1.186 www 890: # ---------------------------------------------------------------- Store Course
891: #
1.560 damieng 892: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
893: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
894: # Expire sheets
895: &Apache::lonnet::expirespread('','','studentcalc');
896: if (($snum==13) || ($snum==9) || ($snum==5)) {
897: &Apache::lonnet::expirespread('','','assesscalc',$symb);
1.578 raeburn 898: } elsif (($snum==17) || ($snum==16) || ($snum==11) || ($snum==10) || ($snum==7) || ($snum==6)) {
1.560 damieng 899: &Apache::lonnet::expirespread('','','assesscalc',$map);
900: } else {
901: &Apache::lonnet::expirespread('','','assesscalc');
902: }
903: # Store parameter
904: if ($delete) {
905: $reply=&Apache::lonnet::del
906: ('resourcedata',[keys(%storecontent)],$cdom,$cnum);
907: &log_parmset(\%storecontent,1);
908: } else {
909: $reply=&Apache::lonnet::cput
910: ('resourcedata',\%storecontent,$cdom,$cnum);
911: &log_parmset(\%storecontent);
1.578 raeburn 912: if ($possreplace) {
913: my $resdata = &Apache::lonnet::get_courseresdata($cnum,$cdom);
914: if (ref($resdata) eq 'HASH') {
915: if (exists($resdata->{$possreplace})) {
916: if (&Apache::lonnet::del
917: ('resourcedata',[$possreplace,$possreplace.'.type'],$cdom,$cnum) eq 'ok') {
918: &log_parmset({$possreplace => '', $possreplace.'.type' => $ntype},1);
919: }
920: }
921: }
922: }
1.560 damieng 923: }
924: &Apache::lonnet::devalidatecourseresdata($cnum,$cdom);
1.186 www 925: } else {
926: # ------------------------------------------------------------------ Store User
927: #
1.560 damieng 928: # Expire sheets
929: &Apache::lonnet::expirespread($uname,$udom,'studentcalc');
930: if ($snum==1) {
931: &Apache::lonnet::expirespread
932: ($uname,$udom,'assesscalc',$symb);
1.578 raeburn 933: } elsif (($snum==2) || ($snum==3)) {
1.560 damieng 934: &Apache::lonnet::expirespread
935: ($uname,$udom,'assesscalc',$map);
936: } else {
937: &Apache::lonnet::expirespread($uname,$udom,'assesscalc');
938: }
939: # Store parameter
940: if ($delete) {
941: $reply=&Apache::lonnet::del
942: ('resourcedata',[keys(%storecontent)],$udom,$uname);
943: &log_parmset(\%storecontent,1,$uname,$udom);
944: } else {
945: $reply=&Apache::lonnet::cput
946: ('resourcedata',\%storecontent,$udom,$uname);
947: &log_parmset(\%storecontent,0,$uname,$udom);
1.578 raeburn 948: if ($possreplace) {
949: my $resdata = &Apache::lonnet::get_userresdata($uname,$udom);
950: if (ref($resdata) eq 'HASH') {
951: if (exists($resdata->{$possreplace})) {
952: if (&Apache::lonnet::del
953: ('resourcedata',[$possreplace,$possreplace.'.type'],$udom,$uname) eq 'ok') {
954: &log_parmset({$possreplace => '',$possreplace.'.type' => $ntype},1,
955: $uname,$udom);
956: }
957: }
958: }
959: }
1.560 damieng 960: }
961: &Apache::lonnet::devalidateuserresdata($uname,$udom);
1.186 www 962: }
1.446 bisitz 963:
1.186 www 964: if ($reply=~/^error\:(.*)/) {
1.560 damieng 965: return "<span class=\"LC_error\">Write Error: $1</span>";
1.186 www 966: }
967: return '';
968: }
969:
1.9 www 970:
1.561 damieng 971: # Returns HTML with the value of the given parameter,
972: # using a readable format for dates, and
973: # a warning if there is a problem with a date.
974: # Used by table mode.
975: # Returns HTML for the editmap.png image if no value is defined and $editable is true.
976: #
977: # @param {string} $value - the parameter value
978: # @param {string} $type - the parameter type
979: # @param {string} $name - the parameter name (unused)
980: # @param {boolean} $editable - Set to true to get an icon when no value is defined.
1.9 www 981: sub valout {
1.554 raeburn 982: my ($value,$type,$name,$editable)=@_;
1.59 matthew 983: my $result = '';
984: # Values of zero are valid.
985: if (! $value && $value ne '0') {
1.528 bisitz 986: if ($editable) {
987: $result =
988: '<img src="/res/adm/pages/editmap.png"'
989: .' alt="'.&mt('Change').'"'
1.539 raeburn 990: .' title="'.&mt('Change').'" style="border:0;" />';
1.528 bisitz 991: } else {
992: $result=' ';
993: }
1.59 matthew 994: } else {
1.66 www 995: if ($type eq 'date_interval') {
1.559 raeburn 996: my ($totalsecs,$donesuffix) = split(/_/,$value,2);
997: my ($usesdone,$donebuttontext,$proctor,$secretkey);
998: if ($donesuffix =~ /^done\:([^\:]+)\:(.*)$/) {
999: $donebuttontext = $1;
1000: (undef,$proctor,$secretkey) = split(/_/,$2);
1001: $usesdone = 'done';
1002: } elsif ($donesuffix =~ /^done(|_.+)$/) {
1003: $donebuttontext = &mt('Done');
1004: ($usesdone,$proctor,$secretkey) = split(/_/,$donesuffix);
1005: }
1.554 raeburn 1006: my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($totalsecs);
1.413 bisitz 1007: my @timer;
1.66 www 1008: $year=$year-70;
1009: $mday--;
1010: if ($year) {
1.413 bisitz 1011: # $result.=&mt('[quant,_1,yr]',$year).' ';
1012: push(@timer,&mt('[quant,_1,yr]',$year));
1.66 www 1013: }
1014: if ($mon) {
1.413 bisitz 1015: # $result.=&mt('[quant,_1,mth]',$mon).' ';
1016: push(@timer,&mt('[quant,_1,mth]',$mon));
1.66 www 1017: }
1018: if ($mday) {
1.413 bisitz 1019: # $result.=&mt('[quant,_1,day]',$mday).' ';
1020: push(@timer,&mt('[quant,_1,day]',$mday));
1.66 www 1021: }
1022: if ($hour) {
1.413 bisitz 1023: # $result.=&mt('[quant,_1,hr]',$hour).' ';
1024: push(@timer,&mt('[quant,_1,hr]',$hour));
1.66 www 1025: }
1026: if ($min) {
1.413 bisitz 1027: # $result.=&mt('[quant,_1,min]',$min).' ';
1028: push(@timer,&mt('[quant,_1,min]',$min));
1.66 www 1029: }
1030: if ($sec) {
1.413 bisitz 1031: # $result.=&mt('[quant,_1,sec]',$sec).' ';
1032: push(@timer,&mt('[quant,_1,sec]',$sec));
1.66 www 1033: }
1.413 bisitz 1034: # $result=~s/\s+$//;
1035: if (!@timer) { # Special case: all entries 0 -> display "0 secs" intead of empty field to keep this field editable
1036: push(@timer,&mt('[quant,_1,sec]',0));
1037: }
1038: $result.=join(", ",@timer);
1.559 raeburn 1039: if ($usesdone eq 'done') {
1.558 raeburn 1040: if ($secretkey) {
1.559 raeburn 1041: $result .= ' '.&mt('+ "[_1]" with proctor key: [_2]',$donebuttontext,$secretkey);
1.558 raeburn 1042: } else {
1.559 raeburn 1043: $result .= ' + "'.$donebuttontext.'"';
1044: }
1.554 raeburn 1045: }
1.213 www 1046: } elsif (&isdateparm($type)) {
1.361 albertel 1047: $result = &Apache::lonlocal::locallocaltime($value).
1.560 damieng 1048: &date_sanity_info($value);
1.59 matthew 1049: } else {
1050: $result = $value;
1.517 www 1051: $result=~s/\,/\, /gs;
1.560 damieng 1052: $result = &HTML::Entities::encode($result,'"<>&');
1.59 matthew 1053: }
1054: }
1055: return $result;
1.9 www 1056: }
1057:
1.59 matthew 1058:
1.561 damieng 1059: # Returns HTML containing a link on a parameter value, for table mode.
1060: # The link uses the javascript function 'pjump'.
1061: #
1062: # @param {string} $type - parameter type
1063: # @param {string} $dis - dialog title for editing the parameter value and type
1064: # @param {string} $value - parameter value
1065: # @param {string} $marker - identifier for the parameter, "resource id&part_parameter name&level", will be passed as pres_marker when the user submits a change.
1066: # @param {string} $return - prefix for the name of the form and field names that will be used to submit the form ('parmform.pres')
1067: # @param {string} $call - javascript function to call to submit the form ('psub')
1.588 ! raeburn 1068: # @param {boolean} $recursive - true if link is for a map/folder where parameter is currently set to be recursive.
! 1069: # @param {string} $extra - optional additional information to send as tenth arg in call to javascript pjump function.
1.5 www 1070: sub plink {
1.588 ! raeburn 1071: my ($type,$dis,$value,$marker,$return,$call,$recursive,$extra)=@_;
1.23 www 1072: my $winvalue=$value;
1073: unless ($winvalue) {
1.560 damieng 1074: if (&isdateparm($type)) {
1.190 albertel 1075: $winvalue=$env{'form.recent_'.$type};
1.23 www 1076: } else {
1.190 albertel 1077: $winvalue=$env{'form.recent_'.(split(/\_/,$type))[0]};
1.23 www 1078: }
1079: }
1.229 www 1080: my ($parmname)=((split(/\&/,$marker))[1]=~/\_([^\_]+)$/);
1081: my ($hour,$min,$sec,$val)=&preset_defaults($parmname);
1082: unless (defined($winvalue)) { $winvalue=$val; }
1.554 raeburn 1083: my $valout = &valout($value,$type,$parmname,1);
1.429 raeburn 1084: my $unencmarker = $marker;
1.378 albertel 1085: foreach my $item (\$type, \$dis, \$winvalue, \$marker, \$return, \$call,
1.588 ! raeburn 1086: \$hour, \$min, \$sec, \$extra) {
1.560 damieng 1087: $$item = &HTML::Entities::encode($$item,'"<>&');
1088: $$item =~ s/\'/\\\'/g;
1.378 albertel 1089: }
1.429 raeburn 1090: return '<table width="100%"><tr valign="top" align="right"><td><a name="'.$unencmarker.'" /></td></tr><tr><td align="center">'.
1.473 amueller 1091: '<a href="javascript:pjump('."'".$type."','".$dis."','".$winvalue."','"
1.588 ! raeburn 1092: .$marker."','".$return."','".$call."','".$hour."','".$min."','".$sec."','".$extra."'".');">'.
1.578 raeburn 1093: $valout.'</a></td></tr>'.($recursive?'<tr><td align="center" class="LC_parm_recursive">'.
1094: &mt('recursive').'</td></tr>' : '').'</table>';
1095:
1.5 www 1096: }
1097:
1.561 damieng 1098: # Javascript for table mode.
1.280 albertel 1099: sub page_js {
1100:
1.81 www 1101: my $selscript=&Apache::loncommon::studentbrowser_javascript();
1.88 matthew 1102: my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
1.280 albertel 1103:
1104: return(<<ENDJS);
1105: <script type="text/javascript">
1.454 bisitz 1106: // <![CDATA[
1.44 albertel 1107:
1.88 matthew 1108: $pjump_def
1.44 albertel 1109:
1110: function psub() {
1111: if (document.parmform.pres_marker.value!='') {
1112: document.parmform.action+='#'+document.parmform.pres_marker.value;
1113: var typedef=new Array();
1114: typedef=document.parmform.pres_type.value.split('_');
1.562 damieng 1115: if (document.parmform.pres_type.value!='') {
1116: if (typedef[0]=='date') {
1117: eval('document.parmform.recent_'+
1118: document.parmform.pres_type.value+
1119: '.value=document.parmform.pres_value.value;');
1120: } else {
1121: eval('document.parmform.recent_'+typedef[0]+
1122: '.value=document.parmform.pres_value.value;');
1123: }
1.44 albertel 1124: }
1125: document.parmform.submit();
1126: } else {
1127: document.parmform.pres_value.value='';
1128: document.parmform.pres_marker.value='';
1129: }
1130: }
1131:
1.57 albertel 1132: function openWindow(url, wdwName, w, h, toolbar,scrollbar) {
1133: var options = "width=" + w + ",height=" + h + ",";
1134: options += "resizable=yes,scrollbars="+scrollbar+",status=no,";
1135: options += "menubar=no,toolbar="+toolbar+",location=no,directories=no";
1136: var newWin = window.open(url, wdwName, options);
1137: newWin.focus();
1138: }
1.523 raeburn 1139:
1.454 bisitz 1140: // ]]>
1.523 raeburn 1141:
1.44 albertel 1142: </script>
1.81 www 1143: $selscript
1.280 albertel 1144: ENDJS
1145:
1146: }
1.507 www 1147:
1.561 damieng 1148: # Javascript to show or hide the map selection (function showHide_courseContent),
1149: # for table and overview modes.
1.523 raeburn 1150: sub showhide_js {
1151: return <<"COURSECONTENTSCRIPT";
1152:
1153: function showHide_courseContent() {
1154: var parmlevValue=document.getElementById("parmlev").value;
1155: if (parmlevValue == 'general') {
1156: document.getElementById('mapmenu').style.display="none";
1157: } else {
1158: if ((parmlevValue == "full") || (parmlevValue == "map")) {
1159: document.getElementById('mapmenu').style.display ="";
1160: } else {
1161: document.getElementById('mapmenu').style.display="none";
1162: }
1163: }
1164: return;
1165: }
1166:
1167: COURSECONTENTSCRIPT
1168: }
1169:
1.561 damieng 1170: # Javascript functions showHideLenient and toggleParmTextbox, for overview mode
1.549 raeburn 1171: sub toggleparmtextbox_js {
1172: return <<"ENDSCRIPT";
1173:
1174: if (!document.getElementsByClassName) {
1175: function getElementsByClassName(node, classname) {
1176: var a = [];
1177: var re = new RegExp('(^| )'+classname+'( |$)');
1178: var els = node.getElementsByTagName("*");
1179: for(var i=0,j=els.length; i<j; i++)
1180: if(re.test(els[i].className))a.push(els[i]);
1181: return a;
1182: }
1183: }
1184:
1185: function showHideLenient() {
1186: var lenients;
1187: var setRegExp = /^set_/;
1188: if (document.getElementsByClassName) {
1189: lenients = document.getElementsByClassName('LC_lenient_radio');
1190: } else {
1191: lenients = getElementsByClassName(document.body,'LC_lenient_radio');
1192: }
1193: if (lenients != 'undefined') {
1194: for (var i=0; i<lenients.length; i++) {
1195: if (lenients[i].checked) {
1196: if (lenients[i].value == 'weighted') {
1197: if (setRegExp.test(lenients[i].name)) {
1198: var identifier = lenients[i].name.replace(setRegExp,'');
1199: toggleParmTextbox(document.parmform,identifier);
1200: }
1201: }
1202: }
1203: }
1204: }
1205: return;
1206: }
1207:
1208: function toggleParmTextbox(form,key) {
1209: var divfortext = document.getElementById('LC_parmtext_'+key);
1210: if (divfortext) {
1211: var caller = form.elements['set_'+key];
1212: if (caller.length) {
1213: for (i=0; i<caller.length; i++) {
1214: if (caller[i].checked) {
1215: if (caller[i].value == 'weighted') {
1216: divfortext.style.display = 'inline';
1217: } else {
1218: divfortext.style.display = 'none';
1219: }
1220: }
1221: }
1222: }
1223: }
1224: return;
1225: }
1226:
1227: ENDSCRIPT
1228: }
1229:
1.561 damieng 1230: # Javascript function validateParms, for overview mode
1.549 raeburn 1231: sub validateparms_js {
1232: return <<'ENDSCRIPT';
1233:
1234: function validateParms() {
1235: var textRegExp = /^settext_/;
1236: var tailLenient = /\.lenient$/;
1237: var patternRelWeight = /^\-?[\d.]+$/;
1238: var patternLenientStd = /^(yes|no|default)$/;
1239: var ipallowRegExp = /^setipallow_/;
1240: var ipdenyRegExp = /^setipdeny_/;
1.588 ! raeburn 1241: var deeplinkRegExp = /^deeplink_(listing|scope)_/;
! 1242: var deeplinkUrlsRegExp = /^deeplink_urls_/;
! 1243: var deeplinkltiRegExp = /^deeplink_lti_/;
! 1244: var deeplinkkeyRegExp = /^deeplink_key_/;
1.549 raeburn 1245: var patternIP = /[\[\]\*\.a-zA-Z\d\-]+/;
1246: if ((document.parmform.elements.length != 'undefined') && (document.parmform.elements.length) != 'null') {
1247: if (document.parmform.elements.length) {
1248: for (i=0; i<document.parmform.elements.length; i++) {
1249: var name=document.parmform.elements[i].name;
1.588 ! raeburn 1250: if (textRegExp.test(name)) {
1.549 raeburn 1251: var identifier = name.replace(textRegExp,'');
1252: if (tailLenient.test(identifier)) {
1253: if (document.parmform.elements['set_'+identifier].length) {
1254: for (var j=0; j<document.parmform.elements['set_'+identifier].length; j++) {
1255: if (document.parmform.elements['set_'+identifier][j].checked) {
1256: if (!(patternLenientStd.test(document.parmform.elements['set_'+identifier][j].value))) {
1257: var relweight = document.parmform.elements[i].value;
1258: relweight = relweight.replace(/^\s+|\s+$/g,'');
1259: if (!patternRelWeight.test(relweight)) {
1260: relweight = '0.0';
1261: }
1262: if (document.parmform.elements['set_'+identifier][j].value == 'weighted') {
1263: document.parmform.elements['set_'+identifier][j].value = relweight;
1264: } else {
1265: document.parmform.elements['set_'+identifier][j].value += ','+relweight;
1266: }
1267: }
1268: break;
1269: }
1270: }
1271: }
1272: }
1.588 ! raeburn 1273: } else if (ipallowRegExp.test(name)) {
! 1274: var identifier = name.replace(ipallowRegExp,'');
! 1275: var possallow = document.parmform.elements[i].value;
! 1276: possallow = possallow.replace(/^\s+|\s+$/g,'');
! 1277: if (patternIP.test(possallow)) {
! 1278: if (document.parmform.elements['set_'+identifier].value) {
! 1279: possallow = ','+possallow;
! 1280: }
! 1281: document.parmform.elements['set_'+identifier].value += possallow;
! 1282: }
! 1283: } else if (ipdenyRegExp.test(name)) {
! 1284: var identifier = name.replace(ipdenyRegExp,'');
! 1285: var possdeny = document.parmform.elements[i].value;
! 1286: possdeny = possdeny.replace(/^\s+|\s+$/g,'');
! 1287: if (patternIP.test(possdeny)) {
! 1288: possdeny = '!'+possdeny;
! 1289: if (document.parmform.elements['set_'+identifier].value) {
! 1290: possdeny = ','+possdeny;
! 1291: }
! 1292: document.parmform.elements['set_'+identifier].value += possdeny;
! 1293: }
! 1294: } else if (deeplinkRegExp.test(name)) {
! 1295: var identifier = name.replace(deeplinkRegExp,'');
! 1296: var possdeeplink = document.parmform.elements[i].value;
! 1297: possdeeplink = possdeeplink.replace(/^\s+|\s+$/g,'');
! 1298: if (document.parmform.elements['set_'+identifier].value) {
! 1299: possdeeplink = ','+possdeeplink;
! 1300: }
! 1301: document.parmform.elements['set_'+identifier].value += possdeeplink;
! 1302: } else if (deeplinkUrlsRegExp.test(name)) {
! 1303: if (document.parmform.elements[i].checked) {
! 1304: var identifier = name.replace(deeplinkUrlsRegExp,'');
! 1305: var posslinkurl = document.parmform.elements[i].value;
! 1306: posslinkurl = posslinkurl.replace(/^\s+|\s+$/g,'');
! 1307: if (document.parmform.elements['set_'+identifier].value) {
! 1308: posslinkurl = ','+posslinkurl;
! 1309: }
! 1310: document.parmform.elements['set_'+identifier].value += posslinkurl;
! 1311: }
! 1312: } else if (deeplinkltiRegExp.test(name)) {
! 1313: var identifier = name.replace(deeplinkltiRegExp,'');
! 1314: var posslti = document.parmform.elements[i].value;
! 1315: posslti = posslti.replace(/\D+/g,'');
! 1316: if (document.parmform.elements['set_'+identifier].value) {
! 1317: posslti = ':'+posslti;
! 1318: }
! 1319: document.parmform.elements['set_'+identifier].value += posslti;
! 1320: } else if (deeplinkkeyRegExp.test(name)) {
! 1321: var identifier = name.replace(deeplinkkeyRegExp,'');
! 1322: var posskey = document.parmform.elements[i].value;
! 1323: posskey = posskey.replace(/\W+/g,'');
! 1324: if (document.parmform.elements['set_'+identifier].value) {
! 1325: posslti = ':'+posskey;
1.549 raeburn 1326: }
1.588 ! raeburn 1327: document.parmform.elements['set_'+identifier].value += posskey;
1.549 raeburn 1328: }
1329: }
1330: }
1331: }
1332: return true;
1333: }
1334:
1335: ENDSCRIPT
1336: }
1337:
1.561 damieng 1338: # Javascript initialization, for overview mode
1.549 raeburn 1339: sub ipacc_boxes_js {
1340: my $remove = &mt('Remove');
1341: return <<"END";
1342: \$(document).ready(function() {
1343: var wrapper = \$(".LC_string_ipacc_wrap");
1344: var add_button = \$(".LC_add_ipacc_button");
1345: var ipaccRegExp = /^LC_string_ipacc_/;
1346:
1347: \$(add_button).click(function(e){
1348: e.preventDefault();
1349: var identifier = \$(this).closest("div").attr("id");
1350: identifier = identifier.replace(ipaccRegExp,'');
1.551 raeburn 1351: \$(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 1352: });
1353:
1354: \$(wrapper).delegate(".LC_remove_ipacc","click", function(e){
1355: e.preventDefault(); \$(this).closest("div").remove();
1356: })
1357: });
1358:
1359:
1360: END
1361: }
1362:
1.561 damieng 1363: # Javascript function toggleSecret, for overview mode.
1.558 raeburn 1364: sub done_proctor_js {
1365: return <<"END";
1366: function toggleSecret(form,radio,key) {
1367: var radios = form[radio+key];
1368: if (radios.length) {
1369: for (var i=0; i<radios.length; i++) {
1370: if (radios[i].checked) {
1371: if (radios[i].value == '_done_proctor') {
1372: if (document.getElementById('done_'+key+'_proctorkey')) {
1373: document.getElementById('done_'+key+'_proctorkey').type='text';
1374: }
1375: } else {
1376: if (document.getElementById('done_'+key+'_proctorkey')) {
1377: document.getElementById('done_'+key+'_proctorkey').type='hidden';
1378: document.getElementById('done_'+key+'_proctorkey').value='';
1379: }
1380: }
1381: }
1382: }
1383: }
1384: }
1385: END
1386:
1387: }
1388:
1.588 ! raeburn 1389: # Javascript function toggle
! 1390: sub deeplink_js {
! 1391: return <<"END";
! 1392: function toggleDeepLink(form,item,key) {
! 1393: var radios = form['deeplink_'+item+'_'+key];
! 1394: if (radios.length) {
! 1395: var keybox;
! 1396: if (document.getElementById('deeplink_key_'+item+'_'+key)) {
! 1397: keybox = document.getElementById('deeplink_key_'+item+'_'+key);
! 1398: }
! 1399: var ltidiv;
! 1400: if (document.getElementById('deeplinkdiv_lti_'+item+'_'+key)) {
! 1401: ltidiv = document.getElementById('deeplinkdiv_lti_'+item+'_'+key);
! 1402: }
! 1403: for (var i=0; i<radios.length; i++) {
! 1404: if (radios[i].checked) {
! 1405: if (radios[i].value == 'lti') {
! 1406: ltidiv.style.display = 'inline-block';
! 1407: keybox.type = 'hidden';
! 1408: keybox.value = '';
! 1409: } else {
! 1410: if (ltidiv != '') {
! 1411: ltidiv.style.display = 'none';
! 1412: form['deeplink_lti_'+key].selectedIndex = 0;
! 1413: }
! 1414: if (radios[i].value == 'key') {
! 1415: keybox.type = 'text';
! 1416: } else {
! 1417: keybox.type = 'hidden';
! 1418: }
! 1419: }
! 1420: }
! 1421: }
! 1422: }
! 1423: }
! 1424: END
! 1425:
! 1426: }
! 1427:
1.561 damieng 1428: # Prints HTML page start for table mode.
1429: # @param {Apache2::RequestRec} $r - the Apache request
1430: # @param {string} $psymb - resource symb
1431: # @param {string} $crstype - course type (Community / Course / Placement Test)
1.280 albertel 1432: sub startpage {
1.531 raeburn 1433: my ($r,$psymb,$crstype) = @_;
1.281 albertel 1434:
1.515 raeburn 1435: my %loaditems = (
1436: 'onload' => "group_or_section('cgroup')",
1437: );
1438: if (!$psymb) {
1.523 raeburn 1439: $loaditems{'onload'} = "showHide_courseContent(); group_or_section('cgroup'); resize_scrollbox('mapmenuscroll','1','1');";
1.515 raeburn 1440: }
1.280 albertel 1441:
1.560 damieng 1442: if ((($env{'form.command'} eq 'set') && ($env{'form.url'}) &&
1443: (!$env{'form.dis'})) || ($env{'form.symb'})) {
1444: &Apache::lonhtmlcommon::add_breadcrumb({help=>'Problem_Parameters',
1445: text=>"Problem Parameters"});
1.414 droeschl 1446: } else {
1.560 damieng 1447: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',
1448: text=>"Table Mode",
1449: help => 'Course_Setting_Parameters'});
1.414 droeschl 1450: }
1.523 raeburn 1451: my $js = &page_js().'
1452: <script type="text/javascript">
1453: // <![CDATA[
1454: '.
1455: &Apache::lonhtmlcommon::resize_scrollbox_js('params').'
1456: // ]]>
1457: </script>
1458: ';
1.446 bisitz 1459: my $start_page =
1.523 raeburn 1460: &Apache::loncommon::start_page('Set/Modify Course Parameters',$js,
1461: {'add_entries' => \%loaditems,});
1.446 bisitz 1462: my $breadcrumbs =
1.473 amueller 1463: &Apache::lonhtmlcommon::breadcrumbs('Table Mode Parameter Setting','Table_Mode');
1.506 www 1464: my $escfilter=&Apache::lonhtmlcommon::entity_encode($env{'form.filter'});
1465: my $escpart=&Apache::lonhtmlcommon::entity_encode($env{'form.part'});
1.507 www 1466: $r->print($start_page.$breadcrumbs);
1.531 raeburn 1467: &startSettingsScreen($r,'parmset',$crstype);
1.280 albertel 1468: $r->print(<<ENDHEAD);
1.193 albertel 1469: <form method="post" action="/adm/parmset?action=settable" name="parmform">
1.419 bisitz 1470: <input type="hidden" value="" name="pres_value" />
1471: <input type="hidden" value="" name="pres_type" />
1472: <input type="hidden" value="" name="pres_marker" />
1473: <input type="hidden" value="1" name="prevvisit" />
1.506 www 1474: <input type="hidden" value="$escfilter" name="filter" />
1475: <input type="hidden" value="$escpart" name="part" />
1.44 albertel 1476: ENDHEAD
1477: }
1478:
1.209 www 1479:
1.561 damieng 1480: # Prints a row for table mode (except for the tr start).
1481: # Every time a hash reference is passed, a single entry is used, so print_row
1482: # could just use these values, but why make it simple when it can be complicated ?
1483: #
1484: # @param {Apache2::RequestRec} $r - the Apache request
1485: # @param {string} $which - parameter key ('parameter_'.part.'_'.name)
1486: # @param {hash reference} $part - parameter key -> parameter part (can be problem part.'_'.response id for response parameters)
1487: # @param {hash reference} $name - parameter key -> parameter name
1.566 damieng 1488: # @param {hash reference} $symbp - map pc or resource/map id -> map src.'___(all)' or resource symb
1.561 damieng 1489: # @param {string} $rid - resource id
1490: # @param {hash reference} $default - parameter key -> resource parameter default value
1491: # @param {hash reference} $defaulttype - parameter key -> resource parameter default type
1492: # @param {hash reference} $display - parameter key -> full title for the parameter
1493: # @param {string} $defbgone - user level and other levels background color
1494: # @param {string} $defbgtwo - section level background color, also used for part number
1495: # @param {string} $defbgthree - group level background color
1496: # @param {string} $parmlev - parameter level (Resource:'full', Map:'map', Course:'general')
1497: # @param {string} $uname - user name
1498: # @param {string} $udom - user domain
1499: # @param {string} $csec - section name
1500: # @param {string} $cgroup - group name
1501: # @param {array reference} $usersgroups - list of groups the user belongs to, if any
1502: # @param {boolean} $noeditgrp - true if no edit is allowed for group level parameters
1.582 raeburn 1503: # @param {boolean} $readonly - true if no editing allowed.
1504: # @param {array reference} - $recurseup - list of maps containing current one, ending at top-level.
1505: # @param {hash reference} - $maptitles - - hash map id or src -> map title
1506: # @param {hash reference} - $allmaps_inverted - hash map src -> map pc
1507: # @param {scalar reference} - $reclinks - number of "parameter in effect" cells with link to map where recursive param was set
1.44 albertel 1508: sub print_row {
1.201 www 1509: my ($r,$which,$part,$name,$symbp,$rid,$default,$defaulttype,$display,$defbgone,
1.568 raeburn 1510: $defbgtwo,$defbgthree,$parmlev,$uname,$udom,$csec,$cgroup,$usersgroups,$noeditgrp,
1.582 raeburn 1511: $readonly,$recurseup,$maptitles,$allmaps_inverted,$reclinks)=@_;
1.275 raeburn 1512: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1513: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1514: my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
1.582 raeburn 1515: my $numlinks = 0;
1.553 raeburn 1516:
1.560 damieng 1517: # get the values for the parameter in cascading order
1518: # empty levels will remain empty
1.44 albertel 1519: my ($result,@outpar)=&parmval($$part{$which}.'.'.$$name{$which},
1.473 amueller 1520: $rid,$$default{$which},$uname,$udom,$csec,$cgroup,$courseopt);
1.560 damieng 1521: # get the type for the parameters
1522: # problem: these may not be set for all levels
1.66 www 1523: my ($typeresult,@typeoutpar)=&parmval($$part{$which}.'.'.
1.275 raeburn 1524: $$name{$which}.'.type',$rid,
1.473 amueller 1525: $$defaulttype{$which},$uname,$udom,$csec,$cgroup,$courseopt);
1.560 damieng 1526: # cascade down manually
1.182 albertel 1527: my $cascadetype=$$defaulttype{$which};
1.556 raeburn 1528: for (my $i=18;$i>0;$i--) {
1.560 damieng 1529: if ($typeoutpar[$i]) {
1.66 www 1530: $cascadetype=$typeoutpar[$i];
1.560 damieng 1531: } else {
1.66 www 1532: $typeoutpar[$i]=$cascadetype;
1533: }
1534: }
1.57 albertel 1535: my $parm=$$display{$which};
1536:
1.203 www 1537: if ($parmlev eq 'full') {
1.419 bisitz 1538: $r->print('<td style="background-color:'.$defbgtwo.';" align="center">'
1.506 www 1539: .($$part{$which} eq '0'?'0 ('.&mt('default').')':$$part{$which}).'</td>');
1.433 raeburn 1540: } else {
1.57 albertel 1541: $parm=~s|\[.*\]\s||g;
1542: }
1.231 www 1543: my $automatic=&rulescache(($which=~/\_([^\_]+)$/)[0].'_triggers');
1544: if ($automatic) {
1.560 damieng 1545: $parm.='<span class="LC_warning"><br />'.&mt('Automatically sets').' '.join(', ',split(/\:/,$automatic)).'</span>';
1.231 www 1546: }
1.427 bisitz 1547: $r->print('<td>'.$parm.'</td>');
1.446 bisitz 1548:
1.44 albertel 1549: my $thismarker=$which;
1550: $thismarker=~s/^parameter\_//;
1551: my $mprefix=$rid.'&'.$thismarker.'&';
1.582 raeburn 1552: my ($parmname)=($thismarker=~/\_([^\_]+)$/);
1553: my ($othergrp,$grp_parm,$controlgrp,$effective_parm,$effparm_rec,$effparm_level,
1.588 ! raeburn 1554: $eff_groupparm,$recurse_check,$recursinfo,$extra);
1.582 raeburn 1555: if ((ref($recurseup) eq 'ARRAY') && (@{$recurseup} > 0)) {
1556: if ($result eq '') {
1557: $recurse_check = 1;
1558: } elsif (($uname ne '') && ($result > 3)) {
1559: $recurse_check = 1;
1560: } elsif (($cgroup ne '') && ($result > 7)) {
1561: $recurse_check = 1;
1562: } elsif (($csec ne '') && ($result > 11)) {
1563: $recurse_check = 1;
1564: } elsif ($result > 17) {
1565: $recurse_check = 1;
1566: }
1567: if ($recurse_check) {
1568: my $what = $$part{$which}.'.'.$$name{$which};
1569: my $prefix;
1570: if (($uname ne '') && ($udom ne '')) {
1571: my $useropt = &Apache::lonnet::get_userresdata($uname,$udom);
1572: $prefix = $env{'request.course.id'};
1573: $recursinfo = &get_recursive($recurseup,$useropt,$what,$prefix);
1574: if (ref($recursinfo) eq 'ARRAY') {
1575: $effparm_rec = 1;
1576: $effparm_level = &mt('user: [_1]',$uname);
1577: }
1578: }
1579: if (($cgroup ne '') && (!$effparm_rec)) {
1580: $prefix = $env{'request.course.id'}.'.['.$cgroup.']';
1581: $recursinfo = &get_recursive($recurseup,$courseopt,$what,$prefix);
1582: if (ref($recursinfo) eq 'ARRAY') {
1583: $effparm_rec = 1;
1584: $effparm_level = &mt('group: [_1]',$cgroup);
1585: }
1586: }
1587: if (($csec ne '') && (!$effparm_rec)) {
1588: $prefix = $env{'request.course.id'}.'.['.$csec.']';
1589: $recursinfo = &get_recursive($recurseup,$courseopt,$what,$prefix);
1590: if (ref($recursinfo) eq 'ARRAY') {
1591: $effparm_rec = 1;
1592: $effparm_level = &mt('section: [_1]',$csec);
1593: }
1594: }
1595: if (!$effparm_rec) {
1596: $prefix = $env{'request.course.id'};
1597: $recursinfo = &get_recursive($recurseup,$courseopt,$what,$prefix);
1598: if (ref($recursinfo) eq 'ARRAY') {
1599: $effparm_rec = 1;
1600: }
1601: }
1602: }
1603: }
1604: if ((!$effparm_rec) && ($result == 17 || $result == 11 || $result == 7 || $result == 3)) {
1605: $effparm_rec = 1;
1606: }
1607: if ((!$effparm_rec) &&
1608: (($$name{$which} eq 'encrypturl') || ($$name{$which} eq 'hiddenresource')) &&
1609: ($result == 16 || $result == 10 || $result == 6 || $result == 2)) {
1.578 raeburn 1610: $effparm_rec = 1;
1611: }
1.588 ! raeburn 1612: if ($parmname eq 'deeplink') {
! 1613: my %posslti;
! 1614: my %lti =
! 1615: &Apache::lonnet::get_domain_lti($env{'course.'.$env{'request.course.id'}.'.domain'},
! 1616: 'provider');
! 1617: foreach my $item (keys(%lti)) {
! 1618: if (ref($lti{$item}) eq 'HASH') {
! 1619: unless ($lti{$item}{'requser'}) {
! 1620: $posslti{$item} = $lti{$item}{'consumer'};
! 1621: }
! 1622: }
! 1623: }
! 1624: if (keys(%posslti)) {
! 1625: $extra = 'lti_';
! 1626: foreach my $lti (sort { $a <=> $b } keys(%posslti)) {
! 1627: $extra .= $lti.':'.&js_escape($posslti{$lti}).',';
! 1628: }
! 1629: $extra =~ s/,$//;
! 1630: }
! 1631: }
1.57 albertel 1632: if ($parmlev eq 'general') {
1633: if ($uname) {
1.588 ! raeburn 1634: &print_td($r,4,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1.269 raeburn 1635: } elsif ($cgroup) {
1.588 ! raeburn 1636: &print_td($r,8,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp,$readonly,'',$extra);
1.57 albertel 1637: } elsif ($csec) {
1.588 ! raeburn 1638: &print_td($r,12,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1.57 albertel 1639: } else {
1.588 ! raeburn 1640: &print_td($r,18,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1.57 albertel 1641: }
1642: } elsif ($parmlev eq 'map') {
1643: if ($uname) {
1.588 ! raeburn 1644: &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,1,$extra);
1.269 raeburn 1645: } elsif ($cgroup) {
1.588 ! raeburn 1646: &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp,$readonly,1,$extra);
1.57 albertel 1647: } elsif ($csec) {
1.588 ! raeburn 1648: &print_td($r,10,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,1,$extra);
1.57 albertel 1649: } else {
1.588 ! raeburn 1650: &print_td($r,16,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,1,$extra);
1.57 albertel 1651: }
1652: } else {
1.275 raeburn 1653: if ($uname) {
1654: if (@{$usersgroups} > 1) {
1.582 raeburn 1655: (my $coursereply,$othergrp,$grp_parm,$controlgrp,my $grp_is_rec) =
1.580 raeburn 1656: &check_other_groups($$part{$which}.'.'.$$name{$which},
1.275 raeburn 1657: $rid,$cgroup,$defbgone,$usersgroups,$result,$courseopt);
1.582 raeburn 1658: if (($coursereply) && ($result > 4)) {
1.275 raeburn 1659: if (defined($controlgrp)) {
1660: if ($cgroup ne $controlgrp) {
1.582 raeburn 1661: $eff_groupparm = $grp_parm;
1662: undef($result);
1663: undef($effparm_rec);
1664: if ($grp_is_rec) {
1665: $effparm_rec = 1;
1666: }
1.275 raeburn 1667: }
1668: }
1669: }
1670: }
1671: }
1.57 albertel 1672:
1.588 ! raeburn 1673: &print_td($r,18,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
! 1674: &print_td($r,16,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,1,$extra);
! 1675: &print_td($r,15,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
! 1676: &print_td($r,14,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
! 1677: &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1.548 raeburn 1678:
1679: if ($csec) {
1.588 ! raeburn 1680: &print_td($r,12,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
! 1681: &print_td($r,10,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,1,$extra);
! 1682: &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1.548 raeburn 1683: }
1.269 raeburn 1684:
1685: if ($cgroup) {
1.588 ! raeburn 1686: &print_td($r,8,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp,$readonly,'',$extra);
! 1687: &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp,$readonly,1,$extra);
! 1688: &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp.$readonly,'',$extra);
1.269 raeburn 1689: }
1.446 bisitz 1690:
1.548 raeburn 1691: if ($uname) {
1.275 raeburn 1692: if ($othergrp) {
1693: $r->print($othergrp);
1694: }
1.588 ! raeburn 1695: &print_td($r,4,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
! 1696: &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,1,$extra);
! 1697: &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1.548 raeburn 1698: }
1.57 albertel 1699: } # end of $parmlev if/else
1.582 raeburn 1700: if (ref($recursinfo) eq 'ARRAY') {
1701: my $rectitle = &mt('recursive');
1702: if ((ref($maptitles) eq 'HASH') && (exists($maptitles->{$recursinfo->[2]}))) {
1703: if ((ref($allmaps_inverted) eq 'HASH') && (exists($allmaps_inverted->{$recursinfo->[2]}))) {
1704: $rectitle = &mt('set in: [_1]','"'.
1705: '<a href="javascript:pjumprec('."'".$allmaps_inverted->{$recursinfo->[2]}."',".
1706: "'$parmname','$$part{$which}'".');">'.
1707: $maptitles->{$recursinfo->[2]}.'</a>"');
1708:
1709: $numlinks ++;
1710: }
1711: }
1712: my ($parmname)=($thismarker=~/\_([^\_]+)$/);
1713: $effective_parm = &valout($recursinfo->[0],$recursinfo->[1],$parmname);
1714: $r->print('<td style="background-color:#CCCCFF;" align="center">'.$effective_parm.
1715: '<br /><span class="LC_parm_recursive">'.$rectitle.' '.
1716: $effparm_level.'</span></td>');
1717: } else {
1718: if ($result) {
1719: $effective_parm = &valout($outpar[$result],$typeoutpar[$result],$parmname);
1720: }
1721: if ($eff_groupparm) {
1722: $effective_parm = $eff_groupparm;
1723: }
1724: $r->print('<td style="background-color:#CCCCFF;" align="center">'.$effective_parm.
1725: ($effparm_rec?'<br /><span class="LC_parm_recursive">'.&mt('recursive').
1726: '</span>':'').'</td>');
1727: }
1.203 www 1728: if ($parmlev eq 'full') {
1.136 albertel 1729: my $sessionval=&Apache::lonnet::EXT('resource.'.$$part{$which}.
1.201 www 1730: '.'.$$name{$which},$$symbp{$rid});
1.136 albertel 1731: my $sessionvaltype=$typeoutpar[$result];
1.560 damieng 1732: if (!defined($sessionvaltype)) {
1733: $sessionvaltype=$$defaulttype{$which};
1734: }
1.419 bisitz 1735: $r->print('<td style="background-color:#999999;" align="center"><font color="#FFFFFF">'.
1.554 raeburn 1736: &valout($sessionval,$sessionvaltype,$$name{$which}).' '.
1.57 albertel 1737: '</font></td>');
1.136 albertel 1738: }
1.44 albertel 1739: $r->print('</tr>');
1.57 albertel 1740: $r->print("\n");
1.582 raeburn 1741: if (($numlinks) && (ref($reclinks))) {
1742: $$reclinks = $numlinks;
1743: }
1.44 albertel 1744: }
1.59 matthew 1745:
1.561 damieng 1746: # Prints a cell for table mode.
1747: #
1748: # FIXME: some of these parameter names are uninspired ($which and $value)
1749: # Also, it would make more sense to pass the display for this cell rather
1750: # than the full display hash and the key to use.
1751: #
1752: # @param {Apache2::RequestRec} $r - the Apache request
1753: # @param {integer} $which - level
1754: # @param {string} $defbg - cell background color
1755: # @param {integer} $result - the most specific level that is defined for that parameter
1756: # @param {array reference} $outpar - array level -> parameter value (when defined)
1757: # @param {string} $mprefix - resource id.'&'.part.'_'.parameter name.'&'
1758: # @param {string} $value - parameter key ('parameter_'.part.'_'.name)
1759: # @param {array reference} $typeoutpar - array level -> parameter type (when defined)
1760: # @param {hash reference} $display - parameter key -> full title for the parameter
1761: # @param {boolean} $noeditgrp - true if no edit is allowed for group level parameters
1.568 raeburn 1762: # @param {boolean} $readonly -true if editing not allowed.
1.588 ! raeburn 1763: # @param {boolean} $ismaplevel - true if level is for a map.
! 1764: # @param {strring} $extra - extra informatio to pass to plink.
1.44 albertel 1765: sub print_td {
1.578 raeburn 1766: my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display,
1.588 ! raeburn 1767: $noeditgrp,$readonly,$ismaplevel,$extra)=@_;
1.578 raeburn 1768: my ($ineffect,$recursive,$currval,$currtype,$currlevel);
1769: $ineffect = 0;
1770: $currval = $$outpar[$which];
1771: $currtype = $$typeoutpar[$which];
1772: $currlevel = $which;
1773: if (($result) && ($result == $which)) {
1774: $ineffect = 1;
1775: }
1776: if ($ismaplevel) {
1777: if ($mprefix =~ /(hiddenresource|encrypturl)\&/) {
1778: if (($result) && ($result == $which)) {
1779: $recursive = 1;
1780: }
1781: } elsif ($$outpar[$which+1] ne '') {
1782: $recursive = 1;
1783: $currlevel = $which+1;
1784: $currval = $$outpar[$currlevel];
1785: $currtype = $$typeoutpar[$currlevel];
1786: if (($result) && ($result == $currlevel)) {
1787: $ineffect = 1;
1788: }
1789: }
1790: }
1791: $r->print('<td style="background-color:'.($ineffect?'#AAFFAA':$defbg).
1.419 bisitz 1792: ';" align="center">');
1.437 raeburn 1793: my $nolink = 0;
1.568 raeburn 1794: if ($readonly) {
1.552 raeburn 1795: $nolink = 1;
1.568 raeburn 1796: } else {
1.578 raeburn 1797: if ($which == 14 || $which == 15 || $mprefix =~ /mapalias\&$/) {
1.553 raeburn 1798: $nolink = 1;
1.568 raeburn 1799: } elsif (($env{'request.course.sec'} ne '') && ($which > 12)) {
1.533 raeburn 1800: $nolink = 1;
1.568 raeburn 1801: } elsif ($which == 5 || $which == 6 || $which == 7 || $which == 8) {
1802: if ($noeditgrp) {
1803: $nolink = 1;
1804: }
1805: } elsif ($mprefix =~ /availablestudent\&$/) {
1806: if ($which > 4) {
1807: $nolink = 1;
1808: }
1809: } elsif ($mprefix =~ /examcode\&$/) {
1810: unless ($which == 2) {
1811: $nolink = 1;
1812: }
1.533 raeburn 1813: }
1.437 raeburn 1814: }
1815: if ($nolink) {
1.577 raeburn 1816: my ($parmname)=((split(/\&/,$mprefix))[1]=~/\_([^\_]+)$/);
1.578 raeburn 1817: $r->print(&valout($currval,$currtype,$parmname));
1.114 www 1818: } else {
1.578 raeburn 1819: $r->print(&plink($currtype,
1820: $$display{$value},$currval,
1.588 ! raeburn 1821: $mprefix.$currlevel,'parmform.pres','psub',$recursive,
! 1822: $extra));
1.114 www 1823: }
1824: $r->print('</td>'."\n");
1.57 albertel 1825: }
1826:
1.561 damieng 1827: # Returns HTML and other info for the cell added when a user is selected
1828: # and that user is in several groups. This is the cell with the title "Control by other group".
1829: #
1830: # @param {string} $what - parameter part.'.'.parameter name
1831: # @param {string} $rid - resource id
1832: # @param {string} $cgroup - group name
1833: # @param {string} $defbg - cell background color
1834: # @param {array reference} $usersgroups - list of groups the user belongs to, if any
1835: # @param {integer} $result - level
1836: # @param {hash reference} $courseopt - course parameters hash (result of lonnet::get_courseresdata, dump of course's resourcedata.db)
1.582 raeburn 1837: # @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 1838: sub check_other_groups {
1839: my ($what,$rid,$cgroup,$defbg,$usersgroups,$result,$courseopt) = @_;
1.275 raeburn 1840: my $courseid = $env{'request.course.id'};
1841: my $output;
1842: my $symb = &symbcache($rid);
1843: my $symbparm=$symb.'.'.$what;
1844: my $map=(&Apache::lonnet::decode_symb($symb))[0];
1.556 raeburn 1845: my $recurseparm=$map.'___(rec).'.$what;
1.275 raeburn 1846: my $mapparm=$map.'___(all).'.$what;
1847: my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype) =
1.556 raeburn 1848: &parm_control_group($courseid,$usersgroups,$symbparm,$mapparm,
1849: $recurseparm,$what,$courseopt);
1.275 raeburn 1850: my $bgcolor = $defbg;
1.582 raeburn 1851: my ($grp_parm,$grp_is_rec);
1.446 bisitz 1852: if (($coursereply) && ($cgroup ne $resultgroup)) {
1.582 raeburn 1853: my ($parmname) = ($what =~ /\.([^.]+)$/);
1.275 raeburn 1854: if ($result > 3) {
1.419 bisitz 1855: $bgcolor = '#AAFFAA';
1.275 raeburn 1856: }
1.582 raeburn 1857: $grp_parm = &valout($coursereply,$resulttype,$parmname);
1.419 bisitz 1858: $output = '<td style="background-color:'.$bgcolor.';" align="center">';
1.275 raeburn 1859: if ($resultgroup && $resultlevel) {
1.582 raeburn 1860: if ($resultlevel eq 'recursive') {
1861: $resultlevel = 'map/folder';
1862: $grp_is_rec = 1;
1863: }
1864: $output .= '<small><b>'.$resultgroup.'</b> ('.$resultlevel.'): </small>'.$grp_parm.
1865: ($grp_is_rec?'<span class="LC_parm_recursive">'.&mt('recursive').'</span>':'');
1866:
1.275 raeburn 1867: } else {
1868: $output .= ' ';
1869: }
1870: $output .= '</td>';
1871: } else {
1.419 bisitz 1872: $output .= '<td style="background-color:'.$bgcolor.';"> </td>';
1.275 raeburn 1873: }
1.582 raeburn 1874: return ($coursereply,$output,$grp_parm,$resultgroup,$grp_is_rec);
1.275 raeburn 1875: }
1876:
1.561 damieng 1877: # Looks for a group with a defined parameter for given user and parameter.
1.580 raeburn 1878: # Used by check_other_groups.
1.561 damieng 1879: #
1880: # @param {string} $courseid - the course id
1881: # @param {array reference} $usersgroups - list of groups the user belongs to, if any
1882: # @param {string} $symbparm - end of the course parameter hash key for the group resource level
1883: # @param {string} $mapparm - end of the course parameter hash key for the group map/folder level
1884: # @param {string} $recurseparm - end of the course parameter hash key for the group recursive level
1885: # @param {string} $what - parameter part.'.'.parameter name
1886: # @param {hash reference} $courseopt - course parameters hash
1887: # @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 1888: sub parm_control_group {
1.556 raeburn 1889: my ($courseid,$usersgroups,$symbparm,$mapparm,$recurseparm,$what,$courseopt) = @_;
1.275 raeburn 1890: my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
1891: my $grpfound = 0;
1.556 raeburn 1892: my @levels = ($symbparm,$mapparm,$recurseparm,$what);
1893: my @levelnames = ('resource','map/folder','recursive','general');
1.275 raeburn 1894: foreach my $group (@{$usersgroups}) {
1895: if ($grpfound) { last; }
1896: for (my $i=0; $i<@levels; $i++) {
1897: my $item = $courseid.'.['.$group.'].'.$levels[$i];
1898: if (defined($$courseopt{$item})) {
1899: $coursereply = $$courseopt{$item};
1900: $resultitem = $item;
1901: $resultgroup = $group;
1902: $resultlevel = $levelnames[$i];
1903: $resulttype = $$courseopt{$item.'.type'};
1904: $grpfound = 1;
1905: last;
1906: }
1907: }
1908: }
1909: return($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
1910: }
1.201 www 1911:
1.63 bowersj2 1912:
1913:
1.562 damieng 1914: # Extracts lots of information about all of the the course's resources into a variety of hashes, using lonnavmaps and lonnet::metadata.
1915: # All the parameters are references and are filled by the sub.
1916: #
1.566 damieng 1917: # @param {array reference} $ids - resource and map ids
1918: # @param {hash reference} $typep - hash resource/map id -> resource type (file extension)
1919: # @param {hash reference} $keyp - hash resource/map id -> comma-separated list of parameter keys from lonnet::metadata
1.562 damieng 1920: # @param {hash reference} $allparms - hash parameter name -> parameter title
1921: # @param {hash reference} $allparts - hash parameter part -> part title (a parameter part can be problem part.'_'.response id for response parameters)
1.566 damieng 1922: # @param {hash reference} $allmaps - hash map pc -> map src
1923: # @param {hash reference} $mapp - hash map pc or resource/map id -> enclosing map src
1924: # @param {hash reference} $symbp - hash map pc or resource/map id -> map src.'___(all)' for a map or resource symb for a resource
1925: # @param {hash reference} $maptitles - hash map pc or src -> map title (this should really be two separate hashes)
1926: # @param {hash reference} $uris - hash resource/map id -> resource src
1.562 damieng 1927: # @param {hash reference} $keyorder - hash parameter key -> appearance rank for this parameter when looking through every resource and every parameter, starting at 100 (integer)
1928: # @param {hash reference} $defkeytype - hash parameter name -> parameter type
1.63 bowersj2 1929: sub extractResourceInformation {
1930: my $ids = shift;
1931: my $typep = shift;
1932: my $keyp = shift;
1933: my $allparms = shift;
1934: my $allparts = shift;
1935: my $allmaps = shift;
1936: my $mapp = shift;
1937: my $symbp = shift;
1.82 www 1938: my $maptitles=shift;
1.196 www 1939: my $uris=shift;
1.210 www 1940: my $keyorder=shift;
1.211 www 1941: my $defkeytype=shift;
1.196 www 1942:
1.210 www 1943: my $keyordercnt=100;
1.63 bowersj2 1944:
1.196 www 1945: my $navmap = Apache::lonnavmaps::navmap->new();
1946: my @allres=$navmap->retrieveResources(undef,undef,1,undef,1);
1947: foreach my $resource (@allres) {
1.480 amueller 1948: my $id=$resource->id();
1.196 www 1949: my ($mapid,$resid)=split(/\./,$id);
1.480 amueller 1950: if ($mapid eq '0') { next; }
1951: $$ids[$#$ids+1]=$id;
1952: my $srcf=$resource->src();
1953: $srcf=~/\.(\w+)$/;
1954: $$typep{$id}=$1;
1.584 raeburn 1955: my $toolsymb;
1956: if ($srcf =~ /ext\.tool$/) {
1957: $toolsymb = $resource->symb();
1958: }
1.480 amueller 1959: $$keyp{$id}='';
1.196 www 1960: $$uris{$id}=$srcf;
1.512 foxr 1961:
1.584 raeburn 1962: foreach my $key (split(/\,/,&Apache::lonnet::metadata($srcf,'allpossiblekeys',$toolsymb))) {
1.480 amueller 1963: next if ($key!~/^parameter_/);
1.363 albertel 1964:
1.209 www 1965: # Hidden parameters
1.584 raeburn 1966: next if (&Apache::lonnet::metadata($srcf,$key.'.hidden',$toolsymb) eq 'parm');
1.209 www 1967: #
1968: # allparms is a hash of parameter names
1969: #
1.584 raeburn 1970: my $name=&Apache::lonnet::metadata($srcf,$key.'.name',$toolsymb);
1.480 amueller 1971: if (!exists($$allparms{$name}) || $$allparms{$name} =~ m/^\s*$/ ) {
1972: my ($display,$parmdis);
1973: $display = &standard_parameter_names($name);
1974: if ($display eq '') {
1.584 raeburn 1975: $display= &Apache::lonnet::metadata($srcf,$key.'.display',$toolsymb);
1.480 amueller 1976: $parmdis = $display;
1977: $parmdis =~ s/\s*\[Part.*$//g;
1978: } else {
1979: $parmdis = &mt($display);
1980: }
1981: $$allparms{$name}=$parmdis;
1982: if (ref($defkeytype)) {
1983: $$defkeytype{$name}=
1.584 raeburn 1984: &Apache::lonnet::metadata($srcf,$key.'.type',$toolsymb);
1.480 amueller 1985: }
1986: }
1.363 albertel 1987:
1.209 www 1988: #
1989: # allparts is a hash of all parts
1990: #
1.584 raeburn 1991: my $part= &Apache::lonnet::metadata($srcf,$key.'.part',$toolsymb);
1.480 amueller 1992: $$allparts{$part} = &mt('Part: [_1]',$part);
1.209 www 1993: #
1994: # Remember all keys going with this resource
1995: #
1.480 amueller 1996: if ($$keyp{$id}) {
1997: $$keyp{$id}.=','.$key;
1998: } else {
1999: $$keyp{$id}=$key;
2000: }
1.210 www 2001: #
2002: # Put in order
1.446 bisitz 2003: #
1.480 amueller 2004: unless ($$keyorder{$key}) {
2005: $$keyorder{$key}=$keyordercnt;
2006: $keyordercnt++;
2007: }
1.473 amueller 2008: }
2009:
2010:
1.480 amueller 2011: if (!exists($$mapp{$mapid})) {
2012: $$mapp{$id}=
2013: &Apache::lonnet::declutter($resource->enclosing_map_src());
2014: $$mapp{$mapid}=$$mapp{$id};
2015: $$allmaps{$mapid}=$$mapp{$id};
2016: if ($mapid eq '1') {
1.532 raeburn 2017: $$maptitles{$mapid}=&mt('Main Content');
1.480 amueller 2018: } else {
2019: $$maptitles{$mapid}=&Apache::lonnet::gettitle($$mapp{$id});
2020: }
2021: $$maptitles{$$mapp{$id}}=$$maptitles{$mapid};
1.556 raeburn 2022: $$symbp{$mapid}=$$mapp{$id}.'___(all)'; # Added in rev. 1.57, but seems not to be used.
2023: # Lines 1038 and 1114 which use $symbp{$mapid}
2024: # are commented out in rev. 1.57
1.473 amueller 2025: } else {
1.480 amueller 2026: $$mapp{$id} = $$mapp{$mapid};
1.473 amueller 2027: }
1.480 amueller 2028: $$symbp{$id}=&Apache::lonnet::encode_symb($$mapp{$id},$resid,$srcf);
1.63 bowersj2 2029: }
2030: }
2031:
1.582 raeburn 2032: sub get_recursive {
2033: my ($recurseup,$resdata,$what,$prefix) = @_;
2034: if ((ref($resdata) eq 'HASH') && (ref($recurseup) eq 'ARRAY')) {
2035: foreach my $item (@{$recurseup}) {
2036: my $norecursechk=$prefix.'.'.$item.'___(all).'.$what;
2037: if (defined($resdata->{$norecursechk})) {
2038: if ($what =~ /\.(encrypturl|hiddenresource)$/) {
2039: my $type = $resdata->{$norecursechk.'.type'};
2040: return [$resdata->{$norecursechk},$type,$item];
2041: } else {
2042: last;
2043: }
2044: }
2045: my $recursechk=$prefix.'.'.$item.'___(rec).'.$what;
2046: if (defined($resdata->{$recursechk})) {
2047: my $type = $resdata->{$recursechk.'.type'};
2048: return [$resdata->{$recursechk},$type,$item];
2049: }
2050: }
2051: }
2052: return;
2053: }
2054:
1.208 www 2055:
1.562 damieng 2056: # Tells if a parameter type is a date.
2057: #
2058: # @param {string} type - parameter type
2059: # @returns{boolean} - true if it is a date
1.213 www 2060: sub isdateparm {
2061: my $type=shift;
2062: return (($type=~/^date/) && (!($type eq 'date_interval')));
2063: }
2064:
1.562 damieng 2065: # Prints the HTML and Javascript to select parameters, with various shortcuts.
1.468 amueller 2066: #
1.581 raeburn 2067: # @param {Apache2::RequestRec} $r - the Apache request
1.208 www 2068: sub parmmenu {
1.581 raeburn 2069: my ($r)=@_;
1.208 www 2070: $r->print(<<ENDSCRIPT);
2071: <script type="text/javascript">
1.454 bisitz 2072: // <![CDATA[
1.208 www 2073: function checkall(value, checkName) {
1.453 schualex 2074:
2075: var li = "_li";
2076: var displayOverview = "";
2077:
2078: if (value == false) {
2079: displayOverview = "none"
2080: }
2081:
1.562 damieng 2082: for (i=0; i<document.forms.parmform.elements.length; i++) {
1.208 www 2083: ele = document.forms.parmform.elements[i];
2084: if (ele.name == checkName) {
2085: document.forms.parmform.elements[i].checked=value;
2086: }
2087: }
2088: }
1.210 www 2089:
2090: function checkthis(thisvalue, checkName) {
1.562 damieng 2091: for (i=0; i<document.forms.parmform.elements.length; i++) {
1.210 www 2092: ele = document.forms.parmform.elements[i];
2093: if (ele.name == checkName) {
1.562 damieng 2094: if (ele.value == thisvalue) {
2095: document.forms.parmform.elements[i].checked=true;
2096: }
1.210 www 2097: }
2098: }
2099: }
2100:
2101: function checkdates() {
1.562 damieng 2102: checkthis('duedate','pscat');
2103: checkthis('opendate','pscat');
2104: checkthis('answerdate','pscat');
1.218 www 2105: }
2106:
2107: function checkdisset() {
1.562 damieng 2108: checkthis('discussend','pscat');
2109: checkthis('discusshide','pscat');
2110: checkthis('discussvote','pscat');
1.218 www 2111: }
2112:
2113: function checkcontdates() {
1.562 damieng 2114: checkthis('contentopen','pscat');
2115: checkthis('contentclose','pscat');
1.218 www 2116: }
1.446 bisitz 2117:
1.210 www 2118: function checkvisi() {
1.562 damieng 2119: checkthis('hiddenresource','pscat');
2120: checkthis('encrypturl','pscat');
2121: checkthis('problemstatus','pscat');
2122: checkthis('contentopen','pscat');
2123: checkthis('opendate','pscat');
1.210 www 2124: }
2125:
2126: function checkparts() {
1.562 damieng 2127: checkthis('hiddenparts','pscat');
2128: checkthis('display','pscat');
2129: checkthis('ordered','pscat');
1.210 www 2130: }
2131:
2132: function checkstandard() {
2133: checkall(false,'pscat');
1.562 damieng 2134: checkdates();
2135: checkthis('weight','pscat');
2136: checkthis('maxtries','pscat');
2137: checkthis('type','pscat');
2138: checkthis('problemstatus','pscat');
1.210 www 2139: }
2140:
1.454 bisitz 2141: // ]]>
1.208 www 2142: </script>
2143: ENDSCRIPT
1.453 schualex 2144:
1.491 bisitz 2145: $r->print('<hr />');
1.581 raeburn 2146: &shortCuts($r);
1.491 bisitz 2147: $r->print('<hr />');
1.453 schualex 2148: }
1.562 damieng 2149:
2150: # Returns parameter categories.
2151: #
2152: # @returns {hash} - category name -> title in English
1.465 amueller 2153: sub categories {
2154: return ('time_settings' => 'Time Settings',
2155: 'grading' => 'Grading',
2156: 'tries' => 'Tries',
2157: 'problem_appearance' => 'Problem Appearance',
2158: 'behaviour_of_input_fields' => 'Behaviour of Input Fields',
2159: 'hiding' => 'Hiding',
2160: 'high_level_randomization' => 'High Level Randomization',
2161: 'slots' => 'Slots',
2162: 'file_submission' => 'File Submission',
2163: 'misc' => 'Miscellaneous' );
2164: }
2165:
1.562 damieng 2166: # Returns the category for each parameter.
2167: #
2168: # @returns {hash} - parameter name -> category name
1.465 amueller 2169: sub lookUpTableParameter {
2170:
2171: return (
2172: 'opendate' => 'time_settings',
2173: 'duedate' => 'time_settings',
2174: 'answerdate' => 'time_settings',
2175: 'interval' => 'time_settings',
2176: 'contentopen' => 'time_settings',
2177: 'contentclose' => 'time_settings',
2178: 'discussend' => 'time_settings',
1.560 damieng 2179: 'printstartdate' => 'time_settings',
2180: 'printenddate' => 'time_settings',
1.465 amueller 2181: 'weight' => 'grading',
2182: 'handgrade' => 'grading',
2183: 'maxtries' => 'tries',
2184: 'hinttries' => 'tries',
1.503 raeburn 2185: 'randomizeontries' => 'tries',
1.465 amueller 2186: 'type' => 'problem_appearance',
2187: 'problemstatus' => 'problem_appearance',
2188: 'display' => 'problem_appearance',
2189: 'ordered' => 'problem_appearance',
2190: 'numbubbles' => 'problem_appearance',
2191: 'tol' => 'behaviour_of_input_fields',
2192: 'sig' => 'behaviour_of_input_fields',
2193: 'turnoffunit' => 'behaviour_of_input_fields',
2194: 'hiddenresource' => 'hiding',
2195: 'hiddenparts' => 'hiding',
2196: 'discusshide' => 'hiding',
2197: 'buttonshide' => 'hiding',
2198: 'turnoffeditor' => 'hiding',
2199: 'encrypturl' => 'hiding',
1.587 raeburn 2200: 'deeplink' => 'hiding',
1.465 amueller 2201: 'randomorder' => 'high_level_randomization',
2202: 'randompick' => 'high_level_randomization',
2203: 'available' => 'slots',
2204: 'useslots' => 'slots',
2205: 'availablestudent' => 'slots',
2206: 'uploadedfiletypes' => 'file_submission',
2207: 'maxfilesize' => 'file_submission',
2208: 'cssfile' => 'misc',
2209: 'mapalias' => 'misc',
2210: 'acc' => 'misc',
2211: 'maxcollaborators' => 'misc',
2212: 'scoreformat' => 'misc',
1.514 raeburn 2213: 'lenient' => 'grading',
1.519 raeburn 2214: 'retrypartial' => 'tries',
1.521 raeburn 2215: 'discussvote' => 'misc',
1.584 raeburn 2216: 'examcode' => 'high_level_randomization',
1.575 raeburn 2217: );
1.465 amueller 2218: }
2219:
1.562 damieng 2220: # Adds the given parameter name to an array of arrays listing all parameters for each category.
2221: #
2222: # @param {string} $name - parameter name
2223: # @param {array reference} $catList - array reference category name -> array reference of parameter names
1.465 amueller 2224: sub whatIsMyCategory {
2225: my $name = shift;
2226: my $catList = shift;
2227: my @list;
2228: my %lookUpList = &lookUpTableParameter; #Initilize the lookupList
2229: my $cat = $lookUpList{$name};
2230: if (defined($cat)) {
2231: if (!defined($$catList{$cat})){
2232: push @list, ($name);
2233: $$catList{$cat} = \@list;
2234: } else {
2235: push @{${$catList}{$cat}}, ($name);
2236: }
2237: } else {
2238: if (!defined($$catList{'misc'})){
2239: push @list, ($name);
2240: $$catList{'misc'} = \@list;
2241: } else {
2242: push @{${$catList}{'misc'}}, ($name);
2243: }
2244: }
2245: }
2246:
1.562 damieng 2247: # Sorts parameter names based on appearance order.
2248: #
2249: # @param {array reference} name - array reference of parameter names
2250: # @param {hash reference} $keyorder - hash parameter key -> appearance rank
2251: # @returns {Array} - array of parameter names
1.465 amueller 2252: sub keysindisplayorderCategory {
2253: my ($name,$keyorder)=@_;
2254: return sort {
1.473 amueller 2255: $$keyorder{'parameter_0_'.$a} <=> $$keyorder{'parameter_0_'.$b};
1.465 amueller 2256: } ( @{$name});
2257: }
2258:
1.562 damieng 2259: # Returns a hash category name -> order, starting at 1 (integer)
2260: #
2261: # @returns {hash}
1.467 amueller 2262: sub category_order {
2263: return (
2264: 'time_settings' => 1,
2265: 'grading' => 2,
2266: 'tries' => 3,
2267: 'problem_appearance' => 4,
2268: 'hiding' => 5,
2269: 'behaviour_of_input_fields' => 6,
2270: 'high_level_randomization' => 7,
2271: 'slots' => 8,
2272: 'file_submission' => 9,
2273: 'misc' => 10
2274: );
2275:
2276: }
1.453 schualex 2277:
1.562 damieng 2278: # Prints HTML to let the user select parameters, from a list of all parameters organized by category.
2279: #
2280: # @param {Apache2::RequestRec} $r - the Apache request
2281: # @param {hash reference} $allparms - hash parameter name -> parameter title
2282: # @param {array reference} $pscat - list of selected parameter names
2283: # @param {hash reference} $keyorder - hash parameter key -> appearance rank
1.453 schualex 2284: sub parmboxes {
2285: my ($r,$allparms,$pscat,$keyorder)=@_;
1.548 raeburn 2286: my %categories = &categories();
1.467 amueller 2287: my %category_order = &category_order();
1.465 amueller 2288: my %categoryList = (
2289: 'time_settings' => [],
2290: 'grading' => [],
2291: 'tries' => [],
2292: 'problem_appearance' => [],
2293: 'behaviour_of_input_fields' => [],
2294: 'hiding' => [],
2295: 'high_level_randomization' => [],
2296: 'slots' => [],
2297: 'file_submission' => [],
2298: 'misc' => [],
1.489 bisitz 2299: );
1.510 www 2300:
1.548 raeburn 2301: foreach my $tempparameter (keys(%$allparms)) {
1.465 amueller 2302: &whatIsMyCategory($tempparameter, \%categoryList);
2303: }
1.453 schualex 2304: #part to print the parm-list
1.536 raeburn 2305: foreach my $key (sort { $category_order{$a} <=> $category_order{$b} } keys(%categoryList)) {
2306: next if (@{$categoryList{$key}} == 0);
2307: next if ($key eq '');
2308: $r->print('<div class="LC_Box LC_400Box">'
2309: .'<h4 class="LC_hcell">'.&mt($categories{$key}).'</h4>'."\n");
2310: foreach my $tempkey (&keysindisplayorderCategory($categoryList{$key},$keyorder)) {
1.575 raeburn 2311: next if ($tempkey eq '');
1.536 raeburn 2312: $r->print('<span class="LC_nobreak">'
2313: .'<label><input type="checkbox" name="pscat" '
2314: .'value="'.$tempkey.'" ');
2315: if ($$pscat[0] eq "all" || grep $_ eq $tempkey, @{$pscat}) {
2316: $r->print( ' checked="checked"');
2317: }
2318: $r->print(' />'.($$allparms{$tempkey}=~/\S/ ? $$allparms{$tempkey}
1.465 amueller 2319: : $tempkey)
1.536 raeburn 2320: .'</label></span><br />'."\n");
1.465 amueller 2321: }
1.536 raeburn 2322: $r->print('</div>');
1.465 amueller 2323: }
1.536 raeburn 2324: $r->print("\n");
1.453 schualex 2325: }
1.562 damieng 2326:
2327: # Prints HTML with shortcuts to select groups of parameters in one click, or deselect all.
1.468 amueller 2328: #
1.562 damieng 2329: # @param {Apache2::RequestRec} $r - the Apache request
1.453 schualex 2330: sub shortCuts {
1.581 raeburn 2331: my ($r)=@_;
1.453 schualex 2332:
1.491 bisitz 2333: # Parameter Selection
2334: $r->print(
2335: &Apache::lonhtmlcommon::start_funclist(&mt('Parameter Selection'))
2336: .&Apache::lonhtmlcommon::add_item_funclist(
2337: '<a href="javascript:checkall(true, \'pscat\')">'.&mt('Select All').'</a>')
2338: .&Apache::lonhtmlcommon::add_item_funclist(
2339: '<a href="javascript:checkstandard()">'.&mt('Select Common Only').'</a>')
2340: .&Apache::lonhtmlcommon::add_item_funclist(
2341: '<a href="javascript:checkall(false, \'pscat\')">'.&mt('Unselect All').'</a>')
2342: .&Apache::lonhtmlcommon::end_funclist()
2343: );
2344:
2345: # Add Selection for...
2346: $r->print(
2347: &Apache::lonhtmlcommon::start_funclist(&mt('Add Selection for...'))
2348: .&Apache::lonhtmlcommon::add_item_funclist(
2349: '<a href="javascript:checkdates()">'.&mt('Problem Dates').'</a>')
2350: .&Apache::lonhtmlcommon::add_item_funclist(
2351: '<a href="javascript:checkcontdates()">'.&mt('Content Dates').'</a>')
2352: .&Apache::lonhtmlcommon::add_item_funclist(
2353: '<a href="javascript:checkdisset()">'.&mt('Discussion Settings').'</a>')
2354: .&Apache::lonhtmlcommon::add_item_funclist(
2355: '<a href="javascript:checkvisi()">'.&mt('Visibilities').'</a>')
2356: .&Apache::lonhtmlcommon::add_item_funclist(
2357: '<a href="javascript:checkparts()">'.&mt('Part Parameters').'</a>')
2358: .&Apache::lonhtmlcommon::end_funclist()
2359: );
1.208 www 2360: }
2361:
1.562 damieng 2362: # Prints HTML to select parts to view (except for the title).
2363: # Used by table and overview modes.
2364: #
2365: # @param {Apache2::RequestRec} $r - the Apache request
2366: # @param {hash reference} $allparts - hash parameter part -> part title
2367: # @param {array reference} $psprt - list of selected parameter parts
1.209 www 2368: sub partmenu {
1.446 bisitz 2369: my ($r,$allparts,$psprt)=@_;
1.523 raeburn 2370: my $selsize = 1+scalar(keys(%{$allparts}));
2371: if ($selsize > 8) {
2372: $selsize = 8;
2373: }
1.446 bisitz 2374:
1.523 raeburn 2375: $r->print('<select multiple="multiple" name="psprt" size="'.$selsize.'">');
1.208 www 2376: $r->print('<option value="all"');
1.562 damieng 2377: $r->print(' selected="selected"') unless (@{$psprt}); # useless, the array is never empty
1.208 www 2378: $r->print('>'.&mt('All Parts').'</option>');
2379: my %temphash=();
2380: foreach (@{$psprt}) { $temphash{$_}=1; }
1.234 albertel 2381: foreach my $tempkey (sort {
1.560 damieng 2382: if ($a==$b) { return ($a cmp $b) } else { return ($a <=> $b); }
2383: } keys(%{$allparts})) {
2384: unless ($tempkey =~ /\./) {
2385: $r->print('<option value="'.$tempkey.'"');
2386: if ($$psprt[0] eq "all" || $temphash{$tempkey}) {
2387: $r->print(' selected="selected"');
2388: }
2389: $r->print('>'.$$allparts{$tempkey}.'</option>');
1.473 amueller 2390: }
1.208 www 2391: }
1.446 bisitz 2392: $r->print('</select>');
1.209 www 2393: }
2394:
1.562 damieng 2395: # Prints HTML to select a user and/or a group.
2396: # Used by table mode.
2397: #
2398: # @param {Apache2::RequestRec} $r - the Apache request
2399: # @param {string} $uname - selected user name
2400: # @param {string} $id - selected Student/Employee ID
2401: # @param {string} $udom - selected user domain
2402: # @param {string} $csec - selected section name
2403: # @param {string} $cgroup - selected group name
2404: # @param {string} $parmlev - parameter level (Resource:'full', Map:'map', Course:'general')
2405: # @param {array reference} $usersgroups - list of groups the user belongs to, if any
2406: # @param {string} $pssymb - resource symb (when a single resource is selected)
1.209 www 2407: sub usermenu {
1.553 raeburn 2408: my ($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,$usersgroups,$pssymb)=@_;
1.209 www 2409: my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '.
2410: &Apache::loncommon::selectstudent_link('parmform','uname','udom');
2411: my $selscript=&Apache::loncommon::studentbrowser_javascript();
1.412 bisitz 2412:
1.209 www 2413: my $sections='';
1.300 albertel 2414: my %sectionhash = &Apache::loncommon::get_sections();
2415:
1.269 raeburn 2416: my $groups;
1.553 raeburn 2417: my %grouphash;
2418: if (($pssymb) || &Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
2419: %grouphash = &Apache::longroup::coursegroups();
2420: } elsif ($env{'request.course.groups'} ne '') {
1.585 raeburn 2421: map { $grouphash{$_} = 1; } split(/:/,$env{'request.course.groups'});
1.553 raeburn 2422: }
1.299 albertel 2423:
1.412 bisitz 2424: my $g_s_header='';
2425: my $g_s_footer='';
1.446 bisitz 2426:
1.552 raeburn 2427: my $currsec = $env{'request.course.sec'};
2428: if ($currsec) {
2429: $sections=&mt('Section:').' '.$currsec;
2430: if (%grouphash) {
2431: $sections .= ';'.(' ' x2);
2432: }
2433: } elsif (%sectionhash && $currsec eq '') {
1.412 bisitz 2434: $sections=&mt('Section:').' <select name="csec"';
1.299 albertel 2435: if (%grouphash && $parmlev ne 'full') {
1.269 raeburn 2436: $sections .= qq| onchange="group_or_section('csec')" |;
2437: }
2438: $sections .= '>';
1.548 raeburn 2439: foreach my $section ('',sort(keys(%sectionhash))) {
1.473 amueller 2440: $sections.='<option value="'.$section.'" '.
2441: ($section eq $csec?'selected="selected"':'').'>'.$section.
1.275 raeburn 2442: '</option>';
1.209 www 2443: }
2444: $sections.='</select>';
1.269 raeburn 2445: }
1.412 bisitz 2446:
1.552 raeburn 2447: if (%sectionhash && %grouphash && $parmlev ne 'full' && $currsec eq '') {
1.412 bisitz 2448: $sections .= ' '.&mt('or').' ';
1.269 raeburn 2449: $sections .= qq|
2450: <script type="text/javascript">
1.454 bisitz 2451: // <![CDATA[
1.269 raeburn 2452: function group_or_section(caller) {
2453: if (caller == "cgroup") {
2454: if (document.parmform.cgroup.selectedIndex != 0) {
2455: document.parmform.csec.selectedIndex = 0;
2456: }
2457: } else {
2458: if (document.parmform.csec.selectedIndex != 0) {
2459: document.parmform.cgroup.selectedIndex = 0;
2460: }
2461: }
2462: }
1.454 bisitz 2463: // ]]>
1.269 raeburn 2464: </script>
2465: |;
1.554 raeburn 2466: } else {
1.269 raeburn 2467: $sections .= qq|
2468: <script type="text/javascript">
1.454 bisitz 2469: // <![CDATA[
1.269 raeburn 2470: function group_or_section(caller) {
2471: return;
2472: }
1.454 bisitz 2473: // ]]>
1.269 raeburn 2474: </script>
2475: |;
1.446 bisitz 2476: }
1.299 albertel 2477:
2478: if (%grouphash) {
1.412 bisitz 2479: $groups=&mt('Group:').' <select name="cgroup"';
1.552 raeburn 2480: if (%sectionhash && $env{'form.action'} eq 'settable' && $currsec eq '') {
1.269 raeburn 2481: $groups .= qq| onchange="group_or_section('cgroup')" |;
2482: }
2483: $groups .= '>';
1.548 raeburn 2484: foreach my $grp ('',sort(keys(%grouphash))) {
1.275 raeburn 2485: $groups.='<option value="'.$grp.'" ';
2486: if ($grp eq $cgroup) {
2487: unless ((defined($uname)) && ($grp eq '')) {
2488: $groups .= 'selected="selected" ';
2489: }
2490: } elsif (!defined($cgroup)) {
2491: if (@{$usersgroups} == 1) {
2492: if ($grp eq $$usersgroups[0]) {
2493: $groups .= 'selected="selected" ';
2494: }
2495: }
2496: }
2497: $groups .= '>'.$grp.'</option>';
1.269 raeburn 2498: }
2499: $groups.='</select>';
2500: }
1.412 bisitz 2501:
1.445 neumanie 2502: if (%sectionhash || %grouphash) {
1.446 bisitz 2503: $r->print(&Apache::lonhtmlcommon::row_title(&mt('Group/Section')));
2504: $r->print($sections.$groups);
1.448 bisitz 2505: $r->print(&Apache::lonhtmlcommon::row_closure());
1.554 raeburn 2506: } else {
2507: $r->print($sections);
1.445 neumanie 2508: }
1.446 bisitz 2509:
2510: $r->print(&Apache::lonhtmlcommon::row_title(&mt('User')));
1.443 neumanie 2511: $r->print(&mt('For User [_1] or Student/Employee ID [_2] at Domain [_3]'
1.412 bisitz 2512: ,'<input type="text" value="'.$uname.'" size="12" name="uname" />'
2513: ,'<input type="text" value="'.$id.'" size="12" name="id" /> '
1.446 bisitz 2514: ,$chooseopt));
1.209 www 2515: }
2516:
1.562 damieng 2517: # Prints HTML to select parameters from a list of all parameters.
2518: # Uses parmmenu and parmboxes.
2519: # Used by table and overview modes.
1.468 amueller 2520: #
1.562 damieng 2521: # @param {Apache2::RequestRec} $r - the Apache request
2522: # @param {hash reference} $allparms - hash parameter name -> parameter title
2523: # @param {array reference} $pscat - list of selected parameter names
2524: # @param {hash reference} $keyorder - hash parameter key -> appearance rank
2525: # @param {string} [$divid] - name used to give an id to the HTML element for the scroll box
1.209 www 2526: sub displaymenu {
1.581 raeburn 2527: my ($r,$allparms,$pscat,$keyorder,$divid)=@_;
1.510 www 2528:
1.445 neumanie 2529: $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.510 www 2530: $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parameters to View')));
2531:
1.581 raeburn 2532: &parmmenu($r);
1.536 raeburn 2533: $r->print(&Apache::loncommon::start_scrollbox('480px','440px','200px',$divid));
1.510 www 2534: &parmboxes($r,$allparms,$pscat,$keyorder);
2535: $r->print(&Apache::loncommon::end_scrollbox());
2536:
2537: $r->print(&Apache::lonhtmlcommon::row_closure(1));
1.453 schualex 2538: $r->print(&Apache::lonhtmlcommon::end_pick_box());
1.510 www 2539:
1.209 www 2540: }
2541:
1.562 damieng 2542: # Prints HTML to select a map.
2543: # Used by table mode and overview mode.
2544: #
2545: # @param {Apache2::RequestRec} $r - the Apache request
1.566 damieng 2546: # @param {hash reference} $allmaps - hash map pc -> map src
2547: # @param {string} $pschp - selected map pc, or 'all'
1.562 damieng 2548: # @param {hash reference} $maptitles - hash map id or src -> map title
1.566 damieng 2549: # @param {hash reference} $symbp - hash map pc or resource/map id -> map src.'___(all)' or resource symb
1.445 neumanie 2550: sub mapmenu {
1.499 raeburn 2551: my ($r,$allmaps,$pschp,$maptitles,$symbp)=@_;
1.468 amueller 2552: my %allmaps_inverted = reverse %$allmaps;
1.461 neumanie 2553: my $navmap = Apache::lonnavmaps::navmap->new();
2554: my $tree=[];
2555: my $treeinfo={};
2556: if (defined($navmap)) {
1.499 raeburn 2557: my $it=$navmap->getIterator(undef,undef,undef,1,1,undef);
1.461 neumanie 2558: my $curRes;
2559: my $depth = 0;
1.468 amueller 2560: my %parent = ();
2561: my $startcount = 5;
2562: my $lastcontainer = $startcount;
2563: # preparing what is to show ...
1.461 neumanie 2564: while ($curRes = $it->next()) {
2565: if ($curRes == $it->BEGIN_MAP()) {
2566: $depth++;
1.468 amueller 2567: $parent{$depth}= $lastcontainer;
1.461 neumanie 2568: }
2569: if ($curRes == $it->END_MAP()) {
2570: $depth--;
1.468 amueller 2571: $lastcontainer = $parent{$depth};
1.461 neumanie 2572: }
2573: if (ref($curRes)) {
1.468 amueller 2574: my $symb = $curRes->symb();
2575: my $ressymb = $symb;
1.461 neumanie 2576: if (($curRes->is_sequence()) || ($curRes->is_page())) {
2577: my $type = 'sequence';
2578: if ($curRes->is_page()) {
2579: $type = 'page';
2580: }
2581: my $id= $curRes->id();
1.468 amueller 2582: my $srcf = $curRes->src();
2583: my $resource_name = &Apache::lonnet::gettitle($srcf);
2584: if(!exists($treeinfo->{$id})) {
2585: push(@$tree,$id);
1.473 amueller 2586: my $enclosing_map_folder = &Apache::lonnet::declutter($curRes->enclosing_map_src());
1.468 amueller 2587: $treeinfo->{$id} = {
1.461 neumanie 2588: depth => $depth,
2589: type => $type,
1.468 amueller 2590: name => $resource_name,
2591: enclosing_map_folder => $enclosing_map_folder,
1.461 neumanie 2592: };
1.462 neumanie 2593: }
1.461 neumanie 2594: }
2595: }
2596: }
1.462 neumanie 2597: }
1.473 amueller 2598: # Show it ...
1.484 amueller 2599: $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Enclosing Map or Folder'),'','',' id="mapmenu"'));
1.461 neumanie 2600: if ((ref($tree) eq 'ARRAY') && (ref($treeinfo) eq 'HASH')) {
2601: my $icon = '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" />';
1.497 bisitz 2602: my $whitespace =
2603: '<img src="'
2604: .&Apache::loncommon::lonhttpdurl('/adm/lonIcons/whitespace_21.gif')
2605: .'" alt="" />';
2606:
1.498 bisitz 2607: # Info about selectable folders/maps
2608: $r->print(
2609: '<div class="LC_info">'
1.508 www 2610: .&mt('You can only select maps and folders which have modifiable settings.')
2611: .' '.&Apache::loncommon::help_open_topic('Parameter_Set_Folder')
1.498 bisitz 2612: .'</div>'
2613: );
2614:
1.536 raeburn 2615: $r->print(&Apache::loncommon::start_scrollbox('700px','680px','400px','mapmenuscroll'));
1.523 raeburn 2616: $r->print(&Apache::loncommon::start_data_table(undef,'mapmenuinner'));
1.497 bisitz 2617:
1.498 bisitz 2618: # Display row: "All Maps or Folders"
2619: $r->print(
1.523 raeburn 2620: &Apache::loncommon::start_data_table_row(undef,'picklevel')
1.498 bisitz 2621: .'<td>'
2622: .'<label>'
2623: .'<input type="radio" name="pschp"'
1.497 bisitz 2624: );
2625: $r->print(' checked="checked"') if ($pschp eq 'all' || !$pschp);
1.498 bisitz 2626: $r->print(
2627: ' value="all" /> '.$icon.' '
2628: .&mt('All Maps or Folders')
2629: .'</label>'
2630: .'<hr /></td>'
2631: .&Apache::loncommon::end_data_table_row()
1.463 bisitz 2632: );
1.497 bisitz 2633:
1.532 raeburn 2634: # Display row: "Main Content"
1.468 amueller 2635: if (exists($$allmaps{1})) {
1.498 bisitz 2636: $r->print(
2637: &Apache::loncommon::start_data_table_row()
2638: .'<td>'
2639: .'<label>'
2640: .'<input type="radio" name="pschp" value="1"'
1.468 amueller 2641: );
1.497 bisitz 2642: $r->print(' checked="checked"') if ($pschp eq '1');
1.498 bisitz 2643: $r->print(
2644: '/> '.$icon.' '
2645: .$$maptitles{1}
2646: .($$allmaps{1} !~/^uploaded/?' ['.$$allmaps{1}.']':'')
2647: .'</label>'
2648: .'</td>'
2649: .&Apache::loncommon::end_data_table_row()
1.468 amueller 2650: );
2651: }
1.497 bisitz 2652:
2653: # Display rows for all course maps and folders
1.468 amueller 2654: foreach my $id (@{$tree}) {
2655: my ($mapid,$resid)=split(/\./,$id);
1.464 bisitz 2656: # Indentation
1.468 amueller 2657: my $depth = $treeinfo->{$id}->{'depth'};
1.464 bisitz 2658: my $indent;
2659: for (my $i = 0; $i < $depth; $i++) {
2660: $indent.= $whitespace;
2661: }
1.461 neumanie 2662: $icon = '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" />';
1.468 amueller 2663: if ($treeinfo->{$id}->{'type'} eq 'page') {
1.461 neumanie 2664: $icon = '<img src="/adm/lonIcons/navmap.page.open.gif" alt="" />';
2665: }
1.468 amueller 2666: my $symb_name = $$symbp{$id};
2667: my ($front, $tail) = split (/___${resid}___/, $symb_name);
2668: $symb_name = $tail;
1.498 bisitz 2669: $r->print(
2670: &Apache::loncommon::start_data_table_row()
2671: .'<td>'
2672: .'<label>'
1.463 bisitz 2673: );
1.498 bisitz 2674: # Only offer radio button for folders/maps which can be parameterized
2675: if ($allmaps_inverted{$symb_name}) {
2676: $r->print(
2677: '<input type ="radio" name="pschp"'
2678: .' value="'.$allmaps_inverted{$symb_name}.'"'
2679: );
2680: $r->print(' checked="checked"') if ($allmaps_inverted{$symb_name} eq $pschp);
2681: $r->print('/>');
2682: } else {
2683: $r->print($whitespace);
1.461 neumanie 2684: }
1.498 bisitz 2685: $r->print(
2686: $indent.$icon.' '
2687: .$treeinfo->{$id}->{name}
2688: .($$allmaps{$mapid}!~/^uploaded/?' ['.$$allmaps{$mapid}.']':'')
2689: .'</label>'
2690: .'</td>'
2691: .&Apache::loncommon::end_data_table_row()
1.463 bisitz 2692: );
1.461 neumanie 2693: }
1.497 bisitz 2694:
1.523 raeburn 2695: $r->print(&Apache::loncommon::end_data_table().
2696: '<br style="line-height:2px;" />'.
2697: &Apache::loncommon::end_scrollbox());
1.209 www 2698: }
2699: }
2700:
1.563 damieng 2701: # Prints HTML to select the parameter level (resource, map/folder or course).
2702: # Used by table and overview modes.
2703: #
2704: # @param {Apache2::RequestRec} $r - the Apache request
2705: # @param {hash reference} $alllevs - all parameter levels, hash English title -> value
2706: # @param {string} $parmlev - selected level value (full|map|general), or ''
1.209 www 2707: sub levelmenu {
1.446 bisitz 2708: my ($r,$alllevs,$parmlev)=@_;
2709:
1.548 raeburn 2710: $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parameter Level').
2711: &Apache::loncommon::help_open_topic('Course_Parameter_Levels')));
1.474 amueller 2712: $r->print('<select id="parmlev" name="parmlev" onchange="showHide_courseContent()">');
1.548 raeburn 2713: foreach my $lev (reverse(sort(keys(%{$alllevs})))) {
2714: $r->print('<option value="'.$$alllevs{$lev}.'"');
2715: if ($parmlev eq $$alllevs{$lev}) {
2716: $r->print(' selected="selected"');
2717: }
2718: $r->print('>'.&mt($lev).'</option>');
1.208 www 2719: }
1.446 bisitz 2720: $r->print("</select>");
1.208 www 2721: }
2722:
1.211 www 2723:
1.563 damieng 2724: # Returns HTML to select a section (with a select HTML element).
2725: # Used by overview mode.
2726: #
2727: # @param {array reference} $selectedsections - list of selected section ids
2728: # @returns {string}
1.211 www 2729: sub sectionmenu {
1.553 raeburn 2730: my ($selectedsections)=@_;
1.300 albertel 2731: my %sectionhash = &Apache::loncommon::get_sections();
1.553 raeburn 2732: return '' if (!%sectionhash);
1.300 albertel 2733:
1.552 raeburn 2734: my (@possibles,$disabled);
2735: if ($env{'request.course.sec'} ne '') {
2736: @possibles = ($env{'request.course.sec'});
2737: $selectedsections = [$env{'request.course.sec'}];
2738: $disabled = ' disabled="disabled"';
2739: } else {
2740: @possibles = ('all',sort(keys(%sectionhash)));
2741: }
1.553 raeburn 2742: my $output = '<select name="Section" multiple="multiple" size="8"'.$disabled.'>';
1.552 raeburn 2743: foreach my $s (@possibles) {
1.553 raeburn 2744: $output .= ' <option value="'.$s.'"';
2745: if ((@{$selectedsections}) && (grep(/^\Q$s\E$/,@{$selectedsections}))) {
2746: $output .= ' selected="selected"';
1.473 amueller 2747: }
1.553 raeburn 2748: $output .= '>'."$s</option>\n";
1.300 albertel 2749: }
1.553 raeburn 2750: $output .= "</select>\n";
2751: return $output;
1.269 raeburn 2752: }
2753:
1.563 damieng 2754: # Returns HTML to select a group (with a select HTML element).
2755: # Used by overview mode.
2756: #
2757: # @param {array reference} $selectedgroups - list of selected group names
2758: # @returns {string}
1.269 raeburn 2759: sub groupmenu {
1.553 raeburn 2760: my ($selectedgroups)=@_;
2761: my %grouphash;
2762: if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
2763: %grouphash = &Apache::longroup::coursegroups();
2764: } elsif ($env{'request.course.groups'} ne '') {
1.585 raeburn 2765: map { $grouphash{$_} = 1; } split(/:/,$env{'request.course.groups'});
1.553 raeburn 2766: }
2767: return '' if (!%grouphash);
1.299 albertel 2768:
1.553 raeburn 2769: my $output = '<select name="Group" multiple="multiple" size="8">';
1.299 albertel 2770: foreach my $group (sort(keys(%grouphash))) {
1.553 raeburn 2771: $output .= ' <option value="'.$group.'"';
2772: if ((@{$selectedgroups}) && (grep(/^\Q$group\E$/,\@{$selectedgroups}))) {
2773: $output .= ' selected="selected"';
1.473 amueller 2774: }
1.553 raeburn 2775: $output .= '>'."$group</option>\n";
1.211 www 2776: }
1.553 raeburn 2777: $output .= "</select>\n";
2778: return $output;
1.211 www 2779: }
2780:
1.563 damieng 2781: # Returns an array with the given parameter split by comma.
2782: # Used by assessparms (table mode).
2783: #
2784: # @param {string} $keyp - the string to split
2785: # @returns {Array<string>}
1.210 www 2786: sub keysplit {
2787: my $keyp=shift;
2788: return (split(/\,/,$keyp));
2789: }
2790:
1.563 damieng 2791: # Returns the keys in $name, sorted using $keyorder.
2792: # Parameters are sorted by key, which means they are sorted by part first, then by name.
2793: # Used by assessparms (table mode) for resource level.
2794: #
2795: # @param {hash reference} $name - parameter key -> parameter name
2796: # @param {hash reference} $keyorder - hash parameter key -> appearance rank
2797: # @returns {Array<string>}
1.210 www 2798: sub keysinorder {
2799: my ($name,$keyorder)=@_;
2800: return sort {
1.560 damieng 2801: $$keyorder{$a} <=> $$keyorder{$b};
1.548 raeburn 2802: } (keys(%{$name}));
1.210 www 2803: }
2804:
1.563 damieng 2805: # Returns the keys in $name, sorted using $keyorder to sort parameters by name first, then by part.
2806: # Used by assessparms (table mode) for map and general levels.
2807: #
2808: # @param {hash reference} $name - parameter key -> parameter name
2809: # @param {hash reference} $keyorder - hash parameter key -> appearance rank
2810: # @returns {Array<string>}
1.236 albertel 2811: sub keysinorder_bytype {
2812: my ($name,$keyorder)=@_;
2813: return sort {
1.563 damieng 2814: my $ta=(split('_',$a))[-1]; # parameter name
1.560 damieng 2815: my $tb=(split('_',$b))[-1];
2816: if ($$keyorder{'parameter_0_'.$ta} == $$keyorder{'parameter_0_'.$tb}) {
2817: return ($a cmp $b);
2818: }
2819: $$keyorder{'parameter_0_'.$ta} <=> $$keyorder{'parameter_0_'.$tb};
1.548 raeburn 2820: } (keys(%{$name}));
1.236 albertel 2821: }
2822:
1.563 damieng 2823: # Returns the keys in $name, sorted using $keyorder to sort parameters by name.
2824: # Used by defaultsetter (parameter settings default actions).
2825: #
2826: # @param {hash reference} $name - hash parameter name -> parameter title
2827: # @param {hash reference} $keyorder - hash parameter key -> appearance rank
2828: # @returns {Array<string>}
1.211 www 2829: sub keysindisplayorder {
2830: my ($name,$keyorder)=@_;
2831: return sort {
1.560 damieng 2832: $$keyorder{'parameter_0_'.$a} <=> $$keyorder{'parameter_0_'.$b};
1.548 raeburn 2833: } (keys(%{$name}));
1.211 www 2834: }
2835:
1.563 damieng 2836: # Prints HTML with a choice to sort results by realm or student first.
2837: # Used by overview mode.
2838: #
2839: # @param {Apache2::RequestRec} $r - the Apache request
2840: # @param {string} $sortorder - realmstudent|studentrealm
1.214 www 2841: sub sortmenu {
2842: my ($r,$sortorder)=@_;
1.236 albertel 2843: $r->print('<br /><label><input type="radio" name="sortorder" value="realmstudent"');
1.214 www 2844: if ($sortorder eq 'realmstudent') {
1.422 bisitz 2845: $r->print(' checked="checked"');
1.214 www 2846: }
2847: $r->print(' />'.&mt('Sort by realm first, then student (group/section)'));
1.236 albertel 2848: $r->print('</label><br /><label><input type="radio" name="sortorder" value="studentrealm"');
1.214 www 2849: if ($sortorder eq 'studentrealm') {
1.422 bisitz 2850: $r->print(' checked="checked"');
1.214 www 2851: }
1.236 albertel 2852: $r->print(' />'.&mt('Sort by student (group/section) first, then realm').
1.473 amueller 2853: '</label>');
1.214 www 2854: }
2855:
1.563 damieng 2856: # Returns a hash parameter key -> order (integer) giving the order for some parameters.
2857: #
2858: # @returns {hash}
1.211 www 2859: sub standardkeyorder {
2860: return ('parameter_0_opendate' => 1,
1.473 amueller 2861: 'parameter_0_duedate' => 2,
2862: 'parameter_0_answerdate' => 3,
2863: 'parameter_0_interval' => 4,
2864: 'parameter_0_weight' => 5,
2865: 'parameter_0_maxtries' => 6,
2866: 'parameter_0_hinttries' => 7,
2867: 'parameter_0_contentopen' => 8,
2868: 'parameter_0_contentclose' => 9,
2869: 'parameter_0_type' => 10,
2870: 'parameter_0_problemstatus' => 11,
2871: 'parameter_0_hiddenresource' => 12,
2872: 'parameter_0_hiddenparts' => 13,
2873: 'parameter_0_display' => 14,
2874: 'parameter_0_ordered' => 15,
2875: 'parameter_0_tol' => 16,
2876: 'parameter_0_sig' => 17,
2877: 'parameter_0_turnoffunit' => 18,
1.521 raeburn 2878: 'parameter_0_discussend' => 19,
2879: 'parameter_0_discusshide' => 20,
2880: 'parameter_0_discussvote' => 21,
1.560 damieng 2881: 'parameter_0_printstartdate' => 22,
2882: 'parameter_0_printenddate' => 23);
1.211 www 2883: }
2884:
1.59 matthew 2885:
1.560 damieng 2886: # Table mode UI.
1.563 damieng 2887: # If nothing is selected, prints HTML forms to select resources, parts, parameters, user, group and section.
2888: # Otherwise, prints the parameter table, with a link to change the selection unless a single resource is selected.
2889: #
2890: # Parameters used from the request:
2891: # action - handler action (see handler), usermenu is checking for value 'settable'
2892: # cgroup - selected group
2893: # command - 'set': direct access to table mode for a resource
2894: # csec - selected section
2895: # dis - set when the "Update Display" button was used, used only to discard command 'set'
2896: # hideparmsel - can be 'hidden' to hide the parameter selection div initially and display the "Change Parameter Selection" link instead (which displays the div)
2897: # id - student/employee ID
2898: # parmlev - selected level (full|map|general)
2899: # part - selected part (unused ?)
2900: # pres_marker - &&&-separated parameter identifiers, "resource id&part_parameter name&level"
2901: # pres_type - &&&-separated parameter types
2902: # pres_value - &&&-separated parameter values
2903: # prevvisit - '1' if the user has submitted the form before
2904: # pscat (multiple values) - selected parameter names
1.566 damieng 2905: # pschp - selected map pc, or 'all'
1.563 damieng 2906: # psprt (multiple values) - list of selected parameter parts
2907: # filter - part of or whole parameter name, to be filtered out when parameters are displayed (unused ?)
2908: # recent_* (* = parameter type) - recent values entered by the user for parameter types
2909: # symb - resource symb (when a single resource is selected)
2910: # udom - selected user domain
2911: # uname - selected user name
2912: # url - used only with command 'set', the resource url
2913: #
2914: # @param {Apache2::RequestRec} $r - the Apache request
1.568 raeburn 2915: # @param $parm_permission - ref to hash of permissions
2916: # if $parm_permission->{'edit'} is true, editing is allowed.
1.30 www 2917: sub assessparms {
1.1 www 2918:
1.568 raeburn 2919: my ($r,$parm_permission) = @_;
1.201 www 2920:
1.512 foxr 2921:
2922: # -------------------------------------------------------- Variable declaration
1.566 damieng 2923: my @ids=(); # resource and map ids
2924: my %symbp=(); # hash map pc or resource/map id -> map src.'___(all)' or resource symb
2925: my %mapp=(); # hash map pc or resource/map id -> enclosing map src
2926: my %typep=(); # hash resource/map id -> resource type (file extension)
2927: my %keyp=(); # hash resource/map id -> comma-separated list of parameter keys
2928: my %uris=(); # hash resource/map id -> resource src
2929: my %maptitles=(); # hash map pc or src -> map title
2930: my %allmaps=(); # hash map pc -> map src
1.582 raeburn 2931: my %allmaps_inverted=(); # hash map src -> map pc
1.563 damieng 2932: my %alllevs=(); # hash English level title -> value
2933:
2934: my $uname; # selected user name
2935: my $udom; # selected user domain
2936: my $uhome; # server with the user's files, or 'no_host'
2937: my $csec; # selected section name
2938: my $cgroup; # selected group name
2939: my @usersgroups = (); # list of the user groups
1.582 raeburn 2940: my $numreclinks = 0;
1.446 bisitz 2941:
1.190 albertel 2942: my $coursename=$env{'course.'.$env{'request.course.id'}.'.description'};
1.187 www 2943:
1.57 albertel 2944: $alllevs{'Resource Level'}='full';
1.215 www 2945: $alllevs{'Map/Folder Level'}='map';
1.57 albertel 2946: $alllevs{'Course Level'}='general';
2947:
1.563 damieng 2948: my %allparms; # hash parameter name -> parameter title
2949: my %allparts; # hash parameter part -> part title
1.512 foxr 2950: # ------------------------------------------------------------------------------
2951:
1.210 www 2952: #
2953: # Order in which these parameters will be displayed
2954: #
1.211 www 2955: my %keyorder=&standardkeyorder();
2956:
1.512 foxr 2957: # @ids=();
2958: # %symbp=(); # These seem defined above already.
2959: # %typep=();
1.43 albertel 2960:
2961: my $message='';
2962:
1.190 albertel 2963: $csec=$env{'form.csec'};
1.552 raeburn 2964: if ($env{'request.course.sec'} ne '') {
2965: $csec = $env{'request.course.sec'};
2966: }
2967:
1.553 raeburn 2968: # Check group privs.
1.269 raeburn 2969: $cgroup=$env{'form.cgroup'};
1.553 raeburn 2970: my $noeditgrp;
2971: if ($cgroup ne '') {
2972: unless (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
2973: if (($env{'request.course.groups'} eq '') ||
1.585 raeburn 2974: (!grep(/^\Q$cgroup\E$/,split(/:/,$env{'request.course.groups'})))) {
1.553 raeburn 2975: $noeditgrp = 1;
2976: }
2977: }
2978: }
1.188 www 2979:
1.190 albertel 2980: if ($udom=$env{'form.udom'}) {
2981: } elsif ($udom=$env{'request.role.domain'}) {
2982: } elsif ($udom=$env{'user.domain'}) {
1.172 albertel 2983: } else {
1.473 amueller 2984: $udom=$r->dir_config('lonDefDomain');
1.172 albertel 2985: }
1.468 amueller 2986:
1.43 albertel 2987:
1.134 albertel 2988: my @pscat=&Apache::loncommon::get_env_multiple('form.pscat');
1.190 albertel 2989: my $pschp=$env{'form.pschp'};
1.506 www 2990:
2991:
1.134 albertel 2992: my @psprt=&Apache::loncommon::get_env_multiple('form.psprt');
1.516 www 2993: if (!@psprt) { $psprt[0]='all'; }
1.506 www 2994: if (($env{'form.part'}) && ($psprt[0] ne 'all')) { $psprt[0]=$env{'form.part'}; }
1.57 albertel 2995:
1.43 albertel 2996: my $pssymb='';
1.57 albertel 2997: my $parmlev='';
1.446 bisitz 2998:
1.190 albertel 2999: unless ($env{'form.parmlev'}) {
1.57 albertel 3000: $parmlev = 'map';
3001: } else {
1.190 albertel 3002: $parmlev = $env{'form.parmlev'};
1.57 albertel 3003: }
1.26 www 3004:
1.29 www 3005: # ----------------------------------------------- Was this started from grades?
3006:
1.560 damieng 3007: if (($env{'form.command'} eq 'set') && ($env{'form.url'}) &&
3008: (!$env{'form.dis'})) {
1.473 amueller 3009: my $url=$env{'form.url'};
3010: $url=~s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
3011: $pssymb=&Apache::lonnet::symbread($url);
3012: if (!@pscat) { @pscat=('all'); }
3013: $pschp='';
1.57 albertel 3014: $parmlev = 'full';
1.190 albertel 3015: } elsif ($env{'form.symb'}) {
1.473 amueller 3016: $pssymb=$env{'form.symb'};
3017: if (!@pscat) { @pscat=('all'); }
3018: $pschp='';
1.57 albertel 3019: $parmlev = 'full';
1.43 albertel 3020: } else {
1.473 amueller 3021: $env{'form.url'}='';
1.43 albertel 3022: }
3023:
1.190 albertel 3024: my $id=$env{'form.id'};
1.43 albertel 3025: if (($id) && ($udom)) {
1.555 raeburn 3026: $uname=(&Apache::lonnet::idget($udom,[$id],'ids'))[1];
1.473 amueller 3027: if ($uname) {
3028: $id='';
3029: } else {
3030: $message=
1.540 bisitz 3031: '<p class="LC_warning">'.
3032: &mt('Unknown ID [_1] at domain [_2]',
3033: "'".$id."'","'".$udom."'").
3034: '</p>';
1.473 amueller 3035: }
1.43 albertel 3036: } else {
1.473 amueller 3037: $uname=$env{'form.uname'};
1.43 albertel 3038: }
3039: unless ($udom) { $uname=''; }
3040: $uhome='';
3041: if ($uname) {
1.473 amueller 3042: $uhome=&Apache::lonnet::homeserver($uname,$udom);
1.43 albertel 3043: if ($uhome eq 'no_host') {
1.473 amueller 3044: $message=
1.540 bisitz 3045: '<p class="LC_warning">'.
3046: &mt('Unknown user [_1] at domain [_2]',
3047: "'".$uname."'","'".$udom."'").
3048: '</p>';
1.473 amueller 3049: $uname='';
1.12 www 3050: } else {
1.473 amueller 3051: $csec=&Apache::lonnet::getsection($udom,$uname,
3052: $env{'request.course.id'});
3053: if ($csec eq '-1') {
1.540 bisitz 3054: $message=
3055: '<p class="LC_warning">'.
3056: &mt('User [_1] at domain [_2] not in this course',
3057: "'".$uname."'","'".$udom."'").
3058: '</p>';
1.473 amueller 3059: $uname='';
3060: $csec=$env{'form.csec'};
1.269 raeburn 3061: $cgroup=$env{'form.cgroup'};
1.473 amueller 3062: } else {
3063: my %name=&Apache::lonnet::userenvironment($udom,$uname,
3064: ('firstname','middlename','lastname','generation','id'));
3065: $message="\n<p>\n".&mt("Full Name").": ".
3066: $name{'firstname'}.' '.$name{'middlename'}.' '
3067: .$name{'lastname'}.' '.$name{'generation'}.
1.501 bisitz 3068: "<br />\n".&mt('Student/Employee ID').": ".$name{'id'}.'<p>';
1.473 amueller 3069: }
1.297 raeburn 3070: @usersgroups = &Apache::lonnet::get_users_groups(
1.275 raeburn 3071: $udom,$uname,$env{'request.course.id'});
1.297 raeburn 3072: if (@usersgroups > 0) {
1.306 albertel 3073: unless (grep(/^\Q$cgroup\E$/,@usersgroups)) {
1.275 raeburn 3074: $cgroup = $usersgroups[0];
1.297 raeburn 3075: }
1.269 raeburn 3076: }
1.12 www 3077: }
1.43 albertel 3078: }
1.2 www 3079:
1.43 albertel 3080: unless ($csec) { $csec=''; }
1.269 raeburn 3081: unless ($cgroup) { $cgroup=''; }
1.12 www 3082:
1.14 www 3083: # --------------------------------------------------------- Get all assessments
1.446 bisitz 3084: &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
1.473 amueller 3085: \%mapp, \%symbp,\%maptitles,\%uris,
3086: \%keyorder);
1.63 bowersj2 3087:
1.582 raeburn 3088: %allmaps_inverted = reverse(%allmaps);
3089:
1.57 albertel 3090: $mapp{'0.0'} = '';
3091: $symbp{'0.0'} = '';
1.99 albertel 3092:
1.14 www 3093: # ---------------------------------------------------------- Anything to store?
1.568 raeburn 3094: if ($env{'form.pres_marker'} && $parm_permission->{'edit'}) {
1.205 www 3095: my @markers=split(/\&\&\&/,$env{'form.pres_marker'});
3096: my @values=split(/\&\&\&/,$env{'form.pres_value'});
3097: my @types=split(/\&\&\&/,$env{'form.pres_type'});
1.500 raeburn 3098: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
3099: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.504 raeburn 3100: my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};
3101: my ($got_chostname,$chostname,$cmajor,$cminor);
3102: my $totalstored = 0;
1.546 raeburn 3103: my $now = time;
1.473 amueller 3104: for (my $i=0;$i<=$#markers;$i++) {
1.557 raeburn 3105: my ($needsrelease,$needsnewer,$name,$namematch);
1.556 raeburn 3106: if (($env{'request.course.sec'} ne '') && ($markers[$i] =~ /\&(9|10|11|12)$/)) {
1.552 raeburn 3107: next if ($csec ne $env{'request.course.sec'});
3108: }
1.556 raeburn 3109: if ($markers[$i] =~ /\&(8|7|6|5)$/) {
1.553 raeburn 3110: next if ($noeditgrp);
1.557 raeburn 3111: }
3112: if ($markers[$i] =~ /\&(17|11|7|3)$/) {
3113: $namematch = 'maplevelrecurse';
3114: }
1.556 raeburn 3115: if ($markers[$i] =~ /^[\d.]+\&0_availablestudent\&(1|2|3|4)$/) {
1.437 raeburn 3116: my (@ok_slots,@fail_slots,@del_slots);
3117: my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
3118: my ($level,@all) =
3119: &parmval_by_symb('0.availablestudent',$pssymb,'',$uname,$udom,
3120: $csec,$cgroup,$courseopt);
3121: foreach my $slot_name (split(/:/,$values[$i])) {
3122: next if ($slot_name eq '');
3123: if (&update_slots($slot_name,$cdom,$cnum,$pssymb,$uname,$udom) eq 'ok') {
3124: push(@ok_slots,$slot_name);
3125:
3126: } else {
3127: push(@fail_slots,$slot_name);
3128: }
3129: }
3130: if (@ok_slots) {
3131: $values[$i] = join(':',@ok_slots);
3132: } else {
3133: $values[$i] = '';
3134: }
3135: if ($all[$level] ne '') {
3136: my @existing = split(/:/,$all[$level]);
3137: foreach my $slot_name (@existing) {
3138: if (!grep(/^\Q$slot_name\E$/,split(/:/,$values[$i]))) {
3139: if (&delete_slots($slot_name,$cdom,$cnum,$uname,$udom,$pssymb) eq 'ok') {
3140: push(@del_slots,$slot_name);
3141: }
3142: }
3143: }
3144: }
1.554 raeburn 3145: } elsif ($markers[$i] =~ /_(type|lenient|retrypartial|discussvote|examcode|printstartdate|printenddate|acc|interval)\&\d+$/) {
1.514 raeburn 3146: $name = $1;
1.533 raeburn 3147: my $val = $values[$i];
1.549 raeburn 3148: my $valmatch = '';
1.533 raeburn 3149: if ($name eq 'examcode') {
1.544 raeburn 3150: if (&Apache::lonnet::validCODE($values[$i])) {
3151: $val = 'valid';
3152: }
1.546 raeburn 3153: } elsif ($name eq 'printstartdate') {
3154: if ($val =~ /^\d+$/) {
3155: if ($val > $now) {
3156: $val = 'future';
3157: }
3158: }
3159: } elsif ($name eq 'printenddate') {
3160: if ($val =~ /^\d+$/) {
3161: if ($val < $now) {
3162: $val = 'past';
3163: }
3164: }
1.549 raeburn 3165: } elsif (($name eq 'lenient') || ($name eq 'acc')) {
3166: my $stringtype = &get_stringtype($name);
3167: my $stringmatch = &standard_string_matches($stringtype);
3168: if (ref($stringmatch) eq 'ARRAY') {
3169: foreach my $item (@{$stringmatch}) {
3170: if (ref($item) eq 'ARRAY') {
3171: my ($regexpname,$pattern) = @{$item};
3172: if ($pattern ne '') {
3173: if ($val =~ /$pattern/) {
3174: $valmatch = $regexpname;
3175: $val = '';
3176: last;
3177: }
3178: }
3179: }
3180: }
3181: }
1.554 raeburn 3182: } elsif ($name eq 'interval') {
3183: my $intervaltype = &get_intervaltype($name);
3184: my $intervalmatch = &standard_interval_matches($intervaltype);
3185: if (ref($intervalmatch) eq 'ARRAY') {
3186: foreach my $item (@{$intervalmatch}) {
3187: if (ref($item) eq 'ARRAY') {
3188: my ($regexpname,$pattern) = @{$item};
3189: if ($pattern ne '') {
3190: if ($val =~ /$pattern/) {
3191: $valmatch = $regexpname;
3192: $val = '';
3193: last;
3194: }
3195: }
3196: }
3197: }
3198: }
1.533 raeburn 3199: }
1.504 raeburn 3200: $needsrelease =
1.557 raeburn 3201: $Apache::lonnet::needsrelease{"parameter:$name:$val:$valmatch:"};
1.504 raeburn 3202: if ($needsrelease) {
1.505 raeburn 3203: unless ($got_chostname) {
1.514 raeburn 3204: ($chostname,$cmajor,$cminor) = ¶meter_release_vars();
1.504 raeburn 3205: $got_chostname = 1;
1.546 raeburn 3206: }
1.557 raeburn 3207: $needsnewer = ¶meter_releasecheck($name,$val,$valmatch,undef,
1.514 raeburn 3208: $needsrelease,
3209: $cmajor,$cminor);
1.500 raeburn 3210: }
1.437 raeburn 3211: }
1.504 raeburn 3212: if ($needsnewer) {
1.557 raeburn 3213: undef($namematch);
3214: } else {
3215: my $currneeded;
3216: if ($needsrelease) {
3217: $currneeded = $needsrelease;
3218: }
3219: if ($namematch) {
3220: $needsrelease =
3221: $Apache::lonnet::needsrelease{"parameter::::$namematch"};
3222: if (($needsrelease) && (($currneeded eq '') || ($needsrelease < $currneeded))) {
3223: unless ($got_chostname) {
3224: ($chostname,$cmajor,$cminor) = ¶meter_release_vars();
3225: $got_chostname = 1;
3226: }
3227: $needsnewer = ¶meter_releasecheck(undef,undef,undef,$namematch,
3228: $needsrelease,
3229: $cmajor,$cminor);
3230: } else {
3231: undef($namematch);
3232: }
3233: }
3234: }
3235: if ($needsnewer) {
3236: $message .= &oldversion_warning($name,$namematch,$values[$i],$chostname,$cmajor,
1.504 raeburn 3237: $cminor,$needsrelease);
3238: } else {
3239: $message.=&storeparm(split(/\&/,$markers[$i]),
3240: $values[$i],
3241: $types[$i],
3242: $uname,$udom,$csec,$cgroup);
3243: $totalstored ++;
3244: }
1.473 amueller 3245: }
1.68 www 3246: # ---------------------------------------------------------------- Done storing
1.504 raeburn 3247: if ($totalstored) {
3248: $message.='<p class="LC_warning">'
3249: .&mt('Changes can take up to 10 minutes before being active for all students.')
3250: .&Apache::loncommon::help_open_topic('Caching')
3251: .'</p>';
3252: }
1.68 www 3253: }
1.584 raeburn 3254:
1.57 albertel 3255: #----------------------------------------------- if all selected, fill in array
1.563 damieng 3256: if ($pscat[0] eq "all") {
3257: @pscat = (keys(%allparms));
3258: }
3259: if (!@pscat) {
3260: @pscat=('duedate','opendate','answerdate','weight','maxtries','type','problemstatus')
3261: };
3262: if ($psprt[0] eq "all" || !@psprt) {
3263: @psprt = (keys(%allparts));
3264: }
1.2 www 3265: # ------------------------------------------------------------------ Start page
1.63 bowersj2 3266:
1.531 raeburn 3267: my $crstype = &Apache::loncommon::course_type();
3268: &startpage($r,$pssymb,$crstype);
1.57 albertel 3269:
1.548 raeburn 3270: foreach my $item ('tolerance','date_default','date_start','date_end',
1.563 damieng 3271: 'date_interval','int','float','string') {
1.473 amueller 3272: $r->print('<input type="hidden" value="'.
1.563 damieng 3273: &HTML::Entities::encode($env{'form.recent_'.$item},'"&<>').
3274: '" name="recent_'.$item.'" />');
1.44 albertel 3275: }
1.446 bisitz 3276:
1.459 bisitz 3277: # ----- Start Parameter Selection
3278:
3279: # Hide parm selection?
3280: $r->print(<<ENDPARMSELSCRIPT);
3281: <script type="text/javascript">
3282: // <![CDATA[
3283: function parmsel_show() {
1.562 damieng 3284: document.getElementById('parmsel').style.display = "";
3285: document.getElementById('parmsellink').style.display = "none";
1.459 bisitz 3286: }
3287: // ]]>
3288: </script>
3289: ENDPARMSELSCRIPT
1.474 amueller 3290:
1.445 neumanie 3291: if (!$pssymb) {
1.563 damieng 3292: # No single resource selected, print forms to select things (hidden after first selection)
1.486 www 3293: my $parmselhiddenstyle=' style="display:none"';
3294: if($env{'form.hideparmsel'} eq 'hidden') {
3295: $r->print('<div id="parmsel"'.$parmselhiddenstyle.'>');
3296: } else {
3297: $r->print('<div id="parmsel">');
3298: }
3299:
1.491 bisitz 3300: # Step 1
1.523 raeburn 3301: $r->print(&Apache::lonhtmlcommon::topic_bar(1,&mt('Resource Specification'),'parmstep1'));
3302: $r->print('
1.474 amueller 3303: <script type="text/javascript">
1.523 raeburn 3304: // <![CDATA['.
3305: &showhide_js().'
1.474 amueller 3306: // ]]>
3307: </script>
1.523 raeburn 3308: ');
3309: $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel'));
1.209 www 3310: &levelmenu($r,\%alllevs,$parmlev);
1.491 bisitz 3311: $r->print(&Apache::lonhtmlcommon::row_closure());
1.474 amueller 3312: &mapmenu($r,\%allmaps,$pschp,\%maptitles, \%symbp);
1.491 bisitz 3313: $r->print(&Apache::lonhtmlcommon::row_closure());
3314: $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View')));
3315: &partmenu($r,\%allparts,\@psprt);
1.474 amueller 3316: $r->print(&Apache::lonhtmlcommon::row_closure(1));
3317: $r->print(&Apache::lonhtmlcommon::end_pick_box());
1.491 bisitz 3318:
3319: # Step 2
1.523 raeburn 3320: $r->print(&Apache::lonhtmlcommon::topic_bar(2,&mt('Parameter Specification'),'parmstep2'));
1.581 raeburn 3321: &displaymenu($r,\%allparms,\@pscat,\%keyorder,'parmmenuscroll');
1.491 bisitz 3322:
3323: # Step 3
1.523 raeburn 3324: $r->print(&Apache::lonhtmlcommon::topic_bar(3,&mt('User Specification (optional)'),'parmstep3'));
1.486 www 3325: $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.553 raeburn 3326: &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups,$pssymb);
1.486 www 3327: $r->print(&Apache::lonhtmlcommon::row_closure(1));
3328: $r->print(&Apache::lonhtmlcommon::end_pick_box());
1.491 bisitz 3329:
3330: # Update Display Button
1.486 www 3331: $r->print('<p>'
3332: .'<input type="submit" name="dis"'
1.511 www 3333: .' value="'.&mt('Update Display').'" />'
1.486 www 3334: .'<input type="hidden" name="hideparmsel" value="hidden" />'
3335: .'</p>');
3336: $r->print('</div>');
1.491 bisitz 3337:
1.486 www 3338: # Offer link to display parameter selection again
3339: $r->print('<p id="parmsellink"');
3340: if ($env{'form.hideparmsel'} ne 'hidden') {
3341: $r->print($parmselhiddenstyle);
3342: }
3343: $r->print('>'
3344: .'<a href="javascript:parmsel_show()">'
3345: .&mt('Change Parameter Selection')
3346: .'</a>'
3347: .'</p>');
1.44 albertel 3348: } else {
1.478 amueller 3349: # parameter screen for a single resource.
1.486 www 3350: my ($map,$iid,$resource)=&Apache::lonnet::decode_symb($pssymb);
1.473 amueller 3351: my $title = &Apache::lonnet::gettitle($pssymb);
1.501 bisitz 3352: $r->print(&mt('Specific Resource: [_1] ([_2])',
3353: $title,'<span class="LC_filename">'.$resource.'</span>').
1.472 amueller 3354: '<input type="hidden" value="'.$pssymb.'" name="symb" />'.
1.486 www 3355: '<br />');
3356: $r->print(&Apache::lonhtmlcommon::topic_bar('',&mt('Additional Display Specification (optional)')));
3357: $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.553 raeburn 3358: &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups,$pssymb);
1.486 www 3359: $r->print(&Apache::lonhtmlcommon::row_closure(1));
3360: $r->print(&Apache::lonhtmlcommon::end_pick_box());
3361: $r->print('<p>'
1.459 bisitz 3362: .'<input type="submit" name="dis"'
1.511 www 3363: .' value="'.&mt('Update Display').'" />'
1.459 bisitz 3364: .'<input type="hidden" name="hideparmsel" value="hidden" />'
1.486 www 3365: .'</p>');
1.459 bisitz 3366: }
1.478 amueller 3367:
1.486 www 3368: # ----- End Parameter Selection
1.57 albertel 3369:
1.459 bisitz 3370: # Display Messages
3371: $r->print('<div>'.$message.'</div>');
1.210 www 3372:
1.57 albertel 3373:
3374: my @temp_pscat;
3375: map {
3376: my $cat = $_;
3377: push(@temp_pscat, map { $_.'.'.$cat } @psprt);
3378: } @pscat;
3379:
3380: @pscat = @temp_pscat;
3381:
1.548 raeburn 3382:
1.209 www 3383: if (($env{'form.prevvisit'}) || ($pschp) || ($pssymb)) {
1.10 www 3384: # ----------------------------------------------------------------- Start Table
1.57 albertel 3385: my @catmarker=map { tr|.|_|; 'parameter_'.$_; } @pscat;
1.190 albertel 3386: my $csuname=$env{'user.name'};
3387: my $csudom=$env{'user.domain'};
1.568 raeburn 3388: my $readonly = 1;
3389: if ($parm_permission->{'edit'}) {
3390: undef($readonly);
3391: }
1.57 albertel 3392:
1.203 www 3393: if ($parmlev eq 'full') {
1.506 www 3394: #
3395: # This produces the cascading table output of parameters
3396: #
1.578 raeburn 3397: my $coursespan=$csec?8:5;
3398: my $userspan=3;
1.560 damieng 3399: if ($cgroup ne '') {
1.578 raeburn 3400: $coursespan += 3;
1.560 damieng 3401: }
1.473 amueller 3402:
1.560 damieng 3403: $r->print(&Apache::loncommon::start_data_table());
3404: #
3405: # This produces the headers
3406: #
3407: $r->print('<tr><td colspan="5"></td>');
3408: $r->print('<th colspan="'.($coursespan).'">'.&mt('Any User').'</th>');
3409: if ($uname) {
1.473 amueller 3410: if (@usersgroups > 1) {
1.560 damieng 3411: $userspan ++;
3412: }
3413: $r->print('<th colspan="'.$userspan.'" rowspan="2">');
3414: $r->print(&mt('User [_1] at Domain [_2]',"'".$uname."'","'".$udom."'").'</th>');
3415: }
3416: my %lt=&Apache::lonlocal::texthash(
1.473 amueller 3417: 'pie' => "Parameter in Effect",
3418: 'csv' => "Current Session Value",
1.472 amueller 3419: 'rl' => "Resource Level",
1.473 amueller 3420: 'ic' => 'in Course',
3421: 'aut' => "Assessment URL and Title",
3422: 'type' => 'Type',
3423: 'emof' => "Enclosing Map or Folder",
3424: 'part' => 'Part',
1.472 amueller 3425: 'pn' => 'Parameter Name',
1.473 amueller 3426: 'def' => 'default',
3427: 'femof' => 'from Enclosing Map or Folder',
3428: 'gen' => 'general',
3429: 'foremf' => 'for Enclosing Map or Folder',
3430: 'fr' => 'for Resource'
3431: );
1.560 damieng 3432: $r->print(<<ENDTABLETWO);
1.419 bisitz 3433: <th rowspan="3">$lt{'pie'}</th>
1.501 bisitz 3434: <th rowspan="3">$lt{'csv'}<br />($csuname:$csudom)</th>
1.578 raeburn 3435: </tr><tr><td colspan="5"></td><th colspan="2">$lt{'ic'}</th><th colspan="2">$lt{'rl'}</th>
1.419 bisitz 3436: <th colspan="1">$lt{'ic'}</th>
1.182 albertel 3437:
1.10 www 3438: ENDTABLETWO
1.560 damieng 3439: if ($csec) {
1.578 raeburn 3440: $r->print('<th colspan="3">'.
1.560 damieng 3441: &mt("in Section")." $csec</th>");
3442: }
3443: if ($cgroup) {
1.578 raeburn 3444: $r->print('<th colspan="3">'.
1.472 amueller 3445: &mt("in Group")." $cgroup</th>");
1.560 damieng 3446: }
3447: $r->print(<<ENDTABLEHEADFOUR);
1.133 www 3448: </tr><tr><th>$lt{'aut'}</th><th>$lt{'type'}</th>
3449: <th>$lt{'emof'}</th><th>$lt{'part'}</th><th>$lt{'pn'}</th>
1.578 raeburn 3450: <th>$lt{'gen'}</th><th>$lt{'foremf'}</th>
1.192 albertel 3451: <th>$lt{'def'}</th><th>$lt{'femof'}</th><th>$lt{'fr'}</th>
1.10 www 3452: ENDTABLEHEADFOUR
1.57 albertel 3453:
1.560 damieng 3454: if ($csec) {
1.578 raeburn 3455: $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'foremf'}.'</th><th>'.$lt{'fr'}.'</th>');
1.560 damieng 3456: }
1.473 amueller 3457:
1.560 damieng 3458: if ($cgroup) {
1.578 raeburn 3459: $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'foremf'}.'</th><th>'.$lt{'fr'}.'</th>');
1.560 damieng 3460: }
3461:
3462: if ($uname) {
3463: if (@usersgroups > 1) {
3464: $r->print('<th>'.&mt('Control by other group?').'</th>');
3465: }
1.578 raeburn 3466: $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'foremf'}.'</th><th>'.$lt{'fr'}.'</th>');
1.560 damieng 3467: }
3468:
3469: $r->print('</tr>');
1.506 www 3470: #
3471: # Done with the headers
3472: #
1.560 damieng 3473: my $defbgone='';
3474: my $defbgtwo='';
3475: my $defbgthree = '';
1.57 albertel 3476:
1.560 damieng 3477: foreach my $rid (@ids) {
1.57 albertel 3478:
3479: my ($inmapid)=($rid=~/\.(\d+)$/);
1.446 bisitz 3480: if ((!$pssymb &&
1.560 damieng 3481: (($pschp eq 'all') || ($allmaps{$pschp} eq $mapp{$rid})))
3482: ||
3483: ($pssymb && $pssymb eq $symbp{$rid})) {
1.4 www 3484: # ------------------------------------------------------ Entry for one resource
1.473 amueller 3485: if ($defbgone eq '#E0E099') {
3486: $defbgone='#E0E0DD';
1.57 albertel 3487: } else {
1.419 bisitz 3488: $defbgone='#E0E099';
1.57 albertel 3489: }
1.419 bisitz 3490: if ($defbgtwo eq '#FFFF99') {
1.473 amueller 3491: $defbgtwo='#FFFFDD';
1.57 albertel 3492: } else {
1.473 amueller 3493: $defbgtwo='#FFFF99';
1.57 albertel 3494: }
1.419 bisitz 3495: if ($defbgthree eq '#FFBB99') {
3496: $defbgthree='#FFBBDD';
1.269 raeburn 3497: } else {
1.419 bisitz 3498: $defbgthree='#FFBB99';
1.269 raeburn 3499: }
3500:
1.57 albertel 3501: my $thistitle='';
3502: my %name= ();
3503: undef %name;
3504: my %part= ();
3505: my %display=();
3506: my %type= ();
3507: my %default=();
1.196 www 3508: my $uri=&Apache::lonnet::declutter($uris{$rid});
1.584 raeburn 3509: my $toolsymb;
3510: if ($uri =~ /ext\.tool$/) {
3511: $toolsymb = $symbp{$rid};
3512: }
1.57 albertel 3513:
1.506 www 3514: my $filter=$env{'form.filter'};
1.548 raeburn 3515: foreach my $tempkeyp (&keysplit($keyp{$rid})) {
1.57 albertel 3516: if (grep $_ eq $tempkeyp, @catmarker) {
1.584 raeburn 3517: my $parmname=&Apache::lonnet::metadata($uri,$tempkeyp.'.name',$toolsymb);
1.560 damieng 3518: # We may only want certain parameters listed
3519: if ($filter) {
3520: unless ($filter=~/\Q$parmname\E/) { next; }
3521: }
3522: $name{$tempkeyp}=$parmname;
1.584 raeburn 3523: $part{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.part',$toolsymb);
1.560 damieng 3524:
1.584 raeburn 3525: my $parmdis=&Apache::lonnet::metadata($uri,$tempkeyp.'.display',$toolsymb);
1.560 damieng 3526: if ($allparms{$name{$tempkeyp}} ne '') {
3527: my $identifier;
3528: if ($parmdis =~ /(\s*\[Part.*)$/) {
3529: $identifier = $1;
3530: }
3531: $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier;
3532: } else {
3533: $display{$tempkeyp} = $parmdis;
3534: }
3535: unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
3536: $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
1.584 raeburn 3537: $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp,$toolsymb);
3538: $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.type',$toolsymb);
3539: $thistitle=&Apache::lonnet::metadata($uri,$tempkeyp.'.title',$toolsymb);
1.57 albertel 3540: }
3541: }
1.548 raeburn 3542: my $totalparms=scalar(keys(%name));
1.57 albertel 3543: if ($totalparms>0) {
1.560 damieng 3544: my $firstrow=1;
1.473 amueller 3545: my $title=&Apache::lonnet::gettitle($symbp{$rid});
1.582 raeburn 3546: my $navmap = Apache::lonnavmaps::navmap->new();
3547: my @recurseup;
3548: if (ref($navmap) && $mapp{$rid}) {
3549: @recurseup = $navmap->recurseup_maps($mapp{$rid});
3550: }
1.419 bisitz 3551: $r->print('<tr><td style="background-color:'.$defbgone.';"'.
1.57 albertel 3552: ' rowspan='.$totalparms.
1.419 bisitz 3553: '><tt><font size="-1">'.
1.57 albertel 3554: join(' / ',split(/\//,$uri)).
3555: '</font></tt><p><b>'.
1.154 albertel 3556: "<a href=\"javascript:openWindow('".
1.473 amueller 3557: &Apache::lonnet::clutter($uri).'?symb='.
3558: &escape($symbp{$rid}).
1.336 albertel 3559: "', 'metadatafile', '450', '500', 'no', 'yes');\"".
3560: " target=\"_self\">$title");
1.57 albertel 3561:
3562: if ($thistitle) {
1.473 amueller 3563: $r->print(' ('.$thistitle.')');
1.57 albertel 3564: }
3565: $r->print('</a></b></td>');
1.419 bisitz 3566: $r->print('<td style="background-color:'.$defbgtwo.';"'.
1.57 albertel 3567: ' rowspan='.$totalparms.'>'.$typep{$rid}.
3568: '</td>');
3569:
1.419 bisitz 3570: $r->print('<td style="background-color:'.$defbgone.';"'.
1.57 albertel 3571: ' rowspan='.$totalparms.
1.238 www 3572: '>'.$maptitles{$mapp{$rid}}.'</td>');
1.548 raeburn 3573: foreach my $item (&keysinorder_bytype(\%name,\%keyorder)) {
1.57 albertel 3574: unless ($firstrow) {
3575: $r->print('<tr>');
3576: } else {
3577: undef $firstrow;
3578: }
1.548 raeburn 3579: &print_row($r,$item,\%part,\%name,\%symbp,$rid,\%default,
1.57 albertel 3580: \%type,\%display,$defbgone,$defbgtwo,
1.269 raeburn 3581: $defbgthree,$parmlev,$uname,$udom,$csec,
1.582 raeburn 3582: $cgroup,\@usersgroups,$noeditgrp,$readonly,
3583: \@recurseup,\%maptitles,\%allmaps_inverted,
3584: \$numreclinks);
1.57 albertel 3585: }
3586: }
3587: }
3588: } # end foreach ids
1.43 albertel 3589: # -------------------------------------------------- End entry for one resource
1.517 www 3590: $r->print(&Apache::loncommon::end_data_table);
1.203 www 3591: } # end of full
1.57 albertel 3592: #--------------------------------------------------- Entry for parm level map
3593: if ($parmlev eq 'map') {
1.419 bisitz 3594: my $defbgone = '#E0E099';
3595: my $defbgtwo = '#FFFF99';
3596: my $defbgthree = '#FFBB99';
1.57 albertel 3597:
3598: my %maplist;
3599:
3600: if ($pschp eq 'all') {
1.446 bisitz 3601: %maplist = %allmaps;
1.57 albertel 3602: } else {
3603: %maplist = ($pschp => $mapp{$pschp});
3604: }
3605:
3606: #-------------------------------------------- for each map, gather information
3607: my $mapid;
1.560 damieng 3608: foreach $mapid (sort {$maplist{$a} cmp $maplist{$b}} keys(%maplist)) {
1.60 albertel 3609: my $maptitle = $maplist{$mapid};
1.57 albertel 3610:
3611: #----------------------- loop through ids and get all parameter types for map
3612: #----------------------------------------- and associated information
3613: my %name = ();
3614: my %part = ();
3615: my %display = ();
3616: my %type = ();
3617: my %default = ();
3618: my $map = 0;
3619:
1.473 amueller 3620: # $r->print("Catmarker: @catmarker<br />\n");
1.446 bisitz 3621:
1.548 raeburn 3622: foreach my $id (@ids) {
3623: ($map)=($id =~ /([\d]*?)\./);
3624: my $rid = $id;
1.446 bisitz 3625:
1.57 albertel 3626: # $r->print("$mapid:$map: $rid <br /> \n");
3627:
1.560 damieng 3628: if ($map eq $mapid) {
1.473 amueller 3629: my $uri=&Apache::lonnet::declutter($uris{$rid});
1.584 raeburn 3630: my $toolsymb;
3631: if ($uri =~ /ext\.tool$/) {
3632: $toolsymb = $symbp{$rid};
3633: }
1.582 raeburn 3634:
1.57 albertel 3635: # $r->print("Keys: $keyp{$rid} <br />\n");
3636:
3637: #--------------------------------------------------------------------
3638: # @catmarker contains list of all possible parameters including part #s
3639: # $fullkeyp contains the full part/id # for the extraction of proper parameters
3640: # $tempkeyp contains part 0 only (no ids - ie, subparts)
3641: # When storing information, store as part 0
3642: # When requesting information, request from full part
3643: #-------------------------------------------------------------------
1.548 raeburn 3644: foreach my $fullkeyp (&keysplit($keyp{$rid})) {
3645: my $tempkeyp = $fullkeyp;
3646: $tempkeyp =~ s/_\w+_/_0_/;
1.473 amueller 3647:
1.548 raeburn 3648: if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
1.473 amueller 3649: $part{$tempkeyp}="0";
1.584 raeburn 3650: $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name',$toolsymb);
3651: my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display',$toolsymb);
1.473 amueller 3652: if ($allparms{$name{$tempkeyp}} ne '') {
3653: my $identifier;
3654: if ($parmdis =~ /(\s*\[Part.*)$/) {
3655: $identifier = $1;
3656: }
3657: $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier;
3658: } else {
3659: $display{$tempkeyp} = $parmdis;
3660: }
3661: unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
3662: $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
3663: $display{$tempkeyp} =~ s/_\w+_/_0_/;
1.584 raeburn 3664: $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp,$toolsymb);
3665: $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type',$toolsymb);
1.473 amueller 3666: }
3667: } # end loop through keys
1.560 damieng 3668: }
1.57 albertel 3669: } # end loop through ids
1.446 bisitz 3670:
1.57 albertel 3671: #---------------------------------------------------- print header information
1.133 www 3672: my $foldermap=&mt($maptitle=~/^uploaded/?'Folder':'Map');
1.82 www 3673: my $showtitle=$maptitles{$maptitle}.($maptitle!~/^uploaded/?' ['.$maptitle.']':'');
1.401 bisitz 3674: my $tmp="";
1.57 albertel 3675: if ($uname) {
1.473 amueller 3676: my $person=&Apache::loncommon::plainname($uname,$udom);
1.401 bisitz 3677: $tmp.=&mt("User")." <font color=\"red\"><i>$uname \($person\) </i></font> ".
3678: &mt('in')." \n";
1.57 albertel 3679: } else {
1.401 bisitz 3680: $tmp.="<font color=\"red\"><i>".&mt('all').'</i></font> '.&mt('users in')." \n";
1.57 albertel 3681: }
1.269 raeburn 3682: if ($cgroup) {
1.401 bisitz 3683: $tmp.=&mt("Group")." <font color=\"red\"><i>$cgroup".
3684: "</i></font> ".&mt('of')." \n";
1.269 raeburn 3685: $csec = '';
3686: } elsif ($csec) {
1.401 bisitz 3687: $tmp.=&mt("Section")." <font color=\"red\"><i>$csec".
3688: "</i></font> ".&mt('of')." \n";
1.269 raeburn 3689: }
1.401 bisitz 3690: $r->print('<div align="center"><h4>'
3691: .&mt('Set Defaults for All Resources in [_1]Specifically for [_2][_3]'
1.404 bisitz 3692: ,$foldermap.'<br /><font color="red"><i>'.$showtitle.'</i></font><br />'
1.401 bisitz 3693: ,$tmp
3694: ,'<font color="red"><i>'.$coursename.'</i></font>'
3695: )
3696: ."<br /></h4>\n"
1.422 bisitz 3697: );
1.57 albertel 3698: #---------------------------------------------------------------- print table
1.419 bisitz 3699: $r->print('<p>'.&Apache::loncommon::start_data_table()
3700: .&Apache::loncommon::start_data_table_header_row()
3701: .'<th>'.&mt('Parameter Name').'</th>'
1.578 raeburn 3702: .'<th>'.&mt('Value').'</th>'
1.419 bisitz 3703: .'<th>'.&mt('Parameter in Effect').'</th>'
3704: .&Apache::loncommon::end_data_table_header_row()
3705: );
1.57 albertel 3706:
1.582 raeburn 3707: my $navmap = Apache::lonnavmaps::navmap->new();
3708: my @recurseup;
3709: if (ref($navmap)) {
3710: my $mapres = $navmap->getByMapPc($mapid);
3711: if (ref($mapres)) {
3712: @recurseup = $navmap->recurseup_maps($mapres->src());
3713: }
3714: }
3715:
3716:
1.548 raeburn 3717: foreach my $item (&keysinorder(\%name,\%keyorder)) {
1.473 amueller 3718: $r->print(&Apache::loncommon::start_data_table_row());
1.548 raeburn 3719: &print_row($r,$item,\%part,\%name,\%symbp,$mapid,\%default,
1.269 raeburn 3720: \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
1.568 raeburn 3721: $parmlev,$uname,$udom,$csec,$cgroup,'',$noeditgrp,
1.582 raeburn 3722: $readonly,\@recurseup,\%maptitles,\%allmaps_inverted,
3723: \$numreclinks);
1.57 albertel 3724: }
1.422 bisitz 3725: $r->print(&Apache::loncommon::end_data_table().'</p>'
3726: .'</div>'
3727: );
1.57 albertel 3728: } # end each map
3729: } # end of $parmlev eq map
3730: #--------------------------------- Entry for parm level general (Course level)
3731: if ($parmlev eq 'general') {
1.473 amueller 3732: my $defbgone = '#E0E099';
1.419 bisitz 3733: my $defbgtwo = '#FFFF99';
3734: my $defbgthree = '#FFBB99';
1.57 albertel 3735:
3736: #-------------------------------------------- for each map, gather information
3737: my $mapid="0.0";
3738: #----------------------- loop through ids and get all parameter types for map
3739: #----------------------------------------- and associated information
3740: my %name = ();
3741: my %part = ();
3742: my %display = ();
3743: my %type = ();
3744: my %default = ();
1.446 bisitz 3745:
1.548 raeburn 3746: foreach $id (@ids) {
3747: my $rid = $id;
1.446 bisitz 3748:
1.196 www 3749: my $uri=&Apache::lonnet::declutter($uris{$rid});
1.584 raeburn 3750: my $toolsymb;
3751: if ($uri =~ /ext\.tool$/) {
3752: $toolsymb = $symbp{$rid};
3753: }
1.57 albertel 3754:
3755: #--------------------------------------------------------------------
3756: # @catmarker contains list of all possible parameters including part #s
3757: # $fullkeyp contains the full part/id # for the extraction of proper parameters
3758: # $tempkeyp contains part 0 only (no ids - ie, subparts)
3759: # When storing information, store as part 0
3760: # When requesting information, request from full part
3761: #-------------------------------------------------------------------
1.548 raeburn 3762: foreach my $fullkeyp (&keysplit($keyp{$rid})) {
3763: my $tempkeyp = $fullkeyp;
3764: $tempkeyp =~ s/_\w+_/_0_/;
3765: if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
1.473 amueller 3766: $part{$tempkeyp}="0";
1.584 raeburn 3767: $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name',$toolsymb);
3768: my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display',$toolsymb);
1.473 amueller 3769: if ($allparms{$name{$tempkeyp}} ne '') {
3770: my $identifier;
3771: if ($parmdis =~ /(\s*\[Part.*)$/) {
3772: $identifier = $1;
3773: }
3774: $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier;
3775: } else {
3776: $display{$tempkeyp} = $parmdis;
3777: }
3778: unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
3779: $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
3780: $display{$tempkeyp} =~ s/_\w+_/_0_/;
1.584 raeburn 3781: $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp,$toolsymb);
3782: $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type',$toolsymb);
1.560 damieng 3783: }
1.57 albertel 3784: } # end loop through keys
3785: } # end loop through ids
1.446 bisitz 3786:
1.57 albertel 3787: #---------------------------------------------------- print header information
1.473 amueller 3788: my $setdef=&mt("Set Defaults for All Resources in Course");
1.57 albertel 3789: $r->print(<<ENDMAPONE);
1.419 bisitz 3790: <center>
3791: <h4>$setdef
1.135 albertel 3792: <font color="red"><i>$coursename</i></font><br />
1.57 albertel 3793: ENDMAPONE
3794: if ($uname) {
1.473 amueller 3795: my $person=&Apache::loncommon::plainname($uname,$udom);
1.135 albertel 3796: $r->print(" ".&mt("User")."<font color=\"red\"> <i>$uname \($person\) </i></font> \n");
1.57 albertel 3797: } else {
1.135 albertel 3798: $r->print("<i><font color=\"red\"> ".&mt("ALL")."</i> ".&mt("USERS")."</font> \n");
1.57 albertel 3799: }
1.446 bisitz 3800:
1.135 albertel 3801: if ($csec) {$r->print(&mt("Section")."<font color=\"red\"> <i>$csec</i></font>\n")};
1.306 albertel 3802: if ($cgroup) {$r->print(&mt("Group")."<font color=\"red\"> <i>$cgroup</i></font>\n")};
1.135 albertel 3803: $r->print("</h4>\n");
1.57 albertel 3804: #---------------------------------------------------------------- print table
1.419 bisitz 3805: $r->print('<p>'.&Apache::loncommon::start_data_table()
3806: .&Apache::loncommon::start_data_table_header_row()
3807: .'<th>'.&mt('Parameter Name').'</th>'
3808: .'<th>'.&mt('Default Value').'</th>'
3809: .'<th>'.&mt('Parameter in Effect').'</th>'
3810: .&Apache::loncommon::end_data_table_header_row()
3811: );
1.57 albertel 3812:
1.548 raeburn 3813: foreach my $item (&keysinorder(\%name,\%keyorder)) {
1.419 bisitz 3814: $r->print(&Apache::loncommon::start_data_table_row());
1.548 raeburn 3815: &print_row($r,$item,\%part,\%name,\%symbp,$mapid,\%default,
1.568 raeburn 3816: \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
3817: $parmlev,$uname,$udom,$csec,$cgroup,'',$noeditgrp,
3818: $readonly);
1.57 albertel 3819: }
1.419 bisitz 3820: $r->print(&Apache::loncommon::end_data_table()
3821: .'</p>'
3822: .'</center>'
3823: );
1.57 albertel 3824: } # end of $parmlev eq general
1.43 albertel 3825: }
1.507 www 3826: $r->print('</form>');
1.582 raeburn 3827: if ($numreclinks) {
3828: $r->print(<<"END");
3829: <form name="recurseform" action="/adm/parmset?action=settable" method="post">
3830: <input type="hidden" name="pschp" />
3831: <input type="hidden" name="pscat" />
3832: <input type="hidden" name="psprt" />
3833: <input type="hidden" name="hideparmsel" value="hidden" />
3834: </form>
3835: <script type="text/javascript">
3836: function pjumprec(rid,name,part) {
3837: document.forms.recurseform.pschp.value = rid;
3838: document.forms.recurseform.pscat.value = name;
3839: document.forms.recurseform.psprt.value = part;
3840: document.forms.recurseform.submit();
3841: return false;
3842: }
3843: </script>
3844: END
3845: }
1.507 www 3846: &endSettingsScreen($r);
3847: $r->print(&Apache::loncommon::end_page());
1.57 albertel 3848: } # end sub assessparms
1.30 www 3849:
1.560 damieng 3850:
3851:
1.120 www 3852: ##################################################
1.560 damieng 3853: # OVERVIEW MODE
1.207 www 3854: ##################################################
1.124 www 3855:
1.563 damieng 3856: my $tableopen; # boolean, true if HTML table is already opened
3857:
3858: # Returns HTML with the HTML table start tag and header, unless the table is already opened.
3859: # @param {boolean} $readonly - true if values cannot be edited (otherwise more columns are added)
3860: # @returns {string}
1.124 www 3861: sub tablestart {
1.576 raeburn 3862: my ($readonly,$is_map) = @_;
1.124 www 3863: if ($tableopen) {
1.552 raeburn 3864: return '';
1.124 www 3865: } else {
1.552 raeburn 3866: $tableopen=1;
3867: my $output = &Apache::loncommon::start_data_table().'<tr><th>'.&mt('Parameter').'</th>';
3868: if ($readonly) {
3869: $output .= '<th>'.&mt('Current value').'</th>';
3870: } else {
1.576 raeburn 3871: $output .= '<th>'.&mt('Delete').'</th>'.
3872: '<th>'.&mt('Set to ...').'</th>';
3873: if ($is_map) {
3874: $output .= '<th>'.&mt('Recursive?').'</th>';
3875: }
1.552 raeburn 3876: }
3877: $output .= '</tr>';
3878: return $output;
1.124 www 3879: }
3880: }
3881:
1.563 damieng 3882: # Returns HTML with the HTML table end tag, unless the table is not opened.
3883: # @returns {string}
1.124 www 3884: sub tableend {
3885: if ($tableopen) {
1.560 damieng 3886: $tableopen=0;
3887: return &Apache::loncommon::end_data_table();
1.124 www 3888: } else {
1.560 damieng 3889: return'';
1.124 www 3890: }
3891: }
3892:
1.563 damieng 3893: # Reads course and user information.
3894: # 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).
3895: # The key for student data is modified with '[useropt:'.username.':'.userdomain.'].'.
3896: # If the context is looking for a list, returns a list with the scalar data and the class list.
3897: # @param {string} $crs - course number
3898: # @param {string} $dom - course domain
3899: # @returns {hash reference|Array}
1.207 www 3900: sub readdata {
3901: my ($crs,$dom)=@_;
3902: # Read coursedata
3903: my $resourcedata=&Apache::lonnet::get_courseresdata($crs,$dom);
3904: # Read userdata
3905:
3906: my $classlist=&Apache::loncoursedata::get_classlist();
1.548 raeburn 3907: foreach my $user (keys(%$classlist)) {
3908: if ($user=~/^($match_username)\:($match_domain)$/) {
3909: my ($tuname,$tudom)=($1,$2);
3910: my $useropt=&Apache::lonnet::get_userresdata($tuname,$tudom);
3911: foreach my $userkey (keys(%{$useropt})) {
3912: if ($userkey=~/^\Q$env{'request.course.id'}\E/) {
1.207 www 3913: my $newkey=$userkey;
1.548 raeburn 3914: $newkey=~s/^($env{'request.course.id'}\.)/$1\[useropt\:$tuname\:$tudom\]\./;
3915: $$resourcedata{$newkey}=$$useropt{$userkey};
3916: }
3917: }
1.473 amueller 3918: }
3919: }
1.552 raeburn 3920: if (wantarray) {
3921: return ($resourcedata,$classlist);
3922: } else {
3923: return $resourcedata;
3924: }
1.207 www 3925: }
3926:
3927:
1.563 damieng 3928: # Stores parameter data, using form parameters directly.
3929: #
3930: # 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 3931: # set_* (except settext, setipallow, setipdeny, setdeeplink) - set a parameter value
1.563 damieng 3932: # del_* - remove a parameter
3933: # datepointer_* - set a date parameter (value is key_* refering to a set of other form parameters)
3934: # dateinterval_* - set a date interval parameter (value refers to more form parameters)
3935: # key_* - date values
3936: # days_* - for date intervals
3937: # hours_* - for date intervals
3938: # minutes_* - for date intervals
3939: # seconds_* - for date intervals
3940: # done_* - for date intervals
3941: # typeof_* - parameter type
3942: #
3943: # @param {Apache2::RequestRec} $r - the Apache request
3944: # @param {string} $crs - course number
3945: # @param {string} $dom - course domain
1.208 www 3946: sub storedata {
3947: my ($r,$crs,$dom)=@_;
1.207 www 3948: # Set userlevel immediately
3949: # Do an intermediate store of course level
3950: my $olddata=&readdata($crs,$dom);
1.124 www 3951: my %newdata=();
3952: undef %newdata;
3953: my @deldata=();
1.576 raeburn 3954: my @delrec=();
3955: my @delnonrec=();
1.124 www 3956: undef @deldata;
1.504 raeburn 3957: my ($got_chostname,$chostname,$cmajor,$cminor);
1.546 raeburn 3958: my $now = time;
1.560 damieng 3959: foreach my $key (keys(%env)) {
3960: if ($key =~ /^form\.([a-z]+)\_(.+)$/) {
3961: my $cmd=$1;
3962: my $thiskey=$2;
1.576 raeburn 3963: my ($altkey,$recursive,$tkey,$tkeyrec,$tkeynonrec);
1.588 ! raeburn 3964: next if ($cmd eq 'rec' || $cmd eq 'settext' || $cmd eq 'setipallow' || $cmd eq 'setipdeny' || $cmd eq 'setdeeplink');
1.576 raeburn 3965: if ((($cmd eq 'set') || ($cmd eq 'datepointer') || ($cmd eq 'dateinterval') || ($cmd eq 'del')) &&
3966: ($thiskey =~ /(?:sequence|page)\Q___(all)\E/)) {
3967: unless ($thiskey =~ /(encrypturl|hiddenresource)$/) {
3968: $altkey = $thiskey;
3969: $altkey =~ s/\Q___(all)\E/___(rec)/;
3970: if ($env{'form.rec_'.$thiskey}) {
3971: $recursive = 1;
3972: }
3973: }
3974: }
1.560 damieng 3975: my ($tuname,$tudom)=&extractuser($thiskey);
1.473 amueller 3976: if ($tuname) {
1.576 raeburn 3977: $tkey=$thiskey;
1.560 damieng 3978: $tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;
1.576 raeburn 3979: if ($altkey) {
3980: $tkeynonrec = $tkey;
3981: $tkeyrec = $altkey;
3982: $tkeyrec=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;
3983: }
1.560 damieng 3984: }
3985: if ($cmd eq 'set' || $cmd eq 'datepointer' || $cmd eq 'dateinterval') {
1.563 damieng 3986: my ($data, $typeof, $text, $name, $valchk, $valmatch, $namematch);
3987: if ($cmd eq 'set') {
3988: $data=$env{$key};
3989: $valmatch = '';
3990: $valchk = $data;
3991: $typeof=$env{'form.typeof_'.$thiskey};
3992: $text = &mt('Saved modified parameter for');
3993: if ($typeof eq 'string_questiontype') {
3994: $name = 'type';
1.588 ! raeburn 3995: } elsif (($typeof eq 'string_lenient') || ($typeof eq 'string_deeplink')) {
! 3996: ($name) = ($typeof =~ /^string_(lenient|deeplink)$/);
1.563 damieng 3997: my $stringmatch = &standard_string_matches($typeof);
3998: if (ref($stringmatch) eq 'ARRAY') {
3999: foreach my $item (@{$stringmatch}) {
4000: if (ref($item) eq 'ARRAY') {
4001: my ($regexpname,$pattern) = @{$item};
4002: if ($pattern ne '') {
4003: if ($data =~ /$pattern/) {
4004: $valmatch = $regexpname;
4005: $valchk = '';
4006: last;
4007: }
1.560 damieng 4008: }
1.549 raeburn 4009: }
4010: }
4011: }
1.563 damieng 4012: } elsif ($typeof eq 'string_discussvote') {
4013: $name = 'discussvote';
4014: } elsif ($typeof eq 'string_examcode') {
4015: $name = 'examcode';
4016: if (&Apache::lonnet::validCODE($data)) {
4017: $valchk = 'valid';
4018: }
4019: } elsif ($typeof eq 'string_yesno') {
4020: if ($thiskey =~ /\.retrypartial$/) {
4021: $name = 'retrypartial';
4022: }
1.549 raeburn 4023: }
1.563 damieng 4024: } elsif ($cmd eq 'datepointer') {
4025: $data=&Apache::lonhtmlcommon::get_date_from_form($env{$key});
4026: $typeof=$env{'form.typeof_'.$thiskey};
4027: $text = &mt('Saved modified date for');
4028: if ($typeof eq 'date_start') {
4029: if ($thiskey =~ /\.printstartdate$/) {
4030: $name = 'printstartdate';
4031: if (($data) && ($data > $now)) {
4032: $valchk = 'future';
4033: }
1.560 damieng 4034: }
1.563 damieng 4035: } elsif ($typeof eq 'date_end') {
4036: if ($thiskey =~ /\.printenddate$/) {
4037: $name = 'printenddate';
4038: if (($data) && ($data < $now)) {
4039: $valchk = 'past';
4040: }
1.560 damieng 4041: }
1.504 raeburn 4042: }
1.563 damieng 4043: } elsif ($cmd eq 'dateinterval') {
4044: $data=&get_date_interval_from_form($thiskey);
4045: if ($thiskey =~ /\.interval$/) {
4046: $name = 'interval';
4047: my $intervaltype = &get_intervaltype($name);
4048: my $intervalmatch = &standard_interval_matches($intervaltype);
4049: if (ref($intervalmatch) eq 'ARRAY') {
4050: foreach my $item (@{$intervalmatch}) {
4051: if (ref($item) eq 'ARRAY') {
4052: my ($regexpname,$pattern) = @{$item};
4053: if ($pattern ne '') {
4054: if ($data =~ /$pattern/) {
4055: $valmatch = $regexpname;
4056: $valchk = '';
4057: last;
4058: }
1.560 damieng 4059: }
1.554 raeburn 4060: }
4061: }
4062: }
4063: }
1.563 damieng 4064: $typeof=$env{'form.typeof_'.$thiskey};
4065: $text = &mt('Saved modified date for');
1.554 raeburn 4066: }
1.576 raeburn 4067: if ($recursive) {
1.563 damieng 4068: $namematch = 'maplevelrecurse';
1.560 damieng 4069: }
1.563 damieng 4070: if (($name ne '') || ($namematch ne '')) {
4071: my ($needsrelease,$needsnewer);
4072: if ($name ne '') {
4073: $needsrelease = $Apache::lonnet::needsrelease{"parameter:$name:$valchk:$valmatch:"};
1.560 damieng 4074: if ($needsrelease) {
4075: unless ($got_chostname) {
1.563 damieng 4076: ($chostname,$cmajor,$cminor)=¶meter_release_vars();
1.560 damieng 4077: $got_chostname = 1;
4078: }
1.563 damieng 4079: $needsnewer = ¶meter_releasecheck($name,$valchk,$valmatch,undef,
4080: $needsrelease,
4081: $cmajor,$cminor);
4082: }
4083: }
4084: if ($namematch ne '') {
4085: if ($needsnewer) {
4086: undef($namematch);
1.560 damieng 4087: } else {
1.563 damieng 4088: my $currneeded;
4089: if ($needsrelease) {
4090: $currneeded = $needsrelease;
4091: }
4092: $needsrelease =
4093: $Apache::lonnet::needsrelease{"parameter::::$namematch"};
4094: if (($needsrelease) &&
4095: (($currneeded eq '') || ($needsrelease < $currneeded))) {
4096: unless ($got_chostname) {
4097: ($chostname,$cmajor,$cminor) = ¶meter_release_vars();
4098: $got_chostname = 1;
4099: }
4100: $needsnewer = ¶meter_releasecheck(undef,$valchk,$valmatch,
4101: $namematch, $needsrelease,$cmajor,$cminor);
4102: } else {
4103: undef($namematch);
4104: }
1.560 damieng 4105: }
1.557 raeburn 4106: }
1.563 damieng 4107: if ($needsnewer) {
4108: $r->print('<br />'.&oldversion_warning($name,$namematch,$data,
4109: $chostname,$cmajor,
4110: $cminor,$needsrelease));
4111: next;
4112: }
1.504 raeburn 4113: }
1.576 raeburn 4114: my ($reconlychg,$haschange,$storekey);
4115: if ($tuname) {
4116: my $ustorekey;
4117: if ($altkey) {
4118: if ($recursive) {
4119: if (exists($$olddata{$thiskey})) {
4120: if ($$olddata{$thiskey} eq $data) {
4121: $reconlychg = 1;
4122: }
4123: &Apache::lonnet::del('resourcedata',[$tkeynonrec,$tkeynonrec.'.type'],$tudom,$tuname);
4124: }
4125: if (exists($$olddata{$altkey})) {
4126: if (defined($data) && $$olddata{$altkey} ne $data) {
4127: $haschange = 1;
4128: }
4129: } elsif ((!$reconlychg) && ($data ne '')) {
4130: $haschange = 1;
4131: }
4132: $ustorekey = $tkeyrec;
4133: } else {
4134: if (exists($$olddata{$altkey})) {
4135: if ($$olddata{$altkey} eq $data) {
4136: $reconlychg = 1;
4137: }
4138: &Apache::lonnet::del('resourcedata',[$tkeyrec,$tkeyrec.'.type'],$tudom,$tuname);
4139: }
4140: if (exists($$olddata{$thiskey})) {
4141: if (defined($data) && $$olddata{$thiskey} ne $data) {
4142: $haschange = 1;
4143: }
4144: } elsif ((!$reconlychg) && ($data ne '')) {
4145: $haschange = 1;
4146: }
4147: $ustorekey = $tkeynonrec;
4148: }
4149: } else {
4150: if (exists($$olddata{$tkey})) {
4151: if (defined($data) && $$olddata{$tkey} ne $data) {
4152: $haschange = 1;
4153: }
4154: $ustorekey = $tkey;
4155: }
4156: }
4157: if ($haschange || $reconlychg) {
4158: unless ($env{'form.del_'.$thiskey}) {
4159: if (&Apache::lonnet::put('resourcedata',{$ustorekey=>$data,
4160: $ustorekey.'.type' => $typeof},
4161: $tudom,$tuname) eq 'ok') {
4162: &log_parmset({$ustorekey=>$data,$ustorekey.'.type' => $typeof},0,$tuname,$tudom);
4163: $r->print('<br />'.$text.' '.
4164: &Apache::loncommon::plainname($tuname,$tudom));
4165: } else {
4166: $r->print('<div class="LC_error">'.
4167: &mt('Error saving parameters').'</div>');
4168: }
4169: &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
4170: }
4171: }
4172: } else {
4173: if ($altkey) {
4174: if ($recursive) {
4175: if (exists($$olddata{$thiskey})) {
4176: if ($$olddata{$thiskey} eq $data) {
4177: $reconlychg = 1;
4178: }
4179: push(@delnonrec,($thiskey,$thiskey.'.type'));
4180: }
4181: if (exists($$olddata{$altkey})) {
4182: if (defined($data) && $$olddata{$altkey} ne $data) {
4183: $haschange = 1;
4184: }
4185: } elsif (($data ne '') && (!$reconlychg)) {
4186: $haschange = 1;
4187: }
4188: $storekey = $altkey;
1.563 damieng 4189: } else {
1.576 raeburn 4190: if (exists($$olddata{$altkey})) {
4191: if ($$olddata{$altkey} eq $data) {
4192: $reconlychg = 1;
4193: }
4194: push(@delrec,($altkey,$altkey.'.type'));
4195: }
4196: if (exists($$olddata{$thiskey})) {
4197: if (defined($data) && $$olddata{$thiskey} ne $data) {
4198: $haschange = 1;
4199: }
4200: } elsif (($data ne '') && (!$reconlychg)) {
4201: $haschange = 1;
4202: }
4203: $storekey = $thiskey;
1.563 damieng 4204: }
1.560 damieng 4205: } else {
1.576 raeburn 4206: if (defined($data) && $$olddata{$thiskey} ne $data) {
4207: $haschange = 1;
4208: $storekey = $thiskey;
4209: }
4210: }
4211: }
4212: if ($reconlychg || $haschange) {
4213: unless ($env{'form.del_'.$thiskey}) {
4214: $newdata{$storekey}=$data;
4215: $newdata{$storekey.'.type'}=$typeof;
1.560 damieng 4216: }
4217: }
4218: } elsif ($cmd eq 'del') {
4219: if ($tuname) {
1.576 raeburn 4220: my $error;
4221: if ($altkey) {
4222: if (exists($$olddata{$altkey})) {
4223: if (&Apache::lonnet::del('resourcedata',[$tkeyrec,$tkeyrec.'.type'],$tudom,$tuname) eq 'ok') {
4224: &log_parmset({$tkeyrec=>''},1,$tuname,$tudom);
4225: if ($recursive) {
4226: $r->print('<br />'.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));
4227: }
4228: } elsif ($recursive) {
4229: $error = 1;
4230: }
4231: }
4232: if (exists($$olddata{$thiskey})) {
4233: if (&Apache::lonnet::del('resourcedata',[$tkeynonrec,$tkeynonrec.'.type'],$tudom,$tuname) eq 'ok') {
4234: &log_parmset({$tkeynonrec=>''},1,$tuname,$tudom);
4235: unless ($recursive) {
4236: $r->print('<br />'.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));
4237: }
4238: } elsif (!$recursive) {
4239: $error = 1;
4240: }
4241: }
1.560 damieng 4242: } else {
1.576 raeburn 4243: if (exists($$olddata{$thiskey})) {
4244: if (&Apache::lonnet::del('resourcedata',[$tkey,$tkey.'.type'],$tudom,$tuname) eq 'ok') {
4245: &log_parmset({$tkey=>''},1,$tuname,$tudom);
4246: $r->print('<br />'.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));
4247: } else {
4248: $error = 1;
4249: }
4250: }
4251: }
4252: if ($error) {
1.560 damieng 4253: $r->print('<div class="LC_error">'.
4254: &mt('Error deleting parameters').'</div>');
4255: }
4256: &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
4257: } else {
1.576 raeburn 4258: if ($altkey) {
4259: if (exists($$olddata{$altkey})) {
4260: unless (grep(/^\Q$altkey\E$/,@delrec)) {
4261: push(@deldata,($altkey,$altkey.'.type'));
4262: }
4263: }
4264: if (exists($$olddata{$thiskey})) {
4265: unless (grep(/^\Q$thiskey\E$/,@delnonrec)) {
4266: push(@deldata,($thiskey,$thiskey.'.type'));
4267: }
4268: }
4269: } elsif (exists($$olddata{$thiskey})) {
4270: push(@deldata,($thiskey,$thiskey.'.type'));
4271: }
1.560 damieng 4272: }
1.473 amueller 4273: }
4274: }
4275: }
1.207 www 4276: # Store all course level
1.144 www 4277: my $delentries=$#deldata+1;
1.576 raeburn 4278: my @alldels;
4279: if (@delrec) {
4280: push(@alldels,@delrec);
4281: }
4282: if (@delnonrec) {
4283: push(@alldels,@delnonrec);
4284: }
4285: if (@deldata) {
4286: push(@alldels,@deldata);
4287: }
1.548 raeburn 4288: my @newdatakeys=keys(%newdata);
1.144 www 4289: my $putentries=$#newdatakeys+1;
1.576 raeburn 4290: my ($delresult,$devalidate);
4291: if (@alldels) {
4292: if (&Apache::lonnet::del('resourcedata',\@alldels,$dom,$crs) eq 'ok') {
4293: my %loghash=map { $_ => '' } @alldels;
1.560 damieng 4294: &log_parmset(\%loghash,1);
1.576 raeburn 4295: if ($delentries) {
4296: $r->print('<h2>'.&mt('Deleted [quant,_1,parameter]',$delentries/2).'</h2>');
4297: }
4298: } elsif ($delentries) {
1.560 damieng 4299: $r->print('<div class="LC_error">'.
4300: &mt('Error deleting parameters').'</div>');
4301: }
1.576 raeburn 4302: $devalidate = 1;
1.144 www 4303: }
4304: if ($putentries) {
1.560 damieng 4305: if (&Apache::lonnet::put('resourcedata',\%newdata,$dom,$crs) eq 'ok') {
4306: &log_parmset(\%newdata,0);
4307: $r->print('<h3>'.&mt('Saved [quant,_1,parameter]',$putentries/2).'</h3>');
4308: } else {
4309: $r->print('<div class="LC_error">'.
4310: &mt('Error saving parameters').'</div>');
4311: }
1.576 raeburn 4312: $devalidate = 1;
4313: }
4314: if ($devalidate) {
1.560 damieng 4315: &Apache::lonnet::devalidatecourseresdata($crs,$dom);
1.144 www 4316: }
1.208 www 4317: }
1.207 www 4318:
1.563 damieng 4319: # Returns the username and domain from a key created in readdata from a resourcedata key.
4320: #
4321: # @param {string} $key - the key
4322: # @returns {Array}
1.208 www 4323: sub extractuser {
4324: my $key=shift;
1.350 albertel 4325: return ($key=~/^$env{'request.course.id'}.\[useropt\:($match_username)\:($match_domain)\]\./);
1.208 www 4326: }
1.206 www 4327:
1.563 damieng 4328: # Parses a parameter key and returns the components.
4329: #
4330: # @param {string} $key -
4331: # @param {hash reference} $listdata -
4332: # @return {Array} - (student, resource, part, parameter)
1.381 albertel 4333: sub parse_listdata_key {
4334: my ($key,$listdata) = @_;
4335: # split into student/section affected, and
4336: # the realm (folder/resource part and parameter
1.446 bisitz 4337: my ($student,$realm) =
1.473 amueller 4338: ($key=~/^\Q$env{'request.course.id'}\E\.\[([^\.]+)\]\.(.+)$/);
1.381 albertel 4339: # if course wide student would be undefined
4340: if (!defined($student)) {
1.560 damieng 4341: ($realm)=($key=~/^\Q$env{'request.course.id'}\E\.(.+)$/);
1.381 albertel 4342: }
4343: # strip off the .type if it's not the Question type parameter
4344: if ($realm=~/\.type$/ && !exists($listdata->{$key.'.type'})) {
1.560 damieng 4345: $realm=~s/\.type//;
1.381 albertel 4346: }
4347: # split into resource+part and parameter name
1.388 albertel 4348: my ($res, $parm) = ($realm=~/^(.*)\.(.*)$/);
4349: ($res, my $part) = ($res =~/^(.*)\.(.*)$/);
1.381 albertel 4350: return ($student,$res,$part,$parm);
4351: }
4352:
1.563 damieng 4353: # Prints HTML with forms for the given parameter data in overview mode (newoverview or overview).
4354: #
4355: # @param {Apache2::RequestRec} $r - the Apache request
4356: # @param {hash reference} $resourcedata - parameter data returned by readdata
4357: # @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
4358: # @param {string} $sortorder - realmstudent|studentrealm
4359: # @param {string} $caller - name of the calling sub (overview|newoverview)
4360: # @param {hash reference} $classlist - from loncoursedata::get_classlist
1.568 raeburn 4361: # @param {boolean} $readonly - true if editing not allowed
1.563 damieng 4362: # @returns{integer} - number of $listdata parameters processed
1.208 www 4363: sub listdata {
1.568 raeburn 4364: my ($r,$resourcedata,$listdata,$sortorder,$caller,$classlist,$readonly)=@_;
1.552 raeburn 4365:
1.207 www 4366: # Start list output
1.206 www 4367:
1.122 www 4368: my $oldsection='';
4369: my $oldrealm='';
4370: my $oldpart='';
1.123 www 4371: my $pointer=0;
1.124 www 4372: $tableopen=0;
1.145 www 4373: my $foundkeys=0;
1.248 albertel 4374: my %keyorder=&standardkeyorder();
1.381 albertel 4375:
1.552 raeburn 4376: my ($secidx,%grouphash);
4377: if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
4378: $secidx = &Apache::loncoursedata::CL_SECTION();
1.553 raeburn 4379: if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
4380: %grouphash = &Apache::longroup::coursegroups();
4381: } elsif ($env{'request.course.groups'} ne '') {
1.585 raeburn 4382: map { $grouphash{$_} = 1; } split(/:/,$env{'request.course.groups'});
1.553 raeburn 4383: }
1.552 raeburn 4384: }
4385:
1.576 raeburn 4386: foreach my $key (sort {
1.560 damieng 4387: my ($astudent,$ares,$apart,$aparm) = &parse_listdata_key($a,$listdata);
4388: my ($bstudent,$bres,$bpart,$bparm) = &parse_listdata_key($b,$listdata);
1.381 albertel 4389:
1.560 damieng 4390: # get the numerical order for the param
4391: $aparm=$keyorder{'parameter_0_'.$aparm};
4392: $bparm=$keyorder{'parameter_0_'.$bparm};
1.381 albertel 4393:
1.560 damieng 4394: my $result=0;
1.381 albertel 4395:
1.560 damieng 4396: if ($sortorder eq 'realmstudent') {
1.381 albertel 4397: if ($ares ne $bres ) {
1.560 damieng 4398: $result = ($ares cmp $bres);
1.446 bisitz 4399: } elsif ($astudent ne $bstudent) {
1.560 damieng 4400: $result = ($astudent cmp $bstudent);
4401: } elsif ($apart ne $bpart ) {
4402: $result = ($apart cmp $bpart);
4403: }
4404: } else {
4405: if ($astudent ne $bstudent) {
4406: $result = ($astudent cmp $bstudent);
4407: } elsif ($ares ne $bres ) {
4408: $result = ($ares cmp $bres);
4409: } elsif ($apart ne $bpart ) {
4410: $result = ($apart cmp $bpart);
4411: }
1.473 amueller 4412: }
1.446 bisitz 4413:
1.560 damieng 4414: if (!$result) {
1.381 albertel 4415: if (defined($aparm) && defined($bparm)) {
1.560 damieng 4416: $result = ($aparm <=> $bparm);
1.381 albertel 4417: } elsif (defined($aparm)) {
1.560 damieng 4418: $result = -1;
1.381 albertel 4419: } elsif (defined($bparm)) {
1.560 damieng 4420: $result = 1;
4421: }
1.473 amueller 4422: }
1.381 albertel 4423:
1.560 damieng 4424: $result;
4425:
1.576 raeburn 4426: } keys(%{$listdata})) { # foreach my $key
4427: my $thiskey = $key;
1.560 damieng 4428: if ($$listdata{$thiskey.'.type'}) {
4429: my $thistype=$$listdata{$thiskey.'.type'};
4430: if ($$resourcedata{$thiskey.'.type'}) {
4431: $thistype=$$resourcedata{$thiskey.'.type'};
4432: }
4433: my ($middle,$part,$name)=
1.572 damieng 4434: ($thiskey=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s\-]+)\.(\w+)$/);
1.560 damieng 4435: my $section=&mt('All Students');
1.576 raeburn 4436: my $showval = $$resourcedata{$thiskey};
1.560 damieng 4437: if ($middle=~/^\[(.*)\]/) {
4438: my $issection=$1;
4439: if ($issection=~/^useropt\:($match_username)\:($match_domain)/) {
4440: my ($stuname,$studom) = ($1,$2);
4441: if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
4442: if (ref($classlist) eq 'HASH') {
4443: if (ref($classlist->{$stuname.':'.$studom}) eq 'ARRAY') {
4444: next unless ($classlist->{$stuname.':'.$studom}->[$secidx] eq $env{'request.course.sec'});
4445: }
4446: }
4447: }
4448: $section=&mt('User').": ".&Apache::loncommon::plainname($stuname,$studom);
4449: } else {
4450: if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
4451: if (exists($grouphash{$issection})) {
4452: $section=&mt('Group').': '.$issection;
4453: } elsif ($issection eq $env{'request.course.sec'}) {
4454: $section = &mt('Section').': '.$issection;
4455: } else {
4456: next;
1.552 raeburn 4457: }
1.560 damieng 4458: } else {
4459: $section=&mt('Group/Section').': '.$issection;
1.552 raeburn 4460: }
4461: }
1.560 damieng 4462: $middle=~s/^\[(.*)\]//;
4463: } elsif (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
4464: $readonly = 1;
4465: }
4466: $middle=~s/\.+$//;
4467: $middle=~s/^\.+//;
4468: my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
1.576 raeburn 4469: my ($is_map,$is_recursive,$mapurl,$maplevel);
4470: if ($caller eq 'overview') {
4471: if ($middle=~/^(.+)\_\_\_\((all|rec)\)$/) {
4472: $mapurl = $1;
4473: $maplevel = $2;
4474: $is_map = 1;
4475: }
4476: } elsif ($caller eq 'newoverview') {
4477: if ($middle=~/^(.+)\_\_\_\((all)\)$/) {
4478: $mapurl = $1;
4479: $maplevel = $2;
4480: $is_map = 1;
4481: }
4482: }
4483: if ($is_map) {
1.560 damieng 4484: my $leveltitle = &mt('Folder/Map');
1.576 raeburn 4485: unless (($name eq 'hiddenresource') || ($name eq 'encrypturl')) {
4486: if ($caller eq 'newoverview') {
4487: my $altkey = $thiskey;
4488: $altkey =~ s/\Q___(all)\E/___(rec)/;
4489: if ((exists($$resourcedata{$altkey})) & (!exists($$resourcedata{$thiskey}))) {
4490: $is_recursive = 1;
4491: if ($$resourcedata{$altkey.'.type'}) {
4492: $thistype=$$resourcedata{$altkey.'.type'};
4493: }
4494: $showval = $$resourcedata{$altkey};
4495: }
4496: } elsif (($caller eq 'overview') && ($maplevel eq 'rec')) {
4497: $thiskey =~ s/\Q___(rec)\E/___(all)/;
4498: $is_recursive = 1;
4499: }
1.560 damieng 4500: }
4501: $realm='<span class="LC_parm_scope_folder">'.$leveltitle.': '.&Apache::lonnet::gettitle($mapurl).' <br /><span class="LC_parm_folder">('.$mapurl.')</span></span>';
4502: } elsif ($middle) {
4503: my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
4504: $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').
4505: ': '.&Apache::lonnet::gettitle($middle).
4506: ' <br /><span class="LC_parm_symb">('.$url.' in '.$map.' id: '.
4507: $id.')</span></span>';
4508: }
4509: if ($sortorder eq 'realmstudent') {
4510: if ($realm ne $oldrealm) {
4511: $r->print(&tableend()."\n<hr /><h1>$realm</h1>");
4512: $oldrealm=$realm;
4513: $oldsection='';
4514: }
4515: if ($section ne $oldsection) {
4516: $r->print(&tableend()."\n<h2>$section</h2>");
4517: $oldsection=$section;
4518: $oldpart='';
4519: }
1.552 raeburn 4520: } else {
1.560 damieng 4521: if ($section ne $oldsection) {
4522: $r->print(&tableend()."\n<hr /><h1>$section</h1>");
4523: $oldsection=$section;
4524: $oldrealm='';
4525: }
4526: if ($realm ne $oldrealm) {
4527: $r->print(&tableend()."\n<h2>$realm</h2>");
4528: $oldrealm=$realm;
4529: $oldpart='';
1.552 raeburn 4530: }
4531: }
1.560 damieng 4532: if ($part ne $oldpart) {
4533: $r->print(&tableend().
4534: "\n".'<span class="LC_parm_part">'.&mt('Part').": $part</span>");
4535: $oldpart=$part;
1.556 raeburn 4536: }
1.560 damieng 4537: #
4538: # Ready to print
4539: #
1.470 raeburn 4540: my $parmitem = &standard_parameter_names($name);
1.576 raeburn 4541: $r->print(&tablestart($readonly,$is_map).
1.560 damieng 4542: &Apache::loncommon::start_data_table_row().
4543: '<td><b>'.&mt($parmitem).
4544: '</b></td>');
4545: unless ($readonly) {
4546: $r->print('<td><input type="checkbox" name="del_'.
4547: $thiskey.'" /></td>');
4548: }
4549: $r->print('<td>');
4550: $foundkeys++;
4551: if (&isdateparm($thistype)) {
4552: my $jskey='key_'.$pointer;
4553: my $state;
4554: $pointer++;
4555: if ($readonly) {
4556: $state = 'disabled';
4557: }
4558: $r->print(
4559: &Apache::lonhtmlcommon::date_setter('parmform',
4560: $jskey,
1.576 raeburn 4561: $showval,
1.560 damieng 4562: '',1,$state));
4563: unless ($readonly) {
4564: $r->print(
4565: '<input type="hidden" name="datepointer_'.$thiskey.'" value="'.$jskey.'" />'.
1.576 raeburn 4566: (($showval!=0)?'<span class="LC_nobreak"><a href="/adm/parmset?&action=dateshift1&timebase='.$showval.'">'.
1.560 damieng 4567: &mt('Shift all dates based on this date').'</a></span>':'').
1.576 raeburn 4568: &date_sanity_info($showval)
1.560 damieng 4569: );
4570: }
4571: } elsif ($thistype eq 'date_interval') {
4572: $r->print(&date_interval_selector($thiskey,$name,
1.576 raeburn 4573: $showval,$readonly));
1.560 damieng 4574: } elsif ($thistype =~ m/^string/) {
4575: $r->print(&string_selector($thistype,$thiskey,
1.576 raeburn 4576: $showval,$name,$readonly));
1.560 damieng 4577: } else {
1.576 raeburn 4578: $r->print(&default_selector($thiskey,$showval,$readonly));
1.552 raeburn 4579: }
1.560 damieng 4580: unless ($readonly) {
4581: $r->print('<input type="hidden" name="typeof_'.$thiskey.'" value="'.
4582: $thistype.'" />');
1.552 raeburn 4583: }
1.576 raeburn 4584: $r->print('</td>');
4585: if ($is_map) {
4586: if (($name eq 'encrypturl') || ($name eq 'hiddenresource')) {
4587: $r->print('<td><table><tr><td>'.&mt('Yes').'</td></tr></table></td>');
4588: } else {
4589: my ($disabled,$recon,$recoff);
4590: if ($readonly) {
4591: $disabled = ' disabled="disabled"';
4592: }
4593: if ($is_recursive) {
4594: $recon = ' checked="checked"';
4595: } else {
4596: $recoff = ' checked="checked"';
4597: }
4598: $r->print('<td><table><tr><td><label><input type="radio" name="rec_'.$thiskey.'" value="1"'.$recon.$disabled.' />'.&mt('Yes').'</label>'.
4599: '</td><td><label><input type="radio" name="rec_'.$thiskey.'" value="0"'.$recoff.$disabled.' />'.&mt('No').'</label></td></tr></table></td>');
4600: }
4601: }
4602: $r->print(&Apache::loncommon::end_data_table_row());
1.473 amueller 4603: }
1.121 www 4604: }
1.208 www 4605: return $foundkeys;
4606: }
4607:
1.563 damieng 4608: # Returns a string representing the interval, directly using form data matching the given key.
4609: # The returned string may also include information related to proctored exams.
4610: # Format: seconds['_done'[':'done button title':']['_proctor'['_'proctor key]]]
4611: #
4612: # @param {string} $key - suffix for form fields related to the interval
4613: # @returns {string}
1.385 albertel 4614: sub get_date_interval_from_form {
4615: my ($key) = @_;
4616: my $seconds = 0;
4617: foreach my $which (['days', 86400],
1.473 amueller 4618: ['hours', 3600],
4619: ['minutes', 60],
4620: ['seconds', 1]) {
1.560 damieng 4621: my ($name, $factor) = @{ $which };
4622: if (defined($env{'form.'.$name.'_'.$key})) {
4623: $seconds += $env{'form.'.$name.'_'.$key} * $factor;
4624: }
1.473 amueller 4625: }
1.560 damieng 4626: if (($key =~ /\.interval$/) &&
4627: (($env{'form.done_'.$key} eq '_done') || ($env{'form.done_'.$key} eq '_done_proctor'))) {
1.559 raeburn 4628: if ($env{'form.done_'.$key.'_buttontext'}) {
4629: $env{'form.done_'.$key.'_buttontext'} =~ s/\://g;
4630: $seconds .= '_done:'.$env{'form.done_'.$key.'_buttontext'}.':';
4631: if ($env{'form.done_'.$key} eq '_done_proctor') {
4632: $seconds .= '_proctor';
4633: }
4634: } else {
4635: $seconds .= $env{'form.done_'.$key};
4636: }
4637: if (($env{'form.done_'.$key} eq '_done_proctor') &&
1.560 damieng 4638: ($env{'form.done_'.$key.'_proctorkey'})) {
1.558 raeburn 4639: $seconds .= '_'.$env{'form.done_'.$key.'_proctorkey'};
4640: }
1.554 raeburn 4641: }
1.385 albertel 4642: return $seconds;
4643: }
4644:
4645:
1.563 damieng 4646: # Returns HTML to enter a text value for a parameter.
4647: #
4648: # @param {string} $thiskey - parameter key
4649: # @param {string} $showval - the current value
4650: # @param {boolean} $readonly - true if the field should not be made editable
4651: # @returns {string}
1.383 albertel 4652: sub default_selector {
1.552 raeburn 4653: my ($thiskey, $showval, $readonly) = @_;
4654: my $disabled;
4655: if ($readonly) {
4656: $disabled = ' disabled="disabled"';
4657: }
4658: return '<input type="text" name="set_'.$thiskey.'" value="'.$showval.'"'.$disabled.' />';
1.383 albertel 4659: }
4660:
1.563 damieng 4661: # Returns HTML to enter allow/deny rules related to IP addresses.
4662: #
4663: # @param {string} $thiskey - parameter key
4664: # @param {string} $showval - the current value
4665: # @param {boolean} $readonly - true if the fields should not be made editable
4666: # @returns {string}
1.549 raeburn 4667: sub string_ip_selector {
1.552 raeburn 4668: my ($thiskey, $showval, $readonly) = @_;
1.549 raeburn 4669: my %access = (
4670: allow => [],
4671: deny => [],
4672: );
4673: if ($showval ne '') {
4674: my @current;
4675: if ($showval =~ /,/) {
4676: @current = split(/,/,$showval);
4677: } else {
4678: @current = ($showval);
4679: }
4680: foreach my $item (@current) {
4681: if ($item =~ /^\!([\[\]a-zA-Z\.\d\*\-]+)$/) {
4682: push(@{$access{'deny'}},$1);
4683: } elsif ($item =~ /^([\[\]a-zA-Z\.\d\*\-]+)$/) {
4684: push(@{$access{'allow'}},$item);
4685: }
4686: }
4687: }
4688: if (!@{$access{'allow'}}) {
4689: @{$access{'allow'}} = ('');
4690: }
4691: if (!@{$access{'deny'}}) {
4692: @{$access{'deny'}} = ('');
4693: }
1.552 raeburn 4694: my ($disabled,$addmore);
1.567 raeburn 4695: if ($readonly) {
1.552 raeburn 4696: $disabled=' disabled="disabled"';
4697: } else {
4698: $addmore = "\n".'<button class="LC_add_ipacc_button">'.&mt('Add more').'</button>';
4699: }
1.549 raeburn 4700: my $output = '<input type="hidden" name="set_'.$thiskey.'" />
4701: <table><tr><th>'.&mt('Allow from').'</th><th>'.&mt('Deny from').'</th></tr><tr>';
4702: foreach my $acctype ('allow','deny') {
4703: $output .= '
4704: <td valign="top">
4705: <div class="LC_string_ipacc_wrap" id="LC_string_ipacc_'.$acctype.'_'.$thiskey.'">
4706: <div class="LC_string_ipacc_inner">'."\n";
4707: my $num = 0;
4708: foreach my $curr (@{$access{$acctype}}) {
1.552 raeburn 4709: $output .= '<div><input type="text" name="setip'.$acctype.'_'.$thiskey.'" value="'.$curr.'"'.$disabled.' />';
1.549 raeburn 4710: if ($num > 0) {
4711: $output .= '<a href="#" class="LC_remove_ipacc">'.&mt('Remove').'</a>';
4712: }
4713: $output .= '</div>'."\n";
4714: $num ++;
4715: }
4716: $output .= '
1.552 raeburn 4717: </div>'.$addmore.'
1.549 raeburn 4718: </div>
4719: </td>';
4720: }
4721: $output .= '
4722: </tr>
4723: </table>'."\n";
4724: return $output;
4725: }
4726:
1.588 ! raeburn 4727: sub string_deeplink_selector {
! 4728: my ($thiskey, $showval, $readonly) = @_;
! 4729: my (@components,%values,@current,%titles,%options,%optiontext,%defaults,%posslti);
! 4730: @components = ('listing','scope','urls');
! 4731: %titles = &Apache::lonlocal::texthash (
! 4732: listing => 'In Contents and/or Gradebook',
! 4733: scope => 'Access scope for link',
! 4734: urls => 'Supported link types',
! 4735: );
! 4736: %options = (
! 4737: listing => ['full','absent','grades','details','datestatus'],
! 4738: scope => ['res','map','rec'],
! 4739: urls => ['any','only','key','lti'],
! 4740: );
! 4741: %optiontext = &Apache::lonlocal::texthash (
! 4742: full => 'Listed (linked) in both',
! 4743: absent => 'Not listed',
! 4744: grades => 'Listed in grades only',
! 4745: details => 'Listed (unlinked) in both',
! 4746: datestatus => 'Listed (unlinked) inc. status in both',
! 4747: res => 'resource only',
! 4748: map => 'enclosing map/folder',
! 4749: rec => 'recursive map/folder',
! 4750: any => 'regular + deep',
! 4751: only => 'deep only',
! 4752: key => 'deep with key',
! 4753: lti => 'deep with LTI launch',
! 4754: );
! 4755: if ($showval =~ /,/) {
! 4756: @current = split(/,/,$showval);
! 4757: ($values{'listing'}) = ($current[0] =~ /^(full|absent|grades|details|datestatus)$/);
! 4758: ($values{'scope'}) = ($current[1] =~ /^(res|map|rec)$/);
! 4759: ($values{'urls'}) = ($current[2] =~ /^(any|only|key:\w+|lti:\d+)$/);
! 4760: } else {
! 4761: $defaults{'listing'} = 'full';
! 4762: $defaults{'scope'} = 'res';
! 4763: $defaults{'urls'} = 'any';
! 4764: }
! 4765: my $disabled;
! 4766: if ($readonly) {
! 4767: $disabled=' disabled="disabled"';
! 4768: }
! 4769: my %lti =
! 4770: &Apache::lonnet::get_domain_lti($env{'course.'.$env{'request.course.id'}.'.domain'},
! 4771: 'provider');
! 4772: foreach my $item (keys(%lti)) {
! 4773: if (ref($lti{$item}) eq 'HASH') {
! 4774: unless ($lti{$item}{'requser'}) {
! 4775: $posslti{$item} = $lti{$item}{'consumer'};
! 4776: }
! 4777: }
! 4778: }
! 4779: my $output = '<input type="hidden" name="set_'.$thiskey.'" /><table><tr>';
! 4780: foreach my $item ('listing','scope','urls') {
! 4781: $output .= '<th>'.$titles{$item}.'</th>';
! 4782: }
! 4783: $output .= '</tr><tr>';
! 4784: foreach my $item (@components) {
! 4785: $output .= '<td>';
! 4786: if ($item eq 'urls') {
! 4787: my $selected = $values{$item};
! 4788: foreach my $option (@{$options{$item}}) {
! 4789: if ($option eq 'lti') {
! 4790: next unless (keys(%posslti));
! 4791: }
! 4792: my $checked;
! 4793: if ($selected =~ /^\Q$option\E/) {
! 4794: $checked = ' checked="checked"';
! 4795: }
! 4796: my $onclick;
! 4797: unless ($readonly) {
! 4798: my $esc_key = &js_escape($thiskey);
! 4799: $onclick = ' onclick="toggleDeepLink(this.form,'."'$item','$esc_key'".');"';
! 4800: }
! 4801: $output .= '<span class="LC_nobreak"><label>'.
! 4802: '<input type="radio" name="deeplink_'.$item.'_'.$thiskey.'" value="'.$option.'"'.$onclick.$disabled.$checked.' />'."\n".
! 4803: $optiontext{$option}.'</label>';
! 4804: if ($option eq 'key') {
! 4805: my $visibility="hidden";
! 4806: my $currkey;
! 4807: if ($checked) {
! 4808: $visibility = "text";
! 4809: $currkey = (split(/\:/,$values{$item}))[1];
! 4810: }
! 4811: $output .= ' '.
! 4812: '<input type="'.$visibility.'" name="deeplink_'.$option.'_'.$thiskey.'" id="deeplink_'.$option.'_'.$item.'_'.$thiskey.'" value="'.$currkey.'" size="6"'.$disabled.' />';
! 4813: } elsif ($option eq 'lti') {
! 4814: my $display="none";
! 4815: my ($currlti,$blankcheck);
! 4816: if ($checked) {
! 4817: $display = 'inline-block';
! 4818: $currlti = (split(/\:/,$values{$item}))[1];
! 4819: } else {
! 4820: $blankcheck = ' selected="selected"';
! 4821: }
! 4822: $output .= '<div id="deeplinkdiv_'.$option.'_'.$item.'_'.$thiskey.'"'.
! 4823: ' style="display: '.$display.'"> <select name="'.
! 4824: 'deeplink_'.$option.'_'.$thiskey.'"'.$disabled.'>'.
! 4825: '<option value=""'.$blankcheck.'>'.&mt('Select Provider').'</option>'."\n";
! 4826: foreach my $lti (sort { $a <=> $b } keys(%posslti)) {
! 4827: my $selected;
! 4828: if ($lti == $currlti) {
! 4829: $selected = ' selected="selected"';
! 4830: }
! 4831: $output .= '<option value="'.$lti.'"'.$selected.'>'.$posslti{$lti}.'</option>';
! 4832: }
! 4833: $output .= '</select></div>';
! 4834: }
! 4835: $output .= '</span> ';
! 4836: }
! 4837: } else {
! 4838: my $selected = $values{$item};
! 4839: my $defsel;
! 4840: if ($selected eq '') {
! 4841: $defsel = ' selected="selected"';
! 4842: }
! 4843: $output .= '<select name="deeplink_'.$item.'_'.$thiskey.'"'.$disabled.'>'."\n".
! 4844: '<option value=""'.$defsel.'>'.&mt('Please select').'</option>'."\n";
! 4845: foreach my $option (@{$options{$item}}) {
! 4846: $output .= '<option value="'.$option.'"';
! 4847: if ($option eq $selected) {
! 4848: $output .= ' selected="selected"';
! 4849: }
! 4850: $output .= '>'.$optiontext{$option}.'</option>';
! 4851: }
! 4852: $output .= '</select>';
! 4853: }
! 4854: $output .= '</td>';
! 4855: }
! 4856: $output .= '</tr></table>'."\n";
! 4857: return $output;
! 4858: }
! 4859:
1.560 damieng 4860:
4861: { # block using some constants related to parameter types (overview mode)
4862:
1.446 bisitz 4863: my %strings =
1.383 albertel 4864: (
4865: 'string_yesno'
4866: => [[ 'yes', 'Yes' ],
1.560 damieng 4867: [ 'no', 'No' ]],
1.383 albertel 4868: 'string_problemstatus'
4869: => [[ 'yes', 'Yes' ],
1.473 amueller 4870: [ 'answer', 'Yes, and show correct answer if they exceed the maximum number of tries.' ],
4871: [ 'no', 'No, don\'t show correct/incorrect feedback.' ],
4872: [ 'no_feedback_ever', 'No, show no feedback at all.' ]],
1.504 raeburn 4873: 'string_questiontype'
4874: => [[ 'problem', 'Standard Problem'],
4875: [ 'survey', 'Survey'],
4876: [ 'anonsurveycred', 'Anonymous Survey (credit for submission)'],
1.530 bisitz 4877: [ 'exam', 'Bubblesheet Exam'],
1.504 raeburn 4878: [ 'anonsurvey', 'Anonymous Survey'],
4879: [ 'randomizetry', 'New Randomization Each N Tries (default N=1)'],
4880: [ 'practice', 'Practice'],
4881: [ 'surveycred', 'Survey (credit for submission)']],
1.514 raeburn 4882: 'string_lenient'
4883: => [['yes', 'Yes' ],
4884: [ 'no', 'No' ],
1.549 raeburn 4885: [ 'default', 'Default - only bubblesheet grading is lenient' ],
4886: [ 'weighted', 'Yes, weighted (optionresponse in checkbox mode)' ]],
1.521 raeburn 4887: 'string_discussvote'
4888: => [['yes','Yes'],
4889: ['notended','Yes, unless discussion ended'],
4890: ['no','No']],
1.549 raeburn 4891: 'string_ip'
4892: => [['_allowfrom_','Hostname(s), or IP(s) from which access is allowed'],
1.587 raeburn 4893: ['_denyfrom_','Hostname(s) or IP(s) from which access is disallowed']],
4894: 'string_deeplink'
1.588 ! raeburn 4895: => [['on','Set choices for link protection, resource listing, and access scope']],
1.587 raeburn 4896: );
4897:
1.383 albertel 4898:
1.549 raeburn 4899: my %stringmatches = (
4900: 'string_lenient'
4901: => [['weighted','^\-?[.\d]+,\-?[.\d]+,\-?[.\d]+,\-?[.\d]+$'],],
4902: 'string_ip'
4903: => [['_allowfrom_','[^\!]+'],
4904: ['_denyfrom_','\!']],
1.588 ! raeburn 4905: 'string_deeplink'
! 4906: => [['on','^(full|absent|grades|details|datestatus)\,(res|map|rec)\,(any|only|key\:\w+|lti\:\d+)$']],
1.549 raeburn 4907: );
4908:
4909: my %stringtypes = (
4910: type => 'string_questiontype',
4911: lenient => 'string_lenient',
4912: retrypartial => 'string_yesno',
4913: discussvote => 'string_discussvote',
4914: examcode => 'string_examcode',
4915: acc => 'string_ip',
1.587 raeburn 4916: deeplink => 'string_deeplink',
1.549 raeburn 4917: );
4918:
1.563 damieng 4919: # Returns the possible values and titles for a given string type, or undef if there are none.
4920: # Used by courseprefs.
4921: #
4922: # @param {string} $string_type - a parameter type for strings
4923: # @returns {array reference} - 2D array, containing values and English titles
1.505 raeburn 4924: sub standard_string_options {
4925: my ($string_type) = @_;
4926: if (ref($strings{$string_type}) eq 'ARRAY') {
4927: return $strings{$string_type};
4928: }
4929: return;
4930: }
1.383 albertel 4931:
1.563 damieng 4932: # Returns regular expressions to match kinds of string types, or undef if there are none.
4933: #
4934: # @param {string} $string_type - a parameter type for strings
4935: # @returns {array reference} - 2D array, containing regular expression names and regular expressions
1.549 raeburn 4936: sub standard_string_matches {
4937: my ($string_type) = @_;
4938: if (ref($stringmatches{$string_type}) eq 'ARRAY') {
4939: return $stringmatches{$string_type};
4940: }
4941: return;
4942: }
4943:
1.563 damieng 4944: # Returns a parameter type for a given parameter with a string type, or undef if not known.
4945: #
4946: # @param {string} $name - parameter name
4947: # @returns {string}
1.549 raeburn 4948: sub get_stringtype {
4949: my ($name) = @_;
4950: if (exists($stringtypes{$name})) {
4951: return $stringtypes{$name};
4952: }
4953: return;
4954: }
4955:
1.563 damieng 4956: # Returns HTML to edit a string parameter.
4957: #
4958: # @param {string} $thistype - parameter type
4959: # @param {string} $thiskey - parameter key
4960: # @param {string} $showval - parameter current value
4961: # @param {string} $name - parameter name
4962: # @param {boolean} $readonly - true if the values should not be made editable
4963: # @returns {string}
1.383 albertel 4964: sub string_selector {
1.552 raeburn 4965: my ($thistype, $thiskey, $showval, $name, $readonly) = @_;
1.446 bisitz 4966:
1.383 albertel 4967: if (!exists($strings{$thistype})) {
1.552 raeburn 4968: return &default_selector($thiskey,$showval,$readonly);
1.383 albertel 4969: }
4970:
1.504 raeburn 4971: my %skiptype;
1.514 raeburn 4972: if (($thistype eq 'string_questiontype') ||
1.560 damieng 4973: ($thistype eq 'string_lenient') ||
4974: ($thistype eq 'string_discussvote') ||
4975: ($thistype eq 'string_ip') ||
1.588 ! raeburn 4976: ($thistype eq 'string_deeplink') ||
1.560 damieng 4977: ($name eq 'retrypartial')) {
1.504 raeburn 4978: my ($got_chostname,$chostname,$cmajor,$cminor);
4979: foreach my $possibilities (@{ $strings{$thistype} }) {
4980: next unless (ref($possibilities) eq 'ARRAY');
1.514 raeburn 4981: my ($parmval, $description) = @{ $possibilities };
1.549 raeburn 4982: my $parmmatch;
4983: if (ref($stringmatches{$thistype}) eq 'ARRAY') {
4984: foreach my $item (@{$stringmatches{$thistype}}) {
4985: if (ref($item) eq 'ARRAY') {
4986: if ($parmval eq $item->[0]) {
4987: $parmmatch = $parmval;
4988: $parmval = '';
4989: last;
4990: }
4991: }
4992: }
4993: }
4994: my $needsrelease=$Apache::lonnet::needsrelease{"parameter:$name:$parmval:$parmmatch"};
1.504 raeburn 4995: if ($needsrelease) {
4996: unless ($got_chostname) {
1.514 raeburn 4997: ($chostname,$cmajor,$cminor)=¶meter_release_vars();
1.504 raeburn 4998: $got_chostname = 1;
4999: }
1.557 raeburn 5000: my $needsnewer=¶meter_releasecheck($name,$parmval,$parmmatch,undef,
1.549 raeburn 5001: $needsrelease,$cmajor,$cminor);
1.504 raeburn 5002: if ($needsnewer) {
1.549 raeburn 5003: if ($parmmatch ne '') {
5004: $skiptype{$parmmatch} = 1;
5005: } elsif ($parmval ne '') {
5006: $skiptype{$parmval} = 1;
5007: }
1.504 raeburn 5008: }
5009: }
5010: }
5011: }
1.549 raeburn 5012:
5013: if ($thistype eq 'string_ip') {
1.552 raeburn 5014: return &string_ip_selector($thiskey,$showval,$readonly);
1.588 ! raeburn 5015: } elsif ($thistype eq 'string_deeplink') {
! 5016: return &string_deeplink_selector($thiskey,$showval,$readonly);
1.549 raeburn 5017: }
1.504 raeburn 5018:
1.552 raeburn 5019: my ($result,$disabled);
5020:
5021: if ($readonly) {
5022: $disabled = ' disabled="disabled"';
5023: }
1.504 raeburn 5024: my $numinrow = 3;
5025: if ($thistype eq 'string_problemstatus') {
5026: $numinrow = 2;
5027: } elsif ($thistype eq 'string_questiontype') {
5028: if (keys(%skiptype) > 0) {
5029: $numinrow = 4;
5030: }
5031: }
5032: my $rem;
5033: if (ref($strings{$thistype}) eq 'ARRAY') {
5034: my $i=0;
5035: foreach my $possibilities (@{ $strings{$thistype} }) {
5036: next unless (ref($possibilities) eq 'ARRAY');
5037: my ($name, $description) = @{ $possibilities };
1.549 raeburn 5038: next if ($skiptype{$name});
1.504 raeburn 5039: $rem = $i%($numinrow);
5040: if ($rem == 0) {
5041: if ($i > 0) {
5042: $result .= '</tr>';
5043: }
5044: $result .= '<tr>';
5045: }
1.549 raeburn 5046: my $colspan;
5047: if ($i == @{ $strings{$thistype} }-1) {
5048: $rem = @{ $strings{$thistype} }%($numinrow);
5049: if ($rem) {
5050: my $colsleft = $numinrow - $rem;
5051: if ($colsleft) {
5052: $colspan = $colsleft+1;
5053: $colspan = ' colspan="'.$colspan.'"';
5054: }
5055: }
5056: }
5057: my ($add,$onchange,$css_class);
5058: if ($thistype eq 'string_lenient') {
5059: if ($name eq 'weighted') {
5060: my $display;
5061: my %relatives = &Apache::lonlocal::texthash(
5062: corrchkd => 'Correct (checked)',
5063: corrunchkd => 'Correct (unchecked)',
5064: incorrchkd => 'Incorrect (checked)',
5065: incorrunchkd => 'Incorrect (unchecked)',
5066: );
5067: my %textval = (
5068: corrchkd => '1.0',
5069: corrunchkd => '1.0',
5070: incorrchkd => '0.0',
5071: incorrunchkd => '0.0',
5072: );
5073: if ($showval =~ /^([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)$/) {
5074: $textval{'corrchkd'} = $1;
5075: $textval{'corrunchkd'} = $2;
5076: $textval{'incorrchkd'} = $3;
5077: $textval{'incorrunchkd'} = $4;
5078: $display = 'inline';
5079: $showval = $name;
5080: } else {
5081: $display = 'none';
5082: }
5083: $add = ' <div id="LC_parmtext_'.$thiskey.'" style="display:'.$display.'"><table>'.
5084: '<tr><th colspan="2">'.&mt("Foil's submission status").'</th><th>'.&mt('Points').'</th></tr>';
5085: foreach my $reltype ('corrchkd','corrunchkd','incorrchkd','incorrunchkd') {
5086: $add .= '<tr><td> </td><td>'.$relatives{$reltype}.'</td>'."\n".
5087: '<td><input type="text" name="settext_'.$thiskey.'"'.
1.552 raeburn 5088: ' value="'.$textval{$reltype}.'" size="3"'.$disabled.' />'.
1.549 raeburn 5089: '</td></tr>';
5090: }
5091: $add .= '</table></div>'."\n";
5092: }
5093: $onchange = ' onclick="javascript:toggleParmTextbox(this.form,'."'$thiskey'".');"';
5094: $css_class = ' class="LC_lenient_radio"';
5095: }
5096: $result .= '<td class="LC_left_item"'.$colspan.'>'.
1.504 raeburn 5097: '<span class="LC_nobreak"><label>'.
5098: '<input type="radio" name="set_'.$thiskey.
1.552 raeburn 5099: '" value="'.$name.'"'.$onchange.$css_class.$disabled;
1.504 raeburn 5100: if ($showval eq $name) {
5101: $result .= ' checked="checked"';
5102: }
1.549 raeburn 5103: $result .= ' />'.&mt($description).'</label>'.$add.'</span></td>';
1.504 raeburn 5104: $i++;
5105: }
5106: $result .= '</tr>';
1.473 amueller 5107: }
1.504 raeburn 5108: if ($result) {
5109: $result = '<table border="0">'.$result.'</table>';
1.383 albertel 5110: }
5111: return $result;
5112: }
5113:
1.554 raeburn 5114: my %intervals =
5115: (
5116: 'date_interval'
5117: => [[ 'done', 'Yes' ],
1.558 raeburn 5118: [ 'done_proctor', 'Yes, with proctor key'],
1.554 raeburn 5119: [ '', 'No' ]],
5120: );
5121:
5122: my %intervalmatches = (
5123: 'date_interval'
1.559 raeburn 5124: => [['done','\d+_done(|\:[^\:]+\:)$'],
5125: ['done_proctor','\d+_done(|\:[^\:]+\:)_proctor_']],
1.554 raeburn 5126: );
5127:
5128: my %intervaltypes = (
5129: interval => 'date_interval',
5130: );
5131:
1.563 damieng 5132: # Returns regular expressions to match kinds of interval type, or undef if there are none.
5133: #
5134: # @param {string} $interval_type - a parameter type for intervals
5135: # @returns {array reference} - 2D array, containing regular expression names and regular expressions
1.554 raeburn 5136: sub standard_interval_matches {
5137: my ($interval_type) = @_;
5138: if (ref($intervalmatches{$interval_type}) eq 'ARRAY') {
5139: return $intervalmatches{$interval_type};
5140: }
5141: return;
5142: }
5143:
1.563 damieng 5144: # Returns a parameter type for a given parameter with an interval type, or undef if not known.
5145: #
5146: # @param {string} $name - parameter name
5147: # @returns {string}
1.554 raeburn 5148: sub get_intervaltype {
5149: my ($name) = @_;
5150: if (exists($intervaltypes{$name})) {
5151: return $intervaltypes{$name};
5152: }
5153: return;
5154: }
5155:
1.563 damieng 5156: # Returns the possible values and titles for a given interval type, or undef if there are none.
5157: # Used by courseprefs.
5158: #
5159: # @param {string} $interval_type - a parameter type for intervals
5160: # @returns {array reference} - 2D array, containing values and English titles
1.554 raeburn 5161: sub standard_interval_options {
5162: my ($interval_type) = @_;
5163: if (ref($intervals{$interval_type}) eq 'ARRAY') {
5164: return $intervals{$interval_type};
5165: }
5166: return;
5167: }
5168:
1.563 damieng 5169: # Returns HTML to edit a date interval parameter.
5170: #
5171: # @param {string} $thiskey - parameter key
5172: # @param {string} $name - parameter name
5173: # @param {string} $showval - parameter current value
5174: # @param {boolean} $readonly - true if the values should not be made editable
5175: # @returns {string}
1.554 raeburn 5176: sub date_interval_selector {
5177: my ($thiskey, $name, $showval, $readonly) = @_;
5178: my ($result,%skipval);
5179: if ($name eq 'interval') {
5180: my $intervaltype = &get_intervaltype($name);
5181: my ($got_chostname,$chostname,$cmajor,$cminor);
5182: foreach my $possibilities (@{ $intervals{$intervaltype} }) {
5183: next unless (ref($possibilities) eq 'ARRAY');
5184: my ($parmval, $description) = @{ $possibilities };
5185: my $parmmatch;
5186: if (ref($intervalmatches{$intervaltype}) eq 'ARRAY') {
5187: foreach my $item (@{$intervalmatches{$intervaltype}}) {
5188: if (ref($item) eq 'ARRAY') {
5189: if ($parmval eq $item->[0]) {
5190: $parmmatch = $parmval;
5191: $parmval = '';
5192: last;
5193: }
5194: }
5195: }
5196: }
5197: my $needsrelease=$Apache::lonnet::needsrelease{"parameter:$name:$parmval:$parmmatch"};
5198: if ($needsrelease) {
5199: unless ($got_chostname) {
5200: ($chostname,$cmajor,$cminor)=¶meter_release_vars();
5201: $got_chostname = 1;
5202: }
1.557 raeburn 5203: my $needsnewer=¶meter_releasecheck($name,$parmval,$parmmatch,undef,
1.554 raeburn 5204: $needsrelease,$cmajor,$cminor);
5205: if ($needsnewer) {
5206: if ($parmmatch ne '') {
5207: $skipval{$parmmatch} = 1;
5208: } elsif ($parmval ne '') {
5209: $skipval{$parmval} = 1;
5210: }
5211: }
5212: }
5213: }
5214: }
5215:
5216: my $currval = $showval;
5217: foreach my $which (['days', 86400, 31],
5218: ['hours', 3600, 23],
5219: ['minutes', 60, 59],
5220: ['seconds', 1, 59]) {
1.560 damieng 5221: my ($name, $factor, $max) = @{ $which };
5222: my $amount = int($showval/$factor);
5223: $showval %= $factor;
5224: my %select = ((map {$_ => $_} (0..$max)),
5225: 'select_form_order' => [0..$max]);
5226: $result .= &Apache::loncommon::select_form($amount,$name.'_'.$thiskey,
5227: \%select,'',$readonly);
5228: $result .= ' '.&mt($name);
1.554 raeburn 5229: }
5230: if ($name eq 'interval') {
5231: unless ($skipval{'done'}) {
5232: my $checkedon = '';
1.558 raeburn 5233: my $checkedproc = '';
5234: my $currproctorkey = '';
5235: my $currprocdisplay = 'hidden';
1.559 raeburn 5236: my $currdonetext = &mt('Done');
1.554 raeburn 5237: my $checkedoff = ' checked="checked"';
1.559 raeburn 5238: if ($currval =~ /^(?:\d+)_done$/) {
5239: $checkedon = ' checked="checked"';
5240: $checkedoff = '';
5241: } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:$/) {
5242: $currdonetext = $1;
1.554 raeburn 5243: $checkedon = ' checked="checked"';
5244: $checkedoff = '';
1.558 raeburn 5245: } elsif ($currval =~ /^(?:\d+)_done_proctor_(.+)$/) {
5246: $currproctorkey = $1;
5247: $checkedproc = ' checked="checked"';
5248: $checkedoff = '';
5249: $currprocdisplay = 'text';
1.559 raeburn 5250: } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:_proctor_(.+)$/) {
5251: $currdonetext = $1;
5252: $currproctorkey = $2;
5253: $checkedproc = ' checked="checked"';
5254: $checkedoff = '';
5255: $currprocdisplay = 'text';
1.554 raeburn 5256: }
1.558 raeburn 5257: my $onclick = ' onclick="toggleSecret(this.form,'."'done_','$thiskey'".');"';
1.567 raeburn 5258: my $disabled;
5259: if ($readonly) {
5260: $disabled = ' disabled="disabled"';
5261: }
1.558 raeburn 5262: $result .= '<br /><span class="LC_nobreak">'.&mt('Include "done" button').
1.567 raeburn 5263: '<label><input type="radio" value="" name="done_'.$thiskey.'"'.$checkedoff.$onclick.$disabled.' />'.
1.558 raeburn 5264: &mt('No').'</label>'.(' 'x2).
1.567 raeburn 5265: '<label><input type="radio" value="_done" name="done_'.$thiskey.'"'.$checkedon.$onclick.$disabled.' />'.
1.558 raeburn 5266: &mt('Yes').'</label>'.(' 'x2).
1.567 raeburn 5267: '<label><input type="radio" value="_done_proctor" name="done_'.$thiskey.'"'.$checkedproc.$onclick.$disabled.' />'.
1.558 raeburn 5268: &mt('Yes, with proctor key').'</label>'.
5269: '<input type="'.$currprocdisplay.'" id="done_'.$thiskey.'_proctorkey" '.
1.567 raeburn 5270: 'name="done_'.$thiskey.'_proctorkey" value="'.&HTML::Entities::encode($currproctorkey,'"<>&').'"'.$disabled.' /></span><br />'.
1.559 raeburn 5271: '<span class="LC_nobreak">'.&mt('Button text').': '.
1.567 raeburn 5272: '<input type="text" name="done_'.$thiskey.'_buttontext" value="'.&HTML::Entities::encode($currdonetext,'"<>&').'"'.$disabled.' /></span>';
1.554 raeburn 5273: }
5274: }
5275: unless ($readonly) {
5276: $result .= '<input type="hidden" name="dateinterval_'.$thiskey.'" />';
5277: }
5278: return $result;
5279: }
5280:
1.563 damieng 5281: # Returns HTML with a warning if a parameter requires a more recent version of LON-CAPA.
5282: #
5283: # @param {string} $name - parameter name
5284: # @param {string} $namematch - parameter level name (recognized: resourcelevel|maplevel|maplevelrecurse|courselevel)
5285: # @param {string} $value - parameter value
5286: # @param {string} $chostname - course server name
5287: # @param {integer} $cmajor - major version number
5288: # @param {integer} $cminor - minor version number
5289: # @param {string} $needsrelease - release version needed (major.minor)
5290: # @returns {string}
1.549 raeburn 5291: sub oldversion_warning {
1.557 raeburn 5292: my ($name,$namematch,$value,$chostname,$cmajor,$cminor,$needsrelease) = @_;
5293: my $standard_name = &standard_parameter_names($name);
5294: if ($namematch) {
5295: my $level = &standard_parameter_levels($namematch);
5296: my $msg = '';
5297: if ($level) {
5298: $msg = &mt('[_1] was [_2]not[_3] set at the level of: [_4].',
5299: $standard_name,'<b>','</b>','"'.$level.'"');
5300: } else {
5301: $msg = &mt('[_1] was [_2]not[_3] set.',
5302: $standard_name,'<b>','</b>');
5303: }
5304: return '<p class="LC_warning">'.$msg.'<br />'.
5305: &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',
5306: $cmajor.'.'.$cminor,$chostname,
5307: $needsrelease).
5308: '</p>';
5309: }
1.549 raeburn 5310: my $desc;
5311: my $stringtype = &get_stringtype($name);
5312: if ($stringtype ne '') {
5313: if ($name eq 'examcode') {
5314: $desc = $value;
5315: } elsif (ref($strings{$stringtypes{$name}}) eq 'ARRAY') {
5316: foreach my $possibilities (@{ $strings{$stringtypes{$name}} }) {
5317: next unless (ref($possibilities) eq 'ARRAY');
5318: my ($parmval, $description) = @{ $possibilities };
5319: my $parmmatch;
5320: if (ref($stringmatches{$stringtypes{$name}}) eq 'ARRAY') {
5321: foreach my $item (@{$stringmatches{$stringtypes{$name}}}) {
5322: if (ref($item) eq 'ARRAY') {
5323: my ($regexpname,$pattern) = @{$item};
5324: if ($parmval eq $regexpname) {
5325: if ($value =~ /$pattern/) {
5326: $desc = $description;
5327: $parmmatch = 1;
5328: last;
5329: }
5330: }
5331: }
5332: }
5333: last if ($parmmatch);
5334: } elsif ($parmval eq $value) {
5335: $desc = $description;
5336: last;
5337: }
5338: }
5339: }
5340: } elsif (($name eq 'printstartdate') || ($name eq 'printenddate')) {
5341: my $now = time;
5342: if ($value =~ /^\d+$/) {
5343: if ($name eq 'printstartdate') {
5344: if ($value > $now) {
5345: $desc = &Apache::lonlocal::locallocaltime($value);
5346: }
5347: } elsif ($name eq 'printenddate') {
5348: if ($value < $now) {
5349: $desc = &Apache::lonlocal::locallocaltime($value);
5350: }
5351: }
5352: }
5353: }
5354: return '<p class="LC_warning">'.
1.557 raeburn 5355: &mt('[_1] was [_2]not[_3] set to [_4].',
5356: $standard_name,'<b>','</b>','"'.$desc.'"').'<br />'.
5357: &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',
5358: $cmajor.'.'.$cminor,$chostname,
5359: $needsrelease).
5360: '</p>';
1.549 raeburn 5361: }
5362:
1.560 damieng 5363: } # end of block using some constants related to parameter types
5364:
1.549 raeburn 5365:
1.563 damieng 5366:
5367: # Shifts all start and end dates in the current course by $shift.
1.389 www 5368: #
1.563 damieng 5369: # @param {integer} $shift - time to shift, in seconds
5370: # @returns {string} - error name or 'ok'
1.389 www 5371: sub dateshift {
5372: my ($shift)=@_;
5373: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
5374: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
5375: my %data=&Apache::lonnet::dump('resourcedata',$dom,$crs);
5376: # ugly retro fix for broken version of types
1.548 raeburn 5377: foreach my $key (keys(%data)) {
1.389 www 5378: if ($key=~/\wtype$/) {
5379: my $newkey=$key;
5380: $newkey=~s/type$/\.type/;
5381: $data{$newkey}=$data{$key};
5382: delete $data{$key};
5383: }
5384: }
1.391 www 5385: my %storecontent=();
1.389 www 5386: # go through all parameters and look for dates
1.548 raeburn 5387: foreach my $key (keys(%data)) {
1.389 www 5388: if ($data{$key.'.type'}=~/^date_(start|end)$/) {
5389: my $newdate=$data{$key}+$shift;
1.391 www 5390: $storecontent{$key}=$newdate;
1.389 www 5391: }
5392: }
1.391 www 5393: my $reply=&Apache::lonnet::cput
5394: ('resourcedata',\%storecontent,$dom,$crs);
5395: if ($reply eq 'ok') {
5396: &log_parmset(\%storecontent);
5397: }
5398: &Apache::lonnet::devalidatecourseresdata($crs,$dom);
5399: return $reply;
1.389 www 5400: }
5401:
1.563 damieng 5402: # Overview mode UI to edit course parameters.
5403: #
5404: # @param {Apache2::RequestRec} $r - the Apache request
1.208 www 5405: sub newoverview {
1.568 raeburn 5406: my ($r,$parm_permission) = @_;
1.280 albertel 5407:
1.208 www 5408: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
5409: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 5410: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.568 raeburn 5411: my $readonly = 1;
5412: if ($parm_permission->{'edit'}) {
5413: undef($readonly);
5414: }
1.414 droeschl 5415: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
1.473 amueller 5416: text=>"Overview Mode"});
1.523 raeburn 5417:
5418: my %loaditems = (
1.549 raeburn 5419: 'onload' => "showHide_courseContent(); resize_scrollbox('mapmenuscroll','1','1'); showHideLenient();",
1.523 raeburn 5420: );
5421: my $js = '
5422: <script type="text/javascript">
5423: // <![CDATA[
5424: '.
5425: &Apache::lonhtmlcommon::resize_scrollbox_js('params')."\n".
5426: &showhide_js()."\n".
1.549 raeburn 5427: &toggleparmtextbox_js()."\n".
5428: &validateparms_js()."\n".
5429: &ipacc_boxes_js()."\n".
1.558 raeburn 5430: &done_proctor_js()."\n".
1.588 ! raeburn 5431: &deeplink_js()."\n".
1.523 raeburn 5432: '// ]]>
5433: </script>
5434: ';
1.549 raeburn 5435:
1.523 raeburn 5436: my $start_page = &Apache::loncommon::start_page('Set Parameters',$js,
5437: {'add_entries' => \%loaditems,});
1.298 albertel 5438: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
1.507 www 5439: $r->print($start_page.$breadcrumbs);
1.531 raeburn 5440: &startSettingsScreen($r,'parmset',$crstype);
1.208 www 5441: $r->print(<<ENDOVER);
1.549 raeburn 5442: <form method="post" action="/adm/parmset?action=newoverview" name="parmform" onsubmit="return validateParms();">
1.208 www 5443: ENDOVER
1.211 www 5444: my @ids=();
5445: my %typep=();
5446: my %keyp=();
5447: my %allparms=();
5448: my %allparts=();
5449: my %allmaps=();
5450: my %mapp=();
5451: my %symbp=();
5452: my %maptitles=();
5453: my %uris=();
5454: my %keyorder=&standardkeyorder();
5455: my %defkeytype=();
5456:
5457: my %alllevs=();
5458: $alllevs{'Resource Level'}='full';
1.215 www 5459: $alllevs{'Map/Folder Level'}='map';
1.211 www 5460: $alllevs{'Course Level'}='general';
5461:
5462: my $csec=$env{'form.csec'};
1.269 raeburn 5463: my $cgroup=$env{'form.cgroup'};
1.211 www 5464:
5465: my @pscat=&Apache::loncommon::get_env_multiple('form.pscat');
5466: my $pschp=$env{'form.pschp'};
1.506 www 5467:
1.211 www 5468: my @psprt=&Apache::loncommon::get_env_multiple('form.psprt');
1.516 www 5469: if (!@psprt) { $psprt[0]='all'; }
1.211 www 5470:
1.446 bisitz 5471: my @selected_sections =
1.473 amueller 5472: &Apache::loncommon::get_env_multiple('form.Section');
1.211 www 5473: @selected_sections = ('all') if (! @selected_sections);
1.374 albertel 5474: foreach my $sec (@selected_sections) {
5475: if ($sec eq 'all') {
1.211 www 5476: @selected_sections = ('all');
5477: }
5478: }
1.552 raeburn 5479: if ($env{'request.course.sec'} ne '') {
5480: @selected_sections = ($env{'request.course.sec'});
5481: }
1.269 raeburn 5482: my @selected_groups =
5483: &Apache::loncommon::get_env_multiple('form.Group');
1.211 www 5484:
5485: my $pssymb='';
5486: my $parmlev='';
1.446 bisitz 5487:
1.211 www 5488: unless ($env{'form.parmlev'}) {
5489: $parmlev = 'map';
5490: } else {
5491: $parmlev = $env{'form.parmlev'};
5492: }
5493:
1.446 bisitz 5494: &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
1.473 amueller 5495: \%mapp, \%symbp,\%maptitles,\%uris,
5496: \%keyorder,\%defkeytype);
1.211 www 5497:
1.374 albertel 5498: if (grep {$_ eq 'all'} (@psprt)) {
1.481 amueller 5499: @psprt = keys(%allparts);
1.374 albertel 5500: }
1.211 www 5501: # Menu to select levels, etc
5502:
1.456 bisitz 5503: $r->print('<div class="LC_Box">');
1.445 neumanie 5504: #$r->print('<h2 class="LC_hcell">Step 1</h2>');
1.452 bisitz 5505: $r->print('<div>');
1.523 raeburn 5506: $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel'));
1.211 www 5507: &levelmenu($r,\%alllevs,$parmlev);
5508: if ($parmlev ne 'general') {
1.447 bisitz 5509: $r->print(&Apache::lonhtmlcommon::row_closure());
1.483 amueller 5510: &mapmenu($r,\%allmaps,$pschp,\%maptitles,\%symbp);
1.211 www 5511: }
1.447 bisitz 5512: $r->print(&Apache::lonhtmlcommon::row_closure(1));
1.445 neumanie 5513: $r->print(&Apache::lonhtmlcommon::end_pick_box());
5514: $r->print('</div></div>');
1.446 bisitz 5515:
1.456 bisitz 5516: $r->print('<div class="LC_Box">');
1.452 bisitz 5517: $r->print('<div>');
1.581 raeburn 5518: &displaymenu($r,\%allparms,\@pscat,\%keyorder);
1.453 schualex 5519: $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.446 bisitz 5520: $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View')));
1.553 raeburn 5521: my $sectionselector = §ionmenu(\@selected_sections);
5522: my $groupselector = &groupmenu(\@selected_groups);
1.481 amueller 5523: $r->print('<table>'.
1.553 raeburn 5524: '<tr><th>'.&mt('Parts').'</th>');
5525: if ($sectionselector) {
5526: $r->print('<th>'.&mt('Section(s)').'</th>');
5527: }
5528: if ($groupselector) {
5529: $r->print('<th>'.&mt('Group(s)').'</th>');
5530: }
5531: $r->print('</tr><tr><td>');
1.211 www 5532: &partmenu($r,\%allparts,\@psprt);
1.553 raeburn 5533: $r->print('</td>');
5534: if ($sectionselector) {
5535: $r->print('<td>'.$sectionselector.'</td>');
5536: }
5537: if ($groupselector) {
5538: $r->print('<td>'.$groupselector.'</td>');
5539: }
5540: $r->print('</tr></table>');
1.447 bisitz 5541: $r->print(&Apache::lonhtmlcommon::row_closure(1));
1.445 neumanie 5542: $r->print(&Apache::lonhtmlcommon::end_pick_box());
5543: $r->print('</div></div>');
5544:
1.456 bisitz 5545: $r->print('<div class="LC_Box">');
1.452 bisitz 5546: $r->print('<div>');
1.214 www 5547: my $sortorder=$env{'form.sortorder'};
5548: unless ($sortorder) { $sortorder='realmstudent'; }
5549: &sortmenu($r,$sortorder);
1.445 neumanie 5550: $r->print('</div></div>');
1.446 bisitz 5551:
1.214 www 5552: $r->print('<p><input type="submit" name="dis" value="'.&mt('Display').'" /></p>');
1.446 bisitz 5553:
1.211 www 5554: # Build the list data hash from the specified parms
5555:
5556: my $listdata;
5557: %{$listdata}=();
5558:
5559: foreach my $cat (@pscat) {
1.269 raeburn 5560: &secgroup_lister($cat,$pschp,$parmlev,$listdata,\@psprt,\@selected_sections,\%defkeytype,\%allmaps,\@ids,\%symbp);
5561: &secgroup_lister($cat,$pschp,$parmlev,$listdata,\@psprt,\@selected_groups,\%defkeytype,\%allmaps,\@ids,\%symbp);
1.211 www 5562: }
5563:
1.212 www 5564: if (($env{'form.store'}) || ($env{'form.dis'})) {
1.211 www 5565:
1.481 amueller 5566: if ($env{'form.store'}) { &storedata($r,$crs,$dom); }
1.211 www 5567:
5568: # Read modified data
5569:
1.481 amueller 5570: my $resourcedata=&readdata($crs,$dom);
1.211 www 5571:
5572: # List data
5573:
1.568 raeburn 5574: &listdata($r,$resourcedata,$listdata,$sortorder,'newoverview',undef,$readonly);
5575: }
5576: $r->print(&tableend());
5577: unless ($readonly) {
5578: $r->print( ((($env{'form.store'}) || ($env{'form.dis'}))?'<p><input type="submit" name="store" value="'.&mt('Save').'" /></p>':'') );
1.211 www 5579: }
1.568 raeburn 5580: $r->print('</form>');
1.507 www 5581: &endSettingsScreen($r);
5582: $r->print(&Apache::loncommon::end_page());
1.208 www 5583: }
5584:
1.563 damieng 5585: # Fills $listdata with parameter information.
5586: # Keys use the format course id.[section id].part.name and course id.[section id].part.name.type.
5587: # The non-type value is always 1.
5588: #
5589: # @param {string} $cat - parameter name
1.566 damieng 5590: # @param {string} $pschp - selected map pc, or 'all'
1.563 damieng 5591: # @param {string} $parmlev - selected level value (full|map|general), or ''
5592: # @param {hash reference} $listdata - the parameter data that will be modified
5593: # @param {array reference} $psprt - selected parts
5594: # @param {array reference} $selections - selected sections
5595: # @param {hash reference} $defkeytype - hash parameter name -> parameter type
1.566 damieng 5596: # @param {hash reference} $allmaps - hash map pc -> map src
5597: # @param {array reference} $ids - resource and map ids
5598: # @param {hash reference} $symbp - hash map pc or resource/map id -> map src.'___(all)' or resource symb
1.269 raeburn 5599: sub secgroup_lister {
5600: my ($cat,$pschp,$parmlev,$listdata,$psprt,$selections,$defkeytype,$allmaps,$ids,$symbp) = @_;
5601: foreach my $item (@{$selections}) {
5602: foreach my $part (@{$psprt}) {
5603: my $rootparmkey=$env{'request.course.id'};
5604: if (($item ne 'all') && ($item ne 'none') && ($item)) {
5605: $rootparmkey.='.['.$item.']';
5606: }
5607: if ($parmlev eq 'general') {
5608: # course-level parameter
5609: my $newparmkey=$rootparmkey.'.'.$part.'.'.$cat;
5610: $$listdata{$newparmkey}=1;
5611: $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
5612: } elsif ($parmlev eq 'map') {
5613: # map-level parameter
1.548 raeburn 5614: foreach my $mapid (keys(%{$allmaps})) {
1.269 raeburn 5615: if (($pschp ne 'all') && ($pschp ne $mapid)) { next; }
5616: my $newparmkey=$rootparmkey.'.'.$$allmaps{$mapid}.'___(all).'.$part.'.'.$cat;
5617: $$listdata{$newparmkey}=1;
5618: $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
5619: }
5620: } else {
5621: # resource-level parameter
5622: foreach my $rid (@{$ids}) {
5623: my ($map,$resid,$url)=&Apache::lonnet::decode_symb($$symbp{$rid});
5624: if (($pschp ne 'all') && ($$allmaps{$pschp} ne $map)) { next; }
5625: my $newparmkey=$rootparmkey.'.'.$$symbp{$rid}.'.'.$part.'.'.$cat;
5626: $$listdata{$newparmkey}=1;
5627: $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
5628: }
5629: }
5630: }
5631: }
5632: }
5633:
1.563 damieng 5634: # UI to edit parameter settings starting with a list of all existing parameters.
5635: # (called by setoverview action)
5636: #
5637: # @param {Apache2::RequestRec} $r - the Apache request
1.208 www 5638: sub overview {
1.568 raeburn 5639: my ($r,$parm_permission) = @_;
1.208 www 5640: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
5641: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 5642: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.568 raeburn 5643: my $readonly = 1;
5644: if ($parm_permission->{'edit'}) {
5645: undef($readonly);
5646: }
1.549 raeburn 5647: my $js = '<script type="text/javascript">'."\n".
5648: '// <![CDATA['."\n".
5649: &toggleparmtextbox_js()."\n".
5650: &validateparms_js()."\n".
5651: &ipacc_boxes_js()."\n".
1.558 raeburn 5652: &done_proctor_js()."\n".
1.588 ! raeburn 5653: &deeplink_js()."\n".
1.549 raeburn 5654: '// ]]>'."\n".
5655: '</script>'."\n";
1.414 droeschl 5656: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
1.473 amueller 5657: text=>"Overview Mode"});
1.549 raeburn 5658: my %loaditems = (
5659: 'onload' => "showHideLenient();",
5660: );
5661:
5662: my $start_page=&Apache::loncommon::start_page('Modify Parameters',$js,{'add_entries' => \%loaditems,});
1.298 albertel 5663: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
1.507 www 5664: $r->print($start_page.$breadcrumbs);
1.531 raeburn 5665: &startSettingsScreen($r,'parmset',$crstype);
1.549 raeburn 5666: $r->print('<form method="post" action="/adm/parmset?action=setoverview" name="parmform" onsubmit="return validateParms();">');
1.507 www 5667:
1.208 www 5668: # Store modified
5669:
1.568 raeburn 5670: unless ($readonly) {
5671: &storedata($r,$crs,$dom);
5672: }
1.208 www 5673:
5674: # Read modified data
5675:
1.552 raeburn 5676: my ($resourcedata,$classlist)=&readdata($crs,$dom);
1.208 www 5677:
1.214 www 5678:
5679: my $sortorder=$env{'form.sortorder'};
5680: unless ($sortorder) { $sortorder='realmstudent'; }
5681: &sortmenu($r,$sortorder);
5682:
1.568 raeburn 5683: my $submitbutton = '<input type="submit" value="'.&mt('Save').'" />';
5684:
5685: if ($readonly) {
5686: $r->print('<p>'.$submitbutton.'</p>');
5687: }
5688:
1.208 www 5689: # List data
5690:
1.568 raeburn 5691: my $foundkeys=&listdata($r,$resourcedata,$resourcedata,$sortorder,'overview',$classlist,$readonly);
5692: $r->print(&tableend().'<p>');
5693: if ($foundkeys) {
5694: unless ($readonly) {
5695: $r->print('<p>'.$submitbutton.'</p>');
5696: }
5697: } else {
5698: $r->print('<p class="LC_info">'.&mt('There are no parameters.').'</p>');
5699: }
5700: $r->print('</form>'.&Apache::loncommon::end_page());
1.120 www 5701: }
1.121 www 5702:
1.560 damieng 5703: # Unused sub.
1.563 damieng 5704: #
5705: # @param {Apache2::RequestRec} $r - the Apache request
1.333 albertel 5706: sub clean_parameters {
5707: my ($r) = @_;
5708: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
5709: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
5710:
1.414 droeschl 5711: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=cleanparameters',
1.473 amueller 5712: text=>"Clean Parameters"});
1.333 albertel 5713: my $start_page=&Apache::loncommon::start_page('Clean Parameters');
5714: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Clean');
5715: $r->print(<<ENDOVER);
5716: $start_page
5717: $breadcrumbs
5718: <form method="post" action="/adm/parmset?action=cleanparameters" name="parmform">
5719: ENDOVER
5720: # Store modified
5721:
5722: &storedata($r,$crs,$dom);
5723:
5724: # Read modified data
5725:
5726: my $resourcedata=&readdata($crs,$dom);
5727:
5728: # List data
5729:
5730: $r->print('<h3>'.
1.473 amueller 5731: &mt('These parameters refer to resources that do not exist.').
5732: '</h3>'.
5733: '<input type="submit" value="'.&mt('Delete Selected').'" />'.'<br />'.
5734: '<br />');
1.333 albertel 5735: $r->print(&Apache::loncommon::start_data_table().
1.473 amueller 5736: '<tr>'.
5737: '<th>'.&mt('Delete').'</th>'.
5738: '<th>'.&mt('Parameter').'</th>'.
5739: '</tr>');
1.333 albertel 5740: foreach my $thiskey (sort(keys(%{$resourcedata}))) {
1.560 damieng 5741: next if (!exists($resourcedata->{$thiskey.'.type'})
5742: && $thiskey=~/\.type$/);
5743: my %data = &parse_key($thiskey);
5744: if (1) { #exists($data{'realm_exists'})
5745: #&& !$data{'realm_exists'}) {
5746: $r->print(&Apache::loncommon::start_data_table_row().
5747: '<tr>'.
5748: '<td><input type="checkbox" name="del_'.$thiskey.'" /></td>' );
5749:
5750: $r->print('<td>');
5751: my $display_value = $resourcedata->{$thiskey};
5752: if (&isdateparm($resourcedata->{$thiskey.'.type'})) {
5753: $display_value =
5754: &Apache::lonlocal::locallocaltime($display_value);
5755: }
1.470 raeburn 5756: my $parmitem = &standard_parameter_names($data{'parameter_name'});
5757: $parmitem = &mt($parmitem);
1.560 damieng 5758: $r->print(&mt('Parameter: "[_1]" with value: "[_2]"',
5759: $parmitem,$resourcedata->{$thiskey}));
5760: $r->print('<br />');
5761: if ($data{'scope_type'} eq 'all') {
5762: $r->print(&mt('All users'));
5763: } elsif ($data{'scope_type'} eq 'user') {
5764: $r->print(&mt('User: [_1]',join(':',@{$data{'scope'}})));
1.581 raeburn 5765: } elsif ($data{'scope_type'} eq 'secgroup') {
5766: $r->print(&mt('Group/Section: [_1]',$data{'scope'}));
1.560 damieng 5767: }
5768: $r->print('<br />');
5769: if ($data{'realm_type'} eq 'all') {
5770: $r->print(&mt('All Resources'));
5771: } elsif ($data{'realm_type'} eq 'folder') {
5772: $r->print(&mt('Folder: [_1]'),$data{'realm'});
5773: } elsif ($data{'realm_type'} eq 'symb') {
5774: my ($map,$resid,$url) =
5775: &Apache::lonnet::decode_symb($data{'realm'});
5776: $r->print(&mt('Resource: [_1]with ID: [_2]in folder [_3]',
5777: $url.' <br /> ',
5778: $resid.' <br /> ',$map));
5779: }
5780: $r->print(' <br /> '.&mt('Part: [_1]',$data{'parameter_part'}));
5781: $r->print('</td></tr>');
5782:
1.473 amueller 5783: }
1.333 albertel 5784: }
5785: $r->print(&Apache::loncommon::end_data_table().'<p>'.
1.473 amueller 5786: '<input type="submit" value="'.&mt('Delete Selected').'" />'.
1.507 www 5787: '</p></form>');
5788: &endSettingsScreen($r);
5789: $r->print(&Apache::loncommon::end_page());
1.333 albertel 5790: }
5791:
1.563 damieng 5792: # UI to shift all dates (called by dateshift1 action).
5793: # Used by overview mode.
5794: #
5795: # @param {Apache2::RequestRec} $r - the Apache request
1.390 www 5796: sub date_shift_one {
5797: my ($r) = @_;
5798: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
5799: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 5800: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.390 www 5801:
1.414 droeschl 5802: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
1.473 amueller 5803: text=>"Shifting Dates"});
1.390 www 5804: my $start_page=&Apache::loncommon::start_page('Shift Dates');
5805: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
1.507 www 5806: $r->print($start_page.$breadcrumbs);
1.531 raeburn 5807: &startSettingsScreen($r,'parmset',$crstype);
1.538 bisitz 5808: $r->print('<form name="shiftform" method="post" action="">'.
1.390 www 5809: '<table><tr><td>'.&mt('Currently set date:').'</td><td>'.
5810: &Apache::lonlocal::locallocaltime($env{'form.timebase'}).'</td></tr>'.
5811: '<tr><td>'.&mt('Shifted date:').'</td><td>'.
1.541 bisitz 5812: &Apache::lonhtmlcommon::date_setter('shiftform',
1.390 www 5813: 'timeshifted',
5814: $env{'form.timebase'},,
5815: '').
5816: '</td></tr></table>'.
5817: '<input type="hidden" name="action" value="dateshift2" />'.
5818: '<input type="hidden" name="timebase" value="'.$env{'form.timebase'}.'" />'.
5819: '<input type="submit" value="'.&mt('Shift all dates accordingly').'" /></form>');
1.507 www 5820: &endSettingsScreen($r);
1.390 www 5821: $r->print(&Apache::loncommon::end_page());
5822: }
5823:
1.563 damieng 5824: # UI to shift all dates (second form).
5825: #
5826: # @param {Apache2::RequestRec} $r - the Apache request
1.390 www 5827: sub date_shift_two {
5828: my ($r) = @_;
5829: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
5830: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 5831: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.414 droeschl 5832: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
1.473 amueller 5833: text=>"Shifting Dates"});
1.390 www 5834: my $start_page=&Apache::loncommon::start_page('Shift Dates');
5835: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
1.507 www 5836: $r->print($start_page.$breadcrumbs);
1.531 raeburn 5837: &startSettingsScreen($r,'parmset',$crstype);
1.390 www 5838: my $timeshifted=&Apache::lonhtmlcommon::get_date_from_form('timeshifted');
1.543 bisitz 5839: $r->print('<h2>'.&mt('Shift Dates').'</h2>'.
5840: '<p>'.&mt('Shifting all dates such that [_1] becomes [_2]',
1.390 www 5841: &Apache::lonlocal::locallocaltime($env{'form.timebase'}),
1.543 bisitz 5842: &Apache::lonlocal::locallocaltime($timeshifted)).'</p>');
1.390 www 5843: my $delta=$timeshifted-$env{'form.timebase'};
5844: &dateshift($delta);
1.543 bisitz 5845: $r->print(
5846: &Apache::lonhtmlcommon::confirm_success(&mt('Done')).
5847: '<br /><br />'.
5848: &Apache::lonhtmlcommon::actionbox(
5849: ['<a href="/adm/parmset">'.&mt('Content and Problem Settings').'</a>']));
1.507 www 5850: &endSettingsScreen($r);
1.390 www 5851: $r->print(&Apache::loncommon::end_page());
5852: }
5853:
1.563 damieng 5854: # Returns the different components of a resourcedata key.
5855: # Keys: scope_type, scope, realm_type, realm, realm_title,
5856: # realm_exists, parameter_part, parameter_name.
5857: # Was used by clean_parameters (which is unused).
5858: #
5859: # @param {string} $key - the parameter key
5860: # @returns {hash}
1.333 albertel 5861: sub parse_key {
5862: my ($key) = @_;
5863: my %data;
5864: my ($middle,$part,$name)=
1.572 damieng 5865: ($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s\-]+)\.(\w+)$/);
1.333 albertel 5866: $data{'scope_type'} = 'all';
5867: if ($middle=~/^\[(.*)\]/) {
1.560 damieng 5868: $data{'scope'} = $1;
5869: if ($data{'scope'}=~/^useropt\:($match_username)\:($match_domain)/) {
5870: $data{'scope_type'} = 'user';
5871: $data{'scope'} = [$1,$2];
5872: } else {
1.581 raeburn 5873: $data{'scope_type'} = 'secgroup';
1.560 damieng 5874: }
5875: $middle=~s/^\[(.*)\]//;
1.333 albertel 5876: }
5877: $middle=~s/\.+$//;
5878: $middle=~s/^\.+//;
5879: $data{'realm_type'}='all';
5880: if ($middle=~/^(.+)\_\_\_\(all\)$/) {
1.560 damieng 5881: $data{'realm'} = $1;
5882: $data{'realm_type'} = 'folder';
5883: $data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});
5884: ($data{'realm_exists'}) = &Apache::lonnet::is_on_map($data{'realm'});
1.333 albertel 5885: } elsif ($middle) {
1.560 damieng 5886: $data{'realm'} = $middle;
5887: $data{'realm_type'} = 'symb';
5888: $data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});
5889: my ($map,$resid,$url) = &Apache::lonnet::decode_symb($data{'realm'});
5890: $data{'realm_exists'} = &Apache::lonnet::symbverify($data{'realm'},$url);
1.333 albertel 5891: }
1.446 bisitz 5892:
1.333 albertel 5893: $data{'parameter_part'} = $part;
5894: $data{'parameter_name'} = $name;
5895:
5896: return %data;
5897: }
5898:
1.239 raeburn 5899:
1.563 damieng 5900: # Calls loncommon::start_page with the "Settings" title.
1.416 jms 5901: sub header {
1.507 www 5902: return &Apache::loncommon::start_page('Settings');
1.416 jms 5903: }
1.193 albertel 5904:
5905:
5906:
1.560 damieng 5907: ##################################################
5908: # MAIN MENU
5909: ##################################################
5910:
1.563 damieng 5911: # Content and problem settings main menu.
5912: #
5913: # @param {Apache2::RequestRec} $r - the Apache request
5914: # @param {boolean} $parm_permission - true if the user has permission to edit the current course or section
1.193 albertel 5915: sub print_main_menu {
5916: my ($r,$parm_permission)=@_;
5917: #
1.414 droeschl 5918: $r->print(&header());
1.507 www 5919: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Content and Problem Settings'));
1.531 raeburn 5920: my $crstype = &Apache::loncommon::course_type();
5921: my $lc_crstype = lc($crstype);
5922:
5923: &startSettingsScreen($r,'parmset',$crstype);
1.193 albertel 5924: $r->print(<<ENDMAINFORMHEAD);
5925: <form method="post" enctype="multipart/form-data"
5926: action="/adm/parmset" name="studentform">
5927: ENDMAINFORMHEAD
5928: #
1.195 albertel 5929: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
5930: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1.268 albertel 5931: my $vgr = &Apache::lonnet::allowed('vgr',$env{'request.course.id'});
1.366 albertel 5932: my $mgr = &Apache::lonnet::allowed('mgr',$env{'request.course.id'});
1.520 raeburn 5933: my $dcm = &Apache::lonnet::allowed('dcm',$env{'request.course.id'});
1.568 raeburn 5934: my $vcb = &Apache::lonnet::allowed('vcb',$env{'request.course.id'});
5935: my $vpa = &Apache::lonnet::allowed('vpa',$env{'request.course.id'});
1.520 raeburn 5936: if ((!$dcm) && ($env{'request.course.sec'} ne '')) {
5937: $dcm = &Apache::lonnet::allowed('dcm',$env{'request.course.id'}.
5938: '/'.$env{'request.course.sec'});
5939: }
1.568 raeburn 5940: if ((!$vcb) && ($env{'request.course.sec'} ne '')) {
5941: $vcb = &Apache::lonnet::allowed('vcb',$env{'request.course.id'}.
5942: '/'.$env{'request.course.sec'});
5943: }
5944: my (%linktext,%linktitle,%url);
5945: if ($parm_permission->{'edit'}) {
5946: %linktext = (
5947: newoverview => 'Edit Resource Parameters - Overview Mode',
5948: settable => 'Edit Resource Parameters - Table Mode',
5949: setoverview => 'Modify Resource Parameters - Overview Mode',
5950: );
5951: %linktitle = (
5952: newoverview => 'Set/Modify resource parameters in overview mode.',
5953: settable => 'Set/Modify resource parameters in table mode.',
5954: setoverview => 'Set/Modify existing resource parameters in overview mode.',
5955: );
5956: } else {
5957: %linktext = (
5958: newoverview => 'View Resource Parameters - Overview Mode',
5959: settable => 'View Resource Parameters - Table Mode',
5960: setoverview => 'View Resource Parameters - Overview Mode',
5961: );
5962: %linktitle = (
5963: newoverview => 'Display resource parameters in overview mode.',
5964: settable => 'Display resource parameters in table mode.',
5965: setoverview => 'Display existing resource parameters in overview mode.',
5966: );
5967: }
5968: if ($mgr) {
5969: $linktext{'resettimes'} = 'Reset Student Access Times';
5970: $linktitle{'resettimes'} = "Reset access times for folders/maps, resources or the $lc_crstype.";
5971: $url{'resettimes'} = '/adm/helper/resettimes.helper';
5972: } elsif ($vgr) {
5973: $linktext{'resettimes'} = 'Display Student Access Times',
5974: $linktitle{'resettimes'} = "Display access times for folders/maps, resources or the $lc_crstype.",
5975: $url{'resettimes'} = '/adm/accesstimes';
5976: }
1.193 albertel 5977: my @menu =
1.507 www 5978: ( { categorytitle=>"Content Settings for this $crstype",
1.473 amueller 5979: items => [
5980: { linktext => 'Portfolio Metadata',
5981: url => '/adm/parmset?action=setrestrictmeta',
1.568 raeburn 5982: permission => $parm_permission->{'setrestrictmeta'},
1.477 raeburn 5983: linktitle => "Restrict metadata for this $lc_crstype." ,
1.473 amueller 5984: icon =>'contact-new.png' ,
5985: },
1.568 raeburn 5986: { linktext => $linktext{'resettimes'},
5987: url => $url{'resettimes'},
5988: permission => ($vgr || $mgr),
5989: linktitle => $linktitle{'resettimes'},
5990: icon => 'start-here.png',
1.473 amueller 5991: },
1.520 raeburn 5992: { linktext => 'Blocking Communication/Resource Access',
5993: url => '/adm/setblock',
1.568 raeburn 5994: permission => ($vcb || $dcm),
1.520 raeburn 5995: linktitle => 'Configure blocking of communication/collaboration and access to resources during an exam',
5996: icon => 'comblock.png',
5997: },
1.473 amueller 5998: { linktext => 'Set Parameter Setting Default Actions',
5999: url => '/adm/parmset?action=setdefaults',
1.568 raeburn 6000: permission => $parm_permission->{'setdefaults'},
1.473 amueller 6001: linktitle =>'Set default actions for parameters.' ,
6002: icon => 'folder-new.png' ,
6003: }]},
6004: { categorytitle => 'New and Existing Parameter Settings for Resources',
6005: items => [
6006: { linktext => 'Edit Resource Parameters - Helper Mode',
6007: url => '/adm/helper/parameter.helper',
1.568 raeburn 6008: permission => $parm_permission->{'helper'},
1.473 amueller 6009: linktitle =>'Set/Modify resource parameters in helper mode.' ,
6010: icon => 'dialog-information.png' ,
6011: #help => 'Parameter_Helper',
6012: },
1.568 raeburn 6013: { linktext => $linktext{'newoverview'},
1.473 amueller 6014: url => '/adm/parmset?action=newoverview',
1.568 raeburn 6015: permission => $parm_permission->{'newoverview'},
6016: linktitle => $linktitle{'newoverview'},
6017: icon => 'edit-find.png',
1.473 amueller 6018: #help => 'Parameter_Overview',
6019: },
1.568 raeburn 6020: { linktext => $linktext{'settable'},
1.473 amueller 6021: url => '/adm/parmset?action=settable',
1.568 raeburn 6022: permission => $parm_permission->{'settable'},
6023: linktitle => $linktitle{'settable'},
6024: icon => 'edit-copy.png',
1.473 amueller 6025: #help => 'Table_Mode',
6026: }]},
1.417 droeschl 6027: { categorytitle => 'Existing Parameter Settings for Resources',
1.473 amueller 6028: items => [
1.570 raeburn 6029: { linktext => $linktext{'setoverview'},
1.473 amueller 6030: url => '/adm/parmset?action=setoverview',
1.568 raeburn 6031: permission => $parm_permission->{'setoverview'},
6032: linktitle => $linktitle{'setoverview'},
6033: icon => 'preferences-desktop-wallpaper.png',
1.473 amueller 6034: #help => 'Parameter_Overview',
6035: },
6036: { linktext => 'Change Log',
6037: url => '/adm/parmset?action=parameterchangelog',
1.568 raeburn 6038: permission => $parm_permission->{'parameterchangelog'},
1.477 raeburn 6039: linktitle =>"View parameter and $lc_crstype blog posting/user notification change log." ,
1.487 wenzelju 6040: icon => 'document-properties.png',
1.473 amueller 6041: }]}
1.193 albertel 6042: );
1.414 droeschl 6043: $r->print(&Apache::lonhtmlcommon::generate_menu(@menu));
1.539 raeburn 6044: $r->print('</form>');
1.507 www 6045: &endSettingsScreen($r);
1.539 raeburn 6046: $r->print(&Apache::loncommon::end_page());
1.193 albertel 6047: return;
6048: }
1.414 droeschl 6049:
1.416 jms 6050:
6051:
1.560 damieng 6052: ##################################################
6053: # PORTFOLIO METADATA
6054: ##################################################
6055:
1.563 damieng 6056: # Prints HTML to edit an item of portfolio metadata. The HTML contains several td elements (no tr).
6057: # It looks like field titles are not localized.
6058: #
6059: # @param {Apache2::RequestRec} $r - the Apache request
6060: # @param {string} $field_name - metadata field name
6061: # @param {string} $field_text - metadata field title, in English unless manually added
6062: # @param {boolean} $added_flag - true if the field was manually added
1.252 banghart 6063: sub output_row {
1.347 banghart 6064: my ($r, $field_name, $field_text, $added_flag) = @_;
1.252 banghart 6065: my $output;
1.263 banghart 6066: my $options=$env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.options'};
6067: my $values=$env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.values'};
1.337 banghart 6068: if (!defined($options)) {
1.254 banghart 6069: $options = 'active,stuadd';
1.261 banghart 6070: $values = '';
1.252 banghart 6071: }
1.337 banghart 6072: if (!($options =~ /deleted/)) {
6073: my @options= ( ['active', 'Show to student'],
1.418 schafran 6074: ['stuadd', 'Provide text area for students to type metadata'],
1.351 banghart 6075: ['choices','Provide choices for students to select from']);
1.473 amueller 6076: # ['onlyone','Student may select only one choice']);
1.337 banghart 6077: if ($added_flag) {
6078: push @options,['deleted', 'Delete Metadata Field'];
6079: }
1.351 banghart 6080: $output = &Apache::loncommon::start_data_table_row();
1.451 bisitz 6081: $output .= '<td><strong>'.$field_text.':</strong></td>';
1.351 banghart 6082: $output .= &Apache::loncommon::end_data_table_row();
1.337 banghart 6083: foreach my $opt (@options) {
1.560 damieng 6084: my $checked = ($options =~ m/$opt->[0]/) ? ' checked="checked" ' : '' ;
6085: $output .= &Apache::loncommon::continue_data_table_row();
6086: $output .= '<td>'.(' ' x 5).'<label>
6087: <input type="checkbox" name="'.
6088: $field_name.'_'.$opt->[0].'" value="yes"'.$checked.' />'.
6089: &mt($opt->[1]).'</label></td>';
6090: $output .= &Apache::loncommon::end_data_table_row();
6091: }
1.351 banghart 6092: $output .= &Apache::loncommon::continue_data_table_row();
1.451 bisitz 6093: $output .= '<td>'.(' ' x 10).'<input name="'.$field_name.'_values" type="text" value="'.$values.'" size="80" /></td>';
1.351 banghart 6094: $output .= &Apache::loncommon::end_data_table_row();
6095: my $multiple_checked;
6096: my $single_checked;
6097: if ($options =~ m/onlyone/) {
1.422 bisitz 6098: $multiple_checked = '';
1.423 bisitz 6099: $single_checked = ' checked="checked"';
1.351 banghart 6100: } else {
1.423 bisitz 6101: $multiple_checked = ' checked="checked"';
1.422 bisitz 6102: $single_checked = '';
1.351 banghart 6103: }
1.560 damieng 6104: $output .= &Apache::loncommon::continue_data_table_row();
6105: $output .= '<td>'.(' ' x 10).'
6106: <input type="radio" name="'.$field_name.'_onlyone" value="multiple"'.$multiple_checked .' />
6107: '.&mt('Student may select multiple choices from list').'</td>';
6108: $output .= &Apache::loncommon::end_data_table_row();
6109: $output .= &Apache::loncommon::continue_data_table_row();
6110: $output .= '<td>'.(' ' x 10).'
6111: <input type="radio" name="'.$field_name.'_onlyone" value="single"'.$single_checked.' />
6112: '.&mt('Student may select only one choice from list').'</td>';
6113: $output .= &Apache::loncommon::end_data_table_row();
1.252 banghart 6114: }
6115: return ($output);
6116: }
1.416 jms 6117:
6118:
1.560 damieng 6119: # UI to order portfolio metadata fields.
1.563 damieng 6120: # Currently useless because addmetafield does not work.
6121: #
6122: # @param {Apache2::RequestRec} $r - the Apache request
1.340 banghart 6123: sub order_meta_fields {
6124: my ($r)=@_;
6125: my $idx = 1;
6126: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
6127: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 6128: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};;
1.341 banghart 6129: $r->print(&Apache::loncommon::start_page('Order Metadata Fields'));
1.560 damieng 6130: &Apache::lonhtmlcommon::add_breadcrumb(
6131: {href=>'/adm/parmset?action=addmetadata',
1.473 amueller 6132: text=>"Add Metadata Field"});
1.560 damieng 6133: &Apache::lonhtmlcommon::add_breadcrumb(
6134: {href=>"/adm/parmset?action=setrestrictmeta",
6135: text=>"Restrict Metadata"},
6136: {text=>"Order Metadata"});
1.345 banghart 6137: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Order Metadata'));
1.531 raeburn 6138: &startSettingsScreen($r,'parmset',$crstype);
1.340 banghart 6139: if ($env{'form.storeorder'}) {
6140: my $newpos = $env{'form.newpos'} - 1;
6141: my $currentpos = $env{'form.currentpos'} - 1;
6142: my @neworder = ();
1.548 raeburn 6143: my @oldorder = split(/,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'});
1.340 banghart 6144: my $i;
1.341 banghart 6145: if ($newpos > $currentpos) {
1.340 banghart 6146: # moving stuff up
6147: for ($i=0;$i<$currentpos;$i++) {
1.560 damieng 6148: $neworder[$i]=$oldorder[$i];
1.340 banghart 6149: }
6150: for ($i=$currentpos;$i<$newpos;$i++) {
1.560 damieng 6151: $neworder[$i]=$oldorder[$i+1];
1.340 banghart 6152: }
6153: $neworder[$newpos]=$oldorder[$currentpos];
6154: for ($i=$newpos+1;$i<=$#oldorder;$i++) {
1.560 damieng 6155: $neworder[$i]=$oldorder[$i];
1.340 banghart 6156: }
6157: } else {
6158: # moving stuff down
1.473 amueller 6159: for ($i=0;$i<$newpos;$i++) {
6160: $neworder[$i]=$oldorder[$i];
6161: }
6162: $neworder[$newpos]=$oldorder[$currentpos];
6163: for ($i=$newpos+1;$i<$currentpos+1;$i++) {
6164: $neworder[$i]=$oldorder[$i-1];
6165: }
6166: for ($i=$currentpos+1;$i<=$#oldorder;$i++) {
6167: $neworder[$i]=$oldorder[$i];
6168: }
1.340 banghart 6169: }
1.560 damieng 6170: my $ordered_fields = join ",", @neworder;
1.343 banghart 6171: my $put_result = &Apache::lonnet::put('environment',
1.560 damieng 6172: {'metadata.addedorder'=>$ordered_fields},$dom,$crs);
6173: &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.metadata.addedorder' => $ordered_fields});
1.340 banghart 6174: }
1.357 raeburn 6175: my $fields = &get_added_meta_fieldnames($env{'request.course.id'});
1.341 banghart 6176: my $ordered_fields;
1.548 raeburn 6177: my @fields_in_order = split(/,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'});
1.340 banghart 6178: if (!@fields_in_order) {
6179: # no order found, pick sorted order then create metadata.addedorder key.
1.548 raeburn 6180: foreach my $key (sort(keys(%$fields))) {
1.340 banghart 6181: push @fields_in_order, $key;
1.341 banghart 6182: $ordered_fields = join ",", @fields_in_order;
1.340 banghart 6183: }
1.341 banghart 6184: my $put_result = &Apache::lonnet::put('environment',
1.446 bisitz 6185: {'metadata.addedorder'=>$ordered_fields},$dom,$crs);
6186: }
1.340 banghart 6187: $r->print('<table>');
6188: my $num_fields = scalar(@fields_in_order);
6189: foreach my $key (@fields_in_order) {
6190: $r->print('<tr><td>');
6191: $r->print('<form method="post" action="">');
1.537 bisitz 6192: $r->print('<select name="newpos" onchange="this.form.submit()">');
1.340 banghart 6193: for (my $i = 1;$i le $num_fields;$i ++) {
6194: if ($i eq $idx) {
6195: $r->print('<option value="'.$i.'" SELECTED>('.$i.')</option>');
6196: } else {
6197: $r->print('<option value="'.$i.'">'.$i.'</option>');
6198: }
6199: }
6200: $r->print('</select></td><td>');
6201: $r->print('<input type="hidden" name="currentpos" value="'.$idx.'" />');
6202: $r->print('<input type="hidden" name="storeorder" value="true" />');
6203: $r->print('</form>');
6204: $r->print($$fields{$key}.'</td></tr>');
6205: $idx ++;
6206: }
6207: $r->print('</table>');
1.507 www 6208: &endSettingsScreen($r);
1.340 banghart 6209: return 'ok';
6210: }
1.416 jms 6211:
6212:
1.563 damieng 6213: # Returns HTML with a Continue button redirecting to the initial portfolio metadata screen.
6214: # @returns {string}
1.359 banghart 6215: sub continue {
6216: my $output;
6217: $output .= '<form action="" method="post">';
6218: $output .= '<input type="hidden" name="action" value="setrestrictmeta" />';
1.586 raeburn 6219: $output .= '<input type="submit" value="'.&mt('Continue').'" />';
1.359 banghart 6220: return ($output);
6221: }
1.416 jms 6222:
6223:
1.563 damieng 6224: # UI to add a metadata field.
6225: # Currenly does not work because of an HTML error (the field is not visible).
6226: #
6227: # @param {Apache2::RequestRec} $r - the Apache request
1.334 banghart 6228: sub addmetafield {
6229: my ($r)=@_;
1.414 droeschl 6230: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=addmetadata',
1.473 amueller 6231: text=>"Add Metadata Field"});
1.334 banghart 6232: $r->print(&Apache::loncommon::start_page('Add Metadata Field'));
6233: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Add Metadata Field'));
1.335 banghart 6234: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
6235: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 6236: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
6237: &startSettingsScreen($r,'parmset',$crstype);
1.339 banghart 6238: if (exists($env{'form.undelete'})) {
1.358 banghart 6239: my @meta_fields = &Apache::loncommon::get_env_multiple('form.undeletefield');
1.339 banghart 6240: foreach my $meta_field(@meta_fields) {
6241: my $options = $env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.options'};
6242: $options =~ s/deleted//;
6243: $options =~ s/,,/,/;
6244: my $put_result = &Apache::lonnet::put('environment',
6245: {'metadata.'.$meta_field.'.options'=>$options},$dom,$crs);
1.446 bisitz 6246:
1.586 raeburn 6247: $r->print(&mt('Undeleted Metadata Field [_1] with result [_2]',
6248: '<strong>'.$env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.added'}.
6249: '</strong>',$put_result).
6250: '<br />');
1.339 banghart 6251: }
1.359 banghart 6252: $r->print(&continue());
1.339 banghart 6253: } elsif (exists($env{'form.fieldname'})) {
1.335 banghart 6254: my $meta_field = $env{'form.fieldname'};
6255: my $display_field = $env{'form.fieldname'};
6256: $meta_field =~ s/\W/_/g;
1.338 banghart 6257: $meta_field =~ tr/A-Z/a-z/;
1.335 banghart 6258: my $put_result = &Apache::lonnet::put('environment',
6259: {'metadata.'.$meta_field.'.values'=>"",
6260: 'metadata.'.$meta_field.'.added'=>"$display_field",
6261: 'metadata.'.$meta_field.'.options'=>""},$dom,$crs);
1.586 raeburn 6262: $r->print(&mt('Added new Metadata Field [_1] with result [_2]',
6263: '<strong>'.$env{'form.fieldname'}.'</strong>',$put_result).
6264: '<br />');
1.359 banghart 6265: $r->print(&continue());
1.335 banghart 6266: } else {
1.357 raeburn 6267: my $fields = &get_deleted_meta_fieldnames($env{'request.course.id'});
1.339 banghart 6268: if ($fields) {
1.586 raeburn 6269: $r->print(&mt('You may undelete previously deleted fields.').
6270: '<br />'.
6271: &mt('Check those you wish to undelete and click Undelete.').
6272: '<br />');
1.339 banghart 6273: $r->print('<form method="post" action="">');
6274: foreach my $key(keys(%$fields)) {
1.581 raeburn 6275: $r->print('<label><input type="checkbox" name="undeletefield" value="'.$key.'" />'.$$fields{$key}.'</label><br /');
1.339 banghart 6276: }
1.586 raeburn 6277: $r->print('<input type="submit" name="undelete" value="'.&mt('Undelete').'" />');
1.339 banghart 6278: $r->print('</form>');
6279: }
1.586 raeburn 6280: $r->print('<hr />'.
6281: &mt('[_1]Or[_2] you may enter a new metadata field name.',
6282: '<strong>','</strong>').
1.581 raeburn 6283: '<form method="post" action="/adm/parmset?action=addmetadata">');
1.335 banghart 6284: $r->print('<input type="text" name="fieldname" /><br />');
1.586 raeburn 6285: $r->print('<input type="submit" value="'.&mt('Add Metadata Field').'" />');
1.581 raeburn 6286: $r->print('</form>');
1.334 banghart 6287: }
1.507 www 6288: &endSettingsScreen($r);
1.334 banghart 6289: }
1.416 jms 6290:
6291:
6292:
1.560 damieng 6293: # Display or save portfolio metadata.
1.563 damieng 6294: #
6295: # @param {Apache2::RequestRec} $r - the Apache request
1.259 banghart 6296: sub setrestrictmeta {
1.240 banghart 6297: my ($r)=@_;
1.242 banghart 6298: my $next_meta;
1.244 banghart 6299: my $output;
1.245 banghart 6300: my $item_num;
1.246 banghart 6301: my $put_result;
1.414 droeschl 6302: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setrestrictmeta',
1.473 amueller 6303: text=>"Restrict Metadata"});
1.280 albertel 6304: $r->print(&Apache::loncommon::start_page('Restrict Metadata'));
1.298 albertel 6305: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Restrict Metadata'));
1.240 banghart 6306: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
6307: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 6308: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
6309: &startSettingsScreen($r,'parmset',$crstype);
1.259 banghart 6310: my $key_base = $env{'course.'.$env{'request.course.id'}.'.'};
1.252 banghart 6311: my $save_field = '';
1.586 raeburn 6312: my %lt = &Apache::lonlocal::texthash(
6313: addm => 'Add Metadata Field',
6314: ordm => 'Order Metadata Fields',
6315: save => 'Save',
6316: );
1.259 banghart 6317: if ($env{'form.restrictmeta'}) {
1.254 banghart 6318: foreach my $field (sort(keys(%env))) {
1.252 banghart 6319: if ($field=~m/^form.(.+)_(.+)$/) {
1.254 banghart 6320: my $options;
1.252 banghart 6321: my $meta_field = $1;
6322: my $meta_key = $2;
1.253 banghart 6323: if ($save_field ne $meta_field) {
1.252 banghart 6324: $save_field = $meta_field;
1.473 amueller 6325: if ($env{'form.'.$meta_field.'_stuadd'}) {
6326: $options.='stuadd,';
6327: }
6328: if ($env{'form.'.$meta_field.'_choices'}) {
6329: $options.='choices,';
6330: }
6331: if ($env{'form.'.$meta_field.'_onlyone'} eq 'single') {
6332: $options.='onlyone,';
6333: }
6334: if ($env{'form.'.$meta_field.'_active'}) {
6335: $options.='active,';
6336: }
6337: if ($env{'form.'.$meta_field.'_deleted'}) {
6338: $options.='deleted,';
6339: }
1.259 banghart 6340: my $name = $save_field;
1.560 damieng 6341: $put_result = &Apache::lonnet::put('environment',
6342: {'metadata.'.$meta_field.'.options'=>$options,
6343: 'metadata.'.$meta_field.'.values'=>$env{'form.'.$meta_field.'_values'},
6344: },$dom,$crs);
1.252 banghart 6345: }
6346: }
6347: }
6348: }
1.296 albertel 6349: &Apache::lonnet::coursedescription($env{'request.course.id'},
1.473 amueller 6350: {'freshen_cache' => 1});
1.335 banghart 6351: # Get the default metadata fields
1.258 albertel 6352: my %metadata_fields = &Apache::lonmeta::fieldnames('portfolio');
1.335 banghart 6353: # Now get possible added metadata fields
1.357 raeburn 6354: my $added_metadata_fields = &get_added_meta_fieldnames($env{'request.course.id'});
1.347 banghart 6355: $output .= &Apache::loncommon::start_data_table();
1.258 albertel 6356: foreach my $field (sort(keys(%metadata_fields))) {
1.265 banghart 6357: if ($field ne 'courserestricted') {
1.586 raeburn 6358: $output.= &output_row($r,$field,$metadata_fields{$field});
1.560 damieng 6359: }
1.255 banghart 6360: }
1.351 banghart 6361: my $buttons = (<<ENDButtons);
1.586 raeburn 6362: <input type="submit" name="restrictmeta" value="$lt{'save'}" />
1.351 banghart 6363: </form><br />
6364: <form method="post" action="/adm/parmset?action=addmetadata" name="form1">
1.586 raeburn 6365: <input type="submit" name="restrictmeta" value="$lt{'addm'}" />
1.351 banghart 6366: </form>
6367: <br />
6368: <form method="post" action="/adm/parmset?action=ordermetadata" name="form2">
1.586 raeburn 6369: <input type="submit" name="restrictmeta" value="$lt{'ordm'}" />
1.351 banghart 6370: ENDButtons
1.337 banghart 6371: my $added_flag = 1;
1.335 banghart 6372: foreach my $field (sort(keys(%$added_metadata_fields))) {
1.586 raeburn 6373: $output.= &output_row($r,$field,$$added_metadata_fields{$field},$added_flag);
1.335 banghart 6374: }
1.347 banghart 6375: $output .= &Apache::loncommon::end_data_table();
1.446 bisitz 6376: $r->print(<<ENDenv);
1.259 banghart 6377: <form method="post" action="/adm/parmset?action=setrestrictmeta" name="form">
1.244 banghart 6378: $output
1.351 banghart 6379: $buttons
1.340 banghart 6380: </form>
1.244 banghart 6381: ENDenv
1.507 www 6382: &endSettingsScreen($r);
1.280 albertel 6383: $r->print(&Apache::loncommon::end_page());
1.240 banghart 6384: return 'ok';
6385: }
1.416 jms 6386:
6387:
1.563 damieng 6388: # Returns metadata fields that have been manually added.
6389: #
6390: # @param {string} $cid - course id
6391: # @returns {hash reference} - hash field name -> field title (not localized)
1.335 banghart 6392: sub get_added_meta_fieldnames {
1.357 raeburn 6393: my ($cid) = @_;
1.335 banghart 6394: my %fields;
6395: foreach my $key(%env) {
1.357 raeburn 6396: if ($key =~ m/\Q$cid\E\.metadata\.(.+)\.added$/) {
1.335 banghart 6397: my $field_name = $1;
6398: my ($display_field_name) = $env{$key};
6399: $fields{$field_name} = $display_field_name;
6400: }
6401: }
6402: return \%fields;
6403: }
1.416 jms 6404:
6405:
1.563 damieng 6406: # Returns metadata fields that have been manually added and deleted.
6407: #
6408: # @param {string} $cid - course id
6409: # @returns {hash reference} - hash field name -> field title (not localized)
1.339 banghart 6410: sub get_deleted_meta_fieldnames {
1.357 raeburn 6411: my ($cid) = @_;
1.339 banghart 6412: my %fields;
6413: foreach my $key(%env) {
1.357 raeburn 6414: if ($key =~ m/\Q$cid\E\.metadata\.(.+)\.added$/) {
1.339 banghart 6415: my $field_name = $1;
6416: if ($env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.options'} =~ m/deleted/) {
6417: my ($display_field_name) = $env{$key};
6418: $fields{$field_name} = $display_field_name;
6419: }
6420: }
6421: }
6422: return \%fields;
6423: }
1.560 damieng 6424:
6425:
6426: ##################################################
6427: # PARAMETER SETTINGS DEFAULT ACTIONS
6428: ##################################################
6429:
6430: # UI to change parameter setting default actions
1.563 damieng 6431: #
6432: # @param {Apache2::RequestRec} $r - the Apache request
1.220 www 6433: sub defaultsetter {
1.280 albertel 6434: my ($r) = @_;
6435:
1.414 droeschl 6436: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setdefaults',
1.473 amueller 6437: text=>"Set Defaults"});
1.531 raeburn 6438: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
6439: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
6440: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.446 bisitz 6441: my $start_page =
1.531 raeburn 6442: &Apache::loncommon::start_page('Parameter Setting Default Actions');
1.298 albertel 6443: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Defaults');
1.507 www 6444: $r->print($start_page.$breadcrumbs);
1.531 raeburn 6445: &startSettingsScreen($r,'parmset',$crstype);
1.507 www 6446: $r->print('<form method="post" action="/adm/parmset?action=setdefaults" name="defaultform">');
1.280 albertel 6447:
1.221 www 6448: my @ids=();
6449: my %typep=();
6450: my %keyp=();
6451: my %allparms=();
6452: my %allparts=();
6453: my %allmaps=();
6454: my %mapp=();
6455: my %symbp=();
6456: my %maptitles=();
6457: my %uris=();
6458: my %keyorder=&standardkeyorder();
6459: my %defkeytype=();
6460:
1.446 bisitz 6461: &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
1.473 amueller 6462: \%mapp, \%symbp,\%maptitles,\%uris,
6463: \%keyorder,\%defkeytype);
1.224 www 6464: if ($env{'form.storerules'}) {
1.560 damieng 6465: my %newrules=();
6466: my @delrules=();
6467: my %triggers=();
6468: foreach my $key (keys(%env)) {
1.225 albertel 6469: if ($key=~/^form\.(\w+)\_action$/) {
1.560 damieng 6470: my $tempkey=$1;
6471: my $action=$env{$key};
1.226 www 6472: if ($action) {
1.560 damieng 6473: $newrules{$tempkey.'_action'}=$action;
6474: if ($action ne 'default') {
6475: my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);
6476: $triggers{$whichparm}.=$tempkey.':';
6477: }
6478: $newrules{$tempkey.'_type'}=$defkeytype{$tempkey};
6479: if (&isdateparm($defkeytype{$tempkey})) {
6480: $newrules{$tempkey.'_days'}=$env{'form.'.$tempkey.'_days'};
6481: $newrules{$tempkey.'_hours'}=$env{'form.'.$tempkey.'_hours'};
6482: $newrules{$tempkey.'_min'}=$env{'form.'.$tempkey.'_min'};
6483: $newrules{$tempkey.'_sec'}=$env{'form.'.$tempkey.'_sec'};
6484: } else {
6485: $newrules{$tempkey.'_value'}=$env{'form.'.$tempkey.'_value'};
6486: $newrules{$tempkey.'_triggervalue'}=$env{'form.'.$tempkey.'_triggervalue'};
6487: }
6488: } else {
6489: push(@delrules,$tempkey.'_action');
6490: push(@delrules,$tempkey.'_type');
6491: push(@delrules,$tempkey.'_hours');
6492: push(@delrules,$tempkey.'_min');
6493: push(@delrules,$tempkey.'_sec');
6494: push(@delrules,$tempkey.'_value');
6495: }
1.473 amueller 6496: }
6497: }
1.560 damieng 6498: foreach my $key (keys(%allparms)) {
6499: $newrules{$key.'_triggers'}=$triggers{$key};
1.473 amueller 6500: }
1.560 damieng 6501: &Apache::lonnet::put('parmdefactions',\%newrules,$cdom,$cnum);
6502: &Apache::lonnet::del('parmdefactions',\@delrules,$cdom,$cnum);
6503: &resetrulescache();
1.224 www 6504: }
1.227 www 6505: my %lt=&Apache::lonlocal::texthash('days' => 'Days',
1.473 amueller 6506: 'hours' => 'Hours',
6507: 'min' => 'Minutes',
6508: 'sec' => 'Seconds',
6509: 'yes' => 'Yes',
6510: 'no' => 'No');
1.222 www 6511: my @standardoptions=('','default');
6512: my @standarddisplay=('',&mt('Default value when manually setting'));
6513: my @dateoptions=('','default');
6514: my @datedisplay=('',&mt('Default value when manually setting'));
6515: foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
1.560 damieng 6516: unless ($tempkey) { next; }
6517: push @standardoptions,'when_setting_'.$tempkey;
6518: push @standarddisplay,&mt('Automatically set when setting ').$tempkey;
6519: if (&isdateparm($defkeytype{$tempkey})) {
6520: push @dateoptions,'later_than_'.$tempkey;
6521: push @datedisplay,&mt('Automatically set later than ').$tempkey;
6522: push @dateoptions,'earlier_than_'.$tempkey;
6523: push @datedisplay,&mt('Automatically set earlier than ').$tempkey;
6524: }
1.222 www 6525: }
1.563 damieng 6526: $r->print(&mt('Manual setting rules apply to all interfaces.').'<br />'.
6527: &mt('Automatic setting rules apply to table mode interfaces only.'));
1.318 albertel 6528: $r->print("\n".&Apache::loncommon::start_data_table().
1.473 amueller 6529: &Apache::loncommon::start_data_table_header_row().
6530: "<th>".&mt('Rule for parameter').'</th><th>'.
6531: &mt('Action').'</th><th>'.&mt('Value').'</th>'.
6532: &Apache::loncommon::end_data_table_header_row());
1.221 www 6533: foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
1.560 damieng 6534: unless ($tempkey) { next; }
6535: $r->print("\n".&Apache::loncommon::start_data_table_row().
6536: "<td>".$allparms{$tempkey}."\n<br />(".$tempkey.')</td><td>');
6537: my $action=&rulescache($tempkey.'_action');
6538: $r->print('<select name="'.$tempkey.'_action">');
6539: if (&isdateparm($defkeytype{$tempkey})) {
6540: for (my $i=0;$i<=$#dateoptions;$i++) {
6541: if ($dateoptions[$i]=~/\_$tempkey$/) { next; }
6542: $r->print("\n<option value='$dateoptions[$i]'".
6543: ($dateoptions[$i] eq $action?' selected="selected"':'').
6544: ">$datedisplay[$i]</option>");
6545: }
6546: } else {
6547: for (my $i=0;$i<=$#standardoptions;$i++) {
6548: if ($standardoptions[$i]=~/\_$tempkey$/) { next; }
6549: $r->print("\n<option value='$standardoptions[$i]'".
6550: ($standardoptions[$i] eq $action?' selected="selected"':'').
6551: ">$standarddisplay[$i]</option>");
6552: }
1.473 amueller 6553: }
1.560 damieng 6554: $r->print('</select>');
6555: unless (&isdateparm($defkeytype{$tempkey})) {
6556: $r->print("\n<br />".&mt('Triggering value(s) of other parameter (optional, comma-separated):').
6557: '<input type="text" size="20" name="'.$tempkey.'_triggervalue" value="'.&rulescache($tempkey.'_triggervalue').'" />');
1.473 amueller 6558: }
1.560 damieng 6559: $r->print("\n</td><td>\n");
1.222 www 6560:
1.221 www 6561: if (&isdateparm($defkeytype{$tempkey})) {
1.560 damieng 6562: my $days=&rulescache($tempkey.'_days');
6563: my $hours=&rulescache($tempkey.'_hours');
6564: my $min=&rulescache($tempkey.'_min');
6565: my $sec=&rulescache($tempkey.'_sec');
6566: $r->print(<<ENDINPUTDATE);
6567: <input name="$tempkey\_days" type="text" size="4" value="$days" />$lt{'days'}<br />
6568: <input name="$tempkey\_hours" type="text" size="4" value="$hours" />$lt{'hours'}<br />
6569: <input name="$tempkey\_min" type="text" size="4" value="$min" />$lt{'min'}<br />
6570: <input name="$tempkey\_sec" type="text" size="4" value="$sec" />$lt{'sec'}
1.564 raeburn 6571: ENDINPUTDATE
1.560 damieng 6572: } elsif ($defkeytype{$tempkey} eq 'string_yesno') {
6573: my $yeschecked='';
6574: my $nochecked='';
6575: if (&rulescache($tempkey.'_value') eq 'yes') { $yeschecked=' checked="checked"'; }
6576: if (&rulescache($tempkey.'_value') eq 'no') { $nochecked=' checked="checked"'; }
6577:
6578: $r->print(<<ENDYESNO);
6579: <label><input type="radio" name="$tempkey\_value" value="yes"$yeschecked /> $lt{'yes'}</label><br />
6580: <label><input type="radio" name="$tempkey\_value" value="no"$nochecked /> $lt{'no'}</label>
1.564 raeburn 6581: ENDYESNO
1.221 www 6582: } else {
1.560 damieng 6583: $r->print('<input type="text" size="20" name="'.$tempkey.'_value" value="'.&rulescache($tempkey.'_value').'" />');
6584: }
1.318 albertel 6585: $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.221 www 6586: }
1.318 albertel 6587: $r->print(&Apache::loncommon::end_data_table().
1.473 amueller 6588: "\n".'<input type="submit" name="storerules" value="'.
1.507 www 6589: &mt('Save').'" /></form>'."\n");
6590: &endSettingsScreen($r);
6591: $r->print(&Apache::loncommon::end_page());
1.220 www 6592: return;
6593: }
1.193 albertel 6594:
1.560 damieng 6595: ##################################################
6596: # PARAMETER CHANGES LOG
6597: ##################################################
6598:
1.563 damieng 6599: # Returns some info for a parameter log entry.
6600: # Returned entries:
6601: # $realm - HTML title for the parameter level and resource
6602: # $section - parameter section
6603: # $name - parameter name
6604: # $part - parameter part
6605: # $what - $part.'.'.$name
6606: # $middle - resource symb ?
6607: # $uname - user name (same as given)
6608: # $udom - user domain (same as given)
6609: # $issection - section or group name
6610: # $realmdescription - title for the parameter level and resource (without using HTML)
6611: #
6612: # @param {string} $key - parameter log key
6613: # @param {string} $uname - user name
6614: # @param {string} $udom - user domain
6615: # @param {boolean} $typeflag - .type log entry
6616: # @returns {Array}
1.290 www 6617: sub components {
1.581 raeburn 6618: my ($key,$uname,$udom,$typeflag)=@_;
1.330 albertel 6619:
6620: if ($typeflag) {
1.560 damieng 6621: $key=~s/\.type$//;
1.290 www 6622: }
1.330 albertel 6623:
6624: my ($middle,$part,$name)=
1.572 damieng 6625: ($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s\-]+)\.(\w+)$/);
1.291 www 6626: my $issection;
1.330 albertel 6627:
1.290 www 6628: my $section=&mt('All Students');
6629: if ($middle=~/^\[(.*)\]/) {
1.560 damieng 6630: $issection=$1;
6631: $section=&mt('Group/Section').': '.$issection;
6632: $middle=~s/^\[(.*)\]//;
1.290 www 6633: }
6634: $middle=~s/\.+$//;
6635: $middle=~s/^\.+//;
1.291 www 6636: if ($uname) {
1.560 damieng 6637: $section=&mt('User').": ".&Apache::loncommon::plainname($uname,$udom);
6638: $issection='';
1.291 www 6639: }
1.316 albertel 6640: my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
1.446 bisitz 6641: my $realmdescription=&mt('all resources');
1.556 raeburn 6642: if ($middle=~/^(.+)\_\_\_\((all|rec)\)$/) {
6643: my $mapurl = $1;
6644: my $maplevel = $2;
6645: my $leveltitle = &mt('Folder/Map');
6646: if ($maplevel eq 'rec') {
6647: $leveltitle = &mt('Recursive');
6648: }
1.560 damieng 6649: $realm='<span class="LC_parm_scope_folder">'.$leveltitle.
6650: ': '.&Apache::lonnet::gettitle($mapurl).' <span class="LC_parm_folder"><br />('.
6651: $mapurl.')</span></span>';
6652: $realmdescription=&mt('folder').' '.&Apache::lonnet::gettitle($mapurl);
6653: } elsif ($middle) {
6654: my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
6655: $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').
6656: ': '.&Apache::lonnet::gettitle($middle).' <br /><span class="LC_parm_symb">('.$url.
6657: ' in '.$map.' id: '.$id.')</span></span>';
6658: $realmdescription=&mt('resource').' '.&Apache::lonnet::gettitle($middle);
1.290 www 6659: }
1.291 www 6660: my $what=$part.'.'.$name;
1.330 albertel 6661: return ($realm,$section,$name,$part,
1.473 amueller 6662: $what,$middle,$uname,$udom,$issection,$realmdescription);
1.290 www 6663: }
1.293 www 6664:
1.563 damieng 6665: my %standard_parms; # hash parameter name -> parameter title (not localized)
6666: my %standard_parms_types; # hash parameter name -> parameter type
1.416 jms 6667:
1.563 damieng 6668: # Reads parameter info from packages.tab into %standard_parms.
1.328 albertel 6669: sub load_parameter_names {
1.583 raeburn 6670: open(my $config,"<","$Apache::lonnet::perlvar{'lonTabDir'}/packages.tab");
1.328 albertel 6671: while (my $configline=<$config>) {
1.560 damieng 6672: if ($configline !~ /\S/ || $configline=~/^\#/) { next; }
6673: chomp($configline);
6674: my ($short,$plain)=split(/:/,$configline);
6675: my (undef,$name,$type)=split(/\&/,$short,3);
6676: if ($type eq 'display') {
6677: $standard_parms{$name} = $plain;
1.469 raeburn 6678: } elsif ($type eq 'type') {
1.560 damieng 6679: $standard_parms_types{$name} = $plain;
1.469 raeburn 6680: }
1.328 albertel 6681: }
6682: close($config);
6683: $standard_parms{'int_pos'} = 'Positive Integer';
6684: $standard_parms{'int_zero_pos'} = 'Positive Integer or Zero';
1.575 raeburn 6685: $standard_parms{'scoreformat'} = 'Format for display of score';
1.328 albertel 6686: }
6687:
1.563 damieng 6688: # Returns a parameter title for standard parameters, the name for others.
6689: #
6690: # @param {string} $name - parameter name
6691: # @returns {string}
1.292 www 6692: sub standard_parameter_names {
6693: my ($name)=@_;
1.328 albertel 6694: if (!%standard_parms) {
1.560 damieng 6695: &load_parameter_names();
1.328 albertel 6696: }
1.292 www 6697: if ($standard_parms{$name}) {
1.560 damieng 6698: return $standard_parms{$name};
1.446 bisitz 6699: } else {
1.560 damieng 6700: return $name;
1.292 www 6701: }
6702: }
1.290 www 6703:
1.563 damieng 6704: # Returns a parameter type for standard parameters, undef for others.
6705: #
6706: # @param {string} $name - parameter name
6707: # @returns {string}
1.469 raeburn 6708: sub standard_parameter_types {
6709: my ($name)=@_;
6710: if (!%standard_parms_types) {
6711: &load_parameter_names();
6712: }
6713: if ($standard_parms_types{$name}) {
6714: return $standard_parms_types{$name};
6715: }
6716: return;
6717: }
1.309 www 6718:
1.563 damieng 6719: # Returns a parameter level title (not localized) from the parameter level name.
6720: #
6721: # @param {string} $name - parameter level name (recognized: resourcelevel|maplevel|maplevelrecurse|courselevel)
6722: # @returns {string}
1.557 raeburn 6723: sub standard_parameter_levels {
6724: my ($name)=@_;
6725: my %levels = (
6726: 'resourcelevel' => 'a single resource',
6727: 'maplevel' => 'the enclosing map/folder',
6728: 'maplevelrecurse' => 'the enclosing map/folder (recursive into sub-folders)',
6729: 'courselevel' => 'the general (course) level',
6730: );
6731: if ($levels{$name}) {
6732: return $levels{$name};
6733: }
6734: return;
6735: }
6736:
1.560 damieng 6737: # Display log for parameter changes, blog postings, user notification changes.
1.563 damieng 6738: #
6739: # @param {Apache2::RequestRec} $r - the Apache request
1.285 albertel 6740: sub parm_change_log {
1.568 raeburn 6741: my ($r,$parm_permission)=@_;
1.531 raeburn 6742: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
6743: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.569 raeburn 6744: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.414 droeschl 6745: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',
1.473 amueller 6746: text=>"Parameter Change Log"});
1.522 raeburn 6747: my $js = '<script type="text/javascript">'."\n".
6748: '// <![CDATA['."\n".
6749: &Apache::loncommon::display_filter_js('parmslog')."\n".
6750: '// ]]>'."\n".
6751: '</script>'."\n";
6752: $r->print(&Apache::loncommon::start_page('Parameter Change Log',$js));
1.327 albertel 6753: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Parameter Change Log'));
1.531 raeburn 6754: &startSettingsScreen($r,'parmset',$crstype);
6755: my %parmlog=&Apache::lonnet::dump('nohist_parameterlog',$cdom,$cnum);
1.311 albertel 6756:
1.301 www 6757: if ((keys(%parmlog))[0]=~/^error\:/) { undef(%parmlog); }
1.311 albertel 6758:
1.522 raeburn 6759: $r->print('<div class="LC_left_float">'.
6760: '<fieldset><legend>'.&mt('Display of Changes').'</legend>'.
6761: '<form action="/adm/parmset?action=parameterchangelog"
1.327 albertel 6762: method="post" name="parameterlog">');
1.446 bisitz 6763:
1.311 albertel 6764: my %saveable_parameters = ('show' => 'scalar',);
6765: &Apache::loncommon::store_course_settings('parameter_log',
6766: \%saveable_parameters);
6767: &Apache::loncommon::restore_course_settings('parameter_log',
6768: \%saveable_parameters);
1.522 raeburn 6769: $r->print(&Apache::loncommon::display_filter('parmslog').' '."\n".
6770: '<input type="submit" value="'.&mt('Display').'" />'.
6771: '</form></fieldset></div><br clear="all" />');
1.301 www 6772:
1.568 raeburn 6773: my $readonly = 1;
6774: if ($parm_permission->{'edit'}) {
6775: undef($readonly);
6776: }
1.531 raeburn 6777: my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
1.301 www 6778: $r->print(&Apache::loncommon::start_data_table().&Apache::loncommon::start_data_table_header_row().
1.473 amueller 6779: '<th>'.&mt('Time').'</th><th>'.&mt('User').'</th><th>'.&mt('Extent').'</th><th>'.&mt('Users').'</th><th>'.
1.568 raeburn 6780: &mt('Parameter').'</th><th>'.&mt('Part').'</th><th>'.&mt('New Value').'</th>');
6781: unless ($readonly) {
6782: $r->print('<th>'.&mt('Announce').'</th>');
6783: }
6784: $r->print(&Apache::loncommon::end_data_table_header_row());
1.309 www 6785: my $shown=0;
1.349 www 6786: my $folder='';
6787: if ($env{'form.displayfilter'} eq 'currentfolder') {
1.560 damieng 6788: my $last='';
6789: if (tie(my %hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db',
6790: &GDBM_READER(),0640)) {
6791: $last=$hash{'last_known'};
6792: untie(%hash);
6793: }
6794: if ($last) { ($folder) = &Apache::lonnet::decode_symb($last); }
6795: }
6796: foreach my $id (sort {
6797: if ($parmlog{$b}{'exe_time'} ne $parmlog{$a}{'exe_time'}) {
6798: return $parmlog{$b}{'exe_time'} <=>$parmlog{$a}{'exe_time'}
6799: }
6800: my $aid = (split('00000',$a))[-1];
6801: my $bid = (split('00000',$b))[-1];
6802: return $bid<=>$aid;
1.473 amueller 6803: } (keys(%parmlog))) {
1.294 www 6804: my @changes=keys(%{$parmlog{$id}{'logentry'}});
1.560 damieng 6805: my $count = 0;
6806: my $time =
6807: &Apache::lonlocal::locallocaltime($parmlog{$id}{'exe_time'});
6808: my $plainname =
6809: &Apache::loncommon::plainname($parmlog{$id}{'exe_uname'},
6810: $parmlog{$id}{'exe_udom'});
6811: my $about_me_link =
6812: &Apache::loncommon::aboutmewrapper($plainname,
6813: $parmlog{$id}{'exe_uname'},
6814: $parmlog{$id}{'exe_udom'});
6815: my $send_msg_link='';
1.568 raeburn 6816: if ((!$readonly) &&
6817: (($parmlog{$id}{'exe_uname'} ne $env{'user.name'})
1.560 damieng 6818: || ($parmlog{$id}{'exe_udom'} ne $env{'user.domain'}))) {
6819: $send_msg_link ='<br />'.
6820: &Apache::loncommon::messagewrapper(&mt('Send message'),
6821: $parmlog{$id}{'exe_uname'},
6822: $parmlog{$id}{'exe_udom'});
6823: }
6824: my $row_start=&Apache::loncommon::start_data_table_row();
6825: my $makenewrow=0;
6826: my %istype=();
6827: my $output;
6828: foreach my $changed (reverse(sort(@changes))) {
6829: my $value=$parmlog{$id}{'logentry'}{$changed};
6830: my $typeflag = ($changed =~/\.type$/ &&
6831: !exists($parmlog{$id}{'logentry'}{$changed.'.type'}));
1.330 albertel 6832: my ($realm,$section,$parmname,$part,$what,$middle,$uname,$udom,$issection,$realmdescription)=
1.581 raeburn 6833: &components($changed,$parmlog{$id}{'uname'},$parmlog{$id}{'udom'},$typeflag);
1.560 damieng 6834: if ($env{'request.course.sec'} ne '') {
6835: next if (($issection ne '') && ($issection ne $env{'request.course.sec'}));
6836: if ($uname ne '') {
6837: my $stusection = &Apache::lonnet::getsection($uname,$udom,$env{'request.course.id'});
6838: next if (($stusection ne '-1') && ($stusection ne $env{'request.course.sec'}));
6839: }
6840: }
6841: if ($env{'form.displayfilter'} eq 'currentfolder') {
6842: if ($folder) {
6843: if ($middle!~/^\Q$folder\E/) { next; }
6844: }
6845: }
6846: if ($typeflag) {
6847: $istype{$parmname}=$value;
6848: if (!$env{'form.includetypes'}) { next; }
6849: }
6850: $count++;
6851: if ($makenewrow) {
6852: $output .= $row_start;
6853: } else {
6854: $makenewrow=1;
6855: }
1.470 raeburn 6856: my $parmitem = &standard_parameter_names($parmname);
1.560 damieng 6857: $output .='<td>'.$realm.'</td><td>'.$section.'</td><td>'.
6858: &mt($parmitem).'</td><td>'.
6859: ($part?&mt('Part: [_1]',$part):&mt('All Parts')).'</td><td>';
6860: my $stillactive=0;
6861: if ($parmlog{$id}{'delflag'}) {
6862: $output .= &mt('Deleted');
6863: } else {
6864: if ($typeflag) {
1.470 raeburn 6865: my $parmitem = &standard_parameter_names($value);
6866: $parmitem = &mt($parmitem);
1.560 damieng 6867: $output .= &mt('Type: [_1]',$parmitem);
6868: } else {
1.584 raeburn 6869: my $toolsymb;
6870: if ($middle =~ /ext\.tool$/) {
6871: $toolsymb = $middle;
6872: }
1.560 damieng 6873: my ($level,@all)=&parmval_by_symb($what,$middle,
1.584 raeburn 6874: &Apache::lonnet::metadata($middle,$what,$toolsymb),
1.560 damieng 6875: $uname,$udom,$issection,$issection,$courseopt);
1.469 raeburn 6876: my $showvalue = $value;
6877: if ($istype{$parmname} eq '') {
6878: my $type = &standard_parameter_types($parmname);
6879: if ($type ne '') {
6880: if (&isdateparm($type)) {
6881: $showvalue =
6882: &Apache::lonlocal::locallocaltime($value);
6883: }
6884: }
6885: } else {
1.560 damieng 6886: if (&isdateparm($istype{$parmname})) {
6887: $showvalue = &Apache::lonlocal::locallocaltime($value);
6888: }
1.469 raeburn 6889: }
6890: $output .= $showvalue;
1.560 damieng 6891: if ($value ne $all[$level]) {
6892: $output .= '<br /><span class="LC_warning">'.&mt('Not active anymore').'</span>';
6893: } else {
6894: $stillactive=1;
6895: }
6896: }
1.473 amueller 6897: }
1.568 raeburn 6898: $output .= '</td>';
6899:
6900: unless ($readonly) {
6901: $output .= '<td>';
6902: if ($stillactive) {
6903: my $parmitem = &standard_parameter_names($parmname);
6904: $parmitem = &mt($parmitem);
6905: my $title=&mt('Changed [_1]',$parmitem);
6906: my $description=&mt('Changed [_1] for [_2] to [_3]',
6907: $parmitem,$realmdescription,
6908: (&isdateparm($istype{$parmname})?&Apache::lonlocal::locallocaltime($value):$value));
6909: if (($uname) && ($udom)) {
6910: $output .=
6911: &Apache::loncommon::messagewrapper('Notify User',
6912: $uname,$udom,$title,
6913: $description);
6914: } else {
6915: $output .=
6916: &Apache::lonrss::course_blog_link($id,$title,
6917: $description);
6918: }
1.560 damieng 6919: }
1.568 raeburn 6920: $output .= '</td>';
1.560 damieng 6921: }
1.568 raeburn 6922: $output .= &Apache::loncommon::end_data_table_row();
1.473 amueller 6923: }
1.560 damieng 6924: if ($env{'form.displayfilter'} eq 'containing') {
6925: my $wholeentry=$about_me_link.':'.
6926: $parmlog{$id}{'exe_uname'}.':'.$parmlog{$id}{'exe_udom'}.':'.
6927: $output;
6928: if ($wholeentry!~/\Q$env{'form.containingphrase'}\E/i) { next; }
1.473 amueller 6929: }
1.349 www 6930: if ($count) {
1.560 damieng 6931: $r->print($row_start.'<td rowspan="'.$count.'">'.$time.'</td>
6932: <td rowspan="'.$count.'">'.$about_me_link.
6933: '<br /><tt>'.$parmlog{$id}{'exe_uname'}.
6934: ':'.$parmlog{$id}{'exe_udom'}.'</tt>'.
6935: $send_msg_link.'</td>'.$output);
6936: $shown++;
6937: }
6938: if (!($env{'form.show'} eq &mt('all')
6939: || $shown<=$env{'form.show'})) { last; }
1.286 www 6940: }
1.301 www 6941: $r->print(&Apache::loncommon::end_data_table());
1.507 www 6942: &endSettingsScreen($r);
1.284 www 6943: $r->print(&Apache::loncommon::end_page());
6944: }
6945:
1.560 damieng 6946: ##################################################
6947: # MISC !
6948: ##################################################
6949:
1.563 damieng 6950: # Stores slot information.
1.560 damieng 6951: # Used by table UI
1.563 damieng 6952: # FIXME: I don't understand how this can work when the symb is not defined (if only a map was selected)
6953: #
6954: # @param {string} $slot_name - slot name
6955: # @param {string} $cdom - course domain
6956: # @param {string} $cnum - course number
6957: # @param {string} $symb - resource symb
6958: # @param {string} $uname - user name
6959: # @param {string} $udom - user domain
6960: # @returns {string} - 'ok' or error name
1.437 raeburn 6961: sub update_slots {
6962: my ($slot_name,$cdom,$cnum,$symb,$uname,$udom) = @_;
6963: my %slot=&Apache::lonnet::get_slot($slot_name);
6964: if (!keys(%slot)) {
6965: return 'error: slot does not exist';
6966: }
6967: my $max=$slot{'maxspace'};
6968: if (!defined($max)) { $max=99999; }
6969:
6970: my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
6971: "^$slot_name\0");
6972: my ($tmp)=%consumed;
6973: if ($tmp=~/^error: 2 / ) {
6974: return 'error: unable to determine current slot status';
6975: }
6976: my $last=0;
6977: foreach my $key (keys(%consumed)) {
6978: my $num=(split('\0',$key))[1];
6979: if ($num > $last) { $last=$num; }
6980: if ($consumed{$key}->{'name'} eq $uname.':'.$udom) {
6981: return 'ok';
6982: }
6983: }
6984:
6985: if (scalar(keys(%consumed)) >= $max) {
6986: return 'error: no space left in slot';
6987: }
6988: my $wanted=$last+1;
6989:
6990: my %reservation=('name' => $uname.':'.$udom,
6991: 'timestamp' => time,
6992: 'symb' => $symb);
6993:
6994: my $success=&Apache::lonnet::newput('slot_reservations',
6995: {"$slot_name\0$wanted" =>
6996: \%reservation},
6997: $cdom, $cnum);
1.438 raeburn 6998: if ($success eq 'ok') {
6999: my %storehash = (
7000: symb => $symb,
7001: slot => $slot_name,
7002: action => 'reserve',
7003: context => 'parameter',
7004: );
1.526 raeburn 7005: &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,
1.524 raeburn 7006: '',$uname,$udom,$cnum,$cdom);
1.438 raeburn 7007:
1.526 raeburn 7008: &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash,
1.524 raeburn 7009: '',$uname,$udom,$uname,$udom);
1.438 raeburn 7010: }
1.437 raeburn 7011: return $success;
7012: }
7013:
1.563 damieng 7014: # Deletes a slot reservation.
1.560 damieng 7015: # Used by table UI
1.563 damieng 7016: # FIXME: I don't understand how this can work when the symb is not defined (if only a map was selected)
7017: #
7018: # @param {string} $slot_name - slot name
7019: # @param {string} $cdom - course domain
7020: # @param {string} $cnum - course number
7021: # @param {string} $uname - user name
7022: # @param {string} $udom - user domain
7023: # @param {string} $symb - resource symb
7024: # @returns {string} - 'ok' or error name
1.437 raeburn 7025: sub delete_slots {
7026: my ($slot_name,$cdom,$cnum,$uname,$udom,$symb) = @_;
7027: my $delresult;
7028: my %consumed = &Apache::lonnet::dump('slot_reservations',$cdom,
7029: $cnum, "^$slot_name\0");
7030: if (&Apache::lonnet::error(%consumed)) {
7031: return 'error: unable to determine current slot status';
7032: }
7033: my ($tmp)=%consumed;
7034: if ($tmp=~/^error: 2 /) {
7035: return 'error: unable to determine current slot status';
7036: }
7037: foreach my $key (keys(%consumed)) {
7038: if ($consumed{$key}->{'name'} eq $uname.':'.$udom) {
7039: my $num=(split('\0',$key))[1];
7040: my $entry = $slot_name.'\0'.$num;
7041: $delresult = &Apache::lonnet::del('slot_reservations',[$entry],
7042: $cdom,$cnum);
7043: if ($delresult eq 'ok') {
7044: my %storehash = (
7045: symb => $symb,
7046: slot => $slot_name,
7047: action => 'release',
7048: context => 'parameter',
7049: );
1.526 raeburn 7050: &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,
1.524 raeburn 7051: 1,$uname,$udom,$cnum,$cdom);
1.526 raeburn 7052: &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash,
1.524 raeburn 7053: 1,$uname,$udom,$uname,$udom);
1.437 raeburn 7054: }
7055: }
7056: }
7057: return $delresult;
7058: }
7059:
1.563 damieng 7060: # Returns true if there is a current course.
1.560 damieng 7061: # Used by handler
1.563 damieng 7062: #
7063: # @returns {boolean}
1.355 albertel 7064: sub check_for_course_info {
7065: my $navmap = Apache::lonnavmaps::navmap->new();
7066: return 1 if ($navmap);
7067: return 0;
7068: }
7069:
1.563 damieng 7070: # Returns the current course host and host LON-CAPA version.
7071: #
7072: # @returns {Array} - (course hostname, major version number, minor version number)
1.514 raeburn 7073: sub parameter_release_vars {
1.504 raeburn 7074: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
7075: my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};
7076: my $chostname = &Apache::lonnet::hostname($chome);
7077: my ($cmajor,$cminor) =
7078: split(/\./,&Apache::lonnet::get_server_loncaparev($cdom,$chome));
7079: return ($chostname,$cmajor,$cminor);
7080: }
7081:
1.563 damieng 7082: # Checks if the course host version can handle a parameter required version,
7083: # and if it does, stores the release needed for the course.
7084: #
7085: # @param {string} $name - parameter name
7086: # @param {string} $value - parameter value
7087: # @param {string} $valmatch - name of the test used for checking the value
7088: # @param {string} $namematch - name of the test used for checking the name
7089: # @param {string} $needsrelease - version needed by the parameter, major.minor
7090: # @param {integer} $cmajor - course major version number
7091: # @param {integer} $cminor - course minor version number
7092: # @returns {boolean} - true if a newer version is needed
1.514 raeburn 7093: sub parameter_releasecheck {
1.557 raeburn 7094: my ($name,$value,$valmatch,$namematch,$needsrelease,$cmajor,$cminor) = @_;
1.504 raeburn 7095: my $needsnewer;
7096: my ($needsmajor,$needsminor) = split(/\./,$needsrelease);
7097: if (($cmajor < $needsmajor) ||
7098: ($cmajor == $needsmajor && $cminor < $needsminor)) {
7099: $needsnewer = 1;
1.557 raeburn 7100: } elsif ($name) {
7101: if ($valmatch) {
7102: &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:'.$name.'::'.$valmatch.':'});
7103: } elsif ($value) {
7104: &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:'.$name.':'.$value.'::'});
7105: }
7106: } elsif ($namematch) {
7107: &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter::::'.$namematch});
1.504 raeburn 7108: }
7109: return $needsnewer;
7110: }
7111:
1.568 raeburn 7112: sub get_permission {
7113: my %permission;
7114: my $allowed = 0;
7115: return (\%permission,$allowed) unless ($env{'request.course.id'});
7116: if ((&Apache::lonnet::allowed('opa',$env{'request.course.id'})) ||
7117: (&Apache::lonnet::allowed('opa',$env{'request.course.id'}.'/'.
7118: $env{'request.course.sec'}))) {
7119: %permission= (
7120: 'edit' => 1,
7121: 'set' => 1,
7122: 'setoverview' => 1,
7123: 'addmetadata' => 1,
7124: 'ordermetadata' => 1,
7125: 'setrestrictmeta' => 1,
7126: 'newoverview' => 1,
7127: 'setdefaults' => 1,
7128: 'settable' => 1,
7129: 'parameterchangelog' => 1,
7130: 'cleanparameters' => 1,
7131: 'dateshift1' => 1,
7132: 'dateshift2' => 1,
7133: 'helper' => 1,
7134: );
7135: } elsif ((&Apache::lonnet::allowed('vpa',$env{'request.course.id'})) ||
7136: (&Apache::lonnet::allowed('vpa',$env{'request.course.id'}.'/'.
7137: $env{'request.course.sec'}))) {
7138: %permission = (
7139: 'set' => 1,
7140: 'settable' => 1,
7141: 'newoverview' => 1,
7142: 'setoverview' => 1,
7143: 'parameterchangelog' => 1,
7144: );
7145: }
7146: foreach my $perm (values(%permission)) {
7147: if ($perm) { $allowed=1; last; }
7148: }
7149: return (\%permission,$allowed);
7150: }
7151:
1.560 damieng 7152: ##################################################
7153: # HANDLER
7154: ##################################################
7155:
7156: # Main handler for lonparmset.
7157: # Sub called based on request parameters action and command:
7158: # no command or action: print_main_menu
7159: # command 'set': assessparms (direct access to table mode for a resource)
7160: # (this can also be accessed simply with the symb parameter)
7161: # action 'setoverview': overview (display all existing parameter settings)
7162: # action 'addmetadata': addmetafield (called to add a portfolio metadata field)
7163: # action 'ordermetadata': order_meta_fields (called to order portfolio metadata fields)
7164: # action 'setrestrictmeta': setrestrictmeta (display or save portfolio metadata)
7165: # action 'newoverview': newoverview (overview mode)
7166: # action 'setdefaults': defaultsetter (UI to change parameter setting default actions)
7167: # action 'settable': assessparms (table mode)
7168: # action 'parameterchangelog': parm_change_log (display log for parameter changes,
7169: # blog postings, user notification changes)
7170: # action 'cleanparameters': clean_parameters (unused)
7171: # action 'dateshift1': date_shift_one (overview mode, shift all dates)
7172: # action 'dateshift2': date_shift_two (overview mode, shift all dates)
1.30 www 7173: sub handler {
1.43 albertel 7174: my $r=shift;
1.30 www 7175:
1.376 albertel 7176: &reset_caches();
7177:
1.414 droeschl 7178: &Apache::loncommon::content_type($r,'text/html');
7179: $r->send_http_header;
7180: return OK if $r->header_only;
7181:
1.193 albertel 7182: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.473 amueller 7183: ['action','state',
1.205 www 7184: 'pres_marker',
7185: 'pres_value',
1.206 www 7186: 'pres_type',
1.506 www 7187: 'filter','part',
1.390 www 7188: 'udom','uname','symb','serial','timebase']);
1.131 www 7189:
1.83 bowersj2 7190:
1.193 albertel 7191: &Apache::lonhtmlcommon::clear_breadcrumbs();
1.194 albertel 7192: &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/parmset",
1.507 www 7193: text=>"Content and Problem Settings",
1.473 amueller 7194: faq=>10,
7195: bug=>'Instructor Interface',
1.442 droeschl 7196: help =>
7197: 'Parameter_Manager,Course_Environment,Parameter_Helper,Parameter_Overview,Table_Mode'});
1.203 www 7198:
1.30 www 7199: # ----------------------------------------------------- Needs to be in a course
1.568 raeburn 7200: my ($parm_permission,$allowed) = &get_permission();
1.355 albertel 7201: my $exists = &check_for_course_info();
7202:
1.568 raeburn 7203: if ($env{'request.course.id'} && $allowed && $exists) {
1.193 albertel 7204: #
7205: # Main switch on form.action and form.state, as appropriate
7206: #
7207: # Check first if coming from someone else headed directly for
7208: # the table mode
1.568 raeburn 7209: if (($parm_permission->{'set'}) &&
7210: ((($env{'form.command'} eq 'set') && ($env{'form.url'})
7211: && (!$env{'form.dis'})) || ($env{'form.symb'}))) {
7212: &assessparms($r,$parm_permission);
1.193 albertel 7213: } elsif (! exists($env{'form.action'})) {
7214: &print_main_menu($r,$parm_permission);
1.568 raeburn 7215: } elsif (!$parm_permission->{$env{'form.action'}}) {
7216: &print_main_menu($r,$parm_permission);
1.414 droeschl 7217: } elsif ($env{'form.action'} eq 'setoverview') {
1.568 raeburn 7218: &overview($r,$parm_permission);
1.560 damieng 7219: } elsif ($env{'form.action'} eq 'addmetadata') {
7220: &addmetafield($r);
7221: } elsif ($env{'form.action'} eq 'ordermetadata') {
7222: &order_meta_fields($r);
1.414 droeschl 7223: } elsif ($env{'form.action'} eq 'setrestrictmeta') {
1.560 damieng 7224: &setrestrictmeta($r);
1.414 droeschl 7225: } elsif ($env{'form.action'} eq 'newoverview') {
1.568 raeburn 7226: &newoverview($r,$parm_permission);
1.414 droeschl 7227: } elsif ($env{'form.action'} eq 'setdefaults') {
1.560 damieng 7228: &defaultsetter($r);
7229: } elsif ($env{'form.action'} eq 'settable') {
1.568 raeburn 7230: &assessparms($r,$parm_permission);
1.414 droeschl 7231: } elsif ($env{'form.action'} eq 'parameterchangelog') {
1.568 raeburn 7232: &parm_change_log($r,$parm_permission);
1.414 droeschl 7233: } elsif ($env{'form.action'} eq 'cleanparameters') {
1.560 damieng 7234: &clean_parameters($r);
1.414 droeschl 7235: } elsif ($env{'form.action'} eq 'dateshift1') {
1.390 www 7236: &date_shift_one($r);
1.414 droeschl 7237: } elsif ($env{'form.action'} eq 'dateshift2') {
1.390 www 7238: &date_shift_two($r);
1.446 bisitz 7239: }
1.43 albertel 7240: } else {
1.1 www 7241: # ----------------------------- Not in a course, or not allowed to modify parms
1.560 damieng 7242: if ($exists) {
7243: $env{'user.error.msg'}=
7244: "/adm/parmset:opa:0:0:Cannot modify assessment parameters";
7245: } else {
7246: $env{'user.error.msg'}=
7247: "/adm/parmset::0:1:Course environment gone, reinitialize the course";
7248: }
7249: return HTTP_NOT_ACCEPTABLE;
1.43 albertel 7250: }
1.376 albertel 7251: &reset_caches();
7252:
1.43 albertel 7253: return OK;
1.1 www 7254: }
7255:
7256: 1;
7257: __END__
7258:
7259:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>