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