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