Annotation of loncom/interface/lonparmset.pm, revision 1.620
1.1 www 1: # The LearningOnline Network with CAPA
2: # Handler to set parameters for assessments
3: #
1.620 ! raeburn 4: # $Id: lonparmset.pm,v 1.619 2023/04/03 19:53:30 raeburn Exp $
1.40 albertel 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
1.59 matthew 28: ###################################################################
29: ###################################################################
30:
31: =pod
32:
33: =head1 NAME
34:
35: lonparmset - Handler to set parameters for assessments and course
36:
37: =head1 SYNOPSIS
38:
1.579 raeburn 39: lonparmset provides an interface to setting content parameters in a
40: course.
1.560 damieng 41:
42: It contains all the code for the "Content and Problem Settings" UI, except
43: for the helpers parameter.helper and resettimes.helper, and lonhelper.pm,
44: and lonblockingmenu.pm.
1.59 matthew 45:
46: =head1 DESCRIPTION
47:
48: This module sets coursewide and assessment parameters.
49:
50: =head1 INTERNAL SUBROUTINES
51:
1.416 jms 52: =over
1.59 matthew 53:
1.416 jms 54: =item parmval()
1.59 matthew 55:
56: Figure out a cascading parameter.
57:
1.71 albertel 58: Inputs: $what - a parameter spec (incluse part info and name I.E. 0.weight)
1.162 albertel 59: $id - a bighash Id number
1.71 albertel 60: $def - the resource's default value 'stupid emacs
61:
1.556 raeburn 62: Returns: A list, the first item is the index into the remaining list of items of parm values that is the active one, the list consists of parm values at the 18 possible levels
1.71 albertel 63:
1.556 raeburn 64: 18 - General Course
65: 17 - Map or Folder level in course (recursive)
66: 16 - Map or Folder level in course (non-recursive)
67: 15 - resource default
68: 14 - map default
69: 13 - resource level in course
70: 12 - General for section
71: 11 - Map or Folder level for section (recursive)
72: 10 - Map or Folder level for section (non-recursive)
73: 9 - resource level in section
74: 8 - General for group
75: 7 - Map or Folder level for group (recursive)
76: 6 - Map or Folder level for group (non-recursive)
77: 5 - resource level in group
78: 4 - General for specific student
79: 3 - Map or Folder level for specific student (recursive)
80: 2 - Map or Folder level for specific student (non-recursive)
1.71 albertel 81: 1 - resource level for specific student
1.2 www 82:
1.416 jms 83: =item parmval_by_symb()
84:
85: =item reset_caches()
86:
87: =item cacheparmhash()
88:
89: =item parmhash()
90:
91: =item symbcache()
92:
93: =item preset_defaults()
94:
95: =item date_sanity_info()
96:
97: =item storeparm()
98:
99: Store a parameter by symb
100:
101: Takes
102: - symb
103: - name of parameter
104: - level
105: - new value
106: - new type
107: - username
108: - userdomain
109:
110: =item log_parmset()
111:
112: =item storeparm_by_symb_inner()
113:
114: =item valout()
115:
116: Format a value for output.
117:
118: Inputs: $value, $type, $editable
119:
120: Returns: $value, formatted for output. If $type indicates it is a date,
121: localtime($value) is returned.
122: $editable will return an icon to click on
123:
124: =item plink()
125:
126: Produces a link anchor.
127:
128: Inputs: $type,$dis,$value,$marker,$return,$call
129:
130: Returns: scalar with html code for a link which will envoke the
131: javascript function 'pjump'.
132:
133: =item page_js()
134:
135: =item startpage()
136:
137: =item print_row()
138:
139: =item print_td()
140:
1.580 raeburn 141: =item check_other_groups()
1.416 jms 142:
143: =item parm_control_group()
144:
145: =item extractResourceInformation() :
146:
1.512 foxr 147: extractResourceInformation extracts lots of information about all of the the course's resources into a variety of hashes.
1.416 jms 148:
1.542 raeburn 149: Input: See list below
150:
151: =over 4
1.416 jms 152:
1.512 foxr 153: =item * B<env{'user.name'}> : Current username
1.416 jms 154:
1.512 foxr 155: =item * B<env{'user.domain'}> : Domain of current user.
1.416 jms 156:
1.542 raeburn 157: =item * B<env{"request.course.fn"}> : Course
158:
159: =back
1.416 jms 160:
1.512 foxr 161: Outputs: See list below:
1.416 jms 162:
1.542 raeburn 163: =over 4
164:
1.512 foxr 165: =item * B<ids> (out) : An array that will contain all of the ids in the course.
1.416 jms 166:
1.512 foxr 167: =item * B<typep>(out) : hash, id->type, where "type" contains the extension of the file, thus, I<problem exam quiz assess survey form>.
1.416 jms 168:
1.512 foxr 169: =item * B<keyp> (out) : hash, id->key list, will contain a comma separated list of the meta-data keys available for the given id
1.416 jms 170:
1.512 foxr 171: =item * B<allparms> (out) : hash, name of parameter->display value (what is the display value?)
1.416 jms 172:
1.512 foxr 173: =item * B<allparts> (out) : hash, part identification->text representation of part, where the text representation is "[Part $part]"
174:
175: =item * B<allmaps> (out) : hash, ???
1.416 jms 176:
177: =item * B<mapp> : ??
178:
179: =item * B<symbp> : hash, id->full sym?
180:
1.512 foxr 181: =item * B<maptitles>
182:
183: =item * B<uris>
1.416 jms 184:
1.512 foxr 185: =item * B<keyorder>
186:
187: =item * B<defkeytype>
1.416 jms 188:
1.542 raeburn 189: =back
190:
1.416 jms 191: =item isdateparm()
192:
193: =item parmmenu()
194:
195: =item partmenu()
196:
197: =item usermenu()
198:
199: =item displaymenu()
200:
201: =item mapmenu()
202:
203: =item levelmenu()
204:
205: =item sectionmenu()
206:
207: =item keysplit()
208:
209: =item keysinorder()
210:
211: =item keysinorder_bytype()
212:
213: =item keysindisplayorder()
214:
215: =item standardkeyorder()
216:
217: =item assessparms() :
218:
219: Show assessment data and parameters. This is a large routine that should
220: be simplified and shortened... someday.
221:
1.513 foxr 222: Inputs: $r - the Apache request object.
223:
1.416 jms 224: Returns: nothing
225:
226: Variables used (guessed by Jeremy):
227:
1.542 raeburn 228: =over
229:
1.416 jms 230: =item * B<pscat>: ParameterS CATegories? ends up a list of the types of parameters that exist, e.g., tol, weight, acc, opendate, duedate, answerdate, sig, maxtries, type.
231:
232: =item * B<psprt>: ParameterS PaRTs? a list of the parts of a problem that we are displaying? Used to display only selected parts?
233:
234: =item * B<@catmarker> contains list of all possible parameters including part #s
235:
236: =item * B<$fullkeyp> contains the full part/id # for the extraction of proper parameters
237:
238: =item * B<$tempkeyp> contains part 0 only (no ids - ie, subparts)
239: When storing information, store as part 0
240: When requesting information, request from full part
241:
1.542 raeburn 242: =back
243:
1.416 jms 244: =item tablestart()
245:
246: =item tableend()
247:
248: =item extractuser()
249:
250: =item parse_listdata_key()
251:
252: =item listdata()
253:
254: =item date_interval_selector()
255:
256: =item get_date_interval_from_form()
257:
258: =item default_selector()
259:
260: =item string_selector()
261:
262: =item dateshift()
263:
264: =item newoverview()
265:
266: =item secgroup_lister()
267:
268: =item overview()
269:
270: =item clean_parameters()
271:
272: =item date_shift_one()
273:
274: =item date_shift_two()
275:
276: =item parse_key()
277:
278: =item header()
279:
280: Output html header for page
281:
282: =item print_main_menu()
283:
284: =item output_row()
285:
286: Set portfolio metadata
287:
288: =item order_meta_fields()
289:
290: =item addmetafield()
291:
292: =item setrestrictmeta()
293:
294: =item get_added_meta_fieldnames()
295:
296: =item get_deleted_meta_fieldnames()
297:
298: =item defaultsetter()
299:
300: =item components()
301:
302: =item load_parameter_names()
303:
304: =item parm_change_log()
305:
306: =item handler() :
307:
1.450 raeburn 308: Main handler. Calls &assessparms subroutine.
1.416 jms 309:
310: =back
311:
1.59 matthew 312: =cut
313:
1.416 jms 314: ###################################################################
315: ###################################################################
316:
317: package Apache::lonparmset;
318:
319: use strict;
320: use Apache::lonnet;
321: use Apache::Constants qw(:common :http REDIRECT);
322: use Apache::lonhtmlcommon();
323: use Apache::loncommon;
324: use GDBM_File;
325: use Apache::lonhomework;
326: use Apache::lonxml;
327: use Apache::lonlocal;
328: use Apache::lonnavmaps;
329: use Apache::longroup;
330: use Apache::lonrss;
1.506 www 331: use HTML::Entities;
1.617 raeburn 332: use Text::Wrap();
1.416 jms 333: use LONCAPA qw(:DEFAULT :match);
334:
335:
1.560 damieng 336: ##################################################
337: # CONTENT AND PROBLEM SETTINGS HTML PAGE HEADER/FOOTER
338: ##################################################
339:
340: # Page header
1.561 damieng 341: #
342: # @param {Apache2::RequestRec} $r - Apache request object
343: # @param {string} $mode - selected tab, 'parmset' for course and problem settings, or 'coursepref' for course settings
344: # @param {string} $crstype - course type ('Community' for community settings)
1.507 www 345: sub startSettingsScreen {
1.531 raeburn 346: my ($r,$mode,$crstype)=@_;
1.507 www 347:
1.531 raeburn 348: my $tabtext = &mt('Course Settings');
349: if ($crstype eq 'Community') {
350: $tabtext = &mt('Community Settings');
351: }
1.507 www 352: $r->print("\n".'<ul class="LC_TabContentBigger" id="main">');
353: $r->print("\n".'<li'.($mode eq 'coursepref'?' class="active"':'').'><a href="/adm/courseprefs"><b> '.
1.531 raeburn 354: $tabtext.
1.507 www 355: ' </b></a></li>');
356:
1.523 raeburn 357: $r->print("\n".'<li'.($mode eq 'parmset'?' class="active"':'').' id="tabbededitor"><a href="/adm/parmset"><b>'.
1.507 www 358: &mt('Content and Problem Settings').'</b></a></li>');
359: $r->print("\n".'</ul>'."\n");
1.523 raeburn 360: $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 361: }
362:
1.560 damieng 363: # Page footer
1.507 www 364: sub endSettingsScreen {
365: my ($r)=@_;
366: $r->print('</div></div></div>');
367: }
368:
369:
370:
1.560 damieng 371: ##################################################
1.563 damieng 372: # (mostly) TABLE MODE
1.560 damieng 373: # (parmval is also used for the log of parameter changes)
374: ##################################################
375:
1.566 damieng 376: # Calls parmval_by_symb, getting the symb from $id with &symbcache.
1.561 damieng 377: #
378: # @param {string} $what - part info and parameter name separated by a dot, e.g. '0.weight'
1.566 damieng 379: # @param {string} $id - resource id or map pc
1.561 damieng 380: # @param {string} $def - the resource's default value for this parameter
381: # @param {string} $uname - user name
382: # @param {string} $udom - user domain
383: # @param {string} $csec - section name
384: # @param {string} $cgroup - group name
385: # @param {hash reference} $courseopt - course parameters hash (result of lonnet::get_courseresdata, dump of course's resourcedata.db)
386: # @returns {Array}
1.2 www 387: sub parmval {
1.275 raeburn 388: my ($what,$id,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;
389: return &parmval_by_symb($what,&symbcache($id),$def,$uname,$udom,$csec,
390: $cgroup,$courseopt);
1.201 www 391: }
392:
1.561 damieng 393: # Returns an array containing
394: # - the most specific level that is defined for that parameter (integer)
395: # - an array with the level as index and the parameter value as value (when defined)
396: # (level 1 is the most specific and will have precedence)
397: #
398: # @param {string} $what - part info and parameter name separated by a dot, e.g. '0.weight'
1.566 damieng 399: # @param {string} $symb - resource symb or map src
1.561 damieng 400: # @param {string} $def - the resource's default value for this parameter
401: # @param {string} $uname - user name
402: # @param {string} $udom - user domain
403: # @param {string} $csec - section name
404: # @param {string} $cgroup - group name
405: # @param {hash reference} $courseopt - course parameters hash (result of lonnet::get_courseresdata, dump of course's resourcedata.db)
406: # @returns {Array}
1.201 www 407: sub parmval_by_symb {
1.275 raeburn 408: my ($what,$symb,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_;
1.200 www 409:
1.352 albertel 410: my $useropt;
411: if ($uname ne '' && $udom ne '') {
1.561 damieng 412: $useropt = &Apache::lonnet::get_userresdata($uname,$udom);
1.352 albertel 413: }
1.200 www 414:
1.8 www 415: my $result='';
1.44 albertel 416: my @outpar=();
1.2 www 417: # ----------------------------------------------------- Cascading lookup scheme
1.446 bisitz 418: my $map=(&Apache::lonnet::decode_symb($symb))[0];
1.305 albertel 419: $map = &Apache::lonnet::deversion($map);
1.561 damieng 420:
421: # NOTE: some of that code looks redondant with code in lonnavmaps::parmval_real,
422: # any change should be reflected there.
423:
1.201 www 424: my $symbparm=$symb.'.'.$what;
1.556 raeburn 425: my $recurseparm=$map.'___(rec).'.$what;
1.201 www 426: my $mapparm=$map.'___(all).'.$what;
1.10 www 427:
1.269 raeburn 428: my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$what;
429: my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;
1.556 raeburn 430: my $grpleveli=$env{'request.course.id'}.'.['.$cgroup.'].'.$recurseparm;
1.269 raeburn 431: my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;
432:
1.190 albertel 433: my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$what;
434: my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;
1.556 raeburn 435: my $secleveli=$env{'request.course.id'}.'.['.$csec.'].'.$recurseparm;
1.190 albertel 436: my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;
437:
438: my $courselevel=$env{'request.course.id'}.'.'.$what;
439: my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;
1.556 raeburn 440: my $courseleveli=$env{'request.course.id'}.'.'.$recurseparm;
1.190 albertel 441: my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;
1.2 www 442:
1.11 www 443:
1.182 albertel 444: # --------------------------------------------------------- first, check course
1.11 www 445:
1.561 damieng 446: # 18 - General Course
1.200 www 447: if (defined($$courseopt{$courselevel})) {
1.556 raeburn 448: $outpar[18]=$$courseopt{$courselevel};
449: $result=18;
450: }
451:
1.561 damieng 452: # 17 - Map or Folder level in course (recursive)
1.556 raeburn 453: if (defined($$courseopt{$courseleveli})) {
454: $outpar[17]=$$courseopt{$courseleveli};
455: $result=17;
1.43 albertel 456: }
1.11 www 457:
1.561 damieng 458: # 16 - Map or Folder level in course (non-recursive)
1.200 www 459: if (defined($$courseopt{$courselevelm})) {
1.556 raeburn 460: $outpar[16]=$$courseopt{$courselevelm};
461: $result=16;
1.43 albertel 462: }
1.11 www 463:
1.182 albertel 464: # ------------------------------------------------------- second, check default
465:
1.561 damieng 466: # 15 - resource default
1.556 raeburn 467: if (defined($def)) { $outpar[15]=$def; $result=15; }
1.182 albertel 468:
469: # ------------------------------------------------------ third, check map parms
470:
1.556 raeburn 471:
1.561 damieng 472: # 14 - map default
1.376 albertel 473: my $thisparm=&parmhash($symbparm);
1.556 raeburn 474: if (defined($thisparm)) { $outpar[14]=$thisparm; $result=14; }
1.182 albertel 475:
1.561 damieng 476: # 13 - resource level in course
1.200 www 477: if (defined($$courseopt{$courselevelr})) {
1.556 raeburn 478: $outpar[13]=$$courseopt{$courselevelr};
479: $result=13;
1.43 albertel 480: }
1.11 www 481:
1.182 albertel 482: # ------------------------------------------------------ fourth, back to course
1.352 albertel 483: if ($csec ne '') {
1.561 damieng 484: # 12 - General for section
1.200 www 485: if (defined($$courseopt{$seclevel})) {
1.556 raeburn 486: $outpar[12]=$$courseopt{$seclevel};
487: $result=12;
488: }
1.561 damieng 489: # 11 - Map or Folder level for section (recursive)
1.556 raeburn 490: if (defined($$courseopt{$secleveli})) {
491: $outpar[11]=$$courseopt{$secleveli};
492: $result=11;
493: }
1.561 damieng 494: # 10 - Map or Folder level for section (non-recursive)
1.200 www 495: if (defined($$courseopt{$seclevelm})) {
1.556 raeburn 496: $outpar[10]=$$courseopt{$seclevelm};
497: $result=10;
498: }
1.561 damieng 499: # 9 - resource level in section
1.200 www 500: if (defined($$courseopt{$seclevelr})) {
1.556 raeburn 501: $outpar[9]=$$courseopt{$seclevelr};
502: $result=9;
503: }
1.43 albertel 504: }
1.275 raeburn 505: # ------------------------------------------------------ fifth, check course group
1.352 albertel 506: if ($cgroup ne '') {
1.561 damieng 507: # 8 - General for group
1.269 raeburn 508: if (defined($$courseopt{$grplevel})) {
1.556 raeburn 509: $outpar[8]=$$courseopt{$grplevel};
510: $result=8;
511: }
1.561 damieng 512: # 7 - Map or Folder level for group (recursive)
1.556 raeburn 513: if (defined($$courseopt{$grpleveli})) {
514: $outpar[7]=$$courseopt{$grpleveli};
515: $result=7;
1.269 raeburn 516: }
1.561 damieng 517: # 6 - Map or Folder level for group (non-recursive)
1.269 raeburn 518: if (defined($$courseopt{$grplevelm})) {
1.556 raeburn 519: $outpar[6]=$$courseopt{$grplevelm};
520: $result=6;
1.269 raeburn 521: }
1.561 damieng 522: # 5 - resource level in group
1.269 raeburn 523: if (defined($$courseopt{$grplevelr})) {
1.556 raeburn 524: $outpar[5]=$$courseopt{$grplevelr};
525: $result=5;
1.269 raeburn 526: }
527: }
1.11 www 528:
1.556 raeburn 529: # ---------------------------------------------------------- sixth, check user
1.11 www 530:
1.352 albertel 531: if ($uname ne '') {
1.561 damieng 532: # 4 - General for specific student
533: if (defined($$useropt{$courselevel})) {
534: $outpar[4]=$$useropt{$courselevel};
535: $result=4;
536: }
1.556 raeburn 537:
1.561 damieng 538: # 3 - Map or Folder level for specific student (recursive)
539: if (defined($$useropt{$courseleveli})) {
540: $outpar[3]=$$useropt{$courseleveli};
541: $result=3;
542: }
1.473 amueller 543:
1.561 damieng 544: # 2 - Map or Folder level for specific student (non-recursive)
545: if (defined($$useropt{$courselevelm})) {
546: $outpar[2]=$$useropt{$courselevelm};
547: $result=2;
548: }
1.473 amueller 549:
1.561 damieng 550: # 1 - resource level for specific student
551: if (defined($$useropt{$courselevelr})) {
552: $outpar[1]=$$useropt{$courselevelr};
553: $result=1;
554: }
1.43 albertel 555: }
1.44 albertel 556: return ($result,@outpar);
1.2 www 557: }
558:
1.198 www 559:
560:
1.376 albertel 561: # --- Caches local to lonparmset
562:
1.446 bisitz 563:
1.561 damieng 564: # Reset lonparmset caches (called at the beginning and end of the handler).
1.376 albertel 565: sub reset_caches {
566: &resetparmhash();
567: &resetsymbcache();
568: &resetrulescache();
1.203 www 569: }
570:
1.561 damieng 571: # cache for map parameters, stored temporarily in $env{'request.course.fn'}_parms.db
572: # (these parameters come from param elements in .sequence files created with the advanced RAT)
1.376 albertel 573: {
1.561 damieng 574: my $parmhashid; # course identifier, to initialize the cache only once for a course
575: my %parmhash; # the parameter cache
576: # reset map parameter hash
1.376 albertel 577: sub resetparmhash {
1.560 damieng 578: undef($parmhashid);
579: undef(%parmhash);
1.376 albertel 580: }
1.446 bisitz 581:
1.561 damieng 582: # dump the _parms.db database into %parmhash
1.376 albertel 583: sub cacheparmhash {
1.560 damieng 584: if ($parmhashid eq $env{'request.course.fn'}) { return; }
585: my %parmhashfile;
586: if (tie(%parmhashfile,'GDBM_File',
587: $env{'request.course.fn'}.'_parms.db',&GDBM_READER(),0640)) {
588: %parmhash=%parmhashfile;
589: untie(%parmhashfile);
590: $parmhashid=$env{'request.course.fn'};
591: }
1.201 www 592: }
1.446 bisitz 593:
1.561 damieng 594: # returns a parameter value for an identifier symb.parts.parameter, using the map parameter cache
1.376 albertel 595: sub parmhash {
1.560 damieng 596: my ($id) = @_;
597: &cacheparmhash();
598: return $parmhash{$id};
1.376 albertel 599: }
1.560 damieng 600: }
1.376 albertel 601:
1.566 damieng 602: # cache resource id or map pc -> resource symb or map src, using lonnavmaps to find association
1.446 bisitz 603: {
1.561 damieng 604: my $symbsid; # course identifier, to initialize the cache only once for a course
605: my %symbs; # hash id->symb
606: # reset the id->symb cache
1.376 albertel 607: sub resetsymbcache {
1.560 damieng 608: undef($symbsid);
609: undef(%symbs);
1.376 albertel 610: }
1.446 bisitz 611:
1.566 damieng 612: # returns the resource symb or map src corresponding to a resource id or map pc
613: # (using lonnavmaps and a cache)
1.376 albertel 614: sub symbcache {
1.560 damieng 615: my $id=shift;
616: if ($symbsid ne $env{'request.course.id'}) {
617: undef(%symbs);
618: }
619: if (!$symbs{$id}) {
620: my $navmap = Apache::lonnavmaps::navmap->new();
621: if ($id=~/\./) {
622: my $resource=$navmap->getById($id);
623: $symbs{$id}=$resource->symb();
624: } else {
625: my $resource=$navmap->getByMapPc($id);
626: $symbs{$id}=&Apache::lonnet::declutter($resource->src());
627: }
628: $symbsid=$env{'request.course.id'};
1.473 amueller 629: }
1.560 damieng 630: return $symbs{$id};
1.473 amueller 631: }
1.560 damieng 632: }
1.201 www 633:
1.561 damieng 634: # cache for parameter default actions (stored in parmdefactions.db)
1.446 bisitz 635: {
1.561 damieng 636: my $rulesid; # course identifier, to initialize the cache only once for a course
637: my %rules; # parameter default actions hash
1.376 albertel 638: sub resetrulescache {
1.560 damieng 639: undef($rulesid);
640: undef(%rules);
1.376 albertel 641: }
1.446 bisitz 642:
1.561 damieng 643: # returns the value for a given key in the parameter default action hash
1.376 albertel 644: sub rulescache {
1.560 damieng 645: my $id=shift;
646: if ($rulesid ne $env{'request.course.id'}
647: && !defined($rules{$id})) {
648: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
649: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
650: %rules=&Apache::lonnet::dump('parmdefactions',$dom,$crs);
651: $rulesid=$env{'request.course.id'};
652: }
653: return $rules{$id};
1.221 www 654: }
655: }
656:
1.416 jms 657:
1.561 damieng 658: # Returns the values of the parameter type default action
659: # "default value when manually setting".
660: # If none is defined, ('','','','','') is returned.
661: #
662: # @param {string} $type - parameter type
663: # @returns {Array<string>} - (hours, min, sec, value)
1.229 www 664: sub preset_defaults {
665: my $type=shift;
666: if (&rulescache($type.'_action') eq 'default') {
1.560 damieng 667: # yes, there is something
668: return (&rulescache($type.'_hours'),
669: &rulescache($type.'_min'),
670: &rulescache($type.'_sec'),
671: &rulescache($type.'_value'));
1.229 www 672: } else {
1.560 damieng 673: # nothing there or something else
674: return ('','','','','');
1.229 www 675: }
676: }
677:
1.416 jms 678:
1.561 damieng 679: # Checks that a date is after enrollment start date and before
680: # enrollment end date.
681: # Returns HTML with a warning if it is not, or the empty string otherwise.
682: # This is used by both overview and table modes.
683: #
684: # @param {integer} $checkdate - the date to check.
685: # @returns {string} - HTML possibly containing a localized warning message.
1.277 www 686: sub date_sanity_info {
687: my $checkdate=shift;
688: unless ($checkdate) { return ''; }
689: my $result='';
690: my $crsprefix='course.'.$env{'request.course.id'}.'.';
691: if ($env{$crsprefix.'default_enrollment_end_date'}) {
692: if ($checkdate>$env{$crsprefix.'default_enrollment_end_date'}) {
1.413 bisitz 693: $result.='<div class="LC_warning">'
694: .&mt('After course enrollment end!')
695: .'</div>';
1.277 www 696: }
697: }
698: if ($env{$crsprefix.'default_enrollment_start_date'}) {
699: if ($checkdate<$env{$crsprefix.'default_enrollment_start_date'}) {
1.413 bisitz 700: $result.='<div class="LC_warning">'
701: .&mt('Before course enrollment start!')
702: .'</div>';
1.277 www 703: }
704: }
1.413 bisitz 705: # Preparation for additional warnings about dates in the past/future.
706: # An improved, more context sensitive version is recommended,
707: # e.g. warn for due and answer dates which are defined before the corresponding open date, etc.
708: # if ($checkdate<time) {
709: # $result.='<div class="LC_info">'
710: # .'('.&mt('in the past').')'
711: # .'</div>';
712: # }
713: # if ($checkdate>time) {
714: # $result.='<div class="LC_info">'
715: # .'('.&mt('in the future').')'
716: # .'</div>';
717: # }
1.277 www 718: return $result;
719: }
1.561 damieng 720:
721:
722: # Store a parameter value and type by ID, also triggering more parameter changes based on parameter default actions.
1.186 www 723: #
1.566 damieng 724: # @param {string} $sresid - resource id or map pc
1.565 damieng 725: # @param {string} $spnam - part info and parameter name separated by a dot or underscore, e.g. '0.weight'
1.561 damieng 726: # @param {integer} $snum - level
727: # @param {string} $nval - new value
728: # @param {string} $ntype - new type
729: # @param {string} $uname - username
730: # @param {string} $udom - userdomain
731: # @param {string} $csec - section name
732: # @param {string} $cgroup - group name
1.186 www 733: sub storeparm {
1.269 raeburn 734: my ($sresid,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;
1.275 raeburn 735: &storeparm_by_symb(&symbcache($sresid),$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,'',$cgroup);
1.197 www 736: }
737:
1.561 damieng 738: my %recstack; # hash parameter name -> 1 when a parameter was used before in a recursive call to storeparm_by_symb
739:
740: # Store a parameter value and type by symb, also triggering more parameter changes based on parameter default actions.
741: # Uses storeparm_by_symb_inner to actually store the parameter, ignoring any returned error.
742: #
1.566 damieng 743: # @param {string} $symb - resource symb or map src
1.565 damieng 744: # @param {string} $spnam - part info and parameter name separated by a dot or underscore, e.g. '0.weight'
1.561 damieng 745: # @param {integer} $snum - level
746: # @param {string} $nval - new value
747: # @param {string} $ntype - new type
748: # @param {string} $uname - username
749: # @param {string} $udom - userdomain
750: # @param {string} $csec - section name
751: # @param {boolean} $recflag - should be true for recursive calls to storeparm_by_symb, false otherwise
752: # @param {string} $cgroup - group name
1.197 www 753: sub storeparm_by_symb {
1.275 raeburn 754: my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$recflag,$cgroup)=@_;
1.226 www 755: unless ($recflag) {
1.560 damieng 756: # first time call
757: %recstack=();
758: $recflag=1;
1.226 www 759: }
1.560 damieng 760: # store parameter
1.226 www 761: &storeparm_by_symb_inner
1.473 amueller 762: ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup);
1.560 damieng 763: # don't do anything if parameter was reset
1.266 www 764: unless ($nval) { return; }
1.226 www 765: my ($prefix,$parm)=($spnam=~/^(.*[\_\.])([^\_\.]+)$/);
1.560 damieng 766: # remember that this was set
1.226 www 767: $recstack{$parm}=1;
1.560 damieng 768: # what does this trigger?
1.226 www 769: foreach my $triggered (split(/\:/,&rulescache($parm.'_triggers'))) {
1.560 damieng 770: # don't backfire
771: unless ((!$triggered) || ($recstack{$triggered})) {
772: my $action=&rulescache($triggered.'_action');
773: my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);
774: # set triggered parameter on same level
775: my $newspnam=$prefix.$triggered;
776: my $newvalue='';
777: my $active=1;
778: if ($action=~/^when\_setting/) {
779: # are there restrictions?
780: if (&rulescache($triggered.'_triggervalue')=~/\w/) {
781: $active=0;
1.565 damieng 782: foreach my $possiblevalue (split(/\s*\,\s*/,&rulescache($triggered.'_triggervalue'))) {
1.560 damieng 783: if (lc($possiblevalue) eq lc($nval)) { $active=1; }
784: }
785: }
786: $newvalue=&rulescache($triggered.'_value');
787: } else {
788: my $totalsecs=((&rulescache($triggered.'_days')*24+&rulescache($triggered.'_hours'))*60+&rulescache($triggered.'_min'))*60+&rulescache($triggered.'_sec');
789: if ($action=~/^later\_than/) {
790: $newvalue=$nval+$totalsecs;
791: } else {
792: $newvalue=$nval-$totalsecs;
793: }
794: }
795: if ($active) {
796: &storeparm_by_symb($symb,$newspnam,$snum,$newvalue,&rulescache($triggered.'_type'),
797: $uname,$udom,$csec,$recflag,$cgroup);
798: }
799: }
1.226 www 800: }
801: return '';
802: }
803:
1.561 damieng 804: # Adds all given arguments to the course parameter log.
805: # @returns {string} - the answer to the lonnet query.
1.293 www 806: sub log_parmset {
1.525 raeburn 807: return &Apache::lonnet::write_log('course','parameterlog',@_);
1.284 www 808: }
809:
1.561 damieng 810: # Store a parameter value and type by symb, without using the parameter default actions.
811: # Expire related sheets.
812: #
1.566 damieng 813: # @param {string} $symb - resource symb or map src
1.561 damieng 814: # @param {string} $spnam - part info and parameter name separated by a dot, e.g. '0.weight'
815: # @param {integer} $snum - level
816: # @param {string} $nval - new value
817: # @param {string} $ntype - new type
818: # @param {string} $uname - username
819: # @param {string} $udom - userdomain
820: # @param {string} $csec - section name
821: # @param {string} $cgroup - group name
822: # @returns {string} - HTML code with an error message if the parameter could not be stored.
1.226 www 823: sub storeparm_by_symb_inner {
1.197 www 824: # ---------------------------------------------------------- Get symb, map, etc
1.269 raeburn 825: my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_;
1.197 www 826: # ---------------------------------------------------------- Construct prefixes
1.186 www 827: $spnam=~s/\_([^\_]+)$/\.$1/;
1.446 bisitz 828: my $map=(&Apache::lonnet::decode_symb($symb))[0];
1.305 albertel 829: $map = &Apache::lonnet::deversion($map);
830:
1.197 www 831: my $symbparm=$symb.'.'.$spnam;
1.556 raeburn 832: my $recurseparm=$map.'___(rec).'.$spnam;
1.197 www 833: my $mapparm=$map.'___(all).'.$spnam;
834:
1.269 raeburn 835: my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$spnam;
836: my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;
1.556 raeburn 837: my $grpleveli=$env{'request.course.id'}.'.['.$cgroup.'].'.$recurseparm;
1.269 raeburn 838: my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;
839:
1.190 albertel 840: my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$spnam;
841: my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;
1.556 raeburn 842: my $secleveli=$env{'request.course.id'}.'.['.$csec.'].'.$recurseparm;
1.190 albertel 843: my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;
1.446 bisitz 844:
1.190 albertel 845: my $courselevel=$env{'request.course.id'}.'.'.$spnam;
846: my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;
1.556 raeburn 847: my $courseleveli=$env{'request.course.id'}.'.'.$recurseparm;
1.190 albertel 848: my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;
1.446 bisitz 849:
1.186 www 850: my $storeunder='';
1.578 raeburn 851: my $possreplace='';
1.556 raeburn 852: if (($snum==18) || ($snum==4)) { $storeunder=$courselevel; }
1.578 raeburn 853: if (($snum==17) || ($snum==3)) {
854: $storeunder=$courseleveli;
855: $possreplace=$courselevelm;
856: }
857: if (($snum==16) || ($snum==2)) {
858: $storeunder=$courselevelm;
859: $possreplace=$courseleveli;
860: }
1.556 raeburn 861: if (($snum==13) || ($snum==1)) { $storeunder=$courselevelr; }
862: if ($snum==12) { $storeunder=$seclevel; }
1.578 raeburn 863: if ($snum==11) {
864: $storeunder=$secleveli;
865: $possreplace=$seclevelm;
866: }
867: if ($snum==10) {
868: $storeunder=$seclevelm;
869: $possreplace=$secleveli;
870: }
1.556 raeburn 871: if ($snum==9) { $storeunder=$seclevelr; }
872: if ($snum==8) { $storeunder=$grplevel; }
1.578 raeburn 873: if ($snum==7) {
874: $storeunder=$grpleveli;
875: $possreplace=$grplevelm;
876: }
877: if ($snum==6) {
878: $storeunder=$grplevelm;
879: $possreplace=$grpleveli;
880: }
1.556 raeburn 881: if ($snum==5) { $storeunder=$grplevelr; }
1.269 raeburn 882:
1.446 bisitz 883:
1.186 www 884: my $delete;
885: if ($nval eq '') { $delete=1;}
886: my %storecontent = ($storeunder => $nval,
1.473 amueller 887: $storeunder.'.type' => $ntype);
1.186 www 888: my $reply='';
1.560 damieng 889:
1.556 raeburn 890: if ($snum>4) {
1.186 www 891: # ---------------------------------------------------------------- Store Course
892: #
1.560 damieng 893: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
894: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
895: # Expire sheets
896: &Apache::lonnet::expirespread('','','studentcalc');
897: if (($snum==13) || ($snum==9) || ($snum==5)) {
898: &Apache::lonnet::expirespread('','','assesscalc',$symb);
1.578 raeburn 899: } elsif (($snum==17) || ($snum==16) || ($snum==11) || ($snum==10) || ($snum==7) || ($snum==6)) {
1.560 damieng 900: &Apache::lonnet::expirespread('','','assesscalc',$map);
901: } else {
902: &Apache::lonnet::expirespread('','','assesscalc');
903: }
904: # Store parameter
905: if ($delete) {
906: $reply=&Apache::lonnet::del
907: ('resourcedata',[keys(%storecontent)],$cdom,$cnum);
908: &log_parmset(\%storecontent,1);
909: } else {
910: $reply=&Apache::lonnet::cput
911: ('resourcedata',\%storecontent,$cdom,$cnum);
912: &log_parmset(\%storecontent);
1.578 raeburn 913: if ($possreplace) {
914: my $resdata = &Apache::lonnet::get_courseresdata($cnum,$cdom);
915: if (ref($resdata) eq 'HASH') {
916: if (exists($resdata->{$possreplace})) {
917: if (&Apache::lonnet::del
918: ('resourcedata',[$possreplace,$possreplace.'.type'],$cdom,$cnum) eq 'ok') {
919: &log_parmset({$possreplace => '', $possreplace.'.type' => $ntype},1);
920: }
921: }
922: }
923: }
1.560 damieng 924: }
925: &Apache::lonnet::devalidatecourseresdata($cnum,$cdom);
1.186 www 926: } else {
927: # ------------------------------------------------------------------ Store User
928: #
1.560 damieng 929: # Expire sheets
930: &Apache::lonnet::expirespread($uname,$udom,'studentcalc');
931: if ($snum==1) {
932: &Apache::lonnet::expirespread
933: ($uname,$udom,'assesscalc',$symb);
1.578 raeburn 934: } elsif (($snum==2) || ($snum==3)) {
1.560 damieng 935: &Apache::lonnet::expirespread
936: ($uname,$udom,'assesscalc',$map);
937: } else {
938: &Apache::lonnet::expirespread($uname,$udom,'assesscalc');
939: }
940: # Store parameter
941: if ($delete) {
942: $reply=&Apache::lonnet::del
943: ('resourcedata',[keys(%storecontent)],$udom,$uname);
944: &log_parmset(\%storecontent,1,$uname,$udom);
945: } else {
946: $reply=&Apache::lonnet::cput
947: ('resourcedata',\%storecontent,$udom,$uname);
948: &log_parmset(\%storecontent,0,$uname,$udom);
1.578 raeburn 949: if ($possreplace) {
950: my $resdata = &Apache::lonnet::get_userresdata($uname,$udom);
951: if (ref($resdata) eq 'HASH') {
952: if (exists($resdata->{$possreplace})) {
953: if (&Apache::lonnet::del
954: ('resourcedata',[$possreplace,$possreplace.'.type'],$udom,$uname) eq 'ok') {
955: &log_parmset({$possreplace => '',$possreplace.'.type' => $ntype},1,
956: $uname,$udom);
957: }
958: }
959: }
960: }
1.560 damieng 961: }
962: &Apache::lonnet::devalidateuserresdata($uname,$udom);
1.186 www 963: }
1.446 bisitz 964:
1.186 www 965: if ($reply=~/^error\:(.*)/) {
1.560 damieng 966: return "<span class=\"LC_error\">Write Error: $1</span>";
1.186 www 967: }
968: return '';
969: }
970:
1.9 www 971:
1.561 damieng 972: # Returns HTML with the value of the given parameter,
973: # using a readable format for dates, and
974: # a warning if there is a problem with a date.
975: # Used by table mode.
976: # Returns HTML for the editmap.png image if no value is defined and $editable is true.
977: #
978: # @param {string} $value - the parameter value
979: # @param {string} $type - the parameter type
980: # @param {boolean} $editable - Set to true to get an icon when no value is defined.
1.9 www 981: sub valout {
1.600 raeburn 982: my ($value,$type,$editable)=@_;
1.59 matthew 983: my $result = '';
984: # Values of zero are valid.
985: if (! $value && $value ne '0') {
1.528 bisitz 986: if ($editable) {
987: $result =
988: '<img src="/res/adm/pages/editmap.png"'
989: .' alt="'.&mt('Change').'"'
1.539 raeburn 990: .' title="'.&mt('Change').'" style="border:0;" />';
1.528 bisitz 991: } else {
992: $result=' ';
993: }
1.59 matthew 994: } else {
1.66 www 995: if ($type eq 'date_interval') {
1.559 raeburn 996: my ($totalsecs,$donesuffix) = split(/_/,$value,2);
997: my ($usesdone,$donebuttontext,$proctor,$secretkey);
998: if ($donesuffix =~ /^done\:([^\:]+)\:(.*)$/) {
999: $donebuttontext = $1;
1000: (undef,$proctor,$secretkey) = split(/_/,$2);
1001: $usesdone = 'done';
1002: } elsif ($donesuffix =~ /^done(|_.+)$/) {
1003: $donebuttontext = &mt('Done');
1004: ($usesdone,$proctor,$secretkey) = split(/_/,$donesuffix);
1005: }
1.554 raeburn 1006: my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($totalsecs);
1.413 bisitz 1007: my @timer;
1.66 www 1008: $year=$year-70;
1009: $mday--;
1010: if ($year) {
1.413 bisitz 1011: # $result.=&mt('[quant,_1,yr]',$year).' ';
1012: push(@timer,&mt('[quant,_1,yr]',$year));
1.66 www 1013: }
1014: if ($mon) {
1.413 bisitz 1015: # $result.=&mt('[quant,_1,mth]',$mon).' ';
1016: push(@timer,&mt('[quant,_1,mth]',$mon));
1.66 www 1017: }
1018: if ($mday) {
1.413 bisitz 1019: # $result.=&mt('[quant,_1,day]',$mday).' ';
1020: push(@timer,&mt('[quant,_1,day]',$mday));
1.66 www 1021: }
1022: if ($hour) {
1.413 bisitz 1023: # $result.=&mt('[quant,_1,hr]',$hour).' ';
1024: push(@timer,&mt('[quant,_1,hr]',$hour));
1.66 www 1025: }
1026: if ($min) {
1.413 bisitz 1027: # $result.=&mt('[quant,_1,min]',$min).' ';
1028: push(@timer,&mt('[quant,_1,min]',$min));
1.66 www 1029: }
1030: if ($sec) {
1.413 bisitz 1031: # $result.=&mt('[quant,_1,sec]',$sec).' ';
1032: push(@timer,&mt('[quant,_1,sec]',$sec));
1.66 www 1033: }
1.413 bisitz 1034: # $result=~s/\s+$//;
1035: if (!@timer) { # Special case: all entries 0 -> display "0 secs" intead of empty field to keep this field editable
1036: push(@timer,&mt('[quant,_1,sec]',0));
1037: }
1038: $result.=join(", ",@timer);
1.559 raeburn 1039: if ($usesdone eq 'done') {
1.558 raeburn 1040: if ($secretkey) {
1.559 raeburn 1041: $result .= ' '.&mt('+ "[_1]" with proctor key: [_2]',$donebuttontext,$secretkey);
1.558 raeburn 1042: } else {
1.559 raeburn 1043: $result .= ' + "'.$donebuttontext.'"';
1044: }
1.554 raeburn 1045: }
1.213 www 1046: } elsif (&isdateparm($type)) {
1.361 albertel 1047: $result = &Apache::lonlocal::locallocaltime($value).
1.560 damieng 1048: &date_sanity_info($value);
1.59 matthew 1049: } else {
1050: $result = $value;
1.517 www 1051: $result=~s/\,/\, /gs;
1.560 damieng 1052: $result = &HTML::Entities::encode($result,'"<>&');
1.59 matthew 1053: }
1054: }
1055: return $result;
1.9 www 1056: }
1057:
1.59 matthew 1058:
1.561 damieng 1059: # Returns HTML containing a link on a parameter value, for table mode.
1060: # The link uses the javascript function 'pjump'.
1061: #
1062: # @param {string} $type - parameter type
1063: # @param {string} $dis - dialog title for editing the parameter value and type
1064: # @param {string} $value - parameter value
1065: # @param {string} $marker - identifier for the parameter, "resource id&part_parameter name&level", will be passed as pres_marker when the user submits a change.
1066: # @param {string} $return - prefix for the name of the form and field names that will be used to submit the form ('parmform.pres')
1067: # @param {string} $call - javascript function to call to submit the form ('psub')
1.588 raeburn 1068: # @param {boolean} $recursive - true if link is for a map/folder where parameter is currently set to be recursive.
1069: # @param {string} $extra - optional additional information to send as tenth arg in call to javascript pjump function.
1.5 www 1070: sub plink {
1.588 raeburn 1071: my ($type,$dis,$value,$marker,$return,$call,$recursive,$extra)=@_;
1.23 www 1072: my $winvalue=$value;
1073: unless ($winvalue) {
1.592 raeburn 1074: if (&isdateparm($type) || (&is_specialstring($type))) {
1.190 albertel 1075: $winvalue=$env{'form.recent_'.$type};
1.591 raeburn 1076: } elsif ($type eq 'string_yesno') {
1077: if ($env{'form.recent_string'} =~ /^(yes|no)$/i) {
1078: $winvalue=$env{'form.recent_string'};
1079: }
1.23 www 1080: } else {
1.190 albertel 1081: $winvalue=$env{'form.recent_'.(split(/\_/,$type))[0]};
1.23 www 1082: }
1083: }
1.229 www 1084: my ($parmname)=((split(/\&/,$marker))[1]=~/\_([^\_]+)$/);
1085: my ($hour,$min,$sec,$val)=&preset_defaults($parmname);
1086: unless (defined($winvalue)) { $winvalue=$val; }
1.593 raeburn 1087: my $valout = &valout($value,$type,1);
1.429 raeburn 1088: my $unencmarker = $marker;
1.378 albertel 1089: foreach my $item (\$type, \$dis, \$winvalue, \$marker, \$return, \$call,
1.588 raeburn 1090: \$hour, \$min, \$sec, \$extra) {
1.560 damieng 1091: $$item = &HTML::Entities::encode($$item,'"<>&');
1092: $$item =~ s/\'/\\\'/g;
1.378 albertel 1093: }
1.429 raeburn 1094: return '<table width="100%"><tr valign="top" align="right"><td><a name="'.$unencmarker.'" /></td></tr><tr><td align="center">'.
1.473 amueller 1095: '<a href="javascript:pjump('."'".$type."','".$dis."','".$winvalue."','"
1.588 raeburn 1096: .$marker."','".$return."','".$call."','".$hour."','".$min."','".$sec."','".$extra."'".');">'.
1.578 raeburn 1097: $valout.'</a></td></tr>'.($recursive?'<tr><td align="center" class="LC_parm_recursive">'.
1098: &mt('recursive').'</td></tr>' : '').'</table>';
1099:
1.5 www 1100: }
1101:
1.561 damieng 1102: # Javascript for table mode.
1.280 albertel 1103: sub page_js {
1104:
1.81 www 1105: my $selscript=&Apache::loncommon::studentbrowser_javascript();
1.88 matthew 1106: my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
1.280 albertel 1107:
1108: return(<<ENDJS);
1109: <script type="text/javascript">
1.454 bisitz 1110: // <![CDATA[
1.44 albertel 1111:
1.88 matthew 1112: $pjump_def
1.44 albertel 1113:
1114: function psub() {
1.591 raeburn 1115: var specstring = /^string_!(yesno|any)/i;
1.44 albertel 1116: if (document.parmform.pres_marker.value!='') {
1117: document.parmform.action+='#'+document.parmform.pres_marker.value;
1118: var typedef=new Array();
1119: typedef=document.parmform.pres_type.value.split('_');
1.562 damieng 1120: if (document.parmform.pres_type.value!='') {
1.589 raeburn 1121: if ((typedef[0]=='date') ||
1.591 raeburn 1122: (specstring.test(document.parmform.pres_type.value))) {
1.562 damieng 1123: eval('document.parmform.recent_'+
1124: document.parmform.pres_type.value+
1125: '.value=document.parmform.pres_value.value;');
1126: } else {
1127: eval('document.parmform.recent_'+typedef[0]+
1128: '.value=document.parmform.pres_value.value;');
1129: }
1.44 albertel 1130: }
1131: document.parmform.submit();
1132: } else {
1133: document.parmform.pres_value.value='';
1134: document.parmform.pres_marker.value='';
1135: }
1136: }
1137:
1.57 albertel 1138: function openWindow(url, wdwName, w, h, toolbar,scrollbar) {
1139: var options = "width=" + w + ",height=" + h + ",";
1140: options += "resizable=yes,scrollbars="+scrollbar+",status=no,";
1141: options += "menubar=no,toolbar="+toolbar+",location=no,directories=no";
1142: var newWin = window.open(url, wdwName, options);
1143: newWin.focus();
1144: }
1.523 raeburn 1145:
1.454 bisitz 1146: // ]]>
1.523 raeburn 1147:
1.44 albertel 1148: </script>
1.81 www 1149: $selscript
1.280 albertel 1150: ENDJS
1151:
1152: }
1.507 www 1153:
1.561 damieng 1154: # Javascript to show or hide the map selection (function showHide_courseContent),
1155: # for table and overview modes.
1.523 raeburn 1156: sub showhide_js {
1157: return <<"COURSECONTENTSCRIPT";
1158:
1159: function showHide_courseContent() {
1160: var parmlevValue=document.getElementById("parmlev").value;
1161: if (parmlevValue == 'general') {
1162: document.getElementById('mapmenu').style.display="none";
1163: } else {
1164: if ((parmlevValue == "full") || (parmlevValue == "map")) {
1165: document.getElementById('mapmenu').style.display ="";
1166: } else {
1167: document.getElementById('mapmenu').style.display="none";
1168: }
1169: }
1170: return;
1171: }
1172:
1173: COURSECONTENTSCRIPT
1174: }
1175:
1.561 damieng 1176: # Javascript functions showHideLenient and toggleParmTextbox, for overview mode
1.549 raeburn 1177: sub toggleparmtextbox_js {
1178: return <<"ENDSCRIPT";
1179:
1180: if (!document.getElementsByClassName) {
1181: function getElementsByClassName(node, classname) {
1182: var a = [];
1183: var re = new RegExp('(^| )'+classname+'( |$)');
1184: var els = node.getElementsByTagName("*");
1185: for(var i=0,j=els.length; i<j; i++)
1186: if(re.test(els[i].className))a.push(els[i]);
1187: return a;
1188: }
1189: }
1190:
1191: function showHideLenient() {
1192: var lenients;
1193: var setRegExp = /^set_/;
1194: if (document.getElementsByClassName) {
1195: lenients = document.getElementsByClassName('LC_lenient_radio');
1196: } else {
1197: lenients = getElementsByClassName(document.body,'LC_lenient_radio');
1198: }
1199: if (lenients != 'undefined') {
1200: for (var i=0; i<lenients.length; i++) {
1201: if (lenients[i].checked) {
1202: if (lenients[i].value == 'weighted') {
1203: if (setRegExp.test(lenients[i].name)) {
1204: var identifier = lenients[i].name.replace(setRegExp,'');
1205: toggleParmTextbox(document.parmform,identifier);
1206: }
1207: }
1208: }
1209: }
1210: }
1211: return;
1212: }
1213:
1214: function toggleParmTextbox(form,key) {
1215: var divfortext = document.getElementById('LC_parmtext_'+key);
1216: if (divfortext) {
1217: var caller = form.elements['set_'+key];
1218: if (caller.length) {
1219: for (i=0; i<caller.length; i++) {
1220: if (caller[i].checked) {
1221: if (caller[i].value == 'weighted') {
1222: divfortext.style.display = 'inline';
1223: } else {
1224: divfortext.style.display = 'none';
1225: }
1226: }
1227: }
1228: }
1229: }
1230: return;
1231: }
1232:
1233: ENDSCRIPT
1234: }
1235:
1.561 damieng 1236: # Javascript function validateParms, for overview mode
1.549 raeburn 1237: sub validateparms_js {
1238: return <<'ENDSCRIPT';
1239:
1240: function validateParms() {
1241: var textRegExp = /^settext_/;
1242: var tailLenient = /\.lenient$/;
1243: var patternRelWeight = /^\-?[\d.]+$/;
1244: var patternLenientStd = /^(yes|no|default)$/;
1.597 raeburn 1245: var ipRegExp = /^setip/;
1.549 raeburn 1246: var ipallowRegExp = /^setipallow_/;
1247: var ipdenyRegExp = /^setipdeny_/;
1.597 raeburn 1248: var deeplinkRegExp = /^deeplink_/;
1.601 raeburn 1249: var dlListScopeRegExp = /^deeplink_(state|others|listing|scope)_/;
1250: var dlLinkProtectRegExp = /^deeplink_protect_/;
1251: var dlLtidRegExp = /^deeplink_ltid_/;
1252: var dlLticRegExp = /^deeplink_ltic_/;
1.597 raeburn 1253: var dlKeyRegExp = /^deeplink_key_/;
1254: var dlMenusRegExp = /^deeplink_menus_/;
1255: var dlCollsRegExp = /^deeplink_colls_/;
1.613 raeburn 1256: var dlTargetRegExp = /^deeplink_target_/;
1.616 raeburn 1257: var dlExitRegExp = /^deeplink_exit_/;
1258: var dlExitTextRegExp = /^deeplink_exittext_/;
1.549 raeburn 1259: var patternIP = /[\[\]\*\.a-zA-Z\d\-]+/;
1.616 raeburn 1260: var numelements = document.parmform.elements.length;
1261: if ((typeof(numelements) != 'undefined') && (numelements != null)) {
1262: if (numelements) {
1263: for (i=0; i<numelements; i++) {
1.549 raeburn 1264: var name=document.parmform.elements[i].name;
1.588 raeburn 1265: if (textRegExp.test(name)) {
1.549 raeburn 1266: var identifier = name.replace(textRegExp,'');
1267: if (tailLenient.test(identifier)) {
1268: if (document.parmform.elements['set_'+identifier].length) {
1269: for (var j=0; j<document.parmform.elements['set_'+identifier].length; j++) {
1270: if (document.parmform.elements['set_'+identifier][j].checked) {
1271: if (!(patternLenientStd.test(document.parmform.elements['set_'+identifier][j].value))) {
1272: var relweight = document.parmform.elements[i].value;
1273: relweight = relweight.replace(/^\s+|\s+$/g,'');
1274: if (!patternRelWeight.test(relweight)) {
1275: relweight = '0.0';
1276: }
1277: if (document.parmform.elements['set_'+identifier][j].value == 'weighted') {
1278: document.parmform.elements['set_'+identifier][j].value = relweight;
1279: } else {
1280: document.parmform.elements['set_'+identifier][j].value += ','+relweight;
1281: }
1282: }
1283: break;
1284: }
1285: }
1286: }
1287: }
1.597 raeburn 1288: } else if (ipRegExp.test(name)) {
1289: if (ipallowRegExp.test(name)) {
1290: var identifier = name.replace(ipallowRegExp,'');
1291: var possallow = document.parmform.elements[i].value;
1292: possallow = possallow.replace(/^\s+|\s+$/g,'');
1293: if (patternIP.test(possallow)) {
1294: if (document.parmform.elements['set_'+identifier].value) {
1295: possallow = ','+possallow;
1296: }
1297: document.parmform.elements['set_'+identifier].value += possallow;
1298: }
1299: } else if (ipdenyRegExp.test(name)) {
1300: var identifier = name.replace(ipdenyRegExp,'');
1301: var possdeny = document.parmform.elements[i].value;
1302: possdeny = possdeny.replace(/^\s+|\s+$/g,'');
1303: if (patternIP.test(possdeny)) {
1304: possdeny = '!'+possdeny;
1305: if (document.parmform.elements['set_'+identifier].value) {
1306: possdeny = ','+possdeny;
1307: }
1308: document.parmform.elements['set_'+identifier].value += possdeny;
1.588 raeburn 1309: }
1310: }
1311: } else if (deeplinkRegExp.test(name)) {
1.597 raeburn 1312: if (dlListScopeRegExp.test(name)) {
1313: var identifier = name.replace(dlListScopeRegExp,'');
1314: var idx = document.parmform.elements[i].selectedIndex;
1315: if (idx > 0) {
1316: var possdeeplink = document.parmform.elements[i].options[idx].value
1317: possdeeplink = possdeeplink.replace(/^\s+|\s+$/g,'');
1318: if (document.parmform.elements['set_'+identifier].value) {
1319: possdeeplink = ','+possdeeplink;
1320: }
1321: document.parmform.elements['set_'+identifier].value += possdeeplink;
1322: }
1.601 raeburn 1323: } else if (dlLinkProtectRegExp.test(name)) {
1.597 raeburn 1324: if (document.parmform.elements[i].checked) {
1.601 raeburn 1325: var identifier = name.replace(dlLinkProtectRegExp,'');
1.597 raeburn 1326: var posslinkurl = document.parmform.elements[i].value;
1327: posslinkurl = posslinkurl.replace(/^\s+|\s+$/g,'');
1328: if (document.parmform.elements['set_'+identifier].value) {
1329: posslinkurl = ','+posslinkurl;
1330: }
1331: document.parmform.elements['set_'+identifier].value += posslinkurl;
1332: }
1.601 raeburn 1333: } else if (dlLtidRegExp.test(name)) {
1334: var identifier = name.replace(dlLtidRegExp,'');
1335: if (isRadioSet('deeplink_protect_'+identifier,'ltid')) {
1336: var possltid = document.parmform.elements[i].value;
1337: possltid = possltid.replace(/\D+/g,'');
1338: if (possltid.length) {
1.597 raeburn 1339: if (document.parmform.elements['set_'+identifier].value) {
1.601 raeburn 1340: possltid = ':'+possltid;
1.597 raeburn 1341: }
1.601 raeburn 1342: document.parmform.elements['set_'+identifier].value += possltid;
1.597 raeburn 1343: } else {
1344: document.parmform.elements['set_'+identifier].value = '';
1.601 raeburn 1345: alert("A link type of 'domain LTI launch' was selected but no domain LTI launcher was selected.\nPlease select one, or choose a different supported link type.");
1.597 raeburn 1346: return false;
1347: }
1348: }
1.601 raeburn 1349: } else if (dlLticRegExp.test(name)) {
1350: var identifier = name.replace(dlLticRegExp,'');
1351: if (isRadioSet('deeplink_protect_'+identifier,'ltic')) {
1352: var possltic = document.parmform.elements[i].value;
1353: possltic = possltic.replace(/\D+/g,'');
1354: if (possltic.length) {
1355: if (document.parmform.elements['set_'+identifier].value) {
1356: possltic = ':'+possltic;
1357: }
1358: document.parmform.elements['set_'+identifier].value += possltic;
1359: } else {
1360: document.parmform.elements['set_'+identifier].value = '';
1361: alert("A link type of 'course LTI launch' was selected but no course LTI launcher was selected.\nPlease select one, or choose a different supported link type.");
1362: return false;
1363: }
1364: }
1.597 raeburn 1365: } else if (dlKeyRegExp.test(name)) {
1366: var identifier = name.replace(dlKeyRegExp,'');
1.601 raeburn 1367: if (isRadioSet('deeplink_protect_'+identifier,'key')) {
1.597 raeburn 1368: var posskey = document.parmform.elements[i].value;
1369: posskey = posskey.replace(/^\s+|\s+$/g,'');
1370: var origlength = posskey.length;
1371: posskey = posskey.replace(/[^a-zA-Z\d_.!@#$%^&*()+=-]/g,'');
1372: var newlength = posskey.length;
1373: if (newlength > 0) {
1374: var change = origlength - newlength;
1375: if (change) {
1376: alert(change+' disallowed character(s) removed from deeplink key');
1377: }
1378: if (document.parmform.elements['set_'+identifier].value) {
1379: posskey = ':'+posskey;
1380: }
1381: document.parmform.elements['set_'+identifier].value += posskey;
1382: } else {
1383: document.parmform.elements['set_'+identifier].value = '';
1384: if (newlength < origlength) {
1385: alert("A link type of 'deep with key' was selected but the key value was blank, after removing disallowed characters.\nPlease enter a key using one or more of: a-zA-Z0-9_.!@#$%^&*()+=-");
1386: } else {
1387: alert("A link type of 'deep with key' was selected but the key value was blank.\nPlease enter a key.");
1388: }
1389: return false;
1390: }
1391: }
1392: } else if (dlMenusRegExp.test(name)) {
1393: if (document.parmform.elements[i].checked) {
1394: var identifier = name.replace(dlMenusRegExp,'');
1395: var posslinkmenu = document.parmform.elements[i].value;
1396: posslinkmenu = posslinkmenu.replace(/^\s+|\s+$/g,'');
1397: if (posslinkmenu == 'std') {
1398: posslinkmenu = '0';
1399: if (document.parmform.elements['set_'+identifier].value) {
1400: posslinkmenu = ','+posslinkmenu;
1401: }
1402: document.parmform.elements['set_'+identifier].value += posslinkmenu;
1403: }
1404: }
1405: } else if (dlCollsRegExp.test(name)) {
1406: var identifier = name.replace(dlCollsRegExp,'');
1407: if (isRadioSet('deeplink_menus_'+identifier,'colls')) {
1408: var posslinkmenu = document.parmform.elements[i].value;
1409: if (document.parmform.elements['set_'+identifier].value) {
1410: posslinkmenu = ','+posslinkmenu;
1411: }
1412: document.parmform.elements['set_'+identifier].value += posslinkmenu;
1413: }
1.614 raeburn 1414: } else if (dlTargetRegExp.test(name)) {
1415: var identifier = name.replace(dlTargetRegExp,'');
1.613 raeburn 1416: var idx = document.parmform.elements[i].selectedIndex;
1417: if (idx > 0) {
1.616 raeburn 1418: var linktarget = document.parmform.elements[i].options[idx].value
1419: linktarget = linktarget.replace(/^\s+|\s+$/g,'');
1420: if (document.parmform.elements['set_'+identifier].value) {
1421: linktarget = ','+linktarget;
1422: }
1423: document.parmform.elements['set_'+identifier].value += linktarget;
1424: }
1425: } else if (dlExitRegExp.test(name)) {
1426: if (document.parmform.elements[i].checked) {
1427: var identifier = name.replace(dlExitRegExp,'');
1428: var posslinkexit = document.parmform.elements[i].value;
1429: posslinkexit = posslinkexit.replace(/^\s+|\s+$/g,'');
1.613 raeburn 1430: if (document.parmform.elements['set_'+identifier].value) {
1.616 raeburn 1431: posslinkexit = ','+posslinkexit;
1432: }
1433: document.parmform.elements['set_'+identifier].value += posslinkexit;
1434: }
1435: } else if (dlExitTextRegExp.test(name)) {
1436: var identifier = name.replace(dlExitTextRegExp,'');
1437: if ((isRadioSet('deeplink_exit_'+identifier,'yes')) ||
1438: (isRadioSet('deeplink_exit_'+identifier,'url'))) {
1439: var posstext = document.parmform.elements[i].value;
1440: posstext = posstext.replace(/^\s+|\s+$/g,'');
1441: var origlength = posstext.length;
1442: posstext = posstext.replace(/[:;'",]/g,'');
1443: var newlength = posstext.length;
1444: if (newlength > 0) {
1445: var change = origlength - newlength;
1446: if (change) {
1447: alert(change+' disallowed character(s) removed from Exit Button text');
1448: }
1449: if (posstext !== 'Exit Tool') {
1450: posstext = ':'+posstext;
1451: document.parmform.elements['set_'+identifier].value += posstext;
1452: }
1453: } else {
1454: document.parmform.elements['set_'+identifier].value = '';
1455: if (newlength < origlength) {
1456: alert("An exit link type of 'In use' was selected but the button text value was blank, after removing disallowed characters.\nDisallowed characters are ,\":;'");
1457: } else {
1458: alert("An exit link type of 'In use' was selected but the button text value was blank.\nPlease enter the text to use.");
1459: }
1460: return false;
1.613 raeburn 1461: }
1462: }
1.549 raeburn 1463: }
1464: }
1465: }
1466: }
1467: }
1468: return true;
1469: }
1470:
1.597 raeburn 1471: function isRadioSet(name,expected) {
1472: var menuitems = document.getElementsByName(name);
1473: var radioLength = menuitems.length;
1474: result = false;
1475: if (radioLength > 1) {
1476: for (var j=0; j<radioLength; j++) {
1477: if (menuitems[j].checked) {
1478: if (menuitems[j].value == expected) {
1479: result = true;
1480: break;
1481: }
1482: }
1483: }
1484: }
1485: return result;
1486: }
1487:
1.549 raeburn 1488: ENDSCRIPT
1489: }
1490:
1.561 damieng 1491: # Javascript initialization, for overview mode
1.549 raeburn 1492: sub ipacc_boxes_js {
1493: my $remove = &mt('Remove');
1494: return <<"END";
1495: \$(document).ready(function() {
1496: var wrapper = \$(".LC_string_ipacc_wrap");
1497: var add_button = \$(".LC_add_ipacc_button");
1498: var ipaccRegExp = /^LC_string_ipacc_/;
1499:
1500: \$(add_button).click(function(e){
1501: e.preventDefault();
1502: var identifier = \$(this).closest("div").attr("id");
1503: identifier = identifier.replace(ipaccRegExp,'');
1.551 raeburn 1504: \$(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 1505: });
1506:
1507: \$(wrapper).delegate(".LC_remove_ipacc","click", function(e){
1508: e.preventDefault(); \$(this).closest("div").remove();
1509: })
1510: });
1511:
1512:
1513: END
1514: }
1515:
1.561 damieng 1516: # Javascript function toggleSecret, for overview mode.
1.558 raeburn 1517: sub done_proctor_js {
1.611 raeburn 1518: my $defaultdone = &mt('Done');
1519: &js_escape(\$defaultdone);
1.558 raeburn 1520: return <<"END";
1521: function toggleSecret(form,radio,key) {
1522: var radios = form[radio+key];
1523: if (radios.length) {
1524: for (var i=0; i<radios.length; i++) {
1525: if (radios[i].checked) {
1526: if (radios[i].value == '_done_proctor') {
1527: if (document.getElementById('done_'+key+'_proctorkey')) {
1528: document.getElementById('done_'+key+'_proctorkey').type='text';
1529: }
1530: } else {
1531: if (document.getElementById('done_'+key+'_proctorkey')) {
1532: document.getElementById('done_'+key+'_proctorkey').type='hidden';
1533: document.getElementById('done_'+key+'_proctorkey').value='';
1534: }
1535: }
1.611 raeburn 1536: if (document.getElementById('done_'+key+'_buttontext')) {
1537: if (radios[i].value == '') {
1538: document.getElementById('done_'+key+'_buttontext').value = '';
1539: } else {
1540: if (document.getElementById('done_'+key+'_buttontext').value == '') {
1541: document.getElementById('done_'+key+'_buttontext').value = '$defaultdone';
1542: }
1543: }
1544: }
1.558 raeburn 1545: }
1546: }
1547: }
1548: }
1549: END
1550:
1551: }
1552:
1.588 raeburn 1553: # Javascript function toggle
1554: sub deeplink_js {
1555: return <<"END";
1556: function toggleDeepLink(form,item,key) {
1557: var radios = form['deeplink_'+item+'_'+key];
1558: if (radios.length) {
1559: var keybox;
1560: if (document.getElementById('deeplink_key_'+item+'_'+key)) {
1561: keybox = document.getElementById('deeplink_key_'+item+'_'+key);
1562: }
1.601 raeburn 1563: var divoptions = new Array();
1564: if (item == 'protect') {
1565: divoptions = ['ltic','ltid'];
1.597 raeburn 1566: } else {
1567: if (item == 'menus') {
1.601 raeburn 1568: divoptions = ['colls'];
1.597 raeburn 1569: }
1570: }
1.601 raeburn 1571: var seldivs = new Array();
1572: if ((item == 'protect') || (item == 'menus')) {
1573: for (var i=0; i<divoptions.length; i++) {
1574: if (document.getElementById('deeplinkdiv_'+divoptions[i]+'_'+item+'_'+key)) {
1575: seldivs[i] = document.getElementById('deeplinkdiv_'+divoptions[i]+'_'+item+'_'+key);
1576: } else {
1577: seldivs[i] = '';
1578: }
1579: }
1.588 raeburn 1580: }
1581: for (var i=0; i<radios.length; i++) {
1582: if (radios[i].checked) {
1.601 raeburn 1583: if ((item == 'protect') || (item == 'menus')) {
1584: for (var j=0; j<seldivs.length; j++) {
1585: if (radios[i].value == divoptions[j]) {
1586: if (seldivs[j] != '') {
1587: seldivs[j].style.display = 'inline-block';
1588: }
1589: if (item == 'protect') {
1590: keybox.type = 'hidden';
1591: keybox.value = '';
1592: }
1593: } else {
1594: if (seldivs[j] != '') {
1595: seldivs[j].style.display = 'none';
1596: form['deeplink_'+divoptions[j]+'_'+key].selectedIndex = 0;
1597: }
1598: }
1.597 raeburn 1599: }
1.601 raeburn 1600: if (item == 'protect') {
1.597 raeburn 1601: if (radios[i].value == 'key') {
1602: keybox.type = 'text';
1603: } else {
1604: keybox.type = 'hidden';
1605: }
1.588 raeburn 1606: }
1.616 raeburn 1607: } else if (item == 'exit') {
1608: if (document.getElementById('deeplinkdiv_'+item+'_'+key)) {
1609: if (radios[i].value == 'no') {
1610: document.getElementById('deeplinkdiv_'+item+'_'+key).style.display = 'none';
1611: if (document.getElementById('deeplink_exittext_'+key)) {
1612: if (document.getElementById('deeplink_exittext_'+key).value != '') {
1613: document.getElementById('deeplink_exittext_'+key).value = '';
1614: }
1615: }
1616: } else {
1617: document.getElementById('deeplinkdiv_'+item+'_'+key).style.display = 'inline-block';
1618: if (document.getElementById('deeplink_exittext_'+key)) {
1619: if (document.getElementById('deeplink_exittext_'+key).value == '') {
1620: document.getElementById('deeplink_exittext_'+key).value = 'Exit Tool';
1621: }
1622: }
1623: }
1624: }
1.588 raeburn 1625: }
1626: }
1627: }
1628: }
1629: }
1630: END
1631:
1632: }
1633:
1.561 damieng 1634: # Prints HTML page start for table mode.
1635: # @param {Apache2::RequestRec} $r - the Apache request
1636: # @param {string} $psymb - resource symb
1637: # @param {string} $crstype - course type (Community / Course / Placement Test)
1.280 albertel 1638: sub startpage {
1.531 raeburn 1639: my ($r,$psymb,$crstype) = @_;
1.281 albertel 1640:
1.515 raeburn 1641: my %loaditems = (
1642: 'onload' => "group_or_section('cgroup')",
1643: );
1644: if (!$psymb) {
1.523 raeburn 1645: $loaditems{'onload'} = "showHide_courseContent(); group_or_section('cgroup'); resize_scrollbox('mapmenuscroll','1','1');";
1.515 raeburn 1646: }
1.280 albertel 1647:
1.560 damieng 1648: if ((($env{'form.command'} eq 'set') && ($env{'form.url'}) &&
1649: (!$env{'form.dis'})) || ($env{'form.symb'})) {
1650: &Apache::lonhtmlcommon::add_breadcrumb({help=>'Problem_Parameters',
1651: text=>"Problem Parameters"});
1.414 droeschl 1652: } else {
1.560 damieng 1653: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',
1654: text=>"Table Mode",
1655: help => 'Course_Setting_Parameters'});
1.414 droeschl 1656: }
1.523 raeburn 1657: my $js = &page_js().'
1658: <script type="text/javascript">
1659: // <![CDATA[
1660: '.
1661: &Apache::lonhtmlcommon::resize_scrollbox_js('params').'
1662: // ]]>
1663: </script>
1664: ';
1.446 bisitz 1665: my $start_page =
1.523 raeburn 1666: &Apache::loncommon::start_page('Set/Modify Course Parameters',$js,
1667: {'add_entries' => \%loaditems,});
1.446 bisitz 1668: my $breadcrumbs =
1.473 amueller 1669: &Apache::lonhtmlcommon::breadcrumbs('Table Mode Parameter Setting','Table_Mode');
1.506 www 1670: my $escfilter=&Apache::lonhtmlcommon::entity_encode($env{'form.filter'});
1671: my $escpart=&Apache::lonhtmlcommon::entity_encode($env{'form.part'});
1.507 www 1672: $r->print($start_page.$breadcrumbs);
1.531 raeburn 1673: &startSettingsScreen($r,'parmset',$crstype);
1.280 albertel 1674: $r->print(<<ENDHEAD);
1.193 albertel 1675: <form method="post" action="/adm/parmset?action=settable" name="parmform">
1.419 bisitz 1676: <input type="hidden" value="" name="pres_value" />
1677: <input type="hidden" value="" name="pres_type" />
1678: <input type="hidden" value="" name="pres_marker" />
1679: <input type="hidden" value="1" name="prevvisit" />
1.506 www 1680: <input type="hidden" value="$escfilter" name="filter" />
1681: <input type="hidden" value="$escpart" name="part" />
1.44 albertel 1682: ENDHEAD
1683: }
1684:
1.209 www 1685:
1.561 damieng 1686: # Prints a row for table mode (except for the tr start).
1687: # Every time a hash reference is passed, a single entry is used, so print_row
1688: # could just use these values, but why make it simple when it can be complicated ?
1689: #
1690: # @param {Apache2::RequestRec} $r - the Apache request
1691: # @param {string} $which - parameter key ('parameter_'.part.'_'.name)
1692: # @param {hash reference} $part - parameter key -> parameter part (can be problem part.'_'.response id for response parameters)
1693: # @param {hash reference} $name - parameter key -> parameter name
1.566 damieng 1694: # @param {hash reference} $symbp - map pc or resource/map id -> map src.'___(all)' or resource symb
1.561 damieng 1695: # @param {string} $rid - resource id
1696: # @param {hash reference} $default - parameter key -> resource parameter default value
1697: # @param {hash reference} $defaulttype - parameter key -> resource parameter default type
1698: # @param {hash reference} $display - parameter key -> full title for the parameter
1699: # @param {string} $defbgone - user level and other levels background color
1700: # @param {string} $defbgtwo - section level background color, also used for part number
1701: # @param {string} $defbgthree - group level background color
1702: # @param {string} $parmlev - parameter level (Resource:'full', Map:'map', Course:'general')
1703: # @param {string} $uname - user name
1704: # @param {string} $udom - user domain
1705: # @param {string} $csec - section name
1706: # @param {string} $cgroup - group name
1707: # @param {array reference} $usersgroups - list of groups the user belongs to, if any
1708: # @param {boolean} $noeditgrp - true if no edit is allowed for group level parameters
1.582 raeburn 1709: # @param {boolean} $readonly - true if no editing allowed.
1710: # @param {array reference} - $recurseup - list of maps containing current one, ending at top-level.
1711: # @param {hash reference} - $maptitles - - hash map id or src -> map title
1712: # @param {hash reference} - $allmaps_inverted - hash map src -> map pc
1713: # @param {scalar reference} - $reclinks - number of "parameter in effect" cells with link to map where recursive param was set
1.44 albertel 1714: sub print_row {
1.201 www 1715: my ($r,$which,$part,$name,$symbp,$rid,$default,$defaulttype,$display,$defbgone,
1.568 raeburn 1716: $defbgtwo,$defbgthree,$parmlev,$uname,$udom,$csec,$cgroup,$usersgroups,$noeditgrp,
1.582 raeburn 1717: $readonly,$recurseup,$maptitles,$allmaps_inverted,$reclinks)=@_;
1.275 raeburn 1718: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1719: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1720: my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
1.582 raeburn 1721: my $numlinks = 0;
1.553 raeburn 1722:
1.560 damieng 1723: # get the values for the parameter in cascading order
1724: # empty levels will remain empty
1.44 albertel 1725: my ($result,@outpar)=&parmval($$part{$which}.'.'.$$name{$which},
1.473 amueller 1726: $rid,$$default{$which},$uname,$udom,$csec,$cgroup,$courseopt);
1.560 damieng 1727: # get the type for the parameters
1728: # problem: these may not be set for all levels
1.66 www 1729: my ($typeresult,@typeoutpar)=&parmval($$part{$which}.'.'.
1.275 raeburn 1730: $$name{$which}.'.type',$rid,
1.473 amueller 1731: $$defaulttype{$which},$uname,$udom,$csec,$cgroup,$courseopt);
1.560 damieng 1732: # cascade down manually
1.182 albertel 1733: my $cascadetype=$$defaulttype{$which};
1.556 raeburn 1734: for (my $i=18;$i>0;$i--) {
1.560 damieng 1735: if ($typeoutpar[$i]) {
1.66 www 1736: $cascadetype=$typeoutpar[$i];
1.560 damieng 1737: } else {
1.66 www 1738: $typeoutpar[$i]=$cascadetype;
1739: }
1740: }
1.57 albertel 1741: my $parm=$$display{$which};
1742:
1.203 www 1743: if ($parmlev eq 'full') {
1.419 bisitz 1744: $r->print('<td style="background-color:'.$defbgtwo.';" align="center">'
1.506 www 1745: .($$part{$which} eq '0'?'0 ('.&mt('default').')':$$part{$which}).'</td>');
1.433 raeburn 1746: } else {
1.57 albertel 1747: $parm=~s|\[.*\]\s||g;
1748: }
1.231 www 1749: my $automatic=&rulescache(($which=~/\_([^\_]+)$/)[0].'_triggers');
1750: if ($automatic) {
1.560 damieng 1751: $parm.='<span class="LC_warning"><br />'.&mt('Automatically sets').' '.join(', ',split(/\:/,$automatic)).'</span>';
1.231 www 1752: }
1.619 raeburn 1753: my $advice;
1754: if ((ref($name) eq 'HASH') && ($name->{$which} eq 'mapalias') &&
1755: (ref($symbp) eq 'HASH') && ($parmlev eq 'full')) {
1756: if ($symbp->{$rid} =~ m{^uploaded/}) {
1757: if ($result == 14) {
1758: $advice = &mt('Use Course Editor to modify this.');
1759: } else {
1760: $advice = &mt('Use Course Editor to set this.');
1761: }
1762: } else {
1763: if ($result == 14) {
1764: $advice = &mt('Use Resource Assembly Tool to modify this.');
1765: } else {
1766: $advice = &mt('Use Resource Assembly Tool to set this.');
1767: }
1768: }
1769: $parm .= '<br /><span class="LC_fontsize_small LC_cusr_emph">'.$advice.'</span>';
1770: }
1.427 bisitz 1771: $r->print('<td>'.$parm.'</td>');
1.446 bisitz 1772:
1.44 albertel 1773: my $thismarker=$which;
1774: $thismarker=~s/^parameter\_//;
1775: my $mprefix=$rid.'&'.$thismarker.'&';
1.582 raeburn 1776: my ($parmname)=($thismarker=~/\_([^\_]+)$/);
1777: my ($othergrp,$grp_parm,$controlgrp,$effective_parm,$effparm_rec,$effparm_level,
1.588 raeburn 1778: $eff_groupparm,$recurse_check,$recursinfo,$extra);
1.582 raeburn 1779: if ((ref($recurseup) eq 'ARRAY') && (@{$recurseup} > 0)) {
1780: if ($result eq '') {
1781: $recurse_check = 1;
1782: } elsif (($uname ne '') && ($result > 3)) {
1783: $recurse_check = 1;
1784: } elsif (($cgroup ne '') && ($result > 7)) {
1785: $recurse_check = 1;
1786: } elsif (($csec ne '') && ($result > 11)) {
1787: $recurse_check = 1;
1788: } elsif ($result > 17) {
1789: $recurse_check = 1;
1790: }
1791: if ($recurse_check) {
1792: my $what = $$part{$which}.'.'.$$name{$which};
1793: my $prefix;
1794: if (($uname ne '') && ($udom ne '')) {
1795: my $useropt = &Apache::lonnet::get_userresdata($uname,$udom);
1796: $prefix = $env{'request.course.id'};
1797: $recursinfo = &get_recursive($recurseup,$useropt,$what,$prefix);
1798: if (ref($recursinfo) eq 'ARRAY') {
1799: $effparm_rec = 1;
1800: $effparm_level = &mt('user: [_1]',$uname);
1801: }
1802: }
1803: if (($cgroup ne '') && (!$effparm_rec)) {
1804: $prefix = $env{'request.course.id'}.'.['.$cgroup.']';
1805: $recursinfo = &get_recursive($recurseup,$courseopt,$what,$prefix);
1806: if (ref($recursinfo) eq 'ARRAY') {
1807: $effparm_rec = 1;
1808: $effparm_level = &mt('group: [_1]',$cgroup);
1809: }
1810: }
1811: if (($csec ne '') && (!$effparm_rec)) {
1812: $prefix = $env{'request.course.id'}.'.['.$csec.']';
1813: $recursinfo = &get_recursive($recurseup,$courseopt,$what,$prefix);
1814: if (ref($recursinfo) eq 'ARRAY') {
1815: $effparm_rec = 1;
1816: $effparm_level = &mt('section: [_1]',$csec);
1817: }
1818: }
1819: if (!$effparm_rec) {
1820: $prefix = $env{'request.course.id'};
1821: $recursinfo = &get_recursive($recurseup,$courseopt,$what,$prefix);
1822: if (ref($recursinfo) eq 'ARRAY') {
1823: $effparm_rec = 1;
1824: }
1825: }
1826: }
1827: }
1828: if ((!$effparm_rec) && ($result == 17 || $result == 11 || $result == 7 || $result == 3)) {
1829: $effparm_rec = 1;
1830: }
1831: if ((!$effparm_rec) &&
1832: (($$name{$which} eq 'encrypturl') || ($$name{$which} eq 'hiddenresource')) &&
1833: ($result == 16 || $result == 10 || $result == 6 || $result == 2)) {
1.578 raeburn 1834: $effparm_rec = 1;
1835: }
1.588 raeburn 1836: if ($parmname eq 'deeplink') {
1.601 raeburn 1837: my ($domltistr,$crsltistr);
1.588 raeburn 1838: my %lti =
1839: &Apache::lonnet::get_domain_lti($env{'course.'.$env{'request.course.id'}.'.domain'},
1.604 raeburn 1840: 'linkprot');
1.601 raeburn 1841: if (keys(%lti)) {
1842: foreach my $item (sort { $a <=> $b } (keys(%lti))) {
1.604 raeburn 1843: if (($item =~ /^\d+$/) && (ref($lti{$item}) eq 'HASH')) {
1844: $domltistr .= $item.':'.&escape(&escape($lti{$item}{'name'})).',';
1.588 raeburn 1845: }
1846: }
1.601 raeburn 1847: $domltistr =~ s/,$//;
1848: if ($domltistr) {
1849: $extra = 'ltid_'.$domltistr;
1850: }
1.588 raeburn 1851: }
1.620 ! raeburn 1852: my %courselti = &Apache::lonnet::get_course_lti($cnum,$cdom,'provider');
1.601 raeburn 1853: if (keys(%courselti)) {
1854: foreach my $item (sort { $a <=> $b } keys(%courselti)) {
1855: if (($item =~ /^\d+$/) && (ref($courselti{$item}) eq 'HASH')) {
1856: $crsltistr .= $item.':'.&escape(&escape($courselti{$item}{'name'})).',';
1857: }
1858: }
1859: $crsltistr =~ s/,$//;
1860: if ($crsltistr) {
1861: if ($extra) {
1862: $extra .= '&';
1863: }
1864: $extra .= 'ltic_'.$crsltistr;
1.588 raeburn 1865: }
1866: }
1.597 raeburn 1867: if ($env{'course.'.$env{'request.course.id'}.'.menucollections'}) {
1868: my @colls;
1869: foreach my $item (split(/;/,$env{'course.'.$env{'request.course.id'}.'.menucollections'})) {
1870: my ($num,$value) = split(/\%/,$item);
1871: if ($num =~ /^\d+$/) {
1872: push(@colls,$num);
1873: }
1874: }
1875: if (@colls) {
1876: if ($extra) {
1877: $extra .= '&';
1878: }
1879: $extra .= 'menus_'.join(',',@colls);
1880: }
1881: }
1.588 raeburn 1882: }
1.57 albertel 1883: if ($parmlev eq 'general') {
1884: if ($uname) {
1.588 raeburn 1885: &print_td($r,4,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1.269 raeburn 1886: } elsif ($cgroup) {
1.588 raeburn 1887: &print_td($r,8,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp,$readonly,'',$extra);
1.57 albertel 1888: } elsif ($csec) {
1.588 raeburn 1889: &print_td($r,12,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1.57 albertel 1890: } else {
1.588 raeburn 1891: &print_td($r,18,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1.57 albertel 1892: }
1893: } elsif ($parmlev eq 'map') {
1894: if ($uname) {
1.588 raeburn 1895: &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,1,$extra);
1.269 raeburn 1896: } elsif ($cgroup) {
1.588 raeburn 1897: &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp,$readonly,1,$extra);
1.57 albertel 1898: } elsif ($csec) {
1.588 raeburn 1899: &print_td($r,10,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,1,$extra);
1.57 albertel 1900: } else {
1.588 raeburn 1901: &print_td($r,16,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,1,$extra);
1.57 albertel 1902: }
1903: } else {
1.275 raeburn 1904: if ($uname) {
1905: if (@{$usersgroups} > 1) {
1.582 raeburn 1906: (my $coursereply,$othergrp,$grp_parm,$controlgrp,my $grp_is_rec) =
1.580 raeburn 1907: &check_other_groups($$part{$which}.'.'.$$name{$which},
1.275 raeburn 1908: $rid,$cgroup,$defbgone,$usersgroups,$result,$courseopt);
1.582 raeburn 1909: if (($coursereply) && ($result > 4)) {
1.275 raeburn 1910: if (defined($controlgrp)) {
1911: if ($cgroup ne $controlgrp) {
1.582 raeburn 1912: $eff_groupparm = $grp_parm;
1913: undef($result);
1914: undef($effparm_rec);
1915: if ($grp_is_rec) {
1916: $effparm_rec = 1;
1917: }
1.275 raeburn 1918: }
1919: }
1920: }
1921: }
1922: }
1.57 albertel 1923:
1.588 raeburn 1924: &print_td($r,18,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1925: &print_td($r,16,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,1,$extra);
1926: &print_td($r,15,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1927: &print_td($r,14,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1928: &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1.548 raeburn 1929:
1930: if ($csec) {
1.588 raeburn 1931: &print_td($r,12,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1932: &print_td($r,10,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,1,$extra);
1933: &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1.548 raeburn 1934: }
1.269 raeburn 1935:
1936: if ($cgroup) {
1.588 raeburn 1937: &print_td($r,8,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp,$readonly,'',$extra);
1938: &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp,$readonly,1,$extra);
1939: &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp.$readonly,'',$extra);
1.269 raeburn 1940: }
1.446 bisitz 1941:
1.548 raeburn 1942: if ($uname) {
1.275 raeburn 1943: if ($othergrp) {
1944: $r->print($othergrp);
1945: }
1.588 raeburn 1946: &print_td($r,4,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1947: &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,1,$extra);
1948: &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,'',$readonly,'',$extra);
1.548 raeburn 1949: }
1.57 albertel 1950: } # end of $parmlev if/else
1.582 raeburn 1951: if (ref($recursinfo) eq 'ARRAY') {
1952: my $rectitle = &mt('recursive');
1953: if ((ref($maptitles) eq 'HASH') && (exists($maptitles->{$recursinfo->[2]}))) {
1954: if ((ref($allmaps_inverted) eq 'HASH') && (exists($allmaps_inverted->{$recursinfo->[2]}))) {
1955: $rectitle = &mt('set in: [_1]','"'.
1956: '<a href="javascript:pjumprec('."'".$allmaps_inverted->{$recursinfo->[2]}."',".
1957: "'$parmname','$$part{$which}'".');">'.
1958: $maptitles->{$recursinfo->[2]}.'</a>"');
1959:
1960: $numlinks ++;
1961: }
1962: }
1963: my ($parmname)=($thismarker=~/\_([^\_]+)$/);
1.593 raeburn 1964: $effective_parm = &valout($recursinfo->[0],$recursinfo->[1]);
1.582 raeburn 1965: $r->print('<td style="background-color:#CCCCFF;" align="center">'.$effective_parm.
1966: '<br /><span class="LC_parm_recursive">'.$rectitle.' '.
1967: $effparm_level.'</span></td>');
1968: } else {
1969: if ($result) {
1.593 raeburn 1970: $effective_parm = &valout($outpar[$result],$typeoutpar[$result]);
1.582 raeburn 1971: }
1972: if ($eff_groupparm) {
1973: $effective_parm = $eff_groupparm;
1974: }
1975: $r->print('<td style="background-color:#CCCCFF;" align="center">'.$effective_parm.
1976: ($effparm_rec?'<br /><span class="LC_parm_recursive">'.&mt('recursive').
1977: '</span>':'').'</td>');
1978: }
1.203 www 1979: if ($parmlev eq 'full') {
1.136 albertel 1980: my $sessionval=&Apache::lonnet::EXT('resource.'.$$part{$which}.
1.201 www 1981: '.'.$$name{$which},$$symbp{$rid});
1.136 albertel 1982: my $sessionvaltype=$typeoutpar[$result];
1.560 damieng 1983: if (!defined($sessionvaltype)) {
1984: $sessionvaltype=$$defaulttype{$which};
1985: }
1.419 bisitz 1986: $r->print('<td style="background-color:#999999;" align="center"><font color="#FFFFFF">'.
1.593 raeburn 1987: &valout($sessionval,$sessionvaltype).' '.
1.57 albertel 1988: '</font></td>');
1.136 albertel 1989: }
1.44 albertel 1990: $r->print('</tr>');
1.57 albertel 1991: $r->print("\n");
1.582 raeburn 1992: if (($numlinks) && (ref($reclinks))) {
1993: $$reclinks = $numlinks;
1994: }
1.44 albertel 1995: }
1.59 matthew 1996:
1.561 damieng 1997: # Prints a cell for table mode.
1998: #
1999: # FIXME: some of these parameter names are uninspired ($which and $value)
2000: # Also, it would make more sense to pass the display for this cell rather
2001: # than the full display hash and the key to use.
2002: #
2003: # @param {Apache2::RequestRec} $r - the Apache request
2004: # @param {integer} $which - level
2005: # @param {string} $defbg - cell background color
2006: # @param {integer} $result - the most specific level that is defined for that parameter
2007: # @param {array reference} $outpar - array level -> parameter value (when defined)
2008: # @param {string} $mprefix - resource id.'&'.part.'_'.parameter name.'&'
2009: # @param {string} $value - parameter key ('parameter_'.part.'_'.name)
2010: # @param {array reference} $typeoutpar - array level -> parameter type (when defined)
2011: # @param {hash reference} $display - parameter key -> full title for the parameter
2012: # @param {boolean} $noeditgrp - true if no edit is allowed for group level parameters
1.568 raeburn 2013: # @param {boolean} $readonly -true if editing not allowed.
1.588 raeburn 2014: # @param {boolean} $ismaplevel - true if level is for a map.
1.597 raeburn 2015: # @param {string} $extra - extra information to pass to plink.
1.44 albertel 2016: sub print_td {
1.578 raeburn 2017: my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display,
1.588 raeburn 2018: $noeditgrp,$readonly,$ismaplevel,$extra)=@_;
1.578 raeburn 2019: my ($ineffect,$recursive,$currval,$currtype,$currlevel);
2020: $ineffect = 0;
2021: $currval = $$outpar[$which];
2022: $currtype = $$typeoutpar[$which];
2023: $currlevel = $which;
2024: if (($result) && ($result == $which)) {
2025: $ineffect = 1;
2026: }
2027: if ($ismaplevel) {
2028: if ($mprefix =~ /(hiddenresource|encrypturl)\&/) {
2029: if (($result) && ($result == $which)) {
2030: $recursive = 1;
2031: }
2032: } elsif ($$outpar[$which+1] ne '') {
2033: $recursive = 1;
2034: $currlevel = $which+1;
2035: $currval = $$outpar[$currlevel];
2036: $currtype = $$typeoutpar[$currlevel];
2037: if (($result) && ($result == $currlevel)) {
2038: $ineffect = 1;
2039: }
2040: }
2041: }
2042: $r->print('<td style="background-color:'.($ineffect?'#AAFFAA':$defbg).
1.419 bisitz 2043: ';" align="center">');
1.437 raeburn 2044: my $nolink = 0;
1.568 raeburn 2045: if ($readonly) {
1.552 raeburn 2046: $nolink = 1;
1.568 raeburn 2047: } else {
1.578 raeburn 2048: if ($which == 14 || $which == 15 || $mprefix =~ /mapalias\&$/) {
1.553 raeburn 2049: $nolink = 1;
1.568 raeburn 2050: } elsif (($env{'request.course.sec'} ne '') && ($which > 12)) {
1.533 raeburn 2051: $nolink = 1;
1.568 raeburn 2052: } elsif ($which == 5 || $which == 6 || $which == 7 || $which == 8) {
2053: if ($noeditgrp) {
2054: $nolink = 1;
2055: }
2056: } elsif ($mprefix =~ /availablestudent\&$/) {
1.599 raeburn 2057: $nolink = 1;
1.568 raeburn 2058: } elsif ($mprefix =~ /examcode\&$/) {
2059: unless ($which == 2) {
2060: $nolink = 1;
2061: }
1.533 raeburn 2062: }
1.437 raeburn 2063: }
2064: if ($nolink) {
1.577 raeburn 2065: my ($parmname)=((split(/\&/,$mprefix))[1]=~/\_([^\_]+)$/);
1.593 raeburn 2066: $r->print(&valout($currval,$currtype));
1.114 www 2067: } else {
1.578 raeburn 2068: $r->print(&plink($currtype,
2069: $$display{$value},$currval,
1.588 raeburn 2070: $mprefix.$currlevel,'parmform.pres','psub',$recursive,
2071: $extra));
1.114 www 2072: }
2073: $r->print('</td>'."\n");
1.57 albertel 2074: }
2075:
1.561 damieng 2076: # Returns HTML and other info for the cell added when a user is selected
2077: # and that user is in several groups. This is the cell with the title "Control by other group".
2078: #
2079: # @param {string} $what - parameter part.'.'.parameter name
2080: # @param {string} $rid - resource id
2081: # @param {string} $cgroup - group name
2082: # @param {string} $defbg - cell background color
2083: # @param {array reference} $usersgroups - list of groups the user belongs to, if any
2084: # @param {integer} $result - level
2085: # @param {hash reference} $courseopt - course parameters hash (result of lonnet::get_courseresdata, dump of course's resourcedata.db)
1.582 raeburn 2086: # @returns {Array} - array (parameter value for the other group, HTML for the cell, HTML with the value, name of the other group, true if recursive)
1.580 raeburn 2087: sub check_other_groups {
2088: my ($what,$rid,$cgroup,$defbg,$usersgroups,$result,$courseopt) = @_;
1.275 raeburn 2089: my $courseid = $env{'request.course.id'};
2090: my $output;
2091: my $symb = &symbcache($rid);
2092: my $symbparm=$symb.'.'.$what;
2093: my $map=(&Apache::lonnet::decode_symb($symb))[0];
1.556 raeburn 2094: my $recurseparm=$map.'___(rec).'.$what;
1.275 raeburn 2095: my $mapparm=$map.'___(all).'.$what;
2096: my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype) =
1.556 raeburn 2097: &parm_control_group($courseid,$usersgroups,$symbparm,$mapparm,
2098: $recurseparm,$what,$courseopt);
1.275 raeburn 2099: my $bgcolor = $defbg;
1.582 raeburn 2100: my ($grp_parm,$grp_is_rec);
1.446 bisitz 2101: if (($coursereply) && ($cgroup ne $resultgroup)) {
1.582 raeburn 2102: my ($parmname) = ($what =~ /\.([^.]+)$/);
1.275 raeburn 2103: if ($result > 3) {
1.419 bisitz 2104: $bgcolor = '#AAFFAA';
1.275 raeburn 2105: }
1.593 raeburn 2106: $grp_parm = &valout($coursereply,$resulttype);
1.419 bisitz 2107: $output = '<td style="background-color:'.$bgcolor.';" align="center">';
1.275 raeburn 2108: if ($resultgroup && $resultlevel) {
1.582 raeburn 2109: if ($resultlevel eq 'recursive') {
2110: $resultlevel = 'map/folder';
2111: $grp_is_rec = 1;
2112: }
2113: $output .= '<small><b>'.$resultgroup.'</b> ('.$resultlevel.'): </small>'.$grp_parm.
2114: ($grp_is_rec?'<span class="LC_parm_recursive">'.&mt('recursive').'</span>':'');
2115:
1.275 raeburn 2116: } else {
2117: $output .= ' ';
2118: }
2119: $output .= '</td>';
2120: } else {
1.419 bisitz 2121: $output .= '<td style="background-color:'.$bgcolor.';"> </td>';
1.275 raeburn 2122: }
1.582 raeburn 2123: return ($coursereply,$output,$grp_parm,$resultgroup,$grp_is_rec);
1.275 raeburn 2124: }
2125:
1.561 damieng 2126: # Looks for a group with a defined parameter for given user and parameter.
1.580 raeburn 2127: # Used by check_other_groups.
1.561 damieng 2128: #
2129: # @param {string} $courseid - the course id
2130: # @param {array reference} $usersgroups - list of groups the user belongs to, if any
2131: # @param {string} $symbparm - end of the course parameter hash key for the group resource level
2132: # @param {string} $mapparm - end of the course parameter hash key for the group map/folder level
2133: # @param {string} $recurseparm - end of the course parameter hash key for the group recursive level
2134: # @param {string} $what - parameter part.'.'.parameter name
2135: # @param {hash reference} $courseopt - course parameters hash
2136: # @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 2137: sub parm_control_group {
1.556 raeburn 2138: my ($courseid,$usersgroups,$symbparm,$mapparm,$recurseparm,$what,$courseopt) = @_;
1.275 raeburn 2139: my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
2140: my $grpfound = 0;
1.556 raeburn 2141: my @levels = ($symbparm,$mapparm,$recurseparm,$what);
2142: my @levelnames = ('resource','map/folder','recursive','general');
1.275 raeburn 2143: foreach my $group (@{$usersgroups}) {
2144: if ($grpfound) { last; }
2145: for (my $i=0; $i<@levels; $i++) {
2146: my $item = $courseid.'.['.$group.'].'.$levels[$i];
2147: if (defined($$courseopt{$item})) {
2148: $coursereply = $$courseopt{$item};
2149: $resultitem = $item;
2150: $resultgroup = $group;
2151: $resultlevel = $levelnames[$i];
2152: $resulttype = $$courseopt{$item.'.type'};
2153: $grpfound = 1;
2154: last;
2155: }
2156: }
2157: }
2158: return($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
2159: }
1.201 www 2160:
1.63 bowersj2 2161:
2162:
1.562 damieng 2163: # Extracts lots of information about all of the the course's resources into a variety of hashes, using lonnavmaps and lonnet::metadata.
2164: # All the parameters are references and are filled by the sub.
2165: #
1.566 damieng 2166: # @param {array reference} $ids - resource and map ids
2167: # @param {hash reference} $typep - hash resource/map id -> resource type (file extension)
2168: # @param {hash reference} $keyp - hash resource/map id -> comma-separated list of parameter keys from lonnet::metadata
1.562 damieng 2169: # @param {hash reference} $allparms - hash parameter name -> parameter title
2170: # @param {hash reference} $allparts - hash parameter part -> part title (a parameter part can be problem part.'_'.response id for response parameters)
1.566 damieng 2171: # @param {hash reference} $allmaps - hash map pc -> map src
2172: # @param {hash reference} $mapp - hash map pc or resource/map id -> enclosing map src
2173: # @param {hash reference} $symbp - hash map pc or resource/map id -> map src.'___(all)' for a map or resource symb for a resource
2174: # @param {hash reference} $maptitles - hash map pc or src -> map title (this should really be two separate hashes)
2175: # @param {hash reference} $uris - hash resource/map id -> resource src
1.562 damieng 2176: # @param {hash reference} $keyorder - hash parameter key -> appearance rank for this parameter when looking through every resource and every parameter, starting at 100 (integer)
2177: # @param {hash reference} $defkeytype - hash parameter name -> parameter type
1.608 raeburn 2178: # @param {string} $pssymb - resource symb (when a single resource is selected)
1.63 bowersj2 2179: sub extractResourceInformation {
2180: my $ids = shift;
2181: my $typep = shift;
2182: my $keyp = shift;
2183: my $allparms = shift;
2184: my $allparts = shift;
2185: my $allmaps = shift;
2186: my $mapp = shift;
2187: my $symbp = shift;
1.82 www 2188: my $maptitles=shift;
1.196 www 2189: my $uris=shift;
1.210 www 2190: my $keyorder=shift;
1.211 www 2191: my $defkeytype=shift;
1.603 raeburn 2192: my $pssymb=shift;
1.196 www 2193:
1.210 www 2194: my $keyordercnt=100;
1.63 bowersj2 2195:
1.196 www 2196: my $navmap = Apache::lonnavmaps::navmap->new();
1.603 raeburn 2197: return unless(ref($navmap));
2198: my @allres;
2199: if ($pssymb ne '') {
2200: my $res = $navmap->getBySymb($pssymb);
2201: if (ref($res)) {
2202: @allres = ($res);
2203: }
2204: }
2205: if (!@allres) {
2206: @allres=$navmap->retrieveResources(undef,undef,1,undef,1);
2207: }
1.196 www 2208: foreach my $resource (@allres) {
1.480 amueller 2209: my $id=$resource->id();
1.196 www 2210: my ($mapid,$resid)=split(/\./,$id);
1.480 amueller 2211: if ($mapid eq '0') { next; }
2212: $$ids[$#$ids+1]=$id;
2213: my $srcf=$resource->src();
2214: $srcf=~/\.(\w+)$/;
2215: $$typep{$id}=$1;
1.584 raeburn 2216: my $toolsymb;
2217: if ($srcf =~ /ext\.tool$/) {
2218: $toolsymb = $resource->symb();
2219: }
1.480 amueller 2220: $$keyp{$id}='';
1.196 www 2221: $$uris{$id}=$srcf;
1.512 foxr 2222:
1.584 raeburn 2223: foreach my $key (split(/\,/,&Apache::lonnet::metadata($srcf,'allpossiblekeys',$toolsymb))) {
1.480 amueller 2224: next if ($key!~/^parameter_/);
1.363 albertel 2225:
1.209 www 2226: # Hidden parameters
1.584 raeburn 2227: next if (&Apache::lonnet::metadata($srcf,$key.'.hidden',$toolsymb) eq 'parm');
1.209 www 2228: #
2229: # allparms is a hash of parameter names
2230: #
1.584 raeburn 2231: my $name=&Apache::lonnet::metadata($srcf,$key.'.name',$toolsymb);
1.480 amueller 2232: if (!exists($$allparms{$name}) || $$allparms{$name} =~ m/^\s*$/ ) {
2233: my ($display,$parmdis);
2234: $display = &standard_parameter_names($name);
2235: if ($display eq '') {
1.584 raeburn 2236: $display= &Apache::lonnet::metadata($srcf,$key.'.display',$toolsymb);
1.480 amueller 2237: $parmdis = $display;
2238: $parmdis =~ s/\s*\[Part.*$//g;
2239: } else {
2240: $parmdis = &mt($display);
2241: }
2242: $$allparms{$name}=$parmdis;
2243: if (ref($defkeytype)) {
2244: $$defkeytype{$name}=
1.584 raeburn 2245: &Apache::lonnet::metadata($srcf,$key.'.type',$toolsymb);
1.480 amueller 2246: }
2247: }
1.363 albertel 2248:
1.209 www 2249: #
2250: # allparts is a hash of all parts
2251: #
1.584 raeburn 2252: my $part= &Apache::lonnet::metadata($srcf,$key.'.part',$toolsymb);
1.480 amueller 2253: $$allparts{$part} = &mt('Part: [_1]',$part);
1.209 www 2254: #
2255: # Remember all keys going with this resource
2256: #
1.480 amueller 2257: if ($$keyp{$id}) {
2258: $$keyp{$id}.=','.$key;
2259: } else {
2260: $$keyp{$id}=$key;
2261: }
1.210 www 2262: #
2263: # Put in order
1.446 bisitz 2264: #
1.480 amueller 2265: unless ($$keyorder{$key}) {
2266: $$keyorder{$key}=$keyordercnt;
2267: $keyordercnt++;
2268: }
1.473 amueller 2269: }
2270:
2271:
1.480 amueller 2272: if (!exists($$mapp{$mapid})) {
2273: $$mapp{$id}=
2274: &Apache::lonnet::declutter($resource->enclosing_map_src());
2275: $$mapp{$mapid}=$$mapp{$id};
2276: $$allmaps{$mapid}=$$mapp{$id};
2277: if ($mapid eq '1') {
1.532 raeburn 2278: $$maptitles{$mapid}=&mt('Main Content');
1.480 amueller 2279: } else {
2280: $$maptitles{$mapid}=&Apache::lonnet::gettitle($$mapp{$id});
2281: }
2282: $$maptitles{$$mapp{$id}}=$$maptitles{$mapid};
1.556 raeburn 2283: $$symbp{$mapid}=$$mapp{$id}.'___(all)'; # Added in rev. 1.57, but seems not to be used.
2284: # Lines 1038 and 1114 which use $symbp{$mapid}
2285: # are commented out in rev. 1.57
1.473 amueller 2286: } else {
1.480 amueller 2287: $$mapp{$id} = $$mapp{$mapid};
1.473 amueller 2288: }
1.480 amueller 2289: $$symbp{$id}=&Apache::lonnet::encode_symb($$mapp{$id},$resid,$srcf);
1.63 bowersj2 2290: }
2291: }
2292:
1.582 raeburn 2293: sub get_recursive {
2294: my ($recurseup,$resdata,$what,$prefix) = @_;
2295: if ((ref($resdata) eq 'HASH') && (ref($recurseup) eq 'ARRAY')) {
2296: foreach my $item (@{$recurseup}) {
2297: my $norecursechk=$prefix.'.'.$item.'___(all).'.$what;
2298: if (defined($resdata->{$norecursechk})) {
2299: if ($what =~ /\.(encrypturl|hiddenresource)$/) {
2300: my $type = $resdata->{$norecursechk.'.type'};
2301: return [$resdata->{$norecursechk},$type,$item];
2302: } else {
2303: last;
2304: }
2305: }
2306: my $recursechk=$prefix.'.'.$item.'___(rec).'.$what;
2307: if (defined($resdata->{$recursechk})) {
2308: my $type = $resdata->{$recursechk.'.type'};
2309: return [$resdata->{$recursechk},$type,$item];
2310: }
2311: }
2312: }
2313: return;
2314: }
2315:
1.208 www 2316:
1.562 damieng 2317: # Tells if a parameter type is a date.
2318: #
2319: # @param {string} type - parameter type
2320: # @returns{boolean} - true if it is a date
1.213 www 2321: sub isdateparm {
2322: my $type=shift;
2323: return (($type=~/^date/) && (!($type eq 'date_interval')));
2324: }
2325:
1.589 raeburn 2326: # Determine if parameter type is specialized string type (i.e.,
2327: # not just string or string_yesno.
2328:
2329: sub is_specialstring {
2330: my $type=shift;
1.603 raeburn 2331: return (($type=~/^string_/) && ($type ne 'string_yesno'));
1.589 raeburn 2332: }
2333:
1.562 damieng 2334: # Prints the HTML and Javascript to select parameters, with various shortcuts.
1.468 amueller 2335: #
1.581 raeburn 2336: # @param {Apache2::RequestRec} $r - the Apache request
1.208 www 2337: sub parmmenu {
1.581 raeburn 2338: my ($r)=@_;
1.208 www 2339: $r->print(<<ENDSCRIPT);
2340: <script type="text/javascript">
1.454 bisitz 2341: // <![CDATA[
1.208 www 2342: function checkall(value, checkName) {
1.453 schualex 2343:
2344: var li = "_li";
2345: var displayOverview = "";
2346:
2347: if (value == false) {
2348: displayOverview = "none"
2349: }
2350:
1.562 damieng 2351: for (i=0; i<document.forms.parmform.elements.length; i++) {
1.208 www 2352: ele = document.forms.parmform.elements[i];
2353: if (ele.name == checkName) {
2354: document.forms.parmform.elements[i].checked=value;
2355: }
2356: }
2357: }
1.210 www 2358:
2359: function checkthis(thisvalue, checkName) {
1.562 damieng 2360: for (i=0; i<document.forms.parmform.elements.length; i++) {
1.210 www 2361: ele = document.forms.parmform.elements[i];
2362: if (ele.name == checkName) {
1.562 damieng 2363: if (ele.value == thisvalue) {
2364: document.forms.parmform.elements[i].checked=true;
2365: }
1.210 www 2366: }
2367: }
2368: }
2369:
2370: function checkdates() {
1.562 damieng 2371: checkthis('duedate','pscat');
2372: checkthis('opendate','pscat');
2373: checkthis('answerdate','pscat');
1.218 www 2374: }
2375:
2376: function checkdisset() {
1.562 damieng 2377: checkthis('discussend','pscat');
2378: checkthis('discusshide','pscat');
2379: checkthis('discussvote','pscat');
1.218 www 2380: }
2381:
2382: function checkcontdates() {
1.562 damieng 2383: checkthis('contentopen','pscat');
2384: checkthis('contentclose','pscat');
1.218 www 2385: }
1.446 bisitz 2386:
1.210 www 2387: function checkvisi() {
1.562 damieng 2388: checkthis('hiddenresource','pscat');
2389: checkthis('encrypturl','pscat');
2390: checkthis('problemstatus','pscat');
2391: checkthis('contentopen','pscat');
2392: checkthis('opendate','pscat');
1.210 www 2393: }
2394:
2395: function checkparts() {
1.562 damieng 2396: checkthis('hiddenparts','pscat');
2397: checkthis('display','pscat');
2398: checkthis('ordered','pscat');
1.210 www 2399: }
2400:
2401: function checkstandard() {
2402: checkall(false,'pscat');
1.562 damieng 2403: checkdates();
2404: checkthis('weight','pscat');
2405: checkthis('maxtries','pscat');
2406: checkthis('type','pscat');
2407: checkthis('problemstatus','pscat');
1.210 www 2408: }
2409:
1.454 bisitz 2410: // ]]>
1.208 www 2411: </script>
2412: ENDSCRIPT
1.453 schualex 2413:
1.491 bisitz 2414: $r->print('<hr />');
1.581 raeburn 2415: &shortCuts($r);
1.491 bisitz 2416: $r->print('<hr />');
1.453 schualex 2417: }
1.562 damieng 2418:
2419: # Returns parameter categories.
2420: #
2421: # @returns {hash} - category name -> title in English
1.465 amueller 2422: sub categories {
2423: return ('time_settings' => 'Time Settings',
2424: 'grading' => 'Grading',
2425: 'tries' => 'Tries',
2426: 'problem_appearance' => 'Problem Appearance',
2427: 'behaviour_of_input_fields' => 'Behaviour of Input Fields',
2428: 'hiding' => 'Hiding',
2429: 'high_level_randomization' => 'High Level Randomization',
2430: 'slots' => 'Slots',
2431: 'file_submission' => 'File Submission',
2432: 'misc' => 'Miscellaneous' );
2433: }
2434:
1.562 damieng 2435: # Returns the category for each parameter.
2436: #
2437: # @returns {hash} - parameter name -> category name
1.465 amueller 2438: sub lookUpTableParameter {
2439:
2440: return (
2441: 'opendate' => 'time_settings',
2442: 'duedate' => 'time_settings',
2443: 'answerdate' => 'time_settings',
2444: 'interval' => 'time_settings',
2445: 'contentopen' => 'time_settings',
2446: 'contentclose' => 'time_settings',
2447: 'discussend' => 'time_settings',
1.560 damieng 2448: 'printstartdate' => 'time_settings',
2449: 'printenddate' => 'time_settings',
1.465 amueller 2450: 'weight' => 'grading',
2451: 'handgrade' => 'grading',
2452: 'maxtries' => 'tries',
2453: 'hinttries' => 'tries',
1.503 raeburn 2454: 'randomizeontries' => 'tries',
1.465 amueller 2455: 'type' => 'problem_appearance',
2456: 'problemstatus' => 'problem_appearance',
2457: 'display' => 'problem_appearance',
2458: 'ordered' => 'problem_appearance',
2459: 'numbubbles' => 'problem_appearance',
2460: 'tol' => 'behaviour_of_input_fields',
2461: 'sig' => 'behaviour_of_input_fields',
2462: 'turnoffunit' => 'behaviour_of_input_fields',
2463: 'hiddenresource' => 'hiding',
2464: 'hiddenparts' => 'hiding',
2465: 'discusshide' => 'hiding',
2466: 'buttonshide' => 'hiding',
2467: 'turnoffeditor' => 'hiding',
2468: 'encrypturl' => 'hiding',
1.587 raeburn 2469: 'deeplink' => 'hiding',
1.465 amueller 2470: 'randomorder' => 'high_level_randomization',
2471: 'randompick' => 'high_level_randomization',
2472: 'available' => 'slots',
2473: 'useslots' => 'slots',
2474: 'availablestudent' => 'slots',
2475: 'uploadedfiletypes' => 'file_submission',
2476: 'maxfilesize' => 'file_submission',
2477: 'cssfile' => 'misc',
2478: 'mapalias' => 'misc',
2479: 'acc' => 'misc',
2480: 'maxcollaborators' => 'misc',
2481: 'scoreformat' => 'misc',
1.514 raeburn 2482: 'lenient' => 'grading',
1.519 raeburn 2483: 'retrypartial' => 'tries',
1.521 raeburn 2484: 'discussvote' => 'misc',
1.584 raeburn 2485: 'examcode' => 'high_level_randomization',
1.575 raeburn 2486: );
1.465 amueller 2487: }
2488:
1.562 damieng 2489: # Adds the given parameter name to an array of arrays listing all parameters for each category.
2490: #
2491: # @param {string} $name - parameter name
2492: # @param {array reference} $catList - array reference category name -> array reference of parameter names
1.465 amueller 2493: sub whatIsMyCategory {
2494: my $name = shift;
2495: my $catList = shift;
2496: my @list;
2497: my %lookUpList = &lookUpTableParameter; #Initilize the lookupList
2498: my $cat = $lookUpList{$name};
2499: if (defined($cat)) {
2500: if (!defined($$catList{$cat})){
2501: push @list, ($name);
2502: $$catList{$cat} = \@list;
2503: } else {
2504: push @{${$catList}{$cat}}, ($name);
2505: }
2506: } else {
2507: if (!defined($$catList{'misc'})){
2508: push @list, ($name);
2509: $$catList{'misc'} = \@list;
2510: } else {
2511: push @{${$catList}{'misc'}}, ($name);
2512: }
2513: }
2514: }
2515:
1.562 damieng 2516: # Sorts parameter names based on appearance order.
2517: #
2518: # @param {array reference} name - array reference of parameter names
2519: # @param {hash reference} $keyorder - hash parameter key -> appearance rank
2520: # @returns {Array} - array of parameter names
1.465 amueller 2521: sub keysindisplayorderCategory {
2522: my ($name,$keyorder)=@_;
2523: return sort {
1.473 amueller 2524: $$keyorder{'parameter_0_'.$a} <=> $$keyorder{'parameter_0_'.$b};
1.465 amueller 2525: } ( @{$name});
2526: }
2527:
1.562 damieng 2528: # Returns a hash category name -> order, starting at 1 (integer)
2529: #
2530: # @returns {hash}
1.467 amueller 2531: sub category_order {
2532: return (
2533: 'time_settings' => 1,
2534: 'grading' => 2,
2535: 'tries' => 3,
2536: 'problem_appearance' => 4,
2537: 'hiding' => 5,
2538: 'behaviour_of_input_fields' => 6,
2539: 'high_level_randomization' => 7,
2540: 'slots' => 8,
2541: 'file_submission' => 9,
2542: 'misc' => 10
2543: );
2544:
2545: }
1.453 schualex 2546:
1.562 damieng 2547: # Prints HTML to let the user select parameters, from a list of all parameters organized by category.
2548: #
2549: # @param {Apache2::RequestRec} $r - the Apache request
2550: # @param {hash reference} $allparms - hash parameter name -> parameter title
2551: # @param {array reference} $pscat - list of selected parameter names
2552: # @param {hash reference} $keyorder - hash parameter key -> appearance rank
1.453 schualex 2553: sub parmboxes {
2554: my ($r,$allparms,$pscat,$keyorder)=@_;
1.548 raeburn 2555: my %categories = &categories();
1.467 amueller 2556: my %category_order = &category_order();
1.465 amueller 2557: my %categoryList = (
2558: 'time_settings' => [],
2559: 'grading' => [],
2560: 'tries' => [],
2561: 'problem_appearance' => [],
2562: 'behaviour_of_input_fields' => [],
2563: 'hiding' => [],
2564: 'high_level_randomization' => [],
2565: 'slots' => [],
2566: 'file_submission' => [],
2567: 'misc' => [],
1.489 bisitz 2568: );
1.510 www 2569:
1.548 raeburn 2570: foreach my $tempparameter (keys(%$allparms)) {
1.465 amueller 2571: &whatIsMyCategory($tempparameter, \%categoryList);
2572: }
1.453 schualex 2573: #part to print the parm-list
1.618 raeburn 2574: $Text::Wrap::columns=60;
2575: $Text::Wrap::separator='<br />';
1.536 raeburn 2576: foreach my $key (sort { $category_order{$a} <=> $category_order{$b} } keys(%categoryList)) {
2577: next if (@{$categoryList{$key}} == 0);
2578: next if ($key eq '');
2579: $r->print('<div class="LC_Box LC_400Box">'
2580: .'<h4 class="LC_hcell">'.&mt($categories{$key}).'</h4>'."\n");
2581: foreach my $tempkey (&keysindisplayorderCategory($categoryList{$key},$keyorder)) {
1.575 raeburn 2582: next if ($tempkey eq '');
1.536 raeburn 2583: $r->print('<span class="LC_nobreak">'
2584: .'<label><input type="checkbox" name="pscat" '
2585: .'value="'.$tempkey.'" ');
2586: if ($$pscat[0] eq "all" || grep $_ eq $tempkey, @{$pscat}) {
2587: $r->print( ' checked="checked"');
2588: }
1.617 raeburn 2589: $r->print(' />'.($$allparms{$tempkey}=~/\S/ ?
2590: Text::Wrap::wrap('',' 'x4,$$allparms{$tempkey})
2591: : $tempkey)
1.536 raeburn 2592: .'</label></span><br />'."\n");
1.465 amueller 2593: }
1.536 raeburn 2594: $r->print('</div>');
1.465 amueller 2595: }
1.536 raeburn 2596: $r->print("\n");
1.453 schualex 2597: }
1.562 damieng 2598:
2599: # Prints HTML with shortcuts to select groups of parameters in one click, or deselect all.
1.468 amueller 2600: #
1.562 damieng 2601: # @param {Apache2::RequestRec} $r - the Apache request
1.453 schualex 2602: sub shortCuts {
1.581 raeburn 2603: my ($r)=@_;
1.453 schualex 2604:
1.491 bisitz 2605: # Parameter Selection
2606: $r->print(
2607: &Apache::lonhtmlcommon::start_funclist(&mt('Parameter Selection'))
2608: .&Apache::lonhtmlcommon::add_item_funclist(
2609: '<a href="javascript:checkall(true, \'pscat\')">'.&mt('Select All').'</a>')
2610: .&Apache::lonhtmlcommon::add_item_funclist(
2611: '<a href="javascript:checkstandard()">'.&mt('Select Common Only').'</a>')
2612: .&Apache::lonhtmlcommon::add_item_funclist(
2613: '<a href="javascript:checkall(false, \'pscat\')">'.&mt('Unselect All').'</a>')
2614: .&Apache::lonhtmlcommon::end_funclist()
2615: );
2616:
2617: # Add Selection for...
2618: $r->print(
2619: &Apache::lonhtmlcommon::start_funclist(&mt('Add Selection for...'))
2620: .&Apache::lonhtmlcommon::add_item_funclist(
2621: '<a href="javascript:checkdates()">'.&mt('Problem Dates').'</a>')
2622: .&Apache::lonhtmlcommon::add_item_funclist(
2623: '<a href="javascript:checkcontdates()">'.&mt('Content Dates').'</a>')
2624: .&Apache::lonhtmlcommon::add_item_funclist(
2625: '<a href="javascript:checkdisset()">'.&mt('Discussion Settings').'</a>')
2626: .&Apache::lonhtmlcommon::add_item_funclist(
2627: '<a href="javascript:checkvisi()">'.&mt('Visibilities').'</a>')
2628: .&Apache::lonhtmlcommon::add_item_funclist(
2629: '<a href="javascript:checkparts()">'.&mt('Part Parameters').'</a>')
2630: .&Apache::lonhtmlcommon::end_funclist()
2631: );
1.208 www 2632: }
2633:
1.562 damieng 2634: # Prints HTML to select parts to view (except for the title).
2635: # Used by table and overview modes.
2636: #
2637: # @param {Apache2::RequestRec} $r - the Apache request
2638: # @param {hash reference} $allparts - hash parameter part -> part title
2639: # @param {array reference} $psprt - list of selected parameter parts
1.209 www 2640: sub partmenu {
1.446 bisitz 2641: my ($r,$allparts,$psprt)=@_;
1.523 raeburn 2642: my $selsize = 1+scalar(keys(%{$allparts}));
2643: if ($selsize > 8) {
2644: $selsize = 8;
2645: }
1.446 bisitz 2646:
1.523 raeburn 2647: $r->print('<select multiple="multiple" name="psprt" size="'.$selsize.'">');
1.208 www 2648: $r->print('<option value="all"');
1.562 damieng 2649: $r->print(' selected="selected"') unless (@{$psprt}); # useless, the array is never empty
1.208 www 2650: $r->print('>'.&mt('All Parts').'</option>');
2651: my %temphash=();
2652: foreach (@{$psprt}) { $temphash{$_}=1; }
1.234 albertel 2653: foreach my $tempkey (sort {
1.560 damieng 2654: if ($a==$b) { return ($a cmp $b) } else { return ($a <=> $b); }
2655: } keys(%{$allparts})) {
2656: unless ($tempkey =~ /\./) {
2657: $r->print('<option value="'.$tempkey.'"');
2658: if ($$psprt[0] eq "all" || $temphash{$tempkey}) {
2659: $r->print(' selected="selected"');
2660: }
2661: $r->print('>'.$$allparts{$tempkey}.'</option>');
1.473 amueller 2662: }
1.208 www 2663: }
1.446 bisitz 2664: $r->print('</select>');
1.209 www 2665: }
2666:
1.562 damieng 2667: # Prints HTML to select a user and/or a group.
2668: # Used by table mode.
2669: #
2670: # @param {Apache2::RequestRec} $r - the Apache request
2671: # @param {string} $uname - selected user name
2672: # @param {string} $id - selected Student/Employee ID
2673: # @param {string} $udom - selected user domain
2674: # @param {string} $csec - selected section name
2675: # @param {string} $cgroup - selected group name
2676: # @param {string} $parmlev - parameter level (Resource:'full', Map:'map', Course:'general')
2677: # @param {array reference} $usersgroups - list of groups the user belongs to, if any
2678: # @param {string} $pssymb - resource symb (when a single resource is selected)
1.209 www 2679: sub usermenu {
1.553 raeburn 2680: my ($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,$usersgroups,$pssymb)=@_;
1.209 www 2681: my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '.
1.596 raeburn 2682: &Apache::loncommon::selectstudent_link('parmform','uname','udom','condition').
2683: &Apache::lonhtmlcommon::scripttag(<<ENDJS);
2684: function setCourseadv(form,caller) {
2685: if (caller.value == 'st') {
2686: form.courseadv.value = 'none';
2687: } else {
2688: form.courseadv.value = '';
2689: }
2690: return;
2691: }
2692: ENDJS
1.412 bisitz 2693:
1.596 raeburn 2694: my (%chkroles,$stuonly,$courseadv);
2695: if ($env{'form.userroles'} eq 'any') {
2696: $chkroles{'any'} = ' checked="checked"';
2697: } else {
2698: $chkroles{'st'} = ' checked="checked"';
2699: $courseadv = 'none';
2700: }
2701: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
2702: if ($crstype eq 'Community') {
2703: $stuonly = &mt('member only');
2704: } else {
2705: $stuonly = &mt('student only');
2706: }
2707: $chooseopt .= '<br /><span class="LC_cusr_subheading">'.
2708: &mt("User's role").': '.
2709: '<label><input type="radio" name="userroles" value="st"'.$chkroles{'st'}.' onclick="setCourseadv(this.form,this);" />'.
2710: $stuonly.'</label> '.
2711: '<label><input type="radio" name="userroles" value="any"'.$chkroles{'any'}.' onclick="setCourseadv(this.form,this);" />'.
2712: &mt('any role').'</label><input type="hidden" id="courseadv" name="courseadv" value="'.$courseadv.'" /></span>';
1.209 www 2713: my $sections='';
1.300 albertel 2714: my %sectionhash = &Apache::loncommon::get_sections();
2715:
1.269 raeburn 2716: my $groups;
1.553 raeburn 2717: my %grouphash;
2718: if (($pssymb) || &Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
2719: %grouphash = &Apache::longroup::coursegroups();
2720: } elsif ($env{'request.course.groups'} ne '') {
1.585 raeburn 2721: map { $grouphash{$_} = 1; } split(/:/,$env{'request.course.groups'});
1.553 raeburn 2722: }
1.299 albertel 2723:
1.412 bisitz 2724: my $g_s_header='';
2725: my $g_s_footer='';
1.446 bisitz 2726:
1.552 raeburn 2727: my $currsec = $env{'request.course.sec'};
2728: if ($currsec) {
2729: $sections=&mt('Section:').' '.$currsec;
2730: if (%grouphash) {
2731: $sections .= ';'.(' ' x2);
2732: }
2733: } elsif (%sectionhash && $currsec eq '') {
1.412 bisitz 2734: $sections=&mt('Section:').' <select name="csec"';
1.299 albertel 2735: if (%grouphash && $parmlev ne 'full') {
1.269 raeburn 2736: $sections .= qq| onchange="group_or_section('csec')" |;
2737: }
2738: $sections .= '>';
1.548 raeburn 2739: foreach my $section ('',sort(keys(%sectionhash))) {
1.473 amueller 2740: $sections.='<option value="'.$section.'" '.
2741: ($section eq $csec?'selected="selected"':'').'>'.$section.
1.275 raeburn 2742: '</option>';
1.209 www 2743: }
2744: $sections.='</select>';
1.269 raeburn 2745: }
1.412 bisitz 2746:
1.552 raeburn 2747: if (%sectionhash && %grouphash && $parmlev ne 'full' && $currsec eq '') {
1.412 bisitz 2748: $sections .= ' '.&mt('or').' ';
1.269 raeburn 2749: $sections .= qq|
2750: <script type="text/javascript">
1.454 bisitz 2751: // <![CDATA[
1.269 raeburn 2752: function group_or_section(caller) {
2753: if (caller == "cgroup") {
2754: if (document.parmform.cgroup.selectedIndex != 0) {
2755: document.parmform.csec.selectedIndex = 0;
2756: }
2757: } else {
2758: if (document.parmform.csec.selectedIndex != 0) {
2759: document.parmform.cgroup.selectedIndex = 0;
2760: }
2761: }
2762: }
1.454 bisitz 2763: // ]]>
1.269 raeburn 2764: </script>
2765: |;
1.554 raeburn 2766: } else {
1.269 raeburn 2767: $sections .= qq|
2768: <script type="text/javascript">
1.454 bisitz 2769: // <![CDATA[
1.269 raeburn 2770: function group_or_section(caller) {
2771: return;
2772: }
1.454 bisitz 2773: // ]]>
1.269 raeburn 2774: </script>
2775: |;
1.446 bisitz 2776: }
1.299 albertel 2777:
2778: if (%grouphash) {
1.597 raeburn 2779: $groups=&mt('Group').': <select name="cgroup"';
1.552 raeburn 2780: if (%sectionhash && $env{'form.action'} eq 'settable' && $currsec eq '') {
1.269 raeburn 2781: $groups .= qq| onchange="group_or_section('cgroup')" |;
2782: }
2783: $groups .= '>';
1.548 raeburn 2784: foreach my $grp ('',sort(keys(%grouphash))) {
1.275 raeburn 2785: $groups.='<option value="'.$grp.'" ';
2786: if ($grp eq $cgroup) {
2787: unless ((defined($uname)) && ($grp eq '')) {
2788: $groups .= 'selected="selected" ';
2789: }
2790: } elsif (!defined($cgroup)) {
2791: if (@{$usersgroups} == 1) {
2792: if ($grp eq $$usersgroups[0]) {
2793: $groups .= 'selected="selected" ';
2794: }
2795: }
2796: }
2797: $groups .= '>'.$grp.'</option>';
1.269 raeburn 2798: }
2799: $groups.='</select>';
2800: }
1.412 bisitz 2801:
1.445 neumanie 2802: if (%sectionhash || %grouphash) {
1.446 bisitz 2803: $r->print(&Apache::lonhtmlcommon::row_title(&mt('Group/Section')));
2804: $r->print($sections.$groups);
1.448 bisitz 2805: $r->print(&Apache::lonhtmlcommon::row_closure());
1.554 raeburn 2806: } else {
2807: $r->print($sections);
1.445 neumanie 2808: }
1.446 bisitz 2809:
2810: $r->print(&Apache::lonhtmlcommon::row_title(&mt('User')));
1.443 neumanie 2811: $r->print(&mt('For User [_1] or Student/Employee ID [_2] at Domain [_3]'
1.412 bisitz 2812: ,'<input type="text" value="'.$uname.'" size="12" name="uname" />'
2813: ,'<input type="text" value="'.$id.'" size="12" name="id" /> '
1.446 bisitz 2814: ,$chooseopt));
1.209 www 2815: }
2816:
1.562 damieng 2817: # Prints HTML to select parameters from a list of all parameters.
2818: # Uses parmmenu and parmboxes.
2819: # Used by table and overview modes.
1.468 amueller 2820: #
1.562 damieng 2821: # @param {Apache2::RequestRec} $r - the Apache request
2822: # @param {hash reference} $allparms - hash parameter name -> parameter title
2823: # @param {array reference} $pscat - list of selected parameter names
2824: # @param {hash reference} $keyorder - hash parameter key -> appearance rank
2825: # @param {string} [$divid] - name used to give an id to the HTML element for the scroll box
1.209 www 2826: sub displaymenu {
1.581 raeburn 2827: my ($r,$allparms,$pscat,$keyorder,$divid)=@_;
1.510 www 2828:
1.445 neumanie 2829: $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.510 www 2830: $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parameters to View')));
2831:
1.581 raeburn 2832: &parmmenu($r);
1.536 raeburn 2833: $r->print(&Apache::loncommon::start_scrollbox('480px','440px','200px',$divid));
1.510 www 2834: &parmboxes($r,$allparms,$pscat,$keyorder);
2835: $r->print(&Apache::loncommon::end_scrollbox());
2836:
2837: $r->print(&Apache::lonhtmlcommon::row_closure(1));
1.453 schualex 2838: $r->print(&Apache::lonhtmlcommon::end_pick_box());
1.510 www 2839:
1.209 www 2840: }
2841:
1.562 damieng 2842: # Prints HTML to select a map.
2843: # Used by table mode and overview mode.
2844: #
2845: # @param {Apache2::RequestRec} $r - the Apache request
1.566 damieng 2846: # @param {hash reference} $allmaps - hash map pc -> map src
2847: # @param {string} $pschp - selected map pc, or 'all'
1.562 damieng 2848: # @param {hash reference} $maptitles - hash map id or src -> map title
1.566 damieng 2849: # @param {hash reference} $symbp - hash map pc or resource/map id -> map src.'___(all)' or resource symb
1.610 raeburn 2850: # @param {string} $parmlev - parameter level (Resource:'full', Map:'map', Course:'general')
1.445 neumanie 2851: sub mapmenu {
1.610 raeburn 2852: my ($r,$allmaps,$pschp,$maptitles,$symbp,$parmlev)=@_;
1.468 amueller 2853: my %allmaps_inverted = reverse %$allmaps;
1.461 neumanie 2854: my $navmap = Apache::lonnavmaps::navmap->new();
2855: my $tree=[];
2856: my $treeinfo={};
2857: if (defined($navmap)) {
1.499 raeburn 2858: my $it=$navmap->getIterator(undef,undef,undef,1,1,undef);
1.461 neumanie 2859: my $curRes;
2860: my $depth = 0;
1.468 amueller 2861: my %parent = ();
2862: my $startcount = 5;
2863: my $lastcontainer = $startcount;
2864: # preparing what is to show ...
1.461 neumanie 2865: while ($curRes = $it->next()) {
2866: if ($curRes == $it->BEGIN_MAP()) {
2867: $depth++;
1.468 amueller 2868: $parent{$depth}= $lastcontainer;
1.461 neumanie 2869: }
2870: if ($curRes == $it->END_MAP()) {
2871: $depth--;
1.468 amueller 2872: $lastcontainer = $parent{$depth};
1.461 neumanie 2873: }
2874: if (ref($curRes)) {
1.468 amueller 2875: my $symb = $curRes->symb();
2876: my $ressymb = $symb;
1.461 neumanie 2877: if (($curRes->is_sequence()) || ($curRes->is_page())) {
2878: my $type = 'sequence';
2879: if ($curRes->is_page()) {
2880: $type = 'page';
2881: }
2882: my $id= $curRes->id();
1.468 amueller 2883: my $srcf = $curRes->src();
2884: my $resource_name = &Apache::lonnet::gettitle($srcf);
2885: if(!exists($treeinfo->{$id})) {
2886: push(@$tree,$id);
1.473 amueller 2887: my $enclosing_map_folder = &Apache::lonnet::declutter($curRes->enclosing_map_src());
1.468 amueller 2888: $treeinfo->{$id} = {
1.461 neumanie 2889: depth => $depth,
2890: type => $type,
1.468 amueller 2891: name => $resource_name,
2892: enclosing_map_folder => $enclosing_map_folder,
1.461 neumanie 2893: };
1.462 neumanie 2894: }
1.461 neumanie 2895: }
2896: }
2897: }
1.462 neumanie 2898: }
1.473 amueller 2899: # Show it ...
1.610 raeburn 2900: my $rowattr = ' id="mapmenu"';
2901: if ($parmlev eq 'general') {
2902: $rowattr .= ' style="display:none"';
2903: }
2904: $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Enclosing Map or Folder'),'','',$rowattr));
1.461 neumanie 2905: if ((ref($tree) eq 'ARRAY') && (ref($treeinfo) eq 'HASH')) {
2906: my $icon = '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" />';
1.497 bisitz 2907: my $whitespace =
2908: '<img src="'
2909: .&Apache::loncommon::lonhttpdurl('/adm/lonIcons/whitespace_21.gif')
2910: .'" alt="" />';
2911:
1.498 bisitz 2912: # Info about selectable folders/maps
2913: $r->print(
2914: '<div class="LC_info">'
1.508 www 2915: .&mt('You can only select maps and folders which have modifiable settings.')
2916: .' '.&Apache::loncommon::help_open_topic('Parameter_Set_Folder')
1.498 bisitz 2917: .'</div>'
2918: );
2919:
1.536 raeburn 2920: $r->print(&Apache::loncommon::start_scrollbox('700px','680px','400px','mapmenuscroll'));
1.523 raeburn 2921: $r->print(&Apache::loncommon::start_data_table(undef,'mapmenuinner'));
1.497 bisitz 2922:
1.498 bisitz 2923: # Display row: "All Maps or Folders"
2924: $r->print(
1.523 raeburn 2925: &Apache::loncommon::start_data_table_row(undef,'picklevel')
1.498 bisitz 2926: .'<td>'
2927: .'<label>'
2928: .'<input type="radio" name="pschp"'
1.497 bisitz 2929: );
2930: $r->print(' checked="checked"') if ($pschp eq 'all' || !$pschp);
1.498 bisitz 2931: $r->print(
2932: ' value="all" /> '.$icon.' '
2933: .&mt('All Maps or Folders')
2934: .'</label>'
2935: .'<hr /></td>'
2936: .&Apache::loncommon::end_data_table_row()
1.463 bisitz 2937: );
1.497 bisitz 2938:
1.532 raeburn 2939: # Display row: "Main Content"
1.468 amueller 2940: if (exists($$allmaps{1})) {
1.498 bisitz 2941: $r->print(
2942: &Apache::loncommon::start_data_table_row()
2943: .'<td>'
2944: .'<label>'
2945: .'<input type="radio" name="pschp" value="1"'
1.468 amueller 2946: );
1.497 bisitz 2947: $r->print(' checked="checked"') if ($pschp eq '1');
1.498 bisitz 2948: $r->print(
2949: '/> '.$icon.' '
2950: .$$maptitles{1}
2951: .($$allmaps{1} !~/^uploaded/?' ['.$$allmaps{1}.']':'')
2952: .'</label>'
2953: .'</td>'
2954: .&Apache::loncommon::end_data_table_row()
1.468 amueller 2955: );
2956: }
1.497 bisitz 2957:
2958: # Display rows for all course maps and folders
1.468 amueller 2959: foreach my $id (@{$tree}) {
2960: my ($mapid,$resid)=split(/\./,$id);
1.464 bisitz 2961: # Indentation
1.468 amueller 2962: my $depth = $treeinfo->{$id}->{'depth'};
1.464 bisitz 2963: my $indent;
2964: for (my $i = 0; $i < $depth; $i++) {
2965: $indent.= $whitespace;
2966: }
1.461 neumanie 2967: $icon = '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" />';
1.468 amueller 2968: if ($treeinfo->{$id}->{'type'} eq 'page') {
1.461 neumanie 2969: $icon = '<img src="/adm/lonIcons/navmap.page.open.gif" alt="" />';
2970: }
1.468 amueller 2971: my $symb_name = $$symbp{$id};
2972: my ($front, $tail) = split (/___${resid}___/, $symb_name);
2973: $symb_name = $tail;
1.498 bisitz 2974: $r->print(
2975: &Apache::loncommon::start_data_table_row()
2976: .'<td>'
2977: .'<label>'
1.463 bisitz 2978: );
1.498 bisitz 2979: # Only offer radio button for folders/maps which can be parameterized
2980: if ($allmaps_inverted{$symb_name}) {
2981: $r->print(
2982: '<input type ="radio" name="pschp"'
2983: .' value="'.$allmaps_inverted{$symb_name}.'"'
2984: );
2985: $r->print(' checked="checked"') if ($allmaps_inverted{$symb_name} eq $pschp);
2986: $r->print('/>');
2987: } else {
2988: $r->print($whitespace);
1.461 neumanie 2989: }
1.498 bisitz 2990: $r->print(
2991: $indent.$icon.' '
2992: .$treeinfo->{$id}->{name}
2993: .($$allmaps{$mapid}!~/^uploaded/?' ['.$$allmaps{$mapid}.']':'')
2994: .'</label>'
2995: .'</td>'
2996: .&Apache::loncommon::end_data_table_row()
1.463 bisitz 2997: );
1.461 neumanie 2998: }
1.497 bisitz 2999:
1.523 raeburn 3000: $r->print(&Apache::loncommon::end_data_table().
3001: '<br style="line-height:2px;" />'.
3002: &Apache::loncommon::end_scrollbox());
1.209 www 3003: }
3004: }
3005:
1.563 damieng 3006: # Prints HTML to select the parameter level (resource, map/folder or course).
3007: # Used by table and overview modes.
3008: #
3009: # @param {Apache2::RequestRec} $r - the Apache request
3010: # @param {hash reference} $alllevs - all parameter levels, hash English title -> value
3011: # @param {string} $parmlev - selected level value (full|map|general), or ''
1.209 www 3012: sub levelmenu {
1.446 bisitz 3013: my ($r,$alllevs,$parmlev)=@_;
3014:
1.548 raeburn 3015: $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parameter Level').
3016: &Apache::loncommon::help_open_topic('Course_Parameter_Levels')));
1.474 amueller 3017: $r->print('<select id="parmlev" name="parmlev" onchange="showHide_courseContent()">');
1.548 raeburn 3018: foreach my $lev (reverse(sort(keys(%{$alllevs})))) {
3019: $r->print('<option value="'.$$alllevs{$lev}.'"');
3020: if ($parmlev eq $$alllevs{$lev}) {
3021: $r->print(' selected="selected"');
3022: }
3023: $r->print('>'.&mt($lev).'</option>');
1.208 www 3024: }
1.446 bisitz 3025: $r->print("</select>");
1.208 www 3026: }
3027:
1.211 www 3028:
1.563 damieng 3029: # Returns HTML to select a section (with a select HTML element).
3030: # Used by overview mode.
3031: #
3032: # @param {array reference} $selectedsections - list of selected section ids
3033: # @returns {string}
1.211 www 3034: sub sectionmenu {
1.553 raeburn 3035: my ($selectedsections)=@_;
1.300 albertel 3036: my %sectionhash = &Apache::loncommon::get_sections();
1.553 raeburn 3037: return '' if (!%sectionhash);
1.300 albertel 3038:
1.552 raeburn 3039: my (@possibles,$disabled);
3040: if ($env{'request.course.sec'} ne '') {
3041: @possibles = ($env{'request.course.sec'});
3042: $selectedsections = [$env{'request.course.sec'}];
3043: $disabled = ' disabled="disabled"';
3044: } else {
3045: @possibles = ('all',sort(keys(%sectionhash)));
3046: }
1.553 raeburn 3047: my $output = '<select name="Section" multiple="multiple" size="8"'.$disabled.'>';
1.552 raeburn 3048: foreach my $s (@possibles) {
1.553 raeburn 3049: $output .= ' <option value="'.$s.'"';
3050: if ((@{$selectedsections}) && (grep(/^\Q$s\E$/,@{$selectedsections}))) {
3051: $output .= ' selected="selected"';
1.473 amueller 3052: }
1.553 raeburn 3053: $output .= '>'."$s</option>\n";
1.300 albertel 3054: }
1.553 raeburn 3055: $output .= "</select>\n";
3056: return $output;
1.269 raeburn 3057: }
3058:
1.563 damieng 3059: # Returns HTML to select a group (with a select HTML element).
3060: # Used by overview mode.
3061: #
3062: # @param {array reference} $selectedgroups - list of selected group names
3063: # @returns {string}
1.269 raeburn 3064: sub groupmenu {
1.553 raeburn 3065: my ($selectedgroups)=@_;
3066: my %grouphash;
3067: if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
3068: %grouphash = &Apache::longroup::coursegroups();
3069: } elsif ($env{'request.course.groups'} ne '') {
1.585 raeburn 3070: map { $grouphash{$_} = 1; } split(/:/,$env{'request.course.groups'});
1.553 raeburn 3071: }
3072: return '' if (!%grouphash);
1.299 albertel 3073:
1.553 raeburn 3074: my $output = '<select name="Group" multiple="multiple" size="8">';
1.299 albertel 3075: foreach my $group (sort(keys(%grouphash))) {
1.553 raeburn 3076: $output .= ' <option value="'.$group.'"';
3077: if ((@{$selectedgroups}) && (grep(/^\Q$group\E$/,\@{$selectedgroups}))) {
3078: $output .= ' selected="selected"';
1.473 amueller 3079: }
1.553 raeburn 3080: $output .= '>'."$group</option>\n";
1.211 www 3081: }
1.553 raeburn 3082: $output .= "</select>\n";
3083: return $output;
1.211 www 3084: }
3085:
1.563 damieng 3086: # Returns an array with the given parameter split by comma.
3087: # Used by assessparms (table mode).
3088: #
3089: # @param {string} $keyp - the string to split
3090: # @returns {Array<string>}
1.210 www 3091: sub keysplit {
3092: my $keyp=shift;
3093: return (split(/\,/,$keyp));
3094: }
3095:
1.563 damieng 3096: # Returns the keys in $name, sorted using $keyorder.
3097: # Parameters are sorted by key, which means they are sorted by part first, then by name.
3098: # Used by assessparms (table mode) for resource level.
3099: #
3100: # @param {hash reference} $name - parameter key -> parameter name
3101: # @param {hash reference} $keyorder - hash parameter key -> appearance rank
3102: # @returns {Array<string>}
1.210 www 3103: sub keysinorder {
3104: my ($name,$keyorder)=@_;
3105: return sort {
1.560 damieng 3106: $$keyorder{$a} <=> $$keyorder{$b};
1.548 raeburn 3107: } (keys(%{$name}));
1.210 www 3108: }
3109:
1.563 damieng 3110: # Returns the keys in $name, sorted using $keyorder to sort parameters by name first, then by part.
3111: # Used by assessparms (table mode) for map and general levels.
3112: #
3113: # @param {hash reference} $name - parameter key -> parameter name
3114: # @param {hash reference} $keyorder - hash parameter key -> appearance rank
3115: # @returns {Array<string>}
1.236 albertel 3116: sub keysinorder_bytype {
3117: my ($name,$keyorder)=@_;
3118: return sort {
1.563 damieng 3119: my $ta=(split('_',$a))[-1]; # parameter name
1.560 damieng 3120: my $tb=(split('_',$b))[-1];
3121: if ($$keyorder{'parameter_0_'.$ta} == $$keyorder{'parameter_0_'.$tb}) {
3122: return ($a cmp $b);
3123: }
3124: $$keyorder{'parameter_0_'.$ta} <=> $$keyorder{'parameter_0_'.$tb};
1.548 raeburn 3125: } (keys(%{$name}));
1.236 albertel 3126: }
3127:
1.563 damieng 3128: # Returns the keys in $name, sorted using $keyorder to sort parameters by name.
3129: # Used by defaultsetter (parameter settings default actions).
3130: #
3131: # @param {hash reference} $name - hash parameter name -> parameter title
3132: # @param {hash reference} $keyorder - hash parameter key -> appearance rank
3133: # @returns {Array<string>}
1.211 www 3134: sub keysindisplayorder {
3135: my ($name,$keyorder)=@_;
3136: return sort {
1.560 damieng 3137: $$keyorder{'parameter_0_'.$a} <=> $$keyorder{'parameter_0_'.$b};
1.548 raeburn 3138: } (keys(%{$name}));
1.211 www 3139: }
3140:
1.563 damieng 3141: # Prints HTML with a choice to sort results by realm or student first.
3142: # Used by overview mode.
3143: #
3144: # @param {Apache2::RequestRec} $r - the Apache request
3145: # @param {string} $sortorder - realmstudent|studentrealm
1.608 raeburn 3146: # @param {string} $context - newoverview|overview
1.214 www 3147: sub sortmenu {
1.608 raeburn 3148: my ($r,$sortorder,$context)=@_;
3149: my %text;
3150: if ($context eq 'newoverview') {
3151: %text = &Apache::lonlocal::texthash (
3152: realmstudent => 'Sort by location in course first, then student (group/section)',
3153: studentrealm => 'Sort by student (group/section) first, then location in course',
3154: );
3155: } else {
3156: %text = &Apache::lonlocal::texthash (
3157: realmstudent => 'Sort by realm first, then student (group/section)',
3158: studentrealm => 'Sort by student (group/section) first, then realm',
3159: );
1.214 www 3160: }
1.608 raeburn 3161: my %sortchecked = (
3162: realmstudent => ' checked="checked"',
3163: studentrealm => '',
3164: );
1.214 www 3165: if ($sortorder eq 'studentrealm') {
1.608 raeburn 3166: $sortchecked{'studentrealm'} = $sortchecked{'realmstudent'};
3167: $sortchecked{'realmstudent'} = '';
3168: }
3169: foreach my $sorttype ('realmstudent','studentrealm') {
3170: $r->print('<br /><label><input type="radio" name="sortorder" value="'.$sorttype.'"'.$sortchecked{$sorttype}.' />'.
3171: $text{$sorttype}.'</label>');
1.214 www 3172: }
3173: }
3174:
1.563 damieng 3175: # Returns a hash parameter key -> order (integer) giving the order for some parameters.
3176: #
3177: # @returns {hash}
1.211 www 3178: sub standardkeyorder {
3179: return ('parameter_0_opendate' => 1,
1.473 amueller 3180: 'parameter_0_duedate' => 2,
3181: 'parameter_0_answerdate' => 3,
3182: 'parameter_0_interval' => 4,
3183: 'parameter_0_weight' => 5,
3184: 'parameter_0_maxtries' => 6,
3185: 'parameter_0_hinttries' => 7,
3186: 'parameter_0_contentopen' => 8,
3187: 'parameter_0_contentclose' => 9,
3188: 'parameter_0_type' => 10,
3189: 'parameter_0_problemstatus' => 11,
3190: 'parameter_0_hiddenresource' => 12,
3191: 'parameter_0_hiddenparts' => 13,
3192: 'parameter_0_display' => 14,
3193: 'parameter_0_ordered' => 15,
3194: 'parameter_0_tol' => 16,
3195: 'parameter_0_sig' => 17,
3196: 'parameter_0_turnoffunit' => 18,
1.521 raeburn 3197: 'parameter_0_discussend' => 19,
3198: 'parameter_0_discusshide' => 20,
3199: 'parameter_0_discussvote' => 21,
1.560 damieng 3200: 'parameter_0_printstartdate' => 22,
3201: 'parameter_0_printenddate' => 23);
1.211 www 3202: }
3203:
1.59 matthew 3204:
1.560 damieng 3205: # Table mode UI.
1.563 damieng 3206: # If nothing is selected, prints HTML forms to select resources, parts, parameters, user, group and section.
3207: # Otherwise, prints the parameter table, with a link to change the selection unless a single resource is selected.
3208: #
3209: # Parameters used from the request:
3210: # action - handler action (see handler), usermenu is checking for value 'settable'
3211: # cgroup - selected group
3212: # command - 'set': direct access to table mode for a resource
3213: # csec - selected section
3214: # dis - set when the "Update Display" button was used, used only to discard command 'set'
3215: # hideparmsel - can be 'hidden' to hide the parameter selection div initially and display the "Change Parameter Selection" link instead (which displays the div)
3216: # id - student/employee ID
3217: # parmlev - selected level (full|map|general)
3218: # part - selected part (unused ?)
3219: # pres_marker - &&&-separated parameter identifiers, "resource id&part_parameter name&level"
3220: # pres_type - &&&-separated parameter types
3221: # pres_value - &&&-separated parameter values
3222: # prevvisit - '1' if the user has submitted the form before
3223: # pscat (multiple values) - selected parameter names
1.566 damieng 3224: # pschp - selected map pc, or 'all'
1.563 damieng 3225: # psprt (multiple values) - list of selected parameter parts
3226: # filter - part of or whole parameter name, to be filtered out when parameters are displayed (unused ?)
3227: # recent_* (* = parameter type) - recent values entered by the user for parameter types
3228: # symb - resource symb (when a single resource is selected)
3229: # udom - selected user domain
3230: # uname - selected user name
3231: # url - used only with command 'set', the resource url
3232: #
3233: # @param {Apache2::RequestRec} $r - the Apache request
1.568 raeburn 3234: # @param $parm_permission - ref to hash of permissions
3235: # if $parm_permission->{'edit'} is true, editing is allowed.
1.30 www 3236: sub assessparms {
1.1 www 3237:
1.568 raeburn 3238: my ($r,$parm_permission) = @_;
1.201 www 3239:
1.512 foxr 3240:
3241: # -------------------------------------------------------- Variable declaration
1.566 damieng 3242: my @ids=(); # resource and map ids
3243: my %symbp=(); # hash map pc or resource/map id -> map src.'___(all)' or resource symb
3244: my %mapp=(); # hash map pc or resource/map id -> enclosing map src
3245: my %typep=(); # hash resource/map id -> resource type (file extension)
3246: my %keyp=(); # hash resource/map id -> comma-separated list of parameter keys
3247: my %uris=(); # hash resource/map id -> resource src
3248: my %maptitles=(); # hash map pc or src -> map title
3249: my %allmaps=(); # hash map pc -> map src
1.582 raeburn 3250: my %allmaps_inverted=(); # hash map src -> map pc
1.563 damieng 3251: my %alllevs=(); # hash English level title -> value
3252:
3253: my $uname; # selected user name
3254: my $udom; # selected user domain
3255: my $uhome; # server with the user's files, or 'no_host'
3256: my $csec; # selected section name
3257: my $cgroup; # selected group name
3258: my @usersgroups = (); # list of the user groups
1.582 raeburn 3259: my $numreclinks = 0;
1.446 bisitz 3260:
1.190 albertel 3261: my $coursename=$env{'course.'.$env{'request.course.id'}.'.description'};
1.187 www 3262:
1.57 albertel 3263: $alllevs{'Resource Level'}='full';
1.215 www 3264: $alllevs{'Map/Folder Level'}='map';
1.57 albertel 3265: $alllevs{'Course Level'}='general';
3266:
1.563 damieng 3267: my %allparms; # hash parameter name -> parameter title
3268: my %allparts; # hash parameter part -> part title
1.512 foxr 3269: # ------------------------------------------------------------------------------
3270:
1.210 www 3271: #
3272: # Order in which these parameters will be displayed
3273: #
1.211 www 3274: my %keyorder=&standardkeyorder();
3275:
1.512 foxr 3276: # @ids=();
3277: # %symbp=(); # These seem defined above already.
3278: # %typep=();
1.43 albertel 3279:
3280: my $message='';
3281:
1.190 albertel 3282: $csec=$env{'form.csec'};
1.552 raeburn 3283: if ($env{'request.course.sec'} ne '') {
3284: $csec = $env{'request.course.sec'};
3285: }
3286:
1.553 raeburn 3287: # Check group privs.
1.269 raeburn 3288: $cgroup=$env{'form.cgroup'};
1.553 raeburn 3289: my $noeditgrp;
3290: if ($cgroup ne '') {
3291: unless (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
3292: if (($env{'request.course.groups'} eq '') ||
1.585 raeburn 3293: (!grep(/^\Q$cgroup\E$/,split(/:/,$env{'request.course.groups'})))) {
1.553 raeburn 3294: $noeditgrp = 1;
3295: }
3296: }
3297: }
1.188 www 3298:
1.190 albertel 3299: if ($udom=$env{'form.udom'}) {
3300: } elsif ($udom=$env{'request.role.domain'}) {
3301: } elsif ($udom=$env{'user.domain'}) {
1.172 albertel 3302: } else {
1.473 amueller 3303: $udom=$r->dir_config('lonDefDomain');
1.172 albertel 3304: }
1.468 amueller 3305:
1.43 albertel 3306:
1.134 albertel 3307: my @pscat=&Apache::loncommon::get_env_multiple('form.pscat');
1.190 albertel 3308: my $pschp=$env{'form.pschp'};
1.506 www 3309:
3310:
1.134 albertel 3311: my @psprt=&Apache::loncommon::get_env_multiple('form.psprt');
1.516 www 3312: if (!@psprt) { $psprt[0]='all'; }
1.506 www 3313: if (($env{'form.part'}) && ($psprt[0] ne 'all')) { $psprt[0]=$env{'form.part'}; }
1.57 albertel 3314:
1.43 albertel 3315: my $pssymb='';
1.57 albertel 3316: my $parmlev='';
1.446 bisitz 3317:
1.190 albertel 3318: unless ($env{'form.parmlev'}) {
1.57 albertel 3319: $parmlev = 'map';
3320: } else {
1.190 albertel 3321: $parmlev = $env{'form.parmlev'};
1.57 albertel 3322: }
1.26 www 3323:
1.29 www 3324: # ----------------------------------------------- Was this started from grades?
3325:
1.560 damieng 3326: if (($env{'form.command'} eq 'set') && ($env{'form.url'}) &&
3327: (!$env{'form.dis'})) {
1.473 amueller 3328: my $url=$env{'form.url'};
3329: $url=~s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
3330: $pssymb=&Apache::lonnet::symbread($url);
3331: if (!@pscat) { @pscat=('all'); }
3332: $pschp='';
1.57 albertel 3333: $parmlev = 'full';
1.190 albertel 3334: } elsif ($env{'form.symb'}) {
1.473 amueller 3335: $pssymb=$env{'form.symb'};
3336: if (!@pscat) { @pscat=('all'); }
3337: $pschp='';
1.57 albertel 3338: $parmlev = 'full';
1.43 albertel 3339: } else {
1.473 amueller 3340: $env{'form.url'}='';
1.43 albertel 3341: }
3342:
1.190 albertel 3343: my $id=$env{'form.id'};
1.43 albertel 3344: if (($id) && ($udom)) {
1.555 raeburn 3345: $uname=(&Apache::lonnet::idget($udom,[$id],'ids'))[1];
1.473 amueller 3346: if ($uname) {
3347: $id='';
3348: } else {
3349: $message=
1.540 bisitz 3350: '<p class="LC_warning">'.
3351: &mt('Unknown ID [_1] at domain [_2]',
3352: "'".$id."'","'".$udom."'").
3353: '</p>';
1.473 amueller 3354: }
1.43 albertel 3355: } else {
1.473 amueller 3356: $uname=$env{'form.uname'};
1.43 albertel 3357: }
3358: unless ($udom) { $uname=''; }
3359: $uhome='';
3360: if ($uname) {
1.473 amueller 3361: $uhome=&Apache::lonnet::homeserver($uname,$udom);
1.43 albertel 3362: if ($uhome eq 'no_host') {
1.473 amueller 3363: $message=
1.540 bisitz 3364: '<p class="LC_warning">'.
3365: &mt('Unknown user [_1] at domain [_2]',
3366: "'".$uname."'","'".$udom."'").
3367: '</p>';
1.473 amueller 3368: $uname='';
1.12 www 3369: } else {
1.473 amueller 3370: $csec=&Apache::lonnet::getsection($udom,$uname,
3371: $env{'request.course.id'});
3372: if ($csec eq '-1') {
1.596 raeburn 3373: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
3374: if ($env{'form.userroles'} eq 'any') {
3375: if (($env{'user.name'} eq $uname) && ($env{'user.domain'} eq $udom)) {
3376: $csec = $env{'request.course.sec'};
3377: $message = '<span class="LC_info">';
3378: if ($crstype eq 'Community') {
3379: $message .= &mt('User [_1] at domain [_2] has a non-member role in this community',
3380: $uname,$udom);
3381: } else {
3382: $message .= &mt('User [_1] at domain [_2] has a non-student role in this course',
3383: $uname,$udom);
3384: }
3385: $message .= '</span>';
3386: } else {
3387: my @possroles = ('in','ep','ta','cr');
3388: if ($crstype eq 'Community') {
3389: unshift(@possroles,'co');
3390: } else {
3391: unshift(@possroles,'cc');
3392: }
3393: my %not_student_roles =
3394: &Apache::lonnet::get_my_roles($uname,$udom,'userroles',['active'],
3395: \@possroles,[$udom],1,1);
3396: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
3397: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
3398: my %sections_by_role;
3399: foreach my $role (keys(%not_student_roles)) {
3400: if ($role =~ /^\Q$cnum:$cdom:\E([^:]+):(|[^:]+)$/) {
3401: my ($rolename,$sec) = ($1,$2);
3402: if ($rolename =~ m{^cr/}) {
3403: $rolename = 'cr';
3404: }
3405: push(@{$sections_by_role{$rolename}},$sec);
3406: }
3407: }
3408: my $numroles = scalar(keys(%sections_by_role));
3409: if ($numroles) {
3410: foreach my $role (@possroles) {
3411: if (ref($sections_by_role{$role}) eq 'ARRAY') {
3412: my @secs = sort { $a <=> $b } @{$sections_by_role{$role}};
3413: $csec = $secs[0];
3414: last;
3415: }
3416: }
3417: }
3418: if ($csec eq '-1') {
3419: $message = '<span class="LC_warning">';
3420: if ($crstype eq 'Community') {
3421: $message .= &mt('User [_1] at domain [_2] does not have a role in this community',
3422: $uname,$udom);
3423: } else {
3424: $message .= &mt('User [_1] at domain [_2] does not have a role in this course',
3425: $uname,$udom);
3426: }
3427: $message .= '</span>';
3428: $uname='';
3429: if ($env{'request.course.sec'} ne '') {
3430: $csec=$env{'request.course.sec'};
3431: } else {
3432: $csec=$env{'form.csec'};
3433: }
3434: $cgroup=$env{'form.cgroup'};
3435: } else {
3436: $message = '<span class="LC_info">';
3437: if ($crstype eq 'Community') {
3438: $message .= &mt('User [_1] at domain [_2] has a non-member role in this community',
3439: $uname,$udom);
3440: } else {
3441: $message .= &mt('User [_1] at domain [_2] has a non-student role in this course',
3442: $uname,$udom);
3443: }
3444: $message .= '</span>';
3445: }
3446: }
1.594 raeburn 3447: } else {
1.596 raeburn 3448: $message = '<span class="LC_warning">';
3449: if ($crstype eq 'Community') {
3450: $message .= &mt('User [_1] at domain [_2] does not have a member role in this community',
3451: $uname,$udom);
3452: } else {
3453: $message .= &mt('User [_1] at domain [_2] does not have a student role in this course',
3454: $uname,$udom);
3455: }
3456: $message .= '</span>';
3457: $uname='';
3458: if ($env{'request.course.sec'} ne '') {
3459: $csec=$env{'request.course.sec'};
3460: } else {
3461: $csec=$env{'form.csec'};
3462: }
3463: $cgroup=$env{'form.cgroup'};
1.594 raeburn 3464: }
3465: } elsif ($env{'request.course.sec'} ne '') {
3466: if ($csec ne $env{'request.course.sec'}) {
1.596 raeburn 3467: $message='<span class="LC_warning">'.
1.594 raeburn 3468: &mt("User '[_1]' at domain '[_2]' not in section '[_3]'",
3469: $uname,$udom,$env{'request.course.sec'}).
3470: '</span>';
3471: $uname='';
3472: $csec=$env{'request.course.sec'};
3473: }
1.269 raeburn 3474: $cgroup=$env{'form.cgroup'};
1.596 raeburn 3475: }
3476: if ($uname ne '') {
1.473 amueller 3477: my %name=&Apache::lonnet::userenvironment($udom,$uname,
3478: ('firstname','middlename','lastname','generation','id'));
1.596 raeburn 3479: $message .= "\n<p>\n".&mt('Full Name').': '
3480: .$name{'firstname'}.' '.$name{'middlename'}.' '
3481: .$name{'lastname'}.' '.$name{'generation'}
3482: ."<br />\n".&mt('Student/Employee ID').': '.$name{'id'}.'</p>';
3483: @usersgroups = &Apache::lonnet::get_users_groups(
3484: $udom,$uname,$env{'request.course.id'});
3485: if (@usersgroups > 0) {
3486: unless (grep(/^\Q$cgroup\E$/,@usersgroups)) {
3487: $cgroup = $usersgroups[0];
3488: }
3489: } else {
3490: $cgroup = '';
1.297 raeburn 3491: }
1.269 raeburn 3492: }
1.12 www 3493: }
1.43 albertel 3494: }
1.2 www 3495:
1.43 albertel 3496: unless ($csec) { $csec=''; }
1.269 raeburn 3497: unless ($cgroup) { $cgroup=''; }
1.12 www 3498:
1.14 www 3499: # --------------------------------------------------------- Get all assessments
1.446 bisitz 3500: &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
1.473 amueller 3501: \%mapp, \%symbp,\%maptitles,\%uris,
1.603 raeburn 3502: \%keyorder,undef,$pssymb);
1.63 bowersj2 3503:
1.582 raeburn 3504: %allmaps_inverted = reverse(%allmaps);
3505:
1.57 albertel 3506: $mapp{'0.0'} = '';
3507: $symbp{'0.0'} = '';
1.99 albertel 3508:
1.14 www 3509: # ---------------------------------------------------------- Anything to store?
1.568 raeburn 3510: if ($env{'form.pres_marker'} && $parm_permission->{'edit'}) {
1.205 www 3511: my @markers=split(/\&\&\&/,$env{'form.pres_marker'});
3512: my @values=split(/\&\&\&/,$env{'form.pres_value'});
3513: my @types=split(/\&\&\&/,$env{'form.pres_type'});
1.500 raeburn 3514: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
3515: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.504 raeburn 3516: my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};
3517: my ($got_chostname,$chostname,$cmajor,$cminor);
3518: my $totalstored = 0;
1.605 raeburn 3519: my $totalskippeduser = 0;
1.546 raeburn 3520: my $now = time;
1.473 amueller 3521: for (my $i=0;$i<=$#markers;$i++) {
1.557 raeburn 3522: my ($needsrelease,$needsnewer,$name,$namematch);
1.556 raeburn 3523: if (($env{'request.course.sec'} ne '') && ($markers[$i] =~ /\&(9|10|11|12)$/)) {
1.552 raeburn 3524: next if ($csec ne $env{'request.course.sec'});
3525: }
1.556 raeburn 3526: if ($markers[$i] =~ /\&(8|7|6|5)$/) {
1.553 raeburn 3527: next if ($noeditgrp);
1.605 raeburn 3528: } elsif ($markers[$i] =~ /\&(4|3|2|1)$/) {
3529: if ($uname eq '') {
3530: $totalskippeduser ++;
3531: next;
3532: }
1.557 raeburn 3533: }
3534: if ($markers[$i] =~ /\&(17|11|7|3)$/) {
3535: $namematch = 'maplevelrecurse';
3536: }
1.556 raeburn 3537: if ($markers[$i] =~ /^[\d.]+\&0_availablestudent\&(1|2|3|4)$/) {
1.437 raeburn 3538: my (@ok_slots,@fail_slots,@del_slots);
3539: my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
3540: my ($level,@all) =
3541: &parmval_by_symb('0.availablestudent',$pssymb,'',$uname,$udom,
3542: $csec,$cgroup,$courseopt);
3543: foreach my $slot_name (split(/:/,$values[$i])) {
3544: next if ($slot_name eq '');
3545: if (&update_slots($slot_name,$cdom,$cnum,$pssymb,$uname,$udom) eq 'ok') {
3546: push(@ok_slots,$slot_name);
3547:
3548: } else {
3549: push(@fail_slots,$slot_name);
3550: }
3551: }
3552: if (@ok_slots) {
3553: $values[$i] = join(':',@ok_slots);
3554: } else {
3555: $values[$i] = '';
3556: }
3557: if ($all[$level] ne '') {
3558: my @existing = split(/:/,$all[$level]);
3559: foreach my $slot_name (@existing) {
3560: if (!grep(/^\Q$slot_name\E$/,split(/:/,$values[$i]))) {
3561: if (&delete_slots($slot_name,$cdom,$cnum,$uname,$udom,$pssymb) eq 'ok') {
3562: push(@del_slots,$slot_name);
3563: }
3564: }
3565: }
3566: }
1.554 raeburn 3567: } elsif ($markers[$i] =~ /_(type|lenient|retrypartial|discussvote|examcode|printstartdate|printenddate|acc|interval)\&\d+$/) {
1.514 raeburn 3568: $name = $1;
1.533 raeburn 3569: my $val = $values[$i];
1.549 raeburn 3570: my $valmatch = '';
1.533 raeburn 3571: if ($name eq 'examcode') {
1.544 raeburn 3572: if (&Apache::lonnet::validCODE($values[$i])) {
3573: $val = 'valid';
3574: }
1.546 raeburn 3575: } elsif ($name eq 'printstartdate') {
3576: if ($val =~ /^\d+$/) {
3577: if ($val > $now) {
3578: $val = 'future';
3579: }
3580: }
3581: } elsif ($name eq 'printenddate') {
3582: if ($val =~ /^\d+$/) {
3583: if ($val < $now) {
3584: $val = 'past';
3585: }
3586: }
1.549 raeburn 3587: } elsif (($name eq 'lenient') || ($name eq 'acc')) {
3588: my $stringtype = &get_stringtype($name);
3589: my $stringmatch = &standard_string_matches($stringtype);
3590: if (ref($stringmatch) eq 'ARRAY') {
3591: foreach my $item (@{$stringmatch}) {
3592: if (ref($item) eq 'ARRAY') {
3593: my ($regexpname,$pattern) = @{$item};
3594: if ($pattern ne '') {
3595: if ($val =~ /$pattern/) {
3596: $valmatch = $regexpname;
3597: $val = '';
3598: last;
3599: }
3600: }
3601: }
3602: }
3603: }
1.554 raeburn 3604: } elsif ($name eq 'interval') {
3605: my $intervaltype = &get_intervaltype($name);
3606: my $intervalmatch = &standard_interval_matches($intervaltype);
3607: if (ref($intervalmatch) eq 'ARRAY') {
3608: foreach my $item (@{$intervalmatch}) {
3609: if (ref($item) eq 'ARRAY') {
3610: my ($regexpname,$pattern) = @{$item};
3611: if ($pattern ne '') {
3612: if ($val =~ /$pattern/) {
3613: $valmatch = $regexpname;
3614: $val = '';
3615: last;
3616: }
3617: }
3618: }
3619: }
3620: }
1.533 raeburn 3621: }
1.504 raeburn 3622: $needsrelease =
1.557 raeburn 3623: $Apache::lonnet::needsrelease{"parameter:$name:$val:$valmatch:"};
1.504 raeburn 3624: if ($needsrelease) {
1.505 raeburn 3625: unless ($got_chostname) {
1.514 raeburn 3626: ($chostname,$cmajor,$cminor) = ¶meter_release_vars();
1.504 raeburn 3627: $got_chostname = 1;
1.546 raeburn 3628: }
1.557 raeburn 3629: $needsnewer = ¶meter_releasecheck($name,$val,$valmatch,undef,
1.514 raeburn 3630: $needsrelease,
3631: $cmajor,$cminor);
1.500 raeburn 3632: }
1.437 raeburn 3633: }
1.504 raeburn 3634: if ($needsnewer) {
1.557 raeburn 3635: undef($namematch);
3636: } else {
3637: my $currneeded;
3638: if ($needsrelease) {
3639: $currneeded = $needsrelease;
3640: }
3641: if ($namematch) {
3642: $needsrelease =
3643: $Apache::lonnet::needsrelease{"parameter::::$namematch"};
3644: if (($needsrelease) && (($currneeded eq '') || ($needsrelease < $currneeded))) {
3645: unless ($got_chostname) {
3646: ($chostname,$cmajor,$cminor) = ¶meter_release_vars();
3647: $got_chostname = 1;
3648: }
3649: $needsnewer = ¶meter_releasecheck(undef,undef,undef,$namematch,
3650: $needsrelease,
3651: $cmajor,$cminor);
3652: } else {
3653: undef($namematch);
3654: }
3655: }
3656: }
3657: if ($needsnewer) {
3658: $message .= &oldversion_warning($name,$namematch,$values[$i],$chostname,$cmajor,
1.504 raeburn 3659: $cminor,$needsrelease);
3660: } else {
3661: $message.=&storeparm(split(/\&/,$markers[$i]),
3662: $values[$i],
3663: $types[$i],
3664: $uname,$udom,$csec,$cgroup);
3665: $totalstored ++;
3666: }
1.473 amueller 3667: }
1.68 www 3668: # ---------------------------------------------------------------- Done storing
1.504 raeburn 3669: if ($totalstored) {
3670: $message.='<p class="LC_warning">'
1.605 raeburn 3671: .&mt('Changes for [quant,_1,parameter] saved.',$totalstored)
3672: .'<br />'
1.504 raeburn 3673: .&mt('Changes can take up to 10 minutes before being active for all students.')
3674: .&Apache::loncommon::help_open_topic('Caching')
3675: .'</p>';
1.605 raeburn 3676: } else {
3677: $message.='<p class="LC_info">'.&mt('No parameter changes saved.').'</p>';
3678: }
3679: if ($totalskippeduser) {
3680: $message .= '<p class="LC_warning">';
3681: if ($uhome eq 'no_host') {
3682: $message .= &mt('Changes for [quant,_1,user-specific parameter] not saved because the username or ID was invalid.',
3683: $totalskippeduser);
3684: } elsif ($env{'form.userroles'} eq 'any') {
3685: $message .= &mt('Changes for [quant,_1,user-specific parameter] not saved because the user does not have a course role.',
3686: $totalskippeduser);
3687: } else {
3688: $message .= &mt('Changes for [quant,_1,user-specific parameter] not saved because the user is not a student.',
3689: $totalskippeduser);
3690: }
3691: $message .= '</p>';
1.504 raeburn 3692: }
1.68 www 3693: }
1.584 raeburn 3694:
1.57 albertel 3695: #----------------------------------------------- if all selected, fill in array
1.563 damieng 3696: if ($pscat[0] eq "all") {
3697: @pscat = (keys(%allparms));
3698: }
3699: if (!@pscat) {
3700: @pscat=('duedate','opendate','answerdate','weight','maxtries','type','problemstatus')
3701: };
3702: if ($psprt[0] eq "all" || !@psprt) {
3703: @psprt = (keys(%allparts));
3704: }
1.2 www 3705: # ------------------------------------------------------------------ Start page
1.63 bowersj2 3706:
1.531 raeburn 3707: my $crstype = &Apache::loncommon::course_type();
3708: &startpage($r,$pssymb,$crstype);
1.57 albertel 3709:
1.548 raeburn 3710: foreach my $item ('tolerance','date_default','date_start','date_end',
1.589 raeburn 3711: 'date_interval','int','float','string','string_lenient',
3712: 'string_examcode','string_deeplink','string_discussvote',
3713: 'string_useslots','string_problemstatus','string_ip',
3714: 'string_questiontype') {
1.473 amueller 3715: $r->print('<input type="hidden" value="'.
1.563 damieng 3716: &HTML::Entities::encode($env{'form.recent_'.$item},'"&<>').
3717: '" name="recent_'.$item.'" />');
1.44 albertel 3718: }
1.446 bisitz 3719:
1.459 bisitz 3720: # ----- Start Parameter Selection
3721:
1.606 raeburn 3722: # Hide parm selection and possibly table?
3723: my ($tablejs,$tabledivsty);
3724: if (((($env{'form.uname'} ne '') || ($env{'form.id'} ne '')) && ($uname eq '')) &&
3725: ($env{'form.dis'}) && ($pssymb eq '')) {
3726: $tablejs = 'document.getElementById('."'parmtable'".').style.display = "";';
3727: $tabledivsty = ' style="display:none"';
3728: }
1.459 bisitz 3729: $r->print(<<ENDPARMSELSCRIPT);
3730: <script type="text/javascript">
3731: // <![CDATA[
3732: function parmsel_show() {
1.562 damieng 3733: document.getElementById('parmsel').style.display = "";
3734: document.getElementById('parmsellink').style.display = "none";
1.606 raeburn 3735: $tablejs
1.459 bisitz 3736: }
3737: // ]]>
3738: </script>
3739: ENDPARMSELSCRIPT
1.474 amueller 3740:
1.445 neumanie 3741: if (!$pssymb) {
1.563 damieng 3742: # No single resource selected, print forms to select things (hidden after first selection)
1.486 www 3743: my $parmselhiddenstyle=' style="display:none"';
3744: if($env{'form.hideparmsel'} eq 'hidden') {
3745: $r->print('<div id="parmsel"'.$parmselhiddenstyle.'>');
3746: } else {
3747: $r->print('<div id="parmsel">');
3748: }
3749:
1.491 bisitz 3750: # Step 1
1.523 raeburn 3751: $r->print(&Apache::lonhtmlcommon::topic_bar(1,&mt('Resource Specification'),'parmstep1'));
3752: $r->print('
1.474 amueller 3753: <script type="text/javascript">
1.523 raeburn 3754: // <![CDATA['.
3755: &showhide_js().'
1.474 amueller 3756: // ]]>
3757: </script>
1.523 raeburn 3758: ');
3759: $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel'));
1.209 www 3760: &levelmenu($r,\%alllevs,$parmlev);
1.491 bisitz 3761: $r->print(&Apache::lonhtmlcommon::row_closure());
1.610 raeburn 3762: &mapmenu($r,\%allmaps,$pschp,\%maptitles,\%symbp,$parmlev);
1.491 bisitz 3763: $r->print(&Apache::lonhtmlcommon::row_closure());
3764: $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View')));
3765: &partmenu($r,\%allparts,\@psprt);
1.474 amueller 3766: $r->print(&Apache::lonhtmlcommon::row_closure(1));
3767: $r->print(&Apache::lonhtmlcommon::end_pick_box());
1.491 bisitz 3768:
3769: # Step 2
1.523 raeburn 3770: $r->print(&Apache::lonhtmlcommon::topic_bar(2,&mt('Parameter Specification'),'parmstep2'));
1.581 raeburn 3771: &displaymenu($r,\%allparms,\@pscat,\%keyorder,'parmmenuscroll');
1.491 bisitz 3772:
3773: # Step 3
1.523 raeburn 3774: $r->print(&Apache::lonhtmlcommon::topic_bar(3,&mt('User Specification (optional)'),'parmstep3'));
1.486 www 3775: $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.553 raeburn 3776: &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups,$pssymb);
1.486 www 3777: $r->print(&Apache::lonhtmlcommon::row_closure(1));
3778: $r->print(&Apache::lonhtmlcommon::end_pick_box());
1.491 bisitz 3779:
3780: # Update Display Button
1.486 www 3781: $r->print('<p>'
3782: .'<input type="submit" name="dis"'
1.511 www 3783: .' value="'.&mt('Update Display').'" />'
1.486 www 3784: .'<input type="hidden" name="hideparmsel" value="hidden" />'
3785: .'</p>');
3786: $r->print('</div>');
1.491 bisitz 3787:
1.486 www 3788: # Offer link to display parameter selection again
3789: $r->print('<p id="parmsellink"');
3790: if ($env{'form.hideparmsel'} ne 'hidden') {
3791: $r->print($parmselhiddenstyle);
3792: }
3793: $r->print('>'
3794: .'<a href="javascript:parmsel_show()">'
3795: .&mt('Change Parameter Selection')
3796: .'</a>'
3797: .'</p>');
1.44 albertel 3798: } else {
1.478 amueller 3799: # parameter screen for a single resource.
1.486 www 3800: my ($map,$iid,$resource)=&Apache::lonnet::decode_symb($pssymb);
1.473 amueller 3801: my $title = &Apache::lonnet::gettitle($pssymb);
1.501 bisitz 3802: $r->print(&mt('Specific Resource: [_1] ([_2])',
3803: $title,'<span class="LC_filename">'.$resource.'</span>').
1.472 amueller 3804: '<input type="hidden" value="'.$pssymb.'" name="symb" />'.
1.486 www 3805: '<br />');
3806: $r->print(&Apache::lonhtmlcommon::topic_bar('',&mt('Additional Display Specification (optional)')));
3807: $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.553 raeburn 3808: &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups,$pssymb);
1.486 www 3809: $r->print(&Apache::lonhtmlcommon::row_closure(1));
3810: $r->print(&Apache::lonhtmlcommon::end_pick_box());
3811: $r->print('<p>'
1.459 bisitz 3812: .'<input type="submit" name="dis"'
1.511 www 3813: .' value="'.&mt('Update Display').'" />'
1.459 bisitz 3814: .'<input type="hidden" name="hideparmsel" value="hidden" />'
1.486 www 3815: .'</p>');
1.459 bisitz 3816: }
1.478 amueller 3817:
1.486 www 3818: # ----- End Parameter Selection
1.57 albertel 3819:
1.459 bisitz 3820: # Display Messages
3821: $r->print('<div>'.$message.'</div>');
1.210 www 3822:
1.57 albertel 3823:
3824: my @temp_pscat;
3825: map {
3826: my $cat = $_;
3827: push(@temp_pscat, map { $_.'.'.$cat } @psprt);
3828: } @pscat;
3829:
3830: @pscat = @temp_pscat;
3831:
1.548 raeburn 3832:
1.209 www 3833: if (($env{'form.prevvisit'}) || ($pschp) || ($pssymb)) {
1.10 www 3834: # ----------------------------------------------------------------- Start Table
1.57 albertel 3835: my @catmarker=map { tr|.|_|; 'parameter_'.$_; } @pscat;
1.190 albertel 3836: my $csuname=$env{'user.name'};
3837: my $csudom=$env{'user.domain'};
1.568 raeburn 3838: my $readonly = 1;
3839: if ($parm_permission->{'edit'}) {
3840: undef($readonly);
3841: }
1.606 raeburn 3842: $r->print('<div id="parmtable"'.$tabledivsty.'>');
1.57 albertel 3843:
1.203 www 3844: if ($parmlev eq 'full') {
1.506 www 3845: #
3846: # This produces the cascading table output of parameters
3847: #
1.578 raeburn 3848: my $coursespan=$csec?8:5;
3849: my $userspan=3;
1.560 damieng 3850: if ($cgroup ne '') {
1.578 raeburn 3851: $coursespan += 3;
1.560 damieng 3852: }
1.473 amueller 3853:
1.560 damieng 3854: $r->print(&Apache::loncommon::start_data_table());
3855: #
3856: # This produces the headers
3857: #
3858: $r->print('<tr><td colspan="5"></td>');
3859: $r->print('<th colspan="'.($coursespan).'">'.&mt('Any User').'</th>');
3860: if ($uname) {
1.473 amueller 3861: if (@usersgroups > 1) {
1.560 damieng 3862: $userspan ++;
3863: }
3864: $r->print('<th colspan="'.$userspan.'" rowspan="2">');
3865: $r->print(&mt('User [_1] at Domain [_2]',"'".$uname."'","'".$udom."'").'</th>');
3866: }
3867: my %lt=&Apache::lonlocal::texthash(
1.473 amueller 3868: 'pie' => "Parameter in Effect",
3869: 'csv' => "Current Session Value",
1.472 amueller 3870: 'rl' => "Resource Level",
1.473 amueller 3871: 'ic' => 'in Course',
3872: 'aut' => "Assessment URL and Title",
3873: 'type' => 'Type',
3874: 'emof' => "Enclosing Map or Folder",
3875: 'part' => 'Part',
1.472 amueller 3876: 'pn' => 'Parameter Name',
1.473 amueller 3877: 'def' => 'default',
3878: 'femof' => 'from Enclosing Map or Folder',
3879: 'gen' => 'general',
3880: 'foremf' => 'for Enclosing Map or Folder',
3881: 'fr' => 'for Resource'
3882: );
1.560 damieng 3883: $r->print(<<ENDTABLETWO);
1.419 bisitz 3884: <th rowspan="3">$lt{'pie'}</th>
1.501 bisitz 3885: <th rowspan="3">$lt{'csv'}<br />($csuname:$csudom)</th>
1.578 raeburn 3886: </tr><tr><td colspan="5"></td><th colspan="2">$lt{'ic'}</th><th colspan="2">$lt{'rl'}</th>
1.419 bisitz 3887: <th colspan="1">$lt{'ic'}</th>
1.182 albertel 3888:
1.10 www 3889: ENDTABLETWO
1.560 damieng 3890: if ($csec) {
1.578 raeburn 3891: $r->print('<th colspan="3">'.
1.560 damieng 3892: &mt("in Section")." $csec</th>");
3893: }
3894: if ($cgroup) {
1.578 raeburn 3895: $r->print('<th colspan="3">'.
1.472 amueller 3896: &mt("in Group")." $cgroup</th>");
1.560 damieng 3897: }
3898: $r->print(<<ENDTABLEHEADFOUR);
1.133 www 3899: </tr><tr><th>$lt{'aut'}</th><th>$lt{'type'}</th>
3900: <th>$lt{'emof'}</th><th>$lt{'part'}</th><th>$lt{'pn'}</th>
1.578 raeburn 3901: <th>$lt{'gen'}</th><th>$lt{'foremf'}</th>
1.192 albertel 3902: <th>$lt{'def'}</th><th>$lt{'femof'}</th><th>$lt{'fr'}</th>
1.10 www 3903: ENDTABLEHEADFOUR
1.57 albertel 3904:
1.560 damieng 3905: if ($csec) {
1.578 raeburn 3906: $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'foremf'}.'</th><th>'.$lt{'fr'}.'</th>');
1.560 damieng 3907: }
1.473 amueller 3908:
1.560 damieng 3909: if ($cgroup) {
1.578 raeburn 3910: $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'foremf'}.'</th><th>'.$lt{'fr'}.'</th>');
1.560 damieng 3911: }
3912:
3913: if ($uname) {
3914: if (@usersgroups > 1) {
3915: $r->print('<th>'.&mt('Control by other group?').'</th>');
3916: }
1.578 raeburn 3917: $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'foremf'}.'</th><th>'.$lt{'fr'}.'</th>');
1.560 damieng 3918: }
3919:
3920: $r->print('</tr>');
1.506 www 3921: #
3922: # Done with the headers
3923: #
1.560 damieng 3924: my $defbgone='';
3925: my $defbgtwo='';
3926: my $defbgthree = '';
1.57 albertel 3927:
1.560 damieng 3928: foreach my $rid (@ids) {
1.57 albertel 3929:
3930: my ($inmapid)=($rid=~/\.(\d+)$/);
1.446 bisitz 3931: if ((!$pssymb &&
1.560 damieng 3932: (($pschp eq 'all') || ($allmaps{$pschp} eq $mapp{$rid})))
3933: ||
3934: ($pssymb && $pssymb eq $symbp{$rid})) {
1.4 www 3935: # ------------------------------------------------------ Entry for one resource
1.473 amueller 3936: if ($defbgone eq '#E0E099') {
3937: $defbgone='#E0E0DD';
1.57 albertel 3938: } else {
1.419 bisitz 3939: $defbgone='#E0E099';
1.57 albertel 3940: }
1.419 bisitz 3941: if ($defbgtwo eq '#FFFF99') {
1.473 amueller 3942: $defbgtwo='#FFFFDD';
1.57 albertel 3943: } else {
1.473 amueller 3944: $defbgtwo='#FFFF99';
1.57 albertel 3945: }
1.419 bisitz 3946: if ($defbgthree eq '#FFBB99') {
3947: $defbgthree='#FFBBDD';
1.269 raeburn 3948: } else {
1.419 bisitz 3949: $defbgthree='#FFBB99';
1.269 raeburn 3950: }
3951:
1.57 albertel 3952: my $thistitle='';
3953: my %name= ();
3954: undef %name;
3955: my %part= ();
3956: my %display=();
3957: my %type= ();
3958: my %default=();
1.196 www 3959: my $uri=&Apache::lonnet::declutter($uris{$rid});
1.584 raeburn 3960: my $toolsymb;
3961: if ($uri =~ /ext\.tool$/) {
3962: $toolsymb = $symbp{$rid};
3963: }
1.57 albertel 3964:
1.506 www 3965: my $filter=$env{'form.filter'};
1.548 raeburn 3966: foreach my $tempkeyp (&keysplit($keyp{$rid})) {
1.57 albertel 3967: if (grep $_ eq $tempkeyp, @catmarker) {
1.584 raeburn 3968: my $parmname=&Apache::lonnet::metadata($uri,$tempkeyp.'.name',$toolsymb);
1.560 damieng 3969: # We may only want certain parameters listed
3970: if ($filter) {
3971: unless ($filter=~/\Q$parmname\E/) { next; }
3972: }
3973: $name{$tempkeyp}=$parmname;
1.584 raeburn 3974: $part{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.part',$toolsymb);
1.560 damieng 3975:
1.584 raeburn 3976: my $parmdis=&Apache::lonnet::metadata($uri,$tempkeyp.'.display',$toolsymb);
1.560 damieng 3977: if ($allparms{$name{$tempkeyp}} ne '') {
3978: my $identifier;
3979: if ($parmdis =~ /(\s*\[Part.*)$/) {
3980: $identifier = $1;
3981: }
3982: $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier;
3983: } else {
3984: $display{$tempkeyp} = $parmdis;
3985: }
3986: unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
3987: $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
1.584 raeburn 3988: $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp,$toolsymb);
3989: $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.type',$toolsymb);
3990: $thistitle=&Apache::lonnet::metadata($uri,$tempkeyp.'.title',$toolsymb);
1.57 albertel 3991: }
3992: }
1.548 raeburn 3993: my $totalparms=scalar(keys(%name));
1.57 albertel 3994: if ($totalparms>0) {
1.560 damieng 3995: my $firstrow=1;
1.473 amueller 3996: my $title=&Apache::lonnet::gettitle($symbp{$rid});
1.582 raeburn 3997: my $navmap = Apache::lonnavmaps::navmap->new();
3998: my @recurseup;
3999: if (ref($navmap) && $mapp{$rid}) {
4000: @recurseup = $navmap->recurseup_maps($mapp{$rid});
4001: }
1.419 bisitz 4002: $r->print('<tr><td style="background-color:'.$defbgone.';"'.
1.57 albertel 4003: ' rowspan='.$totalparms.
1.419 bisitz 4004: '><tt><font size="-1">'.
1.57 albertel 4005: join(' / ',split(/\//,$uri)).
4006: '</font></tt><p><b>'.
1.154 albertel 4007: "<a href=\"javascript:openWindow('".
1.473 amueller 4008: &Apache::lonnet::clutter($uri).'?symb='.
4009: &escape($symbp{$rid}).
1.336 albertel 4010: "', 'metadatafile', '450', '500', 'no', 'yes');\"".
4011: " target=\"_self\">$title");
1.57 albertel 4012:
4013: if ($thistitle) {
1.473 amueller 4014: $r->print(' ('.$thistitle.')');
1.57 albertel 4015: }
4016: $r->print('</a></b></td>');
1.419 bisitz 4017: $r->print('<td style="background-color:'.$defbgtwo.';"'.
1.57 albertel 4018: ' rowspan='.$totalparms.'>'.$typep{$rid}.
4019: '</td>');
4020:
1.419 bisitz 4021: $r->print('<td style="background-color:'.$defbgone.';"'.
1.57 albertel 4022: ' rowspan='.$totalparms.
1.238 www 4023: '>'.$maptitles{$mapp{$rid}}.'</td>');
1.548 raeburn 4024: foreach my $item (&keysinorder_bytype(\%name,\%keyorder)) {
1.57 albertel 4025: unless ($firstrow) {
4026: $r->print('<tr>');
4027: } else {
4028: undef $firstrow;
4029: }
1.548 raeburn 4030: &print_row($r,$item,\%part,\%name,\%symbp,$rid,\%default,
1.57 albertel 4031: \%type,\%display,$defbgone,$defbgtwo,
1.269 raeburn 4032: $defbgthree,$parmlev,$uname,$udom,$csec,
1.582 raeburn 4033: $cgroup,\@usersgroups,$noeditgrp,$readonly,
4034: \@recurseup,\%maptitles,\%allmaps_inverted,
4035: \$numreclinks);
1.57 albertel 4036: }
4037: }
4038: }
4039: } # end foreach ids
1.43 albertel 4040: # -------------------------------------------------- End entry for one resource
1.517 www 4041: $r->print(&Apache::loncommon::end_data_table);
1.203 www 4042: } # end of full
1.57 albertel 4043: #--------------------------------------------------- Entry for parm level map
4044: if ($parmlev eq 'map') {
1.419 bisitz 4045: my $defbgone = '#E0E099';
4046: my $defbgtwo = '#FFFF99';
4047: my $defbgthree = '#FFBB99';
1.57 albertel 4048:
4049: my %maplist;
4050:
4051: if ($pschp eq 'all') {
1.446 bisitz 4052: %maplist = %allmaps;
1.57 albertel 4053: } else {
4054: %maplist = ($pschp => $mapp{$pschp});
4055: }
4056:
4057: #-------------------------------------------- for each map, gather information
4058: my $mapid;
1.607 raeburn 4059: foreach $mapid (sort { $a <=> $b } keys(%maplist)) {
1.60 albertel 4060: my $maptitle = $maplist{$mapid};
1.57 albertel 4061:
4062: #----------------------- loop through ids and get all parameter types for map
4063: #----------------------------------------- and associated information
4064: my %name = ();
4065: my %part = ();
4066: my %display = ();
4067: my %type = ();
4068: my %default = ();
4069: my $map = 0;
4070:
1.473 amueller 4071: # $r->print("Catmarker: @catmarker<br />\n");
1.446 bisitz 4072:
1.548 raeburn 4073: foreach my $id (@ids) {
4074: ($map)=($id =~ /([\d]*?)\./);
4075: my $rid = $id;
1.446 bisitz 4076:
1.57 albertel 4077: # $r->print("$mapid:$map: $rid <br /> \n");
4078:
1.560 damieng 4079: if ($map eq $mapid) {
1.473 amueller 4080: my $uri=&Apache::lonnet::declutter($uris{$rid});
1.584 raeburn 4081: my $toolsymb;
4082: if ($uri =~ /ext\.tool$/) {
4083: $toolsymb = $symbp{$rid};
4084: }
1.582 raeburn 4085:
1.57 albertel 4086: # $r->print("Keys: $keyp{$rid} <br />\n");
4087:
4088: #--------------------------------------------------------------------
4089: # @catmarker contains list of all possible parameters including part #s
4090: # $fullkeyp contains the full part/id # for the extraction of proper parameters
4091: # $tempkeyp contains part 0 only (no ids - ie, subparts)
4092: # When storing information, store as part 0
4093: # When requesting information, request from full part
4094: #-------------------------------------------------------------------
1.548 raeburn 4095: foreach my $fullkeyp (&keysplit($keyp{$rid})) {
4096: my $tempkeyp = $fullkeyp;
4097: $tempkeyp =~ s/_\w+_/_0_/;
1.473 amueller 4098:
1.548 raeburn 4099: if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
1.473 amueller 4100: $part{$tempkeyp}="0";
1.584 raeburn 4101: $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name',$toolsymb);
4102: my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display',$toolsymb);
1.473 amueller 4103: if ($allparms{$name{$tempkeyp}} ne '') {
4104: my $identifier;
4105: if ($parmdis =~ /(\s*\[Part.*)$/) {
4106: $identifier = $1;
4107: }
4108: $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier;
4109: } else {
4110: $display{$tempkeyp} = $parmdis;
4111: }
4112: unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
4113: $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
4114: $display{$tempkeyp} =~ s/_\w+_/_0_/;
1.584 raeburn 4115: $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp,$toolsymb);
4116: $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type',$toolsymb);
1.473 amueller 4117: }
4118: } # end loop through keys
1.560 damieng 4119: }
1.57 albertel 4120: } # end loop through ids
1.446 bisitz 4121:
1.57 albertel 4122: #---------------------------------------------------- print header information
1.133 www 4123: my $foldermap=&mt($maptitle=~/^uploaded/?'Folder':'Map');
1.82 www 4124: my $showtitle=$maptitles{$maptitle}.($maptitle!~/^uploaded/?' ['.$maptitle.']':'');
1.401 bisitz 4125: my $tmp="";
1.57 albertel 4126: if ($uname) {
1.473 amueller 4127: my $person=&Apache::loncommon::plainname($uname,$udom);
1.401 bisitz 4128: $tmp.=&mt("User")." <font color=\"red\"><i>$uname \($person\) </i></font> ".
4129: &mt('in')." \n";
1.57 albertel 4130: } else {
1.401 bisitz 4131: $tmp.="<font color=\"red\"><i>".&mt('all').'</i></font> '.&mt('users in')." \n";
1.57 albertel 4132: }
1.269 raeburn 4133: if ($cgroup) {
1.401 bisitz 4134: $tmp.=&mt("Group")." <font color=\"red\"><i>$cgroup".
4135: "</i></font> ".&mt('of')." \n";
1.269 raeburn 4136: $csec = '';
4137: } elsif ($csec) {
1.401 bisitz 4138: $tmp.=&mt("Section")." <font color=\"red\"><i>$csec".
4139: "</i></font> ".&mt('of')." \n";
1.269 raeburn 4140: }
1.401 bisitz 4141: $r->print('<div align="center"><h4>'
4142: .&mt('Set Defaults for All Resources in [_1]Specifically for [_2][_3]'
1.404 bisitz 4143: ,$foldermap.'<br /><font color="red"><i>'.$showtitle.'</i></font><br />'
1.401 bisitz 4144: ,$tmp
4145: ,'<font color="red"><i>'.$coursename.'</i></font>'
4146: )
4147: ."<br /></h4>\n"
1.422 bisitz 4148: );
1.57 albertel 4149: #---------------------------------------------------------------- print table
1.419 bisitz 4150: $r->print('<p>'.&Apache::loncommon::start_data_table()
4151: .&Apache::loncommon::start_data_table_header_row()
4152: .'<th>'.&mt('Parameter Name').'</th>'
1.578 raeburn 4153: .'<th>'.&mt('Value').'</th>'
1.419 bisitz 4154: .'<th>'.&mt('Parameter in Effect').'</th>'
4155: .&Apache::loncommon::end_data_table_header_row()
4156: );
1.57 albertel 4157:
1.582 raeburn 4158: my $navmap = Apache::lonnavmaps::navmap->new();
4159: my @recurseup;
4160: if (ref($navmap)) {
4161: my $mapres = $navmap->getByMapPc($mapid);
4162: if (ref($mapres)) {
4163: @recurseup = $navmap->recurseup_maps($mapres->src());
4164: }
4165: }
4166:
4167:
1.548 raeburn 4168: foreach my $item (&keysinorder(\%name,\%keyorder)) {
1.473 amueller 4169: $r->print(&Apache::loncommon::start_data_table_row());
1.548 raeburn 4170: &print_row($r,$item,\%part,\%name,\%symbp,$mapid,\%default,
1.269 raeburn 4171: \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
1.568 raeburn 4172: $parmlev,$uname,$udom,$csec,$cgroup,'',$noeditgrp,
1.582 raeburn 4173: $readonly,\@recurseup,\%maptitles,\%allmaps_inverted,
4174: \$numreclinks);
1.57 albertel 4175: }
1.422 bisitz 4176: $r->print(&Apache::loncommon::end_data_table().'</p>'
4177: .'</div>'
4178: );
1.57 albertel 4179: } # end each map
4180: } # end of $parmlev eq map
4181: #--------------------------------- Entry for parm level general (Course level)
4182: if ($parmlev eq 'general') {
1.473 amueller 4183: my $defbgone = '#E0E099';
1.419 bisitz 4184: my $defbgtwo = '#FFFF99';
4185: my $defbgthree = '#FFBB99';
1.57 albertel 4186:
4187: #-------------------------------------------- for each map, gather information
4188: my $mapid="0.0";
4189: #----------------------- loop through ids and get all parameter types for map
4190: #----------------------------------------- and associated information
4191: my %name = ();
4192: my %part = ();
4193: my %display = ();
4194: my %type = ();
4195: my %default = ();
1.446 bisitz 4196:
1.548 raeburn 4197: foreach $id (@ids) {
4198: my $rid = $id;
1.446 bisitz 4199:
1.196 www 4200: my $uri=&Apache::lonnet::declutter($uris{$rid});
1.584 raeburn 4201: my $toolsymb;
4202: if ($uri =~ /ext\.tool$/) {
4203: $toolsymb = $symbp{$rid};
4204: }
1.57 albertel 4205:
4206: #--------------------------------------------------------------------
4207: # @catmarker contains list of all possible parameters including part #s
4208: # $fullkeyp contains the full part/id # for the extraction of proper parameters
4209: # $tempkeyp contains part 0 only (no ids - ie, subparts)
4210: # When storing information, store as part 0
4211: # When requesting information, request from full part
4212: #-------------------------------------------------------------------
1.548 raeburn 4213: foreach my $fullkeyp (&keysplit($keyp{$rid})) {
4214: my $tempkeyp = $fullkeyp;
4215: $tempkeyp =~ s/_\w+_/_0_/;
4216: if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) {
1.473 amueller 4217: $part{$tempkeyp}="0";
1.584 raeburn 4218: $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name',$toolsymb);
4219: my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display',$toolsymb);
1.473 amueller 4220: if ($allparms{$name{$tempkeyp}} ne '') {
4221: my $identifier;
4222: if ($parmdis =~ /(\s*\[Part.*)$/) {
4223: $identifier = $1;
4224: }
4225: $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier;
4226: } else {
4227: $display{$tempkeyp} = $parmdis;
4228: }
4229: unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; }
4230: $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')';
4231: $display{$tempkeyp} =~ s/_\w+_/_0_/;
1.584 raeburn 4232: $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp,$toolsymb);
4233: $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.type',$toolsymb);
1.560 damieng 4234: }
1.57 albertel 4235: } # end loop through keys
4236: } # end loop through ids
1.446 bisitz 4237:
1.57 albertel 4238: #---------------------------------------------------- print header information
1.473 amueller 4239: my $setdef=&mt("Set Defaults for All Resources in Course");
1.57 albertel 4240: $r->print(<<ENDMAPONE);
1.419 bisitz 4241: <center>
4242: <h4>$setdef
1.135 albertel 4243: <font color="red"><i>$coursename</i></font><br />
1.57 albertel 4244: ENDMAPONE
4245: if ($uname) {
1.473 amueller 4246: my $person=&Apache::loncommon::plainname($uname,$udom);
1.135 albertel 4247: $r->print(" ".&mt("User")."<font color=\"red\"> <i>$uname \($person\) </i></font> \n");
1.57 albertel 4248: } else {
1.135 albertel 4249: $r->print("<i><font color=\"red\"> ".&mt("ALL")."</i> ".&mt("USERS")."</font> \n");
1.57 albertel 4250: }
1.446 bisitz 4251:
1.135 albertel 4252: if ($csec) {$r->print(&mt("Section")."<font color=\"red\"> <i>$csec</i></font>\n")};
1.306 albertel 4253: if ($cgroup) {$r->print(&mt("Group")."<font color=\"red\"> <i>$cgroup</i></font>\n")};
1.135 albertel 4254: $r->print("</h4>\n");
1.57 albertel 4255: #---------------------------------------------------------------- print table
1.419 bisitz 4256: $r->print('<p>'.&Apache::loncommon::start_data_table()
4257: .&Apache::loncommon::start_data_table_header_row()
4258: .'<th>'.&mt('Parameter Name').'</th>'
4259: .'<th>'.&mt('Default Value').'</th>'
4260: .'<th>'.&mt('Parameter in Effect').'</th>'
4261: .&Apache::loncommon::end_data_table_header_row()
4262: );
1.57 albertel 4263:
1.548 raeburn 4264: foreach my $item (&keysinorder(\%name,\%keyorder)) {
1.419 bisitz 4265: $r->print(&Apache::loncommon::start_data_table_row());
1.548 raeburn 4266: &print_row($r,$item,\%part,\%name,\%symbp,$mapid,\%default,
1.568 raeburn 4267: \%type,\%display,$defbgone,$defbgtwo,$defbgthree,
4268: $parmlev,$uname,$udom,$csec,$cgroup,'',$noeditgrp,
4269: $readonly);
1.57 albertel 4270: }
1.419 bisitz 4271: $r->print(&Apache::loncommon::end_data_table()
4272: .'</p>'
4273: .'</center>'
4274: );
1.57 albertel 4275: } # end of $parmlev eq general
1.606 raeburn 4276: $r->print('</div>');
1.43 albertel 4277: }
1.507 www 4278: $r->print('</form>');
1.582 raeburn 4279: if ($numreclinks) {
4280: $r->print(<<"END");
4281: <form name="recurseform" action="/adm/parmset?action=settable" method="post">
4282: <input type="hidden" name="pschp" />
4283: <input type="hidden" name="pscat" />
4284: <input type="hidden" name="psprt" />
4285: <input type="hidden" name="hideparmsel" value="hidden" />
4286: </form>
4287: <script type="text/javascript">
4288: function pjumprec(rid,name,part) {
4289: document.forms.recurseform.pschp.value = rid;
4290: document.forms.recurseform.pscat.value = name;
4291: document.forms.recurseform.psprt.value = part;
4292: document.forms.recurseform.submit();
4293: return false;
4294: }
4295: </script>
4296: END
4297: }
1.507 www 4298: &endSettingsScreen($r);
4299: $r->print(&Apache::loncommon::end_page());
1.57 albertel 4300: } # end sub assessparms
1.30 www 4301:
1.560 damieng 4302:
4303:
1.120 www 4304: ##################################################
1.560 damieng 4305: # OVERVIEW MODE
1.207 www 4306: ##################################################
1.124 www 4307:
1.563 damieng 4308: my $tableopen; # boolean, true if HTML table is already opened
4309:
4310: # Returns HTML with the HTML table start tag and header, unless the table is already opened.
4311: # @param {boolean} $readonly - true if values cannot be edited (otherwise more columns are added)
4312: # @returns {string}
1.124 www 4313: sub tablestart {
1.576 raeburn 4314: my ($readonly,$is_map) = @_;
1.124 www 4315: if ($tableopen) {
1.552 raeburn 4316: return '';
1.124 www 4317: } else {
1.552 raeburn 4318: $tableopen=1;
4319: my $output = &Apache::loncommon::start_data_table().'<tr><th>'.&mt('Parameter').'</th>';
4320: if ($readonly) {
4321: $output .= '<th>'.&mt('Current value').'</th>';
4322: } else {
1.576 raeburn 4323: $output .= '<th>'.&mt('Delete').'</th>'.
4324: '<th>'.&mt('Set to ...').'</th>';
4325: if ($is_map) {
4326: $output .= '<th>'.&mt('Recursive?').'</th>';
4327: }
1.552 raeburn 4328: }
4329: $output .= '</tr>';
4330: return $output;
1.124 www 4331: }
4332: }
4333:
1.563 damieng 4334: # Returns HTML with the HTML table end tag, unless the table is not opened.
4335: # @returns {string}
1.124 www 4336: sub tableend {
4337: if ($tableopen) {
1.560 damieng 4338: $tableopen=0;
4339: return &Apache::loncommon::end_data_table();
1.124 www 4340: } else {
1.560 damieng 4341: return'';
1.124 www 4342: }
4343: }
4344:
1.563 damieng 4345: # Reads course and user information.
4346: # 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).
4347: # The key for student data is modified with '[useropt:'.username.':'.userdomain.'].'.
4348: # If the context is looking for a list, returns a list with the scalar data and the class list.
4349: # @param {string} $crs - course number
4350: # @param {string} $dom - course domain
4351: # @returns {hash reference|Array}
1.207 www 4352: sub readdata {
4353: my ($crs,$dom)=@_;
4354: # Read coursedata
4355: my $resourcedata=&Apache::lonnet::get_courseresdata($crs,$dom);
4356: # Read userdata
4357:
4358: my $classlist=&Apache::loncoursedata::get_classlist();
1.548 raeburn 4359: foreach my $user (keys(%$classlist)) {
4360: if ($user=~/^($match_username)\:($match_domain)$/) {
4361: my ($tuname,$tudom)=($1,$2);
4362: my $useropt=&Apache::lonnet::get_userresdata($tuname,$tudom);
4363: foreach my $userkey (keys(%{$useropt})) {
4364: if ($userkey=~/^\Q$env{'request.course.id'}\E/) {
1.207 www 4365: my $newkey=$userkey;
1.548 raeburn 4366: $newkey=~s/^($env{'request.course.id'}\.)/$1\[useropt\:$tuname\:$tudom\]\./;
4367: $$resourcedata{$newkey}=$$useropt{$userkey};
4368: }
4369: }
1.473 amueller 4370: }
4371: }
1.552 raeburn 4372: if (wantarray) {
4373: return ($resourcedata,$classlist);
4374: } else {
4375: return $resourcedata;
4376: }
1.207 www 4377: }
4378:
4379:
1.563 damieng 4380: # Stores parameter data, using form parameters directly.
4381: #
4382: # Uses the following form parameters. The variable part in the names is a resourcedata key (except for a modification for user data).
1.588 raeburn 4383: # set_* (except settext, setipallow, setipdeny, setdeeplink) - set a parameter value
1.563 damieng 4384: # del_* - remove a parameter
4385: # datepointer_* - set a date parameter (value is key_* refering to a set of other form parameters)
4386: # dateinterval_* - set a date interval parameter (value refers to more form parameters)
4387: # key_* - date values
4388: # days_* - for date intervals
4389: # hours_* - for date intervals
4390: # minutes_* - for date intervals
4391: # seconds_* - for date intervals
4392: # done_* - for date intervals
4393: # typeof_* - parameter type
4394: #
4395: # @param {Apache2::RequestRec} $r - the Apache request
4396: # @param {string} $crs - course number
4397: # @param {string} $dom - course domain
1.208 www 4398: sub storedata {
4399: my ($r,$crs,$dom)=@_;
1.207 www 4400: # Set userlevel immediately
4401: # Do an intermediate store of course level
4402: my $olddata=&readdata($crs,$dom);
1.124 www 4403: my %newdata=();
4404: undef %newdata;
4405: my @deldata=();
1.576 raeburn 4406: my @delrec=();
4407: my @delnonrec=();
1.124 www 4408: undef @deldata;
1.504 raeburn 4409: my ($got_chostname,$chostname,$cmajor,$cminor);
1.546 raeburn 4410: my $now = time;
1.560 damieng 4411: foreach my $key (keys(%env)) {
4412: if ($key =~ /^form\.([a-z]+)\_(.+)$/) {
4413: my $cmd=$1;
4414: my $thiskey=$2;
1.576 raeburn 4415: my ($altkey,$recursive,$tkey,$tkeyrec,$tkeynonrec);
1.588 raeburn 4416: next if ($cmd eq 'rec' || $cmd eq 'settext' || $cmd eq 'setipallow' || $cmd eq 'setipdeny' || $cmd eq 'setdeeplink');
1.576 raeburn 4417: if ((($cmd eq 'set') || ($cmd eq 'datepointer') || ($cmd eq 'dateinterval') || ($cmd eq 'del')) &&
4418: ($thiskey =~ /(?:sequence|page)\Q___(all)\E/)) {
4419: unless ($thiskey =~ /(encrypturl|hiddenresource)$/) {
4420: $altkey = $thiskey;
4421: $altkey =~ s/\Q___(all)\E/___(rec)/;
4422: if ($env{'form.rec_'.$thiskey}) {
4423: $recursive = 1;
4424: }
4425: }
4426: }
1.560 damieng 4427: my ($tuname,$tudom)=&extractuser($thiskey);
1.473 amueller 4428: if ($tuname) {
1.576 raeburn 4429: $tkey=$thiskey;
1.560 damieng 4430: $tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;
1.576 raeburn 4431: if ($altkey) {
4432: $tkeynonrec = $tkey;
4433: $tkeyrec = $altkey;
4434: $tkeyrec=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;
4435: }
1.560 damieng 4436: }
4437: if ($cmd eq 'set' || $cmd eq 'datepointer' || $cmd eq 'dateinterval') {
1.563 damieng 4438: my ($data, $typeof, $text, $name, $valchk, $valmatch, $namematch);
4439: if ($cmd eq 'set') {
4440: $data=$env{$key};
4441: $valmatch = '';
4442: $valchk = $data;
4443: $typeof=$env{'form.typeof_'.$thiskey};
4444: $text = &mt('Saved modified parameter for');
4445: if ($typeof eq 'string_questiontype') {
4446: $name = 'type';
1.588 raeburn 4447: } elsif (($typeof eq 'string_lenient') || ($typeof eq 'string_deeplink')) {
4448: ($name) = ($typeof =~ /^string_(lenient|deeplink)$/);
1.563 damieng 4449: my $stringmatch = &standard_string_matches($typeof);
4450: if (ref($stringmatch) eq 'ARRAY') {
4451: foreach my $item (@{$stringmatch}) {
4452: if (ref($item) eq 'ARRAY') {
4453: my ($regexpname,$pattern) = @{$item};
4454: if ($pattern ne '') {
4455: if ($data =~ /$pattern/) {
4456: $valmatch = $regexpname;
4457: $valchk = '';
4458: last;
4459: }
1.560 damieng 4460: }
1.549 raeburn 4461: }
4462: }
4463: }
1.563 damieng 4464: } elsif ($typeof eq 'string_discussvote') {
4465: $name = 'discussvote';
4466: } elsif ($typeof eq 'string_examcode') {
4467: $name = 'examcode';
4468: if (&Apache::lonnet::validCODE($data)) {
4469: $valchk = 'valid';
4470: }
4471: } elsif ($typeof eq 'string_yesno') {
4472: if ($thiskey =~ /\.retrypartial$/) {
4473: $name = 'retrypartial';
4474: }
1.549 raeburn 4475: }
1.563 damieng 4476: } elsif ($cmd eq 'datepointer') {
4477: $data=&Apache::lonhtmlcommon::get_date_from_form($env{$key});
4478: $typeof=$env{'form.typeof_'.$thiskey};
4479: $text = &mt('Saved modified date for');
4480: if ($typeof eq 'date_start') {
4481: if ($thiskey =~ /\.printstartdate$/) {
4482: $name = 'printstartdate';
4483: if (($data) && ($data > $now)) {
4484: $valchk = 'future';
4485: }
1.560 damieng 4486: }
1.563 damieng 4487: } elsif ($typeof eq 'date_end') {
4488: if ($thiskey =~ /\.printenddate$/) {
4489: $name = 'printenddate';
4490: if (($data) && ($data < $now)) {
4491: $valchk = 'past';
4492: }
1.560 damieng 4493: }
1.504 raeburn 4494: }
1.563 damieng 4495: } elsif ($cmd eq 'dateinterval') {
4496: $data=&get_date_interval_from_form($thiskey);
4497: if ($thiskey =~ /\.interval$/) {
4498: $name = 'interval';
4499: my $intervaltype = &get_intervaltype($name);
4500: my $intervalmatch = &standard_interval_matches($intervaltype);
4501: if (ref($intervalmatch) eq 'ARRAY') {
4502: foreach my $item (@{$intervalmatch}) {
4503: if (ref($item) eq 'ARRAY') {
4504: my ($regexpname,$pattern) = @{$item};
4505: if ($pattern ne '') {
4506: if ($data =~ /$pattern/) {
4507: $valmatch = $regexpname;
4508: $valchk = '';
4509: last;
4510: }
1.560 damieng 4511: }
1.554 raeburn 4512: }
4513: }
4514: }
4515: }
1.563 damieng 4516: $typeof=$env{'form.typeof_'.$thiskey};
4517: $text = &mt('Saved modified date for');
1.554 raeburn 4518: }
1.576 raeburn 4519: if ($recursive) {
1.563 damieng 4520: $namematch = 'maplevelrecurse';
1.560 damieng 4521: }
1.563 damieng 4522: if (($name ne '') || ($namematch ne '')) {
4523: my ($needsrelease,$needsnewer);
4524: if ($name ne '') {
4525: $needsrelease = $Apache::lonnet::needsrelease{"parameter:$name:$valchk:$valmatch:"};
1.560 damieng 4526: if ($needsrelease) {
4527: unless ($got_chostname) {
1.563 damieng 4528: ($chostname,$cmajor,$cminor)=¶meter_release_vars();
1.560 damieng 4529: $got_chostname = 1;
4530: }
1.563 damieng 4531: $needsnewer = ¶meter_releasecheck($name,$valchk,$valmatch,undef,
4532: $needsrelease,
4533: $cmajor,$cminor);
4534: }
4535: }
4536: if ($namematch ne '') {
4537: if ($needsnewer) {
4538: undef($namematch);
1.560 damieng 4539: } else {
1.563 damieng 4540: my $currneeded;
4541: if ($needsrelease) {
4542: $currneeded = $needsrelease;
4543: }
4544: $needsrelease =
4545: $Apache::lonnet::needsrelease{"parameter::::$namematch"};
4546: if (($needsrelease) &&
4547: (($currneeded eq '') || ($needsrelease < $currneeded))) {
4548: unless ($got_chostname) {
4549: ($chostname,$cmajor,$cminor) = ¶meter_release_vars();
4550: $got_chostname = 1;
4551: }
4552: $needsnewer = ¶meter_releasecheck(undef,$valchk,$valmatch,
4553: $namematch, $needsrelease,$cmajor,$cminor);
4554: } else {
4555: undef($namematch);
4556: }
1.560 damieng 4557: }
1.557 raeburn 4558: }
1.563 damieng 4559: if ($needsnewer) {
4560: $r->print('<br />'.&oldversion_warning($name,$namematch,$data,
4561: $chostname,$cmajor,
4562: $cminor,$needsrelease));
4563: next;
4564: }
1.504 raeburn 4565: }
1.576 raeburn 4566: my ($reconlychg,$haschange,$storekey);
4567: if ($tuname) {
4568: my $ustorekey;
4569: if ($altkey) {
4570: if ($recursive) {
4571: if (exists($$olddata{$thiskey})) {
4572: if ($$olddata{$thiskey} eq $data) {
4573: $reconlychg = 1;
4574: }
4575: &Apache::lonnet::del('resourcedata',[$tkeynonrec,$tkeynonrec.'.type'],$tudom,$tuname);
4576: }
4577: if (exists($$olddata{$altkey})) {
4578: if (defined($data) && $$olddata{$altkey} ne $data) {
4579: $haschange = 1;
4580: }
4581: } elsif ((!$reconlychg) && ($data ne '')) {
4582: $haschange = 1;
4583: }
4584: $ustorekey = $tkeyrec;
4585: } else {
4586: if (exists($$olddata{$altkey})) {
4587: if ($$olddata{$altkey} eq $data) {
4588: $reconlychg = 1;
4589: }
4590: &Apache::lonnet::del('resourcedata',[$tkeyrec,$tkeyrec.'.type'],$tudom,$tuname);
4591: }
4592: if (exists($$olddata{$thiskey})) {
4593: if (defined($data) && $$olddata{$thiskey} ne $data) {
4594: $haschange = 1;
4595: }
4596: } elsif ((!$reconlychg) && ($data ne '')) {
4597: $haschange = 1;
4598: }
4599: $ustorekey = $tkeynonrec;
4600: }
4601: } else {
4602: if (exists($$olddata{$tkey})) {
4603: if (defined($data) && $$olddata{$tkey} ne $data) {
4604: $haschange = 1;
4605: }
4606: $ustorekey = $tkey;
4607: }
4608: }
4609: if ($haschange || $reconlychg) {
4610: unless ($env{'form.del_'.$thiskey}) {
4611: if (&Apache::lonnet::put('resourcedata',{$ustorekey=>$data,
4612: $ustorekey.'.type' => $typeof},
4613: $tudom,$tuname) eq 'ok') {
4614: &log_parmset({$ustorekey=>$data,$ustorekey.'.type' => $typeof},0,$tuname,$tudom);
4615: $r->print('<br />'.$text.' '.
4616: &Apache::loncommon::plainname($tuname,$tudom));
4617: } else {
4618: $r->print('<div class="LC_error">'.
4619: &mt('Error saving parameters').'</div>');
4620: }
4621: &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
4622: }
4623: }
4624: } else {
4625: if ($altkey) {
4626: if ($recursive) {
4627: if (exists($$olddata{$thiskey})) {
4628: if ($$olddata{$thiskey} eq $data) {
4629: $reconlychg = 1;
4630: }
4631: push(@delnonrec,($thiskey,$thiskey.'.type'));
4632: }
4633: if (exists($$olddata{$altkey})) {
4634: if (defined($data) && $$olddata{$altkey} ne $data) {
4635: $haschange = 1;
4636: }
4637: } elsif (($data ne '') && (!$reconlychg)) {
4638: $haschange = 1;
4639: }
4640: $storekey = $altkey;
1.563 damieng 4641: } else {
1.576 raeburn 4642: if (exists($$olddata{$altkey})) {
4643: if ($$olddata{$altkey} eq $data) {
4644: $reconlychg = 1;
4645: }
4646: push(@delrec,($altkey,$altkey.'.type'));
4647: }
4648: if (exists($$olddata{$thiskey})) {
4649: if (defined($data) && $$olddata{$thiskey} ne $data) {
4650: $haschange = 1;
4651: }
4652: } elsif (($data ne '') && (!$reconlychg)) {
4653: $haschange = 1;
4654: }
4655: $storekey = $thiskey;
1.563 damieng 4656: }
1.560 damieng 4657: } else {
1.576 raeburn 4658: if (defined($data) && $$olddata{$thiskey} ne $data) {
4659: $haschange = 1;
4660: $storekey = $thiskey;
4661: }
4662: }
4663: }
4664: if ($reconlychg || $haschange) {
4665: unless ($env{'form.del_'.$thiskey}) {
4666: $newdata{$storekey}=$data;
4667: $newdata{$storekey.'.type'}=$typeof;
1.560 damieng 4668: }
4669: }
4670: } elsif ($cmd eq 'del') {
4671: if ($tuname) {
1.576 raeburn 4672: my $error;
4673: if ($altkey) {
4674: if (exists($$olddata{$altkey})) {
4675: if (&Apache::lonnet::del('resourcedata',[$tkeyrec,$tkeyrec.'.type'],$tudom,$tuname) eq 'ok') {
4676: &log_parmset({$tkeyrec=>''},1,$tuname,$tudom);
4677: if ($recursive) {
4678: $r->print('<br />'.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));
4679: }
4680: } elsif ($recursive) {
4681: $error = 1;
4682: }
4683: }
4684: if (exists($$olddata{$thiskey})) {
4685: if (&Apache::lonnet::del('resourcedata',[$tkeynonrec,$tkeynonrec.'.type'],$tudom,$tuname) eq 'ok') {
4686: &log_parmset({$tkeynonrec=>''},1,$tuname,$tudom);
4687: unless ($recursive) {
4688: $r->print('<br />'.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));
4689: }
4690: } elsif (!$recursive) {
4691: $error = 1;
4692: }
4693: }
1.560 damieng 4694: } else {
1.576 raeburn 4695: if (exists($$olddata{$thiskey})) {
4696: if (&Apache::lonnet::del('resourcedata',[$tkey,$tkey.'.type'],$tudom,$tuname) eq 'ok') {
4697: &log_parmset({$tkey=>''},1,$tuname,$tudom);
4698: $r->print('<br />'.&mt('Deleted parameter for').' '.&Apache::loncommon::plainname($tuname,$tudom));
4699: } else {
4700: $error = 1;
4701: }
4702: }
4703: }
4704: if ($error) {
1.560 damieng 4705: $r->print('<div class="LC_error">'.
4706: &mt('Error deleting parameters').'</div>');
4707: }
4708: &Apache::lonnet::devalidateuserresdata($tuname,$tudom);
4709: } else {
1.576 raeburn 4710: if ($altkey) {
4711: if (exists($$olddata{$altkey})) {
4712: unless (grep(/^\Q$altkey\E$/,@delrec)) {
4713: push(@deldata,($altkey,$altkey.'.type'));
4714: }
4715: }
4716: if (exists($$olddata{$thiskey})) {
4717: unless (grep(/^\Q$thiskey\E$/,@delnonrec)) {
4718: push(@deldata,($thiskey,$thiskey.'.type'));
4719: }
4720: }
4721: } elsif (exists($$olddata{$thiskey})) {
4722: push(@deldata,($thiskey,$thiskey.'.type'));
4723: }
1.560 damieng 4724: }
1.473 amueller 4725: }
4726: }
4727: }
1.207 www 4728: # Store all course level
1.144 www 4729: my $delentries=$#deldata+1;
1.576 raeburn 4730: my @alldels;
4731: if (@delrec) {
4732: push(@alldels,@delrec);
4733: }
4734: if (@delnonrec) {
4735: push(@alldels,@delnonrec);
4736: }
4737: if (@deldata) {
4738: push(@alldels,@deldata);
4739: }
1.548 raeburn 4740: my @newdatakeys=keys(%newdata);
1.144 www 4741: my $putentries=$#newdatakeys+1;
1.576 raeburn 4742: my ($delresult,$devalidate);
4743: if (@alldels) {
4744: if (&Apache::lonnet::del('resourcedata',\@alldels,$dom,$crs) eq 'ok') {
4745: my %loghash=map { $_ => '' } @alldels;
1.560 damieng 4746: &log_parmset(\%loghash,1);
1.576 raeburn 4747: if ($delentries) {
4748: $r->print('<h2>'.&mt('Deleted [quant,_1,parameter]',$delentries/2).'</h2>');
4749: }
4750: } elsif ($delentries) {
1.560 damieng 4751: $r->print('<div class="LC_error">'.
4752: &mt('Error deleting parameters').'</div>');
4753: }
1.576 raeburn 4754: $devalidate = 1;
1.144 www 4755: }
4756: if ($putentries) {
1.560 damieng 4757: if (&Apache::lonnet::put('resourcedata',\%newdata,$dom,$crs) eq 'ok') {
4758: &log_parmset(\%newdata,0);
4759: $r->print('<h3>'.&mt('Saved [quant,_1,parameter]',$putentries/2).'</h3>');
4760: } else {
4761: $r->print('<div class="LC_error">'.
4762: &mt('Error saving parameters').'</div>');
4763: }
1.576 raeburn 4764: $devalidate = 1;
4765: }
4766: if ($devalidate) {
1.560 damieng 4767: &Apache::lonnet::devalidatecourseresdata($crs,$dom);
1.144 www 4768: }
1.208 www 4769: }
1.207 www 4770:
1.563 damieng 4771: # Returns the username and domain from a key created in readdata from a resourcedata key.
4772: #
4773: # @param {string} $key - the key
4774: # @returns {Array}
1.208 www 4775: sub extractuser {
4776: my $key=shift;
1.350 albertel 4777: return ($key=~/^$env{'request.course.id'}.\[useropt\:($match_username)\:($match_domain)\]\./);
1.208 www 4778: }
1.206 www 4779:
1.563 damieng 4780: # Parses a parameter key and returns the components.
4781: #
4782: # @param {string} $key -
4783: # @param {hash reference} $listdata -
4784: # @return {Array} - (student, resource, part, parameter)
1.381 albertel 4785: sub parse_listdata_key {
4786: my ($key,$listdata) = @_;
4787: # split into student/section affected, and
4788: # the realm (folder/resource part and parameter
1.446 bisitz 4789: my ($student,$realm) =
1.473 amueller 4790: ($key=~/^\Q$env{'request.course.id'}\E\.\[([^\.]+)\]\.(.+)$/);
1.381 albertel 4791: # if course wide student would be undefined
4792: if (!defined($student)) {
1.560 damieng 4793: ($realm)=($key=~/^\Q$env{'request.course.id'}\E\.(.+)$/);
1.381 albertel 4794: }
4795: # strip off the .type if it's not the Question type parameter
4796: if ($realm=~/\.type$/ && !exists($listdata->{$key.'.type'})) {
1.560 damieng 4797: $realm=~s/\.type//;
1.381 albertel 4798: }
4799: # split into resource+part and parameter name
1.388 albertel 4800: my ($res, $parm) = ($realm=~/^(.*)\.(.*)$/);
4801: ($res, my $part) = ($res =~/^(.*)\.(.*)$/);
1.381 albertel 4802: return ($student,$res,$part,$parm);
4803: }
4804:
1.563 damieng 4805: # Prints HTML with forms for the given parameter data in overview mode (newoverview or overview).
4806: #
4807: # @param {Apache2::RequestRec} $r - the Apache request
4808: # @param {hash reference} $resourcedata - parameter data returned by readdata
4809: # @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
4810: # @param {string} $sortorder - realmstudent|studentrealm
4811: # @param {string} $caller - name of the calling sub (overview|newoverview)
4812: # @param {hash reference} $classlist - from loncoursedata::get_classlist
1.568 raeburn 4813: # @param {boolean} $readonly - true if editing not allowed
1.608 raeburn 4814: # @param {string} $parmlev - full|map
4815: # @param {hash reference} $hash_for_realm - keys: realm, values: numeric order
4816: # @param {string} $pschp - selected map pc, or 'all'
1.563 damieng 4817: # @returns{integer} - number of $listdata parameters processed
1.208 www 4818: sub listdata {
1.608 raeburn 4819: my ($r,$resourcedata,$listdata,$sortorder,$caller,$classlist,$readonly,$parmlev,$hash_for_realm,$pschp)=@_;
1.552 raeburn 4820:
1.207 www 4821: # Start list output
1.206 www 4822:
1.122 www 4823: my $oldsection='';
4824: my $oldrealm='';
4825: my $oldpart='';
1.123 www 4826: my $pointer=0;
1.124 www 4827: $tableopen=0;
1.145 www 4828: my $foundkeys=0;
1.248 albertel 4829: my %keyorder=&standardkeyorder();
1.594 raeburn 4830: my $readonlyall = $readonly;
1.381 albertel 4831:
1.552 raeburn 4832: my ($secidx,%grouphash);
4833: if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
4834: $secidx = &Apache::loncoursedata::CL_SECTION();
1.553 raeburn 4835: if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) {
4836: %grouphash = &Apache::longroup::coursegroups();
4837: } elsif ($env{'request.course.groups'} ne '') {
1.585 raeburn 4838: map { $grouphash{$_} = 1; } split(/:/,$env{'request.course.groups'});
1.553 raeburn 4839: }
1.552 raeburn 4840: }
4841:
1.576 raeburn 4842: foreach my $key (sort {
1.560 damieng 4843: my ($astudent,$ares,$apart,$aparm) = &parse_listdata_key($a,$listdata);
4844: my ($bstudent,$bres,$bpart,$bparm) = &parse_listdata_key($b,$listdata);
1.608 raeburn 4845: my ($aid,$bid);
4846: if ($caller eq 'newoverview') {
4847: if (ref($hash_for_realm) eq 'HASH') {
4848: if (($parmlev eq 'map') && ($pschp eq 'all')) {
4849: my ($aurl) = ($ares =~ /^(.+\.(?:sequence|page))___\(all\)$/);
4850: my ($burl) = ($bres =~ /^(.+\.(?:sequence|page))___\(all\)$/);
4851: $aid = $hash_for_realm->{$aurl};
4852: $bid = $hash_for_realm->{$burl};
4853: } elsif ($parmlev eq 'full') {
4854: $aid = $hash_for_realm->{$ares};
4855: $bid = $hash_for_realm->{$bres};
4856: }
4857: }
4858: }
1.381 albertel 4859:
1.560 damieng 4860: # get the numerical order for the param
4861: $aparm=$keyorder{'parameter_0_'.$aparm};
4862: $bparm=$keyorder{'parameter_0_'.$bparm};
1.381 albertel 4863:
1.560 damieng 4864: my $result=0;
1.381 albertel 4865:
1.560 damieng 4866: if ($sortorder eq 'realmstudent') {
1.381 albertel 4867: if ($ares ne $bres ) {
1.608 raeburn 4868: if ($caller eq 'newoverview') {
4869: if (ref($hash_for_realm) eq 'HASH') {
4870: if (($parmlev eq 'map') && ($pschp eq 'all')) {
4871: $result = ($aid <=> $bid);
4872: } elsif ($parmlev eq 'full') {
4873: $result = ($aid <=> $bid);
4874: } else {
4875: $result = ($ares cmp $bres);
4876: }
4877: } else {
4878: $result = ($ares cmp $bres);
4879: }
4880: } else {
4881: $result = ($ares cmp $bres);
4882: }
1.446 bisitz 4883: } elsif ($astudent ne $bstudent) {
1.560 damieng 4884: $result = ($astudent cmp $bstudent);
4885: } elsif ($apart ne $bpart ) {
4886: $result = ($apart cmp $bpart);
4887: }
4888: } else {
4889: if ($astudent ne $bstudent) {
4890: $result = ($astudent cmp $bstudent);
4891: } elsif ($ares ne $bres ) {
1.608 raeburn 4892: if ($caller eq 'newoverview') {
4893: if (ref($hash_for_realm) eq 'HASH') {
4894: if (($parmlev eq 'map') && ($pschp eq 'all')) {
4895: $result = ($aid <=> $bid);
4896: } elsif ($parmlev eq 'full') {
4897: $result = ($aid <=> $bid);
4898: } else {
4899: $result = ($ares cmp $bres);
4900: }
4901: } else {
4902: $result = ($ares cmp $bres);
4903: }
4904: } else {
4905: $result = ($ares cmp $bres);
4906: }
1.560 damieng 4907: } elsif ($apart ne $bpart ) {
4908: $result = ($apart cmp $bpart);
4909: }
1.473 amueller 4910: }
1.446 bisitz 4911:
1.560 damieng 4912: if (!$result) {
1.381 albertel 4913: if (defined($aparm) && defined($bparm)) {
1.560 damieng 4914: $result = ($aparm <=> $bparm);
1.381 albertel 4915: } elsif (defined($aparm)) {
1.560 damieng 4916: $result = -1;
1.381 albertel 4917: } elsif (defined($bparm)) {
1.560 damieng 4918: $result = 1;
4919: }
1.473 amueller 4920: }
1.381 albertel 4921:
1.560 damieng 4922: $result;
4923:
1.576 raeburn 4924: } keys(%{$listdata})) { # foreach my $key
4925: my $thiskey = $key;
1.560 damieng 4926: if ($$listdata{$thiskey.'.type'}) {
4927: my $thistype=$$listdata{$thiskey.'.type'};
4928: if ($$resourcedata{$thiskey.'.type'}) {
4929: $thistype=$$resourcedata{$thiskey.'.type'};
4930: }
4931: my ($middle,$part,$name)=
1.572 damieng 4932: ($thiskey=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s\-]+)\.(\w+)$/);
1.560 damieng 4933: my $section=&mt('All Students');
1.594 raeburn 4934: $readonly = $readonlyall;
1.599 raeburn 4935: my $userscope;
1.576 raeburn 4936: my $showval = $$resourcedata{$thiskey};
1.560 damieng 4937: if ($middle=~/^\[(.*)\]/) {
4938: my $issection=$1;
4939: if ($issection=~/^useropt\:($match_username)\:($match_domain)/) {
4940: my ($stuname,$studom) = ($1,$2);
4941: if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
4942: if (ref($classlist) eq 'HASH') {
4943: if (ref($classlist->{$stuname.':'.$studom}) eq 'ARRAY') {
4944: next unless ($classlist->{$stuname.':'.$studom}->[$secidx] eq $env{'request.course.sec'});
4945: }
4946: }
4947: }
4948: $section=&mt('User').": ".&Apache::loncommon::plainname($stuname,$studom);
1.599 raeburn 4949: $userscope = 1;
1.560 damieng 4950: } else {
4951: if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
4952: if (exists($grouphash{$issection})) {
4953: $section=&mt('Group').': '.$issection;
4954: } elsif ($issection eq $env{'request.course.sec'}) {
4955: $section = &mt('Section').': '.$issection;
4956: } else {
4957: next;
1.552 raeburn 4958: }
1.560 damieng 4959: } else {
4960: $section=&mt('Group/Section').': '.$issection;
1.552 raeburn 4961: }
4962: }
1.560 damieng 4963: $middle=~s/^\[(.*)\]//;
4964: } elsif (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
4965: $readonly = 1;
4966: }
4967: $middle=~s/\.+$//;
4968: $middle=~s/^\.+//;
4969: my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
1.576 raeburn 4970: my ($is_map,$is_recursive,$mapurl,$maplevel);
4971: if ($caller eq 'overview') {
4972: if ($middle=~/^(.+)\_\_\_\((all|rec)\)$/) {
4973: $mapurl = $1;
4974: $maplevel = $2;
4975: $is_map = 1;
4976: }
4977: } elsif ($caller eq 'newoverview') {
4978: if ($middle=~/^(.+)\_\_\_\((all)\)$/) {
4979: $mapurl = $1;
4980: $maplevel = $2;
4981: $is_map = 1;
4982: }
4983: }
4984: if ($is_map) {
1.560 damieng 4985: my $leveltitle = &mt('Folder/Map');
1.615 raeburn 4986: my $title = &Apache::lonnet::gettitle($mapurl);
1.608 raeburn 4987: if (ref($hash_for_realm) eq 'HASH') {
4988: if ($hash_for_realm->{$mapurl} eq '1') {
4989: $title = &mt('Main Content');
4990: }
4991: }
1.576 raeburn 4992: unless (($name eq 'hiddenresource') || ($name eq 'encrypturl')) {
4993: if ($caller eq 'newoverview') {
4994: my $altkey = $thiskey;
4995: $altkey =~ s/\Q___(all)\E/___(rec)/;
4996: if ((exists($$resourcedata{$altkey})) & (!exists($$resourcedata{$thiskey}))) {
4997: $is_recursive = 1;
4998: if ($$resourcedata{$altkey.'.type'}) {
4999: $thistype=$$resourcedata{$altkey.'.type'};
5000: }
5001: $showval = $$resourcedata{$altkey};
5002: }
5003: } elsif (($caller eq 'overview') && ($maplevel eq 'rec')) {
5004: $thiskey =~ s/\Q___(rec)\E/___(all)/;
5005: $is_recursive = 1;
5006: }
1.560 damieng 5007: }
1.608 raeburn 5008: $realm='<span class="LC_parm_scope_folder">'.$leveltitle.': '.$title.' <br /><span class="LC_parm_folder">('.$mapurl.')</span></span>';
1.560 damieng 5009: } elsif ($middle) {
5010: my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
1.609 raeburn 5011: next if (($url =~ /\.(page|sequence)$/) && ($parmlev eq 'full') && ($caller eq 'newoverview'));
1.560 damieng 5012: $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').
5013: ': '.&Apache::lonnet::gettitle($middle).
5014: ' <br /><span class="LC_parm_symb">('.$url.' in '.$map.' id: '.
5015: $id.')</span></span>';
5016: }
5017: if ($sortorder eq 'realmstudent') {
5018: if ($realm ne $oldrealm) {
5019: $r->print(&tableend()."\n<hr /><h1>$realm</h1>");
5020: $oldrealm=$realm;
5021: $oldsection='';
5022: }
5023: if ($section ne $oldsection) {
5024: $r->print(&tableend()."\n<h2>$section</h2>");
5025: $oldsection=$section;
5026: $oldpart='';
5027: }
1.552 raeburn 5028: } else {
1.560 damieng 5029: if ($section ne $oldsection) {
5030: $r->print(&tableend()."\n<hr /><h1>$section</h1>");
5031: $oldsection=$section;
5032: $oldrealm='';
5033: }
5034: if ($realm ne $oldrealm) {
5035: $r->print(&tableend()."\n<h2>$realm</h2>");
5036: $oldrealm=$realm;
5037: $oldpart='';
1.552 raeburn 5038: }
5039: }
1.560 damieng 5040: if ($part ne $oldpart) {
5041: $r->print(&tableend().
5042: "\n".'<span class="LC_parm_part">'.&mt('Part').": $part</span>");
5043: $oldpart=$part;
1.556 raeburn 5044: }
1.560 damieng 5045: #
5046: # Ready to print
5047: #
1.470 raeburn 5048: my $parmitem = &standard_parameter_names($name);
1.619 raeburn 5049: my $advice;
5050: if (($name eq 'mapalias') && ($middle) && (!$is_map)) {
5051: if ($middle =~ m{^uploaded/}) {
5052: $advice = &mt('Use Course Editor to set this.');
5053: } else {
5054: $advice = &mt('Use Resource Assembly Tool to set this.');
5055: }
5056: $advice = '<br /><span class="LC_fontsize_small LC_cusr_emph">'.$advice.'</span>';
5057: }
1.576 raeburn 5058: $r->print(&tablestart($readonly,$is_map).
1.560 damieng 5059: &Apache::loncommon::start_data_table_row().
5060: '<td><b>'.&mt($parmitem).
1.619 raeburn 5061: '</b>'.$advice.'</td>');
1.560 damieng 5062: unless ($readonly) {
1.599 raeburn 5063: my $disabled;
5064: if (($name eq 'availablestudent') &&
5065: (($showval eq '') || ($userscope))) {
5066: $disabled = ' disabled="disabled"';
1.619 raeburn 5067: } elsif (($name eq 'mapalias') && ($showval eq '')) {
5068: $disabled = ' disabled="disabled"';
1.599 raeburn 5069: }
1.560 damieng 5070: $r->print('<td><input type="checkbox" name="del_'.
1.599 raeburn 5071: $thiskey.'"'.$disabled.' /></td>');
1.560 damieng 5072: }
5073: $r->print('<td>');
5074: $foundkeys++;
5075: if (&isdateparm($thistype)) {
5076: my $jskey='key_'.$pointer;
5077: my $state;
5078: $pointer++;
5079: if ($readonly) {
5080: $state = 'disabled';
5081: }
5082: $r->print(
5083: &Apache::lonhtmlcommon::date_setter('parmform',
5084: $jskey,
1.576 raeburn 5085: $showval,
1.560 damieng 5086: '',1,$state));
5087: unless ($readonly) {
5088: $r->print(
5089: '<input type="hidden" name="datepointer_'.$thiskey.'" value="'.$jskey.'" />'.
1.576 raeburn 5090: (($showval!=0)?'<span class="LC_nobreak"><a href="/adm/parmset?&action=dateshift1&timebase='.$showval.'">'.
1.560 damieng 5091: &mt('Shift all dates based on this date').'</a></span>':'').
1.576 raeburn 5092: &date_sanity_info($showval)
1.560 damieng 5093: );
5094: }
5095: } elsif ($thistype eq 'date_interval') {
5096: $r->print(&date_interval_selector($thiskey,$name,
1.576 raeburn 5097: $showval,$readonly));
1.560 damieng 5098: } elsif ($thistype =~ m/^string/) {
1.599 raeburn 5099: if ($name eq 'availablestudent') {
5100: $readonly = 1;
1.619 raeburn 5101: } elsif (($name eq 'mapalias') && ($showval eq '')) {
5102: $readonly = 1;
1.599 raeburn 5103: }
1.560 damieng 5104: $r->print(&string_selector($thistype,$thiskey,
1.576 raeburn 5105: $showval,$name,$readonly));
1.560 damieng 5106: } else {
1.576 raeburn 5107: $r->print(&default_selector($thiskey,$showval,$readonly));
1.552 raeburn 5108: }
1.560 damieng 5109: unless ($readonly) {
5110: $r->print('<input type="hidden" name="typeof_'.$thiskey.'" value="'.
5111: $thistype.'" />');
1.552 raeburn 5112: }
1.576 raeburn 5113: $r->print('</td>');
5114: if ($is_map) {
5115: if (($name eq 'encrypturl') || ($name eq 'hiddenresource')) {
5116: $r->print('<td><table><tr><td>'.&mt('Yes').'</td></tr></table></td>');
5117: } else {
5118: my ($disabled,$recon,$recoff);
5119: if ($readonly) {
5120: $disabled = ' disabled="disabled"';
5121: }
5122: if ($is_recursive) {
5123: $recon = ' checked="checked"';
5124: } else {
5125: $recoff = ' checked="checked"';
5126: }
5127: $r->print('<td><table><tr><td><label><input type="radio" name="rec_'.$thiskey.'" value="1"'.$recon.$disabled.' />'.&mt('Yes').'</label>'.
5128: '</td><td><label><input type="radio" name="rec_'.$thiskey.'" value="0"'.$recoff.$disabled.' />'.&mt('No').'</label></td></tr></table></td>');
5129: }
5130: }
5131: $r->print(&Apache::loncommon::end_data_table_row());
1.473 amueller 5132: }
1.121 www 5133: }
1.208 www 5134: return $foundkeys;
5135: }
5136:
1.563 damieng 5137: # Returns a string representing the interval, directly using form data matching the given key.
5138: # The returned string may also include information related to proctored exams.
5139: # Format: seconds['_done'[':'done button title':']['_proctor'['_'proctor key]]]
5140: #
5141: # @param {string} $key - suffix for form fields related to the interval
5142: # @returns {string}
1.385 albertel 5143: sub get_date_interval_from_form {
5144: my ($key) = @_;
5145: my $seconds = 0;
1.611 raeburn 5146: my $numnotnull = 0;
1.385 albertel 5147: foreach my $which (['days', 86400],
1.473 amueller 5148: ['hours', 3600],
5149: ['minutes', 60],
5150: ['seconds', 1]) {
1.560 damieng 5151: my ($name, $factor) = @{ $which };
5152: if (defined($env{'form.'.$name.'_'.$key})) {
1.611 raeburn 5153: unless ($env{'form.'.$name.'_'.$key} eq '') {
5154: $numnotnull ++;
5155: $seconds += $env{'form.'.$name.'_'.$key} * $factor;
5156: }
1.560 damieng 5157: }
1.473 amueller 5158: }
1.560 damieng 5159: if (($key =~ /\.interval$/) &&
5160: (($env{'form.done_'.$key} eq '_done') || ($env{'form.done_'.$key} eq '_done_proctor'))) {
1.559 raeburn 5161: if ($env{'form.done_'.$key.'_buttontext'}) {
5162: $env{'form.done_'.$key.'_buttontext'} =~ s/\://g;
5163: $seconds .= '_done:'.$env{'form.done_'.$key.'_buttontext'}.':';
5164: if ($env{'form.done_'.$key} eq '_done_proctor') {
5165: $seconds .= '_proctor';
5166: }
5167: } else {
5168: $seconds .= $env{'form.done_'.$key};
5169: }
5170: if (($env{'form.done_'.$key} eq '_done_proctor') &&
1.560 damieng 5171: ($env{'form.done_'.$key.'_proctorkey'})) {
1.558 raeburn 5172: $seconds .= '_'.$env{'form.done_'.$key.'_proctorkey'};
5173: }
1.554 raeburn 5174: }
1.611 raeburn 5175: return if (!$numnotnull);
1.385 albertel 5176: return $seconds;
5177: }
5178:
5179:
1.563 damieng 5180: # Returns HTML to enter a text value for a parameter.
5181: #
5182: # @param {string} $thiskey - parameter key
5183: # @param {string} $showval - the current value
5184: # @param {boolean} $readonly - true if the field should not be made editable
5185: # @returns {string}
1.383 albertel 5186: sub default_selector {
1.552 raeburn 5187: my ($thiskey, $showval, $readonly) = @_;
5188: my $disabled;
5189: if ($readonly) {
5190: $disabled = ' disabled="disabled"';
5191: }
5192: return '<input type="text" name="set_'.$thiskey.'" value="'.$showval.'"'.$disabled.' />';
1.383 albertel 5193: }
5194:
1.563 damieng 5195: # Returns HTML to enter allow/deny rules related to IP addresses.
5196: #
5197: # @param {string} $thiskey - parameter key
5198: # @param {string} $showval - the current value
5199: # @param {boolean} $readonly - true if the fields should not be made editable
5200: # @returns {string}
1.549 raeburn 5201: sub string_ip_selector {
1.552 raeburn 5202: my ($thiskey, $showval, $readonly) = @_;
1.549 raeburn 5203: my %access = (
5204: allow => [],
5205: deny => [],
5206: );
5207: if ($showval ne '') {
5208: my @current;
5209: if ($showval =~ /,/) {
5210: @current = split(/,/,$showval);
5211: } else {
5212: @current = ($showval);
5213: }
5214: foreach my $item (@current) {
5215: if ($item =~ /^\!([\[\]a-zA-Z\.\d\*\-]+)$/) {
5216: push(@{$access{'deny'}},$1);
5217: } elsif ($item =~ /^([\[\]a-zA-Z\.\d\*\-]+)$/) {
5218: push(@{$access{'allow'}},$item);
5219: }
5220: }
5221: }
5222: if (!@{$access{'allow'}}) {
5223: @{$access{'allow'}} = ('');
5224: }
5225: if (!@{$access{'deny'}}) {
5226: @{$access{'deny'}} = ('');
5227: }
1.552 raeburn 5228: my ($disabled,$addmore);
1.567 raeburn 5229: if ($readonly) {
1.552 raeburn 5230: $disabled=' disabled="disabled"';
5231: } else {
5232: $addmore = "\n".'<button class="LC_add_ipacc_button">'.&mt('Add more').'</button>';
5233: }
1.549 raeburn 5234: my $output = '<input type="hidden" name="set_'.$thiskey.'" />
5235: <table><tr><th>'.&mt('Allow from').'</th><th>'.&mt('Deny from').'</th></tr><tr>';
5236: foreach my $acctype ('allow','deny') {
5237: $output .= '
5238: <td valign="top">
5239: <div class="LC_string_ipacc_wrap" id="LC_string_ipacc_'.$acctype.'_'.$thiskey.'">
5240: <div class="LC_string_ipacc_inner">'."\n";
5241: my $num = 0;
5242: foreach my $curr (@{$access{$acctype}}) {
1.552 raeburn 5243: $output .= '<div><input type="text" name="setip'.$acctype.'_'.$thiskey.'" value="'.$curr.'"'.$disabled.' />';
1.549 raeburn 5244: if ($num > 0) {
5245: $output .= '<a href="#" class="LC_remove_ipacc">'.&mt('Remove').'</a>';
5246: }
5247: $output .= '</div>'."\n";
5248: $num ++;
5249: }
5250: $output .= '
1.552 raeburn 5251: </div>'.$addmore.'
1.549 raeburn 5252: </div>
5253: </td>';
5254: }
5255: $output .= '
5256: </tr>
5257: </table>'."\n";
5258: return $output;
5259: }
5260:
1.588 raeburn 5261: sub string_deeplink_selector {
5262: my ($thiskey, $showval, $readonly) = @_;
1.616 raeburn 5263: my (@tables,%values,@current,%titles,%options,%optiontext,%defaults,
5264: %selectnull,%domlti,%crslti,@possmenus,%components);
5265: @tables = ('upper','lower');
5266: %components = (
5267: upper => ['state','others','listing','scope'],
5268: lower => ['protect','menus','target','exit'],
5269: );
1.588 raeburn 5270: %titles = &Apache::lonlocal::texthash (
1.601 raeburn 5271: state => 'Access status',
5272: others => 'Hide other resources',
1.588 raeburn 5273: listing => 'In Contents and/or Gradebook',
5274: scope => 'Access scope for link',
1.601 raeburn 5275: protect => 'Link protection',
1.597 raeburn 5276: menus => 'Menu Items Displayed',
1.613 raeburn 5277: target => 'Embedded?',
1.616 raeburn 5278: exit => 'Exit Tool Button?',
1.588 raeburn 5279: );
5280: %options = (
1.601 raeburn 5281: state => ['only','off','both'],
5282: others => ['hide','unhide'],
1.588 raeburn 5283: listing => ['full','absent','grades','details','datestatus'],
5284: scope => ['res','map','rec'],
1.601 raeburn 5285: protect => ['none','key','ltid','ltic'],
1.597 raeburn 5286: menus => ['std','colls'],
1.613 raeburn 5287: target => ['_self','_top'],
1.616 raeburn 5288: exit => ['no','yes','url'],
1.588 raeburn 5289: );
5290: %optiontext = &Apache::lonlocal::texthash (
1.601 raeburn 5291: only => 'deep only',
5292: off => 'deeplink off',
5293: both => 'regular + deep',
5294: hide => 'Hidden',
5295: unhide => 'Unhidden',
1.588 raeburn 5296: full => 'Listed (linked) in both',
5297: absent => 'Not listed',
5298: grades => 'Listed in grades only',
5299: details => 'Listed (unlinked) in both',
5300: datestatus => 'Listed (unlinked) inc. status in both',
5301: res => 'resource only',
5302: map => 'enclosing map/folder',
5303: rec => 'recursive map/folder',
1.601 raeburn 5304: none => 'not in use',
5305: key => 'key access',
5306: ltic => 'LTI access (course)',
5307: ltid => 'LTI access (domain)' ,
1.597 raeburn 5308: std => 'Standard (all menus)',
5309: colls => 'Numbered collection',
1.614 raeburn 5310: _self => 'Embedded',
1.613 raeburn 5311: _top => 'Not embedded',
1.616 raeburn 5312: no => 'Not in use',
5313: yes => 'In use, no URL redirect',
5314: url => 'In use, redirect to URL',
1.597 raeburn 5315: );
5316: %selectnull = &Apache::lonlocal::texthash (
1.601 raeburn 5317: ltic => 'Select Launcher',
5318: ltid => 'Select Launcher',
1.597 raeburn 5319: colls => 'Select',
1.588 raeburn 5320: );
5321: if ($showval =~ /,/) {
1.597 raeburn 5322: %values=();
1.588 raeburn 5323: @current = split(/,/,$showval);
1.601 raeburn 5324: ($values{'state'}) = ($current[0] =~ /^(only|off|both)$/);
5325: ($values{'others'}) = ($current[1] =~ /^(hide|unhide)$/);
5326: ($values{'listing'}) = ($current[2] =~ /^(full|absent|grades|details|datestatus)$/);
5327: ($values{'scope'}) = ($current[3] =~ /^(res|map|rec)$/);
5328: ($values{'protect'}) = ($current[4] =~ /^(key:[a-zA-Z\d_.!\@#\$%^&*()+=-]+|ltic:\d+|ltid:\d+)$/);
5329: ($values{'menus'}) = ($current[5] =~ /^(\d+)$/);
1.613 raeburn 5330: ($values{'target'}) = ($current[6] =~ /^(_self|_top)$/);
1.616 raeburn 5331: ($values{'exit'}) = ($current[7] =~ /^((?:(?:yes|url)(?:|\:[^:;"',]+))|no)$/);
1.588 raeburn 5332: } else {
1.601 raeburn 5333: $defaults{'state'} = 'off',
5334: $defaults{'others'} = 'unhide',
1.588 raeburn 5335: $defaults{'listing'} = 'full';
5336: $defaults{'scope'} = 'res';
1.601 raeburn 5337: $defaults{'protect'} = 'none';
1.597 raeburn 5338: $defaults{'menus'} = '0';
1.613 raeburn 5339: $defaults{'target'} = '_top';
1.616 raeburn 5340: $defaults{'exit'} = 'yes';
1.588 raeburn 5341: }
5342: my $disabled;
5343: if ($readonly) {
5344: $disabled=' disabled="disabled"';
5345: }
1.601 raeburn 5346: my %courselti =
5347: &Apache::lonnet::get_course_lti($env{'course.'.$env{'request.course.id'}.'.num'},
1.620 ! raeburn 5348: $env{'course.'.$env{'request.course.id'}.'.domain'},
! 5349: 'provider');
1.601 raeburn 5350: foreach my $item (keys(%courselti)) {
5351: if (ref($courselti{$item}) eq 'HASH') {
5352: $crslti{$item} = $courselti{$item}{'name'};
5353: }
5354: }
5355: my %lti =
1.588 raeburn 5356: &Apache::lonnet::get_domain_lti($env{'course.'.$env{'request.course.id'}.'.domain'},
1.604 raeburn 5357: 'linkprot');
1.588 raeburn 5358: foreach my $item (keys(%lti)) {
1.604 raeburn 5359: if (($item =~ /^\d+$/) && (ref($lti{$item}) eq 'HASH')) {
5360: $domlti{$item} = $lti{$item}{'name'};
1.588 raeburn 5361: }
5362: }
1.597 raeburn 5363: if ($env{'course.'.$env{'request.course.id'}.'.menucollections'}) {
5364: foreach my $item (split(/;/,$env{'course.'.$env{'request.course.id'}.'.menucollections'})) {
5365: my ($num,$value) = split(/\%/,$item);
5366: if ($num =~ /^\d+$/) {
5367: push(@possmenus,$num);
5368: }
5369: }
5370: }
5371:
1.616 raeburn 5372: my $output = '<input type="hidden" name="set_'.$thiskey.'" />';
5373: foreach my $table ('upper','lower') {
5374: next unless (ref($components{$table}) eq 'ARRAY');
5375: $output .= '<table width="100%"><tr>';
5376: foreach my $item (@{$components{$table}}) {
5377: $output .= '<th>'.$titles{$item}.'</th>';
5378: }
5379: $output .= '</tr><tr>';
5380: foreach my $item (@{$components{$table}}) {
5381: $output .= '<td>';
5382: if (($item eq 'protect') || ($item eq 'menus') || ($item eq 'exit')) {
5383: my $selected = $values{$item};
5384: foreach my $option (@{$options{$item}}) {
5385: if ($item eq 'protect') {
5386: if ($option eq 'ltid') {
5387: next unless (keys(%domlti));
5388: } elsif ($option eq 'ltic') {
5389: next unless (keys(%crslti));
5390: }
5391: } elsif (($item eq 'menus') && ($option eq 'colls')) {
5392: next unless (@possmenus);
5393: }
5394: my $checked;
5395: if ($item eq 'menus') {
5396: if (($selected =~ /^\d+$/) && (@possmenus) &&
5397: (grep(/^\Q$selected\E$/,@possmenus))) {
5398: if ($option eq 'colls') {
5399: $checked = ' checked="checked"';
5400: }
5401: } elsif (($option eq 'std') && ($selected == 0) && ($selected ne '')) {
1.597 raeburn 5402: $checked = ' checked="checked"';
5403: }
1.616 raeburn 5404: } elsif ($selected =~ /^\Q$option\E/) {
1.597 raeburn 5405: $checked = ' checked="checked"';
5406: }
1.616 raeburn 5407: my $onclick;
5408: unless ($readonly) {
5409: my $esc_key = &js_escape($thiskey);
5410: $onclick = ' onclick="toggleDeepLink(this.form,'."'$item','$esc_key'".');"';
5411: }
5412: $output .= '<span class="LC_nobreak"><label>'.
5413: '<input type="radio" name="deeplink_'.$item.'_'.$thiskey.'" value="'.$option.'"'.$onclick.$disabled.$checked.' />'."\n".
5414: $optiontext{$option}.'</label>';
5415: if (($item eq 'protect') && ($option eq 'key')) {
5416: my $visibility="hidden";
5417: my $currkey;
5418: if ($checked) {
5419: $visibility = "text";
5420: $currkey = (split(/\:/,$values{$item}))[1];
5421: }
5422: $output .= ' '.
5423: '<input type="'.$visibility.'" name="deeplink_'.$option.'_'.$thiskey.'" id="deeplink_'.$option.'_'.$item.'_'.$thiskey.'" value="'.$currkey.'" size="10"'.$disabled.' />';
5424: } elsif (($option eq 'ltic') || ($option eq 'ltid') || ($option eq 'colls')) {
5425: my $display="none";
5426: my ($current,$blankcheck,@possibles);
5427: if ($checked) {
5428: $display = 'inline-block';
5429: if (($option eq 'ltic') || ($option eq 'ltid')) {
5430: $current = (split(/\:/,$selected))[1];
5431: } else {
5432: $current = $selected;
5433: }
1.597 raeburn 5434: } else {
1.616 raeburn 5435: $blankcheck = ' selected="selected"';
1.597 raeburn 5436: }
1.601 raeburn 5437: if ($option eq 'ltid') {
1.616 raeburn 5438: @possibles = keys(%domlti);
1.601 raeburn 5439: } elsif ($option eq 'ltic') {
1.616 raeburn 5440: @possibles = keys(%crslti);
5441: } else {
5442: @possibles = @possmenus;
5443: }
5444: $output .= '<div id="deeplinkdiv_'.$option.'_'.$item.'_'.$thiskey.'"'.
5445: ' style="display: '.$display.'"> <select name="'.
5446: 'deeplink_'.$option.'_'.$thiskey.'"'.$disabled.'>';
5447: if (@possibles > 1) {
5448: $output .= '<option value=""'.$blankcheck.'>'.$selectnull{$option}.
5449: '</option>'."\n";
5450: }
5451: foreach my $poss (sort { $a <=> $b } @possibles) {
5452: my $selected;
5453: if (($poss == $current) || (scalar(@possibles) ==1)) {
5454: $selected = ' selected="selected"';
5455: }
5456: my $shown = $poss;
5457: if ($option eq 'ltid') {
5458: $shown = $domlti{$poss};
5459: } elsif ($option eq 'ltic') {
5460: $shown = $crslti{$poss};
5461: }
5462: $output .= '<option value="'.$poss.'"'.$selected.'>'.$shown.'</option>';
5463: }
5464: $output .= '</select></div>';
5465: }
5466: $output .= '</span> ';
5467: }
5468: if ($item eq 'exit') {
5469: my $exitsty = 'none';
5470: my $displayval;
5471: if ($values{$item} =~ /^(yes|url)/) {
5472: $exitsty = 'inline-block';
5473: my $currval = (split(/\:/,$values{$item}))[1];
5474: if ($currval eq '') {
5475: $displayval = 'Exit Tool';
5476: } else {
5477: $displayval = $currval;
1.597 raeburn 5478: }
1.588 raeburn 5479: }
1.616 raeburn 5480: $output .= '<div id="deeplinkdiv_'.$item.'_'.$thiskey.'"'.
5481: ' style="display: '.$exitsty.'"><br />'.&mt('Button text').': '.
5482: '<input type="text" name="deeplink_exittext_'.$thiskey.'"'.
5483: ' id="deeplink_exittext_'.$thiskey.'" value="'.$displayval.'"'.
5484: ' size="10"'.$disabled.' /></div>';
1.588 raeburn 5485: }
1.616 raeburn 5486: } else {
5487: my $selected = $values{$item};
5488: my $defsel;
5489: if ($selected eq '') {
5490: $defsel = ' selected="selected"';
5491: }
5492: $output .= '<select name="deeplink_'.$item.'_'.$thiskey.'"'.$disabled.'>'."\n".
5493: '<option value=""'.$defsel.'>'.&mt('Please select').'</option>'."\n";
5494: foreach my $option (@{$options{$item}}) {
5495: $output .= '<option value="'.$option.'"';
5496: if ($option eq $selected) {
5497: $output .= ' selected="selected"';
5498: }
5499: $output .= '>'.$optiontext{$option}.'</option>';
1.588 raeburn 5500: }
1.616 raeburn 5501: $output .= '</select>';
1.588 raeburn 5502: }
1.616 raeburn 5503: $output .= '</td>';
5504: }
5505: $output .= '</tr></table>'."\n";
5506: if ($table eq 'upper') {
5507: $output .= '<br />';
1.588 raeburn 5508: }
5509: }
5510: return $output;
5511: }
5512:
1.560 damieng 5513:
5514: { # block using some constants related to parameter types (overview mode)
5515:
1.446 bisitz 5516: my %strings =
1.383 albertel 5517: (
5518: 'string_yesno'
5519: => [[ 'yes', 'Yes' ],
1.560 damieng 5520: [ 'no', 'No' ]],
1.383 albertel 5521: 'string_problemstatus'
5522: => [[ 'yes', 'Yes' ],
1.473 amueller 5523: [ 'answer', 'Yes, and show correct answer if they exceed the maximum number of tries.' ],
5524: [ 'no', 'No, don\'t show correct/incorrect feedback.' ],
5525: [ 'no_feedback_ever', 'No, show no feedback at all.' ]],
1.504 raeburn 5526: 'string_questiontype'
5527: => [[ 'problem', 'Standard Problem'],
5528: [ 'survey', 'Survey'],
5529: [ 'anonsurveycred', 'Anonymous Survey (credit for submission)'],
1.530 bisitz 5530: [ 'exam', 'Bubblesheet Exam'],
1.504 raeburn 5531: [ 'anonsurvey', 'Anonymous Survey'],
5532: [ 'randomizetry', 'New Randomization Each N Tries (default N=1)'],
5533: [ 'practice', 'Practice'],
5534: [ 'surveycred', 'Survey (credit for submission)']],
1.514 raeburn 5535: 'string_lenient'
5536: => [['yes', 'Yes' ],
5537: [ 'no', 'No' ],
1.549 raeburn 5538: [ 'default', 'Default - only bubblesheet grading is lenient' ],
5539: [ 'weighted', 'Yes, weighted (optionresponse in checkbox mode)' ]],
1.521 raeburn 5540: 'string_discussvote'
5541: => [['yes','Yes'],
5542: ['notended','Yes, unless discussion ended'],
5543: ['no','No']],
1.549 raeburn 5544: 'string_ip'
5545: => [['_allowfrom_','Hostname(s), or IP(s) from which access is allowed'],
1.587 raeburn 5546: ['_denyfrom_','Hostname(s) or IP(s) from which access is disallowed']],
5547: 'string_deeplink'
1.616 raeburn 5548: => [['on','Set choices for link protection, resource listing, access scope, shown menu items, embedding, and exit link']],
1.587 raeburn 5549: );
5550:
1.383 albertel 5551:
1.549 raeburn 5552: my %stringmatches = (
5553: 'string_lenient'
5554: => [['weighted','^\-?[.\d]+,\-?[.\d]+,\-?[.\d]+,\-?[.\d]+$'],],
5555: 'string_ip'
5556: => [['_allowfrom_','[^\!]+'],
5557: ['_denyfrom_','\!']],
1.588 raeburn 5558: 'string_deeplink'
1.616 raeburn 5559: => [['on','^(only|off|both)\,(hide|unhide)\,(full|absent|grades|details|datestatus)\,(res|map|rec)\,(none|key\:\w+|ltic\:\d+|ltid\:\d+)\,(\d+|)\,_(self|top),(yes|url|no)(|:[^:;\'",]+)$']],
1.549 raeburn 5560: );
5561:
5562: my %stringtypes = (
5563: type => 'string_questiontype',
5564: lenient => 'string_lenient',
5565: retrypartial => 'string_yesno',
5566: discussvote => 'string_discussvote',
5567: examcode => 'string_examcode',
5568: acc => 'string_ip',
1.587 raeburn 5569: deeplink => 'string_deeplink',
1.549 raeburn 5570: );
5571:
1.563 damieng 5572: # Returns the possible values and titles for a given string type, or undef if there are none.
5573: # Used by courseprefs.
5574: #
5575: # @param {string} $string_type - a parameter type for strings
5576: # @returns {array reference} - 2D array, containing values and English titles
1.505 raeburn 5577: sub standard_string_options {
5578: my ($string_type) = @_;
5579: if (ref($strings{$string_type}) eq 'ARRAY') {
5580: return $strings{$string_type};
5581: }
5582: return;
5583: }
1.383 albertel 5584:
1.563 damieng 5585: # Returns regular expressions to match kinds of string types, or undef if there are none.
5586: #
5587: # @param {string} $string_type - a parameter type for strings
5588: # @returns {array reference} - 2D array, containing regular expression names and regular expressions
1.549 raeburn 5589: sub standard_string_matches {
5590: my ($string_type) = @_;
5591: if (ref($stringmatches{$string_type}) eq 'ARRAY') {
5592: return $stringmatches{$string_type};
5593: }
5594: return;
5595: }
5596:
1.563 damieng 5597: # Returns a parameter type for a given parameter with a string type, or undef if not known.
5598: #
5599: # @param {string} $name - parameter name
5600: # @returns {string}
1.549 raeburn 5601: sub get_stringtype {
5602: my ($name) = @_;
5603: if (exists($stringtypes{$name})) {
5604: return $stringtypes{$name};
5605: }
5606: return;
5607: }
5608:
1.563 damieng 5609: # Returns HTML to edit a string parameter.
5610: #
5611: # @param {string} $thistype - parameter type
5612: # @param {string} $thiskey - parameter key
5613: # @param {string} $showval - parameter current value
5614: # @param {string} $name - parameter name
5615: # @param {boolean} $readonly - true if the values should not be made editable
5616: # @returns {string}
1.383 albertel 5617: sub string_selector {
1.552 raeburn 5618: my ($thistype, $thiskey, $showval, $name, $readonly) = @_;
1.446 bisitz 5619:
1.383 albertel 5620: if (!exists($strings{$thistype})) {
1.552 raeburn 5621: return &default_selector($thiskey,$showval,$readonly);
1.383 albertel 5622: }
5623:
1.504 raeburn 5624: my %skiptype;
1.514 raeburn 5625: if (($thistype eq 'string_questiontype') ||
1.560 damieng 5626: ($thistype eq 'string_lenient') ||
5627: ($thistype eq 'string_discussvote') ||
5628: ($thistype eq 'string_ip') ||
1.588 raeburn 5629: ($thistype eq 'string_deeplink') ||
1.560 damieng 5630: ($name eq 'retrypartial')) {
1.504 raeburn 5631: my ($got_chostname,$chostname,$cmajor,$cminor);
5632: foreach my $possibilities (@{ $strings{$thistype} }) {
5633: next unless (ref($possibilities) eq 'ARRAY');
1.514 raeburn 5634: my ($parmval, $description) = @{ $possibilities };
1.549 raeburn 5635: my $parmmatch;
5636: if (ref($stringmatches{$thistype}) eq 'ARRAY') {
5637: foreach my $item (@{$stringmatches{$thistype}}) {
5638: if (ref($item) eq 'ARRAY') {
5639: if ($parmval eq $item->[0]) {
5640: $parmmatch = $parmval;
5641: $parmval = '';
5642: last;
5643: }
5644: }
5645: }
5646: }
5647: my $needsrelease=$Apache::lonnet::needsrelease{"parameter:$name:$parmval:$parmmatch"};
1.504 raeburn 5648: if ($needsrelease) {
5649: unless ($got_chostname) {
1.514 raeburn 5650: ($chostname,$cmajor,$cminor)=¶meter_release_vars();
1.504 raeburn 5651: $got_chostname = 1;
5652: }
1.557 raeburn 5653: my $needsnewer=¶meter_releasecheck($name,$parmval,$parmmatch,undef,
1.549 raeburn 5654: $needsrelease,$cmajor,$cminor);
1.504 raeburn 5655: if ($needsnewer) {
1.549 raeburn 5656: if ($parmmatch ne '') {
5657: $skiptype{$parmmatch} = 1;
5658: } elsif ($parmval ne '') {
5659: $skiptype{$parmval} = 1;
5660: }
1.504 raeburn 5661: }
5662: }
5663: }
5664: }
1.549 raeburn 5665:
5666: if ($thistype eq 'string_ip') {
1.552 raeburn 5667: return &string_ip_selector($thiskey,$showval,$readonly);
1.588 raeburn 5668: } elsif ($thistype eq 'string_deeplink') {
5669: return &string_deeplink_selector($thiskey,$showval,$readonly);
1.549 raeburn 5670: }
1.504 raeburn 5671:
1.552 raeburn 5672: my ($result,$disabled);
5673:
5674: if ($readonly) {
5675: $disabled = ' disabled="disabled"';
5676: }
1.504 raeburn 5677: my $numinrow = 3;
5678: if ($thistype eq 'string_problemstatus') {
5679: $numinrow = 2;
5680: } elsif ($thistype eq 'string_questiontype') {
5681: if (keys(%skiptype) > 0) {
5682: $numinrow = 4;
5683: }
5684: }
5685: my $rem;
5686: if (ref($strings{$thistype}) eq 'ARRAY') {
5687: my $i=0;
5688: foreach my $possibilities (@{ $strings{$thistype} }) {
5689: next unless (ref($possibilities) eq 'ARRAY');
5690: my ($name, $description) = @{ $possibilities };
1.549 raeburn 5691: next if ($skiptype{$name});
1.504 raeburn 5692: $rem = $i%($numinrow);
5693: if ($rem == 0) {
5694: if ($i > 0) {
5695: $result .= '</tr>';
5696: }
5697: $result .= '<tr>';
5698: }
1.549 raeburn 5699: my $colspan;
5700: if ($i == @{ $strings{$thistype} }-1) {
5701: $rem = @{ $strings{$thistype} }%($numinrow);
5702: if ($rem) {
5703: my $colsleft = $numinrow - $rem;
5704: if ($colsleft) {
5705: $colspan = $colsleft+1;
5706: $colspan = ' colspan="'.$colspan.'"';
5707: }
5708: }
5709: }
5710: my ($add,$onchange,$css_class);
5711: if ($thistype eq 'string_lenient') {
5712: if ($name eq 'weighted') {
5713: my $display;
5714: my %relatives = &Apache::lonlocal::texthash(
5715: corrchkd => 'Correct (checked)',
5716: corrunchkd => 'Correct (unchecked)',
5717: incorrchkd => 'Incorrect (checked)',
5718: incorrunchkd => 'Incorrect (unchecked)',
5719: );
5720: my %textval = (
5721: corrchkd => '1.0',
5722: corrunchkd => '1.0',
5723: incorrchkd => '0.0',
5724: incorrunchkd => '0.0',
5725: );
5726: if ($showval =~ /^([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)$/) {
5727: $textval{'corrchkd'} = $1;
5728: $textval{'corrunchkd'} = $2;
5729: $textval{'incorrchkd'} = $3;
5730: $textval{'incorrunchkd'} = $4;
5731: $display = 'inline';
5732: $showval = $name;
5733: } else {
5734: $display = 'none';
5735: }
5736: $add = ' <div id="LC_parmtext_'.$thiskey.'" style="display:'.$display.'"><table>'.
5737: '<tr><th colspan="2">'.&mt("Foil's submission status").'</th><th>'.&mt('Points').'</th></tr>';
5738: foreach my $reltype ('corrchkd','corrunchkd','incorrchkd','incorrunchkd') {
5739: $add .= '<tr><td> </td><td>'.$relatives{$reltype}.'</td>'."\n".
5740: '<td><input type="text" name="settext_'.$thiskey.'"'.
1.552 raeburn 5741: ' value="'.$textval{$reltype}.'" size="3"'.$disabled.' />'.
1.549 raeburn 5742: '</td></tr>';
5743: }
5744: $add .= '</table></div>'."\n";
5745: }
5746: $onchange = ' onclick="javascript:toggleParmTextbox(this.form,'."'$thiskey'".');"';
5747: $css_class = ' class="LC_lenient_radio"';
5748: }
5749: $result .= '<td class="LC_left_item"'.$colspan.'>'.
1.504 raeburn 5750: '<span class="LC_nobreak"><label>'.
5751: '<input type="radio" name="set_'.$thiskey.
1.552 raeburn 5752: '" value="'.$name.'"'.$onchange.$css_class.$disabled;
1.504 raeburn 5753: if ($showval eq $name) {
5754: $result .= ' checked="checked"';
5755: }
1.549 raeburn 5756: $result .= ' />'.&mt($description).'</label>'.$add.'</span></td>';
1.504 raeburn 5757: $i++;
5758: }
5759: $result .= '</tr>';
1.473 amueller 5760: }
1.504 raeburn 5761: if ($result) {
5762: $result = '<table border="0">'.$result.'</table>';
1.383 albertel 5763: }
5764: return $result;
5765: }
5766:
1.554 raeburn 5767: my %intervals =
5768: (
5769: 'date_interval'
5770: => [[ 'done', 'Yes' ],
1.558 raeburn 5771: [ 'done_proctor', 'Yes, with proctor key'],
1.554 raeburn 5772: [ '', 'No' ]],
5773: );
5774:
5775: my %intervalmatches = (
5776: 'date_interval'
1.559 raeburn 5777: => [['done','\d+_done(|\:[^\:]+\:)$'],
5778: ['done_proctor','\d+_done(|\:[^\:]+\:)_proctor_']],
1.554 raeburn 5779: );
5780:
5781: my %intervaltypes = (
5782: interval => 'date_interval',
5783: );
5784:
1.563 damieng 5785: # Returns regular expressions to match kinds of interval type, or undef if there are none.
5786: #
5787: # @param {string} $interval_type - a parameter type for intervals
5788: # @returns {array reference} - 2D array, containing regular expression names and regular expressions
1.554 raeburn 5789: sub standard_interval_matches {
5790: my ($interval_type) = @_;
5791: if (ref($intervalmatches{$interval_type}) eq 'ARRAY') {
5792: return $intervalmatches{$interval_type};
5793: }
5794: return;
5795: }
5796:
1.563 damieng 5797: # Returns a parameter type for a given parameter with an interval type, or undef if not known.
5798: #
5799: # @param {string} $name - parameter name
5800: # @returns {string}
1.554 raeburn 5801: sub get_intervaltype {
5802: my ($name) = @_;
5803: if (exists($intervaltypes{$name})) {
5804: return $intervaltypes{$name};
5805: }
5806: return;
5807: }
5808:
1.563 damieng 5809: # Returns the possible values and titles for a given interval type, or undef if there are none.
5810: # Used by courseprefs.
5811: #
5812: # @param {string} $interval_type - a parameter type for intervals
5813: # @returns {array reference} - 2D array, containing values and English titles
1.554 raeburn 5814: sub standard_interval_options {
5815: my ($interval_type) = @_;
5816: if (ref($intervals{$interval_type}) eq 'ARRAY') {
5817: return $intervals{$interval_type};
5818: }
5819: return;
5820: }
5821:
1.563 damieng 5822: # Returns HTML to edit a date interval parameter.
5823: #
5824: # @param {string} $thiskey - parameter key
5825: # @param {string} $name - parameter name
5826: # @param {string} $showval - parameter current value
5827: # @param {boolean} $readonly - true if the values should not be made editable
5828: # @returns {string}
1.554 raeburn 5829: sub date_interval_selector {
5830: my ($thiskey, $name, $showval, $readonly) = @_;
5831: my ($result,%skipval);
5832: if ($name eq 'interval') {
5833: my $intervaltype = &get_intervaltype($name);
5834: my ($got_chostname,$chostname,$cmajor,$cminor);
5835: foreach my $possibilities (@{ $intervals{$intervaltype} }) {
5836: next unless (ref($possibilities) eq 'ARRAY');
5837: my ($parmval, $description) = @{ $possibilities };
5838: my $parmmatch;
5839: if (ref($intervalmatches{$intervaltype}) eq 'ARRAY') {
5840: foreach my $item (@{$intervalmatches{$intervaltype}}) {
5841: if (ref($item) eq 'ARRAY') {
5842: if ($parmval eq $item->[0]) {
5843: $parmmatch = $parmval;
5844: $parmval = '';
5845: last;
5846: }
5847: }
5848: }
5849: }
5850: my $needsrelease=$Apache::lonnet::needsrelease{"parameter:$name:$parmval:$parmmatch"};
5851: if ($needsrelease) {
5852: unless ($got_chostname) {
5853: ($chostname,$cmajor,$cminor)=¶meter_release_vars();
5854: $got_chostname = 1;
5855: }
1.557 raeburn 5856: my $needsnewer=¶meter_releasecheck($name,$parmval,$parmmatch,undef,
1.554 raeburn 5857: $needsrelease,$cmajor,$cminor);
5858: if ($needsnewer) {
5859: if ($parmmatch ne '') {
5860: $skipval{$parmmatch} = 1;
5861: } elsif ($parmval ne '') {
5862: $skipval{$parmval} = 1;
5863: }
5864: }
5865: }
5866: }
5867: }
5868:
5869: my $currval = $showval;
5870: foreach my $which (['days', 86400, 31],
5871: ['hours', 3600, 23],
5872: ['minutes', 60, 59],
5873: ['seconds', 1, 59]) {
1.560 damieng 5874: my ($name, $factor, $max) = @{ $which };
5875: my $amount = int($showval/$factor);
5876: $showval %= $factor;
5877: my %select = ((map {$_ => $_} (0..$max)),
5878: 'select_form_order' => [0..$max]);
1.611 raeburn 5879: if ($currval eq '') {
5880: unshift(@{$select{'select_form_order'}},'');
5881: $select{''} = '';
5882: $amount = '';
5883: }
1.560 damieng 5884: $result .= &Apache::loncommon::select_form($amount,$name.'_'.$thiskey,
5885: \%select,'',$readonly);
5886: $result .= ' '.&mt($name);
1.554 raeburn 5887: }
5888: if ($name eq 'interval') {
5889: unless ($skipval{'done'}) {
5890: my $checkedon = '';
1.611 raeburn 5891: my $checkedoff = '';
1.558 raeburn 5892: my $checkedproc = '';
5893: my $currproctorkey = '';
5894: my $currprocdisplay = 'hidden';
1.559 raeburn 5895: my $currdonetext = &mt('Done');
5896: if ($currval =~ /^(?:\d+)_done$/) {
5897: $checkedon = ' checked="checked"';
5898: } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:$/) {
5899: $currdonetext = $1;
1.554 raeburn 5900: $checkedon = ' checked="checked"';
1.558 raeburn 5901: } elsif ($currval =~ /^(?:\d+)_done_proctor_(.+)$/) {
5902: $currproctorkey = $1;
5903: $checkedproc = ' checked="checked"';
5904: $currprocdisplay = 'text';
1.559 raeburn 5905: } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:_proctor_(.+)$/) {
5906: $currdonetext = $1;
5907: $currproctorkey = $2;
5908: $checkedproc = ' checked="checked"';
5909: $currprocdisplay = 'text';
1.611 raeburn 5910: } elsif ($currval ne '') {
5911: $checkedoff = ' checked="checked"';
5912: } else {
5913: $currdonetext = '';
1.554 raeburn 5914: }
1.558 raeburn 5915: my $onclick = ' onclick="toggleSecret(this.form,'."'done_','$thiskey'".');"';
1.567 raeburn 5916: my $disabled;
5917: if ($readonly) {
5918: $disabled = ' disabled="disabled"';
5919: }
1.558 raeburn 5920: $result .= '<br /><span class="LC_nobreak">'.&mt('Include "done" button').
1.567 raeburn 5921: '<label><input type="radio" value="" name="done_'.$thiskey.'"'.$checkedoff.$onclick.$disabled.' />'.
1.558 raeburn 5922: &mt('No').'</label>'.(' 'x2).
1.567 raeburn 5923: '<label><input type="radio" value="_done" name="done_'.$thiskey.'"'.$checkedon.$onclick.$disabled.' />'.
1.558 raeburn 5924: &mt('Yes').'</label>'.(' 'x2).
1.567 raeburn 5925: '<label><input type="radio" value="_done_proctor" name="done_'.$thiskey.'"'.$checkedproc.$onclick.$disabled.' />'.
1.558 raeburn 5926: &mt('Yes, with proctor key').'</label>'.
5927: '<input type="'.$currprocdisplay.'" id="done_'.$thiskey.'_proctorkey" '.
1.567 raeburn 5928: 'name="done_'.$thiskey.'_proctorkey" value="'.&HTML::Entities::encode($currproctorkey,'"<>&').'"'.$disabled.' /></span><br />'.
1.559 raeburn 5929: '<span class="LC_nobreak">'.&mt('Button text').': '.
1.611 raeburn 5930: '<input type="text" name="done_'.$thiskey.'_buttontext" id="done_'.$thiskey.'_buttontext" value="'.
5931: &HTML::Entities::encode($currdonetext,'"<>&').'"'.$disabled.' /></span>';
1.554 raeburn 5932: }
5933: }
5934: unless ($readonly) {
5935: $result .= '<input type="hidden" name="dateinterval_'.$thiskey.'" />';
5936: }
5937: return $result;
5938: }
5939:
1.563 damieng 5940: # Returns HTML with a warning if a parameter requires a more recent version of LON-CAPA.
5941: #
5942: # @param {string} $name - parameter name
5943: # @param {string} $namematch - parameter level name (recognized: resourcelevel|maplevel|maplevelrecurse|courselevel)
5944: # @param {string} $value - parameter value
5945: # @param {string} $chostname - course server name
5946: # @param {integer} $cmajor - major version number
5947: # @param {integer} $cminor - minor version number
5948: # @param {string} $needsrelease - release version needed (major.minor)
5949: # @returns {string}
1.549 raeburn 5950: sub oldversion_warning {
1.557 raeburn 5951: my ($name,$namematch,$value,$chostname,$cmajor,$cminor,$needsrelease) = @_;
5952: my $standard_name = &standard_parameter_names($name);
5953: if ($namematch) {
5954: my $level = &standard_parameter_levels($namematch);
5955: my $msg = '';
5956: if ($level) {
5957: $msg = &mt('[_1] was [_2]not[_3] set at the level of: [_4].',
5958: $standard_name,'<b>','</b>','"'.$level.'"');
5959: } else {
5960: $msg = &mt('[_1] was [_2]not[_3] set.',
5961: $standard_name,'<b>','</b>');
5962: }
5963: return '<p class="LC_warning">'.$msg.'<br />'.
5964: &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',
5965: $cmajor.'.'.$cminor,$chostname,
5966: $needsrelease).
5967: '</p>';
5968: }
1.549 raeburn 5969: my $desc;
5970: my $stringtype = &get_stringtype($name);
5971: if ($stringtype ne '') {
5972: if ($name eq 'examcode') {
5973: $desc = $value;
5974: } elsif (ref($strings{$stringtypes{$name}}) eq 'ARRAY') {
5975: foreach my $possibilities (@{ $strings{$stringtypes{$name}} }) {
5976: next unless (ref($possibilities) eq 'ARRAY');
5977: my ($parmval, $description) = @{ $possibilities };
5978: my $parmmatch;
5979: if (ref($stringmatches{$stringtypes{$name}}) eq 'ARRAY') {
5980: foreach my $item (@{$stringmatches{$stringtypes{$name}}}) {
5981: if (ref($item) eq 'ARRAY') {
5982: my ($regexpname,$pattern) = @{$item};
5983: if ($parmval eq $regexpname) {
5984: if ($value =~ /$pattern/) {
5985: $desc = $description;
5986: $parmmatch = 1;
5987: last;
5988: }
5989: }
5990: }
5991: }
5992: last if ($parmmatch);
5993: } elsif ($parmval eq $value) {
5994: $desc = $description;
5995: last;
5996: }
5997: }
5998: }
5999: } elsif (($name eq 'printstartdate') || ($name eq 'printenddate')) {
6000: my $now = time;
6001: if ($value =~ /^\d+$/) {
6002: if ($name eq 'printstartdate') {
6003: if ($value > $now) {
6004: $desc = &Apache::lonlocal::locallocaltime($value);
6005: }
6006: } elsif ($name eq 'printenddate') {
6007: if ($value < $now) {
6008: $desc = &Apache::lonlocal::locallocaltime($value);
6009: }
6010: }
6011: }
6012: }
6013: return '<p class="LC_warning">'.
1.557 raeburn 6014: &mt('[_1] was [_2]not[_3] set to [_4].',
6015: $standard_name,'<b>','</b>','"'.$desc.'"').'<br />'.
6016: &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',
6017: $cmajor.'.'.$cminor,$chostname,
6018: $needsrelease).
6019: '</p>';
1.549 raeburn 6020: }
6021:
1.560 damieng 6022: } # end of block using some constants related to parameter types
6023:
1.549 raeburn 6024:
1.563 damieng 6025:
6026: # Shifts all start and end dates in the current course by $shift.
1.389 www 6027: #
1.563 damieng 6028: # @param {integer} $shift - time to shift, in seconds
6029: # @returns {string} - error name or 'ok'
1.389 www 6030: sub dateshift {
1.594 raeburn 6031: my ($shift,$numchanges)=@_;
1.389 www 6032: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
6033: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.594 raeburn 6034: my $sec = $env{'request.course.sec'};
1.595 raeburn 6035: my $secgrpregex;
6036: if ($sec ne '') {
6037: my @groups;
6038: if ($env{'request.course.groups'} ne '') {
6039: @groups = split(/:/,$env{'request.course.groups'});
6040: }
6041: if (@groups) {
6042: $secgrpregex = '(?:'.join('|',($sec,@groups)).')';
6043: } else {
6044: $secgrpregex = $sec;
6045: }
6046: }
1.389 www 6047: my %data=&Apache::lonnet::dump('resourcedata',$dom,$crs);
6048: # ugly retro fix for broken version of types
1.548 raeburn 6049: foreach my $key (keys(%data)) {
1.389 www 6050: if ($key=~/\wtype$/) {
6051: my $newkey=$key;
6052: $newkey=~s/type$/\.type/;
6053: $data{$newkey}=$data{$key};
6054: delete $data{$key};
6055: }
6056: }
1.391 www 6057: my %storecontent=();
1.389 www 6058: # go through all parameters and look for dates
1.548 raeburn 6059: foreach my $key (keys(%data)) {
1.389 www 6060: if ($data{$key.'.type'}=~/^date_(start|end)$/) {
1.594 raeburn 6061: if ($sec ne '') {
1.595 raeburn 6062: next unless ($key =~ /^$env{'request.course.id'}\.\[$secgrpregex\]\./);
1.594 raeburn 6063: }
1.389 www 6064: my $newdate=$data{$key}+$shift;
1.594 raeburn 6065: $$numchanges ++;
1.391 www 6066: $storecontent{$key}=$newdate;
1.389 www 6067: }
6068: }
1.391 www 6069: my $reply=&Apache::lonnet::cput
6070: ('resourcedata',\%storecontent,$dom,$crs);
6071: if ($reply eq 'ok') {
6072: &log_parmset(\%storecontent);
6073: }
6074: &Apache::lonnet::devalidatecourseresdata($crs,$dom);
6075: return $reply;
1.389 www 6076: }
6077:
1.563 damieng 6078: # Overview mode UI to edit course parameters.
6079: #
6080: # @param {Apache2::RequestRec} $r - the Apache request
1.208 www 6081: sub newoverview {
1.568 raeburn 6082: my ($r,$parm_permission) = @_;
1.280 albertel 6083:
1.208 www 6084: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
6085: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 6086: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.568 raeburn 6087: my $readonly = 1;
6088: if ($parm_permission->{'edit'}) {
6089: undef($readonly);
6090: }
1.414 droeschl 6091: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
1.473 amueller 6092: text=>"Overview Mode"});
1.523 raeburn 6093:
6094: my %loaditems = (
1.549 raeburn 6095: 'onload' => "showHide_courseContent(); resize_scrollbox('mapmenuscroll','1','1'); showHideLenient();",
1.523 raeburn 6096: );
6097: my $js = '
6098: <script type="text/javascript">
6099: // <![CDATA[
6100: '.
6101: &Apache::lonhtmlcommon::resize_scrollbox_js('params')."\n".
6102: &showhide_js()."\n".
1.549 raeburn 6103: &toggleparmtextbox_js()."\n".
6104: &validateparms_js()."\n".
6105: &ipacc_boxes_js()."\n".
1.558 raeburn 6106: &done_proctor_js()."\n".
1.588 raeburn 6107: &deeplink_js()."\n".
1.523 raeburn 6108: '// ]]>
6109: </script>
6110: ';
1.549 raeburn 6111:
1.523 raeburn 6112: my $start_page = &Apache::loncommon::start_page('Set Parameters',$js,
6113: {'add_entries' => \%loaditems,});
1.298 albertel 6114: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
1.507 www 6115: $r->print($start_page.$breadcrumbs);
1.531 raeburn 6116: &startSettingsScreen($r,'parmset',$crstype);
1.208 www 6117: $r->print(<<ENDOVER);
1.549 raeburn 6118: <form method="post" action="/adm/parmset?action=newoverview" name="parmform" onsubmit="return validateParms();">
1.208 www 6119: ENDOVER
1.211 www 6120: my @ids=();
6121: my %typep=();
6122: my %keyp=();
6123: my %allparms=();
6124: my %allparts=();
6125: my %allmaps=();
6126: my %mapp=();
6127: my %symbp=();
6128: my %maptitles=();
6129: my %uris=();
6130: my %keyorder=&standardkeyorder();
6131: my %defkeytype=();
6132:
6133: my %alllevs=();
6134: $alllevs{'Resource Level'}='full';
1.215 www 6135: $alllevs{'Map/Folder Level'}='map';
1.211 www 6136: $alllevs{'Course Level'}='general';
6137:
6138: my $csec=$env{'form.csec'};
1.269 raeburn 6139: my $cgroup=$env{'form.cgroup'};
1.211 www 6140:
6141: my @pscat=&Apache::loncommon::get_env_multiple('form.pscat');
6142: my $pschp=$env{'form.pschp'};
1.506 www 6143:
1.211 www 6144: my @psprt=&Apache::loncommon::get_env_multiple('form.psprt');
1.516 www 6145: if (!@psprt) { $psprt[0]='all'; }
1.211 www 6146:
1.446 bisitz 6147: my @selected_sections =
1.473 amueller 6148: &Apache::loncommon::get_env_multiple('form.Section');
1.211 www 6149: @selected_sections = ('all') if (! @selected_sections);
1.374 albertel 6150: foreach my $sec (@selected_sections) {
6151: if ($sec eq 'all') {
1.211 www 6152: @selected_sections = ('all');
6153: }
6154: }
1.552 raeburn 6155: if ($env{'request.course.sec'} ne '') {
6156: @selected_sections = ($env{'request.course.sec'});
6157: }
1.269 raeburn 6158: my @selected_groups =
6159: &Apache::loncommon::get_env_multiple('form.Group');
1.211 www 6160:
6161: my $pssymb='';
6162: my $parmlev='';
1.446 bisitz 6163:
1.211 www 6164: unless ($env{'form.parmlev'}) {
6165: $parmlev = 'map';
6166: } else {
6167: $parmlev = $env{'form.parmlev'};
6168: }
6169:
1.446 bisitz 6170: &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
1.473 amueller 6171: \%mapp, \%symbp,\%maptitles,\%uris,
1.603 raeburn 6172: \%keyorder,\%defkeytype,$pssymb);
1.211 www 6173:
1.374 albertel 6174: if (grep {$_ eq 'all'} (@psprt)) {
1.481 amueller 6175: @psprt = keys(%allparts);
1.374 albertel 6176: }
1.211 www 6177: # Menu to select levels, etc
6178:
1.456 bisitz 6179: $r->print('<div class="LC_Box">');
1.445 neumanie 6180: #$r->print('<h2 class="LC_hcell">Step 1</h2>');
1.452 bisitz 6181: $r->print('<div>');
1.523 raeburn 6182: $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel'));
1.211 www 6183: &levelmenu($r,\%alllevs,$parmlev);
1.610 raeburn 6184: $r->print(&Apache::lonhtmlcommon::row_closure());
6185: &mapmenu($r,\%allmaps,$pschp,\%maptitles,\%symbp,$parmlev);
1.447 bisitz 6186: $r->print(&Apache::lonhtmlcommon::row_closure(1));
1.445 neumanie 6187: $r->print(&Apache::lonhtmlcommon::end_pick_box());
6188: $r->print('</div></div>');
1.446 bisitz 6189:
1.456 bisitz 6190: $r->print('<div class="LC_Box">');
1.452 bisitz 6191: $r->print('<div>');
1.581 raeburn 6192: &displaymenu($r,\%allparms,\@pscat,\%keyorder);
1.453 schualex 6193: $r->print(&Apache::lonhtmlcommon::start_pick_box());
1.446 bisitz 6194: $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View')));
1.553 raeburn 6195: my $sectionselector = §ionmenu(\@selected_sections);
6196: my $groupselector = &groupmenu(\@selected_groups);
1.481 amueller 6197: $r->print('<table>'.
1.553 raeburn 6198: '<tr><th>'.&mt('Parts').'</th>');
6199: if ($sectionselector) {
6200: $r->print('<th>'.&mt('Section(s)').'</th>');
6201: }
6202: if ($groupselector) {
6203: $r->print('<th>'.&mt('Group(s)').'</th>');
6204: }
6205: $r->print('</tr><tr><td>');
1.211 www 6206: &partmenu($r,\%allparts,\@psprt);
1.553 raeburn 6207: $r->print('</td>');
6208: if ($sectionselector) {
6209: $r->print('<td>'.$sectionselector.'</td>');
6210: }
6211: if ($groupselector) {
6212: $r->print('<td>'.$groupselector.'</td>');
6213: }
6214: $r->print('</tr></table>');
1.447 bisitz 6215: $r->print(&Apache::lonhtmlcommon::row_closure(1));
1.445 neumanie 6216: $r->print(&Apache::lonhtmlcommon::end_pick_box());
6217: $r->print('</div></div>');
6218:
1.456 bisitz 6219: $r->print('<div class="LC_Box">');
1.452 bisitz 6220: $r->print('<div>');
1.214 www 6221: my $sortorder=$env{'form.sortorder'};
6222: unless ($sortorder) { $sortorder='realmstudent'; }
1.612 raeburn 6223: &sortmenu($r,$sortorder,'newoverview');
1.445 neumanie 6224: $r->print('</div></div>');
1.446 bisitz 6225:
1.214 www 6226: $r->print('<p><input type="submit" name="dis" value="'.&mt('Display').'" /></p>');
1.446 bisitz 6227:
1.211 www 6228: # Build the list data hash from the specified parms
6229:
6230: my $listdata;
6231: %{$listdata}=();
6232:
6233: foreach my $cat (@pscat) {
1.269 raeburn 6234: &secgroup_lister($cat,$pschp,$parmlev,$listdata,\@psprt,\@selected_sections,\%defkeytype,\%allmaps,\@ids,\%symbp);
6235: &secgroup_lister($cat,$pschp,$parmlev,$listdata,\@psprt,\@selected_groups,\%defkeytype,\%allmaps,\@ids,\%symbp);
1.211 www 6236: }
6237:
1.212 www 6238: if (($env{'form.store'}) || ($env{'form.dis'})) {
1.211 www 6239:
1.481 amueller 6240: if ($env{'form.store'}) { &storedata($r,$crs,$dom); }
1.211 www 6241:
6242: # Read modified data
6243:
1.481 amueller 6244: my $resourcedata=&readdata($crs,$dom);
1.211 www 6245:
6246: # List data
6247:
1.608 raeburn 6248: my $hash_for_realm;
6249: if (($parmlev eq 'map') && (keys(%allmaps))) {
6250: %{$hash_for_realm} = reverse(%allmaps);
6251: } elsif (($parmlev eq 'full') && (keys(%symbp))) {
6252: for (my $i=0; $i<@ids; $i++) {
6253: $hash_for_realm->{$symbp{$ids[$i]}} = $i;
6254: }
6255: }
6256: &listdata($r,$resourcedata,$listdata,$sortorder,'newoverview',undef,$readonly,$parmlev,$hash_for_realm,$pschp);
1.568 raeburn 6257: }
6258: $r->print(&tableend());
6259: unless ($readonly) {
6260: $r->print( ((($env{'form.store'}) || ($env{'form.dis'}))?'<p><input type="submit" name="store" value="'.&mt('Save').'" /></p>':'') );
1.211 www 6261: }
1.568 raeburn 6262: $r->print('</form>');
1.507 www 6263: &endSettingsScreen($r);
6264: $r->print(&Apache::loncommon::end_page());
1.208 www 6265: }
6266:
1.563 damieng 6267: # Fills $listdata with parameter information.
6268: # Keys use the format course id.[section id].part.name and course id.[section id].part.name.type.
6269: # The non-type value is always 1.
6270: #
6271: # @param {string} $cat - parameter name
1.566 damieng 6272: # @param {string} $pschp - selected map pc, or 'all'
1.563 damieng 6273: # @param {string} $parmlev - selected level value (full|map|general), or ''
6274: # @param {hash reference} $listdata - the parameter data that will be modified
6275: # @param {array reference} $psprt - selected parts
6276: # @param {array reference} $selections - selected sections
6277: # @param {hash reference} $defkeytype - hash parameter name -> parameter type
1.566 damieng 6278: # @param {hash reference} $allmaps - hash map pc -> map src
6279: # @param {array reference} $ids - resource and map ids
6280: # @param {hash reference} $symbp - hash map pc or resource/map id -> map src.'___(all)' or resource symb
1.269 raeburn 6281: sub secgroup_lister {
6282: my ($cat,$pschp,$parmlev,$listdata,$psprt,$selections,$defkeytype,$allmaps,$ids,$symbp) = @_;
6283: foreach my $item (@{$selections}) {
6284: foreach my $part (@{$psprt}) {
6285: my $rootparmkey=$env{'request.course.id'};
6286: if (($item ne 'all') && ($item ne 'none') && ($item)) {
6287: $rootparmkey.='.['.$item.']';
6288: }
6289: if ($parmlev eq 'general') {
6290: # course-level parameter
6291: my $newparmkey=$rootparmkey.'.'.$part.'.'.$cat;
6292: $$listdata{$newparmkey}=1;
6293: $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
6294: } elsif ($parmlev eq 'map') {
6295: # map-level parameter
1.548 raeburn 6296: foreach my $mapid (keys(%{$allmaps})) {
1.269 raeburn 6297: if (($pschp ne 'all') && ($pschp ne $mapid)) { next; }
6298: my $newparmkey=$rootparmkey.'.'.$$allmaps{$mapid}.'___(all).'.$part.'.'.$cat;
6299: $$listdata{$newparmkey}=1;
6300: $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
6301: }
6302: } else {
6303: # resource-level parameter
6304: foreach my $rid (@{$ids}) {
6305: my ($map,$resid,$url)=&Apache::lonnet::decode_symb($$symbp{$rid});
6306: if (($pschp ne 'all') && ($$allmaps{$pschp} ne $map)) { next; }
6307: my $newparmkey=$rootparmkey.'.'.$$symbp{$rid}.'.'.$part.'.'.$cat;
6308: $$listdata{$newparmkey}=1;
6309: $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
6310: }
6311: }
6312: }
6313: }
6314: }
6315:
1.563 damieng 6316: # UI to edit parameter settings starting with a list of all existing parameters.
6317: # (called by setoverview action)
6318: #
6319: # @param {Apache2::RequestRec} $r - the Apache request
1.208 www 6320: sub overview {
1.568 raeburn 6321: my ($r,$parm_permission) = @_;
1.208 www 6322: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
6323: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 6324: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.568 raeburn 6325: my $readonly = 1;
6326: if ($parm_permission->{'edit'}) {
6327: undef($readonly);
6328: }
1.549 raeburn 6329: my $js = '<script type="text/javascript">'."\n".
6330: '// <![CDATA['."\n".
6331: &toggleparmtextbox_js()."\n".
6332: &validateparms_js()."\n".
6333: &ipacc_boxes_js()."\n".
1.558 raeburn 6334: &done_proctor_js()."\n".
1.588 raeburn 6335: &deeplink_js()."\n".
1.549 raeburn 6336: '// ]]>'."\n".
6337: '</script>'."\n";
1.414 droeschl 6338: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
1.473 amueller 6339: text=>"Overview Mode"});
1.549 raeburn 6340: my %loaditems = (
6341: 'onload' => "showHideLenient();",
6342: );
6343:
6344: my $start_page=&Apache::loncommon::start_page('Modify Parameters',$js,{'add_entries' => \%loaditems,});
1.298 albertel 6345: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
1.507 www 6346: $r->print($start_page.$breadcrumbs);
1.531 raeburn 6347: &startSettingsScreen($r,'parmset',$crstype);
1.549 raeburn 6348: $r->print('<form method="post" action="/adm/parmset?action=setoverview" name="parmform" onsubmit="return validateParms();">');
1.507 www 6349:
1.208 www 6350: # Store modified
6351:
1.568 raeburn 6352: unless ($readonly) {
6353: &storedata($r,$crs,$dom);
6354: }
1.208 www 6355:
6356: # Read modified data
6357:
1.552 raeburn 6358: my ($resourcedata,$classlist)=&readdata($crs,$dom);
1.208 www 6359:
1.214 www 6360:
6361: my $sortorder=$env{'form.sortorder'};
6362: unless ($sortorder) { $sortorder='realmstudent'; }
1.608 raeburn 6363: &sortmenu($r,$sortorder,'overview');
1.214 www 6364:
1.568 raeburn 6365: my $submitbutton = '<input type="submit" value="'.&mt('Save').'" />';
6366:
6367: if ($readonly) {
6368: $r->print('<p>'.$submitbutton.'</p>');
6369: }
6370:
1.208 www 6371: # List data
6372:
1.568 raeburn 6373: my $foundkeys=&listdata($r,$resourcedata,$resourcedata,$sortorder,'overview',$classlist,$readonly);
6374: $r->print(&tableend().'<p>');
6375: if ($foundkeys) {
6376: unless ($readonly) {
6377: $r->print('<p>'.$submitbutton.'</p>');
6378: }
6379: } else {
6380: $r->print('<p class="LC_info">'.&mt('There are no parameters.').'</p>');
6381: }
6382: $r->print('</form>'.&Apache::loncommon::end_page());
1.120 www 6383: }
1.121 www 6384:
1.560 damieng 6385: # Unused sub.
1.563 damieng 6386: #
6387: # @param {Apache2::RequestRec} $r - the Apache request
1.333 albertel 6388: sub clean_parameters {
6389: my ($r) = @_;
6390: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
6391: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
6392:
1.414 droeschl 6393: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=cleanparameters',
1.473 amueller 6394: text=>"Clean Parameters"});
1.333 albertel 6395: my $start_page=&Apache::loncommon::start_page('Clean Parameters');
6396: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Clean');
6397: $r->print(<<ENDOVER);
6398: $start_page
6399: $breadcrumbs
6400: <form method="post" action="/adm/parmset?action=cleanparameters" name="parmform">
6401: ENDOVER
6402: # Store modified
6403:
6404: &storedata($r,$crs,$dom);
6405:
6406: # Read modified data
6407:
6408: my $resourcedata=&readdata($crs,$dom);
6409:
6410: # List data
6411:
6412: $r->print('<h3>'.
1.473 amueller 6413: &mt('These parameters refer to resources that do not exist.').
6414: '</h3>'.
6415: '<input type="submit" value="'.&mt('Delete Selected').'" />'.'<br />'.
6416: '<br />');
1.333 albertel 6417: $r->print(&Apache::loncommon::start_data_table().
1.473 amueller 6418: '<tr>'.
6419: '<th>'.&mt('Delete').'</th>'.
6420: '<th>'.&mt('Parameter').'</th>'.
6421: '</tr>');
1.333 albertel 6422: foreach my $thiskey (sort(keys(%{$resourcedata}))) {
1.560 damieng 6423: next if (!exists($resourcedata->{$thiskey.'.type'})
6424: && $thiskey=~/\.type$/);
6425: my %data = &parse_key($thiskey);
6426: if (1) { #exists($data{'realm_exists'})
6427: #&& !$data{'realm_exists'}) {
6428: $r->print(&Apache::loncommon::start_data_table_row().
6429: '<tr>'.
6430: '<td><input type="checkbox" name="del_'.$thiskey.'" /></td>' );
6431:
6432: $r->print('<td>');
6433: my $display_value = $resourcedata->{$thiskey};
6434: if (&isdateparm($resourcedata->{$thiskey.'.type'})) {
6435: $display_value =
6436: &Apache::lonlocal::locallocaltime($display_value);
6437: }
1.470 raeburn 6438: my $parmitem = &standard_parameter_names($data{'parameter_name'});
6439: $parmitem = &mt($parmitem);
1.560 damieng 6440: $r->print(&mt('Parameter: "[_1]" with value: "[_2]"',
6441: $parmitem,$resourcedata->{$thiskey}));
6442: $r->print('<br />');
6443: if ($data{'scope_type'} eq 'all') {
6444: $r->print(&mt('All users'));
6445: } elsif ($data{'scope_type'} eq 'user') {
6446: $r->print(&mt('User: [_1]',join(':',@{$data{'scope'}})));
1.581 raeburn 6447: } elsif ($data{'scope_type'} eq 'secgroup') {
6448: $r->print(&mt('Group/Section: [_1]',$data{'scope'}));
1.560 damieng 6449: }
6450: $r->print('<br />');
6451: if ($data{'realm_type'} eq 'all') {
6452: $r->print(&mt('All Resources'));
6453: } elsif ($data{'realm_type'} eq 'folder') {
6454: $r->print(&mt('Folder: [_1]'),$data{'realm'});
6455: } elsif ($data{'realm_type'} eq 'symb') {
6456: my ($map,$resid,$url) =
6457: &Apache::lonnet::decode_symb($data{'realm'});
6458: $r->print(&mt('Resource: [_1]with ID: [_2]in folder [_3]',
6459: $url.' <br /> ',
6460: $resid.' <br /> ',$map));
6461: }
6462: $r->print(' <br /> '.&mt('Part: [_1]',$data{'parameter_part'}));
6463: $r->print('</td></tr>');
6464:
1.473 amueller 6465: }
1.333 albertel 6466: }
6467: $r->print(&Apache::loncommon::end_data_table().'<p>'.
1.473 amueller 6468: '<input type="submit" value="'.&mt('Delete Selected').'" />'.
1.507 www 6469: '</p></form>');
6470: &endSettingsScreen($r);
6471: $r->print(&Apache::loncommon::end_page());
1.333 albertel 6472: }
6473:
1.563 damieng 6474: # UI to shift all dates (called by dateshift1 action).
6475: # Used by overview mode.
6476: #
6477: # @param {Apache2::RequestRec} $r - the Apache request
1.390 www 6478: sub date_shift_one {
6479: my ($r) = @_;
6480: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
6481: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 6482: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.594 raeburn 6483: my $sec = $env{'request.course.sec'};
1.414 droeschl 6484: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
1.473 amueller 6485: text=>"Shifting Dates"});
1.594 raeburn 6486: my $submit_text = &mt('Shift all dates accordingly');
6487: if ($sec ne '') {
1.595 raeburn 6488: my @groups;
6489: if ($env{'request.course.groups'} ne '') {
6490: @groups = split(/:/,$env{'request.course.groups'});
6491: }
6492: if (@groups) {
6493: $submit_text = &mt("Shift dates set just for your section/group(s), accordingly");
6494: } else {
6495: $submit_text = &mt("Shift dates set just for your section, accordingly");
6496: }
1.594 raeburn 6497: }
1.390 www 6498: my $start_page=&Apache::loncommon::start_page('Shift Dates');
6499: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
1.507 www 6500: $r->print($start_page.$breadcrumbs);
1.531 raeburn 6501: &startSettingsScreen($r,'parmset',$crstype);
1.538 bisitz 6502: $r->print('<form name="shiftform" method="post" action="">'.
1.390 www 6503: '<table><tr><td>'.&mt('Currently set date:').'</td><td>'.
6504: &Apache::lonlocal::locallocaltime($env{'form.timebase'}).'</td></tr>'.
6505: '<tr><td>'.&mt('Shifted date:').'</td><td>'.
1.541 bisitz 6506: &Apache::lonhtmlcommon::date_setter('shiftform',
1.390 www 6507: 'timeshifted',
6508: $env{'form.timebase'},,
6509: '').
6510: '</td></tr></table>'.
6511: '<input type="hidden" name="action" value="dateshift2" />'.
6512: '<input type="hidden" name="timebase" value="'.$env{'form.timebase'}.'" />'.
1.594 raeburn 6513: '<input type="submit" value="'.$submit_text.'" /></form>');
1.507 www 6514: &endSettingsScreen($r);
1.390 www 6515: $r->print(&Apache::loncommon::end_page());
6516: }
6517:
1.563 damieng 6518: # UI to shift all dates (second form).
6519: #
6520: # @param {Apache2::RequestRec} $r - the Apache request
1.390 www 6521: sub date_shift_two {
6522: my ($r) = @_;
6523: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
6524: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.594 raeburn 6525: my $sec = $env{'request.course.sec'};
1.531 raeburn 6526: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.414 droeschl 6527: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
1.473 amueller 6528: text=>"Shifting Dates"});
1.390 www 6529: my $start_page=&Apache::loncommon::start_page('Shift Dates');
6530: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
1.507 www 6531: $r->print($start_page.$breadcrumbs);
1.531 raeburn 6532: &startSettingsScreen($r,'parmset',$crstype);
1.390 www 6533: my $timeshifted=&Apache::lonhtmlcommon::get_date_from_form('timeshifted');
1.594 raeburn 6534: $r->print('<h2>'.&mt('Shift Dates').'</h2>');
6535: if ($sec ne '') {
1.595 raeburn 6536: my @groups;
6537: if ($env{'request.course.groups'} ne '') {
6538: @groups = split(/:/,$env{'request.course.groups'});
6539: }
6540: if (@groups) {
6541: $r->print('<p>'.
6542: &mt("Shift dates set just for your section/group(s), such that [_1] becomes [_2]",
6543: &Apache::lonlocal::locallocaltime($env{'form.timebase'}),
6544: &Apache::lonlocal::locallocaltime($timeshifted)).
6545: '</p>');
6546: } else {
6547: $r->print('<p>'.
6548: &mt("Shift dates set just for your section, such that [_1] becomes [_2]",
6549: &Apache::lonlocal::locallocaltime($env{'form.timebase'}),
6550: &Apache::lonlocal::locallocaltime($timeshifted)).
6551: '</p>');
6552: }
1.594 raeburn 6553: } else {
6554: $r->print('<p>'.&mt('Shifting all dates such that [_1] becomes [_2]',
6555: &Apache::lonlocal::locallocaltime($env{'form.timebase'}),
6556: &Apache::lonlocal::locallocaltime($timeshifted)).
6557: '</p>');
6558: }
1.390 www 6559: my $delta=$timeshifted-$env{'form.timebase'};
1.594 raeburn 6560: my $numchanges = 0;
6561: my $result = &dateshift($delta,\$numchanges);
6562: if ($result eq 'ok') {
6563: $r->print(
6564: &Apache::lonhtmlcommon::confirm_success(&mt('Completed shifting of [quant,_1,date setting]',
6565: $numchanges)));
6566: } elsif ($result eq 'con_delayed') {
6567: $r->print(
6568: &Apache::lonhtmlcommon::confirm_success(&mt('Queued shifting of [quant,_1,date setting]',
6569: $numchanges)));
6570: } else {
6571: $r->print(
6572: &Apache::lonhtmlcommon::confirm_success(&mt('An error occurred attempting to shift dates'),1));
6573: }
1.543 bisitz 6574: $r->print(
6575: '<br /><br />'.
6576: &Apache::lonhtmlcommon::actionbox(
6577: ['<a href="/adm/parmset">'.&mt('Content and Problem Settings').'</a>']));
1.507 www 6578: &endSettingsScreen($r);
1.390 www 6579: $r->print(&Apache::loncommon::end_page());
6580: }
6581:
1.563 damieng 6582: # Returns the different components of a resourcedata key.
6583: # Keys: scope_type, scope, realm_type, realm, realm_title,
6584: # realm_exists, parameter_part, parameter_name.
6585: # Was used by clean_parameters (which is unused).
6586: #
6587: # @param {string} $key - the parameter key
6588: # @returns {hash}
1.333 albertel 6589: sub parse_key {
6590: my ($key) = @_;
6591: my %data;
6592: my ($middle,$part,$name)=
1.572 damieng 6593: ($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s\-]+)\.(\w+)$/);
1.333 albertel 6594: $data{'scope_type'} = 'all';
6595: if ($middle=~/^\[(.*)\]/) {
1.560 damieng 6596: $data{'scope'} = $1;
6597: if ($data{'scope'}=~/^useropt\:($match_username)\:($match_domain)/) {
6598: $data{'scope_type'} = 'user';
6599: $data{'scope'} = [$1,$2];
6600: } else {
1.581 raeburn 6601: $data{'scope_type'} = 'secgroup';
1.560 damieng 6602: }
6603: $middle=~s/^\[(.*)\]//;
1.333 albertel 6604: }
6605: $middle=~s/\.+$//;
6606: $middle=~s/^\.+//;
6607: $data{'realm_type'}='all';
6608: if ($middle=~/^(.+)\_\_\_\(all\)$/) {
1.560 damieng 6609: $data{'realm'} = $1;
6610: $data{'realm_type'} = 'folder';
6611: $data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});
6612: ($data{'realm_exists'}) = &Apache::lonnet::is_on_map($data{'realm'});
1.333 albertel 6613: } elsif ($middle) {
1.560 damieng 6614: $data{'realm'} = $middle;
6615: $data{'realm_type'} = 'symb';
6616: $data{'realm_title'} = &Apache::lonnet::gettitle($data{'realm'});
6617: my ($map,$resid,$url) = &Apache::lonnet::decode_symb($data{'realm'});
6618: $data{'realm_exists'} = &Apache::lonnet::symbverify($data{'realm'},$url);
1.333 albertel 6619: }
1.446 bisitz 6620:
1.333 albertel 6621: $data{'parameter_part'} = $part;
6622: $data{'parameter_name'} = $name;
6623:
6624: return %data;
6625: }
6626:
1.239 raeburn 6627:
1.563 damieng 6628: # Calls loncommon::start_page with the "Settings" title.
1.416 jms 6629: sub header {
1.507 www 6630: return &Apache::loncommon::start_page('Settings');
1.416 jms 6631: }
1.193 albertel 6632:
6633:
6634:
1.560 damieng 6635: ##################################################
6636: # MAIN MENU
6637: ##################################################
6638:
1.563 damieng 6639: # Content and problem settings main menu.
6640: #
6641: # @param {Apache2::RequestRec} $r - the Apache request
6642: # @param {boolean} $parm_permission - true if the user has permission to edit the current course or section
1.193 albertel 6643: sub print_main_menu {
6644: my ($r,$parm_permission)=@_;
6645: #
1.414 droeschl 6646: $r->print(&header());
1.507 www 6647: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Content and Problem Settings'));
1.531 raeburn 6648: my $crstype = &Apache::loncommon::course_type();
6649: my $lc_crstype = lc($crstype);
6650:
6651: &startSettingsScreen($r,'parmset',$crstype);
1.193 albertel 6652: $r->print(<<ENDMAINFORMHEAD);
6653: <form method="post" enctype="multipart/form-data"
6654: action="/adm/parmset" name="studentform">
6655: ENDMAINFORMHEAD
6656: #
1.195 albertel 6657: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
6658: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1.268 albertel 6659: my $vgr = &Apache::lonnet::allowed('vgr',$env{'request.course.id'});
1.366 albertel 6660: my $mgr = &Apache::lonnet::allowed('mgr',$env{'request.course.id'});
1.520 raeburn 6661: my $dcm = &Apache::lonnet::allowed('dcm',$env{'request.course.id'});
1.568 raeburn 6662: my $vcb = &Apache::lonnet::allowed('vcb',$env{'request.course.id'});
6663: my $vpa = &Apache::lonnet::allowed('vpa',$env{'request.course.id'});
1.520 raeburn 6664: if ((!$dcm) && ($env{'request.course.sec'} ne '')) {
6665: $dcm = &Apache::lonnet::allowed('dcm',$env{'request.course.id'}.
6666: '/'.$env{'request.course.sec'});
6667: }
1.568 raeburn 6668: if ((!$vcb) && ($env{'request.course.sec'} ne '')) {
6669: $vcb = &Apache::lonnet::allowed('vcb',$env{'request.course.id'}.
6670: '/'.$env{'request.course.sec'});
6671: }
6672: my (%linktext,%linktitle,%url);
6673: if ($parm_permission->{'edit'}) {
6674: %linktext = (
6675: newoverview => 'Edit Resource Parameters - Overview Mode',
6676: settable => 'Edit Resource Parameters - Table Mode',
6677: setoverview => 'Modify Resource Parameters - Overview Mode',
6678: );
6679: %linktitle = (
6680: newoverview => 'Set/Modify resource parameters in overview mode.',
6681: settable => 'Set/Modify resource parameters in table mode.',
6682: setoverview => 'Set/Modify existing resource parameters in overview mode.',
6683: );
6684: } else {
6685: %linktext = (
6686: newoverview => 'View Resource Parameters - Overview Mode',
6687: settable => 'View Resource Parameters - Table Mode',
6688: setoverview => 'View Resource Parameters - Overview Mode',
6689: );
6690: %linktitle = (
6691: newoverview => 'Display resource parameters in overview mode.',
6692: settable => 'Display resource parameters in table mode.',
6693: setoverview => 'Display existing resource parameters in overview mode.',
6694: );
6695: }
6696: if ($mgr) {
6697: $linktext{'resettimes'} = 'Reset Student Access Times';
6698: $linktitle{'resettimes'} = "Reset access times for folders/maps, resources or the $lc_crstype.";
6699: $url{'resettimes'} = '/adm/helper/resettimes.helper';
6700: } elsif ($vgr) {
6701: $linktext{'resettimes'} = 'Display Student Access Times',
6702: $linktitle{'resettimes'} = "Display access times for folders/maps, resources or the $lc_crstype.",
6703: $url{'resettimes'} = '/adm/accesstimes';
6704: }
1.193 albertel 6705: my @menu =
1.507 www 6706: ( { categorytitle=>"Content Settings for this $crstype",
1.473 amueller 6707: items => [
6708: { linktext => 'Portfolio Metadata',
6709: url => '/adm/parmset?action=setrestrictmeta',
1.568 raeburn 6710: permission => $parm_permission->{'setrestrictmeta'},
1.477 raeburn 6711: linktitle => "Restrict metadata for this $lc_crstype." ,
1.473 amueller 6712: icon =>'contact-new.png' ,
6713: },
1.568 raeburn 6714: { linktext => $linktext{'resettimes'},
6715: url => $url{'resettimes'},
6716: permission => ($vgr || $mgr),
6717: linktitle => $linktitle{'resettimes'},
6718: icon => 'start-here.png',
1.473 amueller 6719: },
1.520 raeburn 6720: { linktext => 'Blocking Communication/Resource Access',
6721: url => '/adm/setblock',
1.568 raeburn 6722: permission => ($vcb || $dcm),
1.520 raeburn 6723: linktitle => 'Configure blocking of communication/collaboration and access to resources during an exam',
6724: icon => 'comblock.png',
6725: },
1.473 amueller 6726: { linktext => 'Set Parameter Setting Default Actions',
6727: url => '/adm/parmset?action=setdefaults',
1.568 raeburn 6728: permission => $parm_permission->{'setdefaults'},
1.473 amueller 6729: linktitle =>'Set default actions for parameters.' ,
6730: icon => 'folder-new.png' ,
6731: }]},
6732: { categorytitle => 'New and Existing Parameter Settings for Resources',
6733: items => [
6734: { linktext => 'Edit Resource Parameters - Helper Mode',
6735: url => '/adm/helper/parameter.helper',
1.568 raeburn 6736: permission => $parm_permission->{'helper'},
1.473 amueller 6737: linktitle =>'Set/Modify resource parameters in helper mode.' ,
6738: icon => 'dialog-information.png' ,
6739: #help => 'Parameter_Helper',
6740: },
1.568 raeburn 6741: { linktext => $linktext{'newoverview'},
1.473 amueller 6742: url => '/adm/parmset?action=newoverview',
1.568 raeburn 6743: permission => $parm_permission->{'newoverview'},
6744: linktitle => $linktitle{'newoverview'},
6745: icon => 'edit-find.png',
1.473 amueller 6746: #help => 'Parameter_Overview',
6747: },
1.568 raeburn 6748: { linktext => $linktext{'settable'},
1.473 amueller 6749: url => '/adm/parmset?action=settable',
1.568 raeburn 6750: permission => $parm_permission->{'settable'},
6751: linktitle => $linktitle{'settable'},
6752: icon => 'edit-copy.png',
1.473 amueller 6753: #help => 'Table_Mode',
6754: }]},
1.417 droeschl 6755: { categorytitle => 'Existing Parameter Settings for Resources',
1.473 amueller 6756: items => [
1.570 raeburn 6757: { linktext => $linktext{'setoverview'},
1.473 amueller 6758: url => '/adm/parmset?action=setoverview',
1.568 raeburn 6759: permission => $parm_permission->{'setoverview'},
6760: linktitle => $linktitle{'setoverview'},
6761: icon => 'preferences-desktop-wallpaper.png',
1.473 amueller 6762: #help => 'Parameter_Overview',
6763: },
6764: { linktext => 'Change Log',
6765: url => '/adm/parmset?action=parameterchangelog',
1.568 raeburn 6766: permission => $parm_permission->{'parameterchangelog'},
1.477 raeburn 6767: linktitle =>"View parameter and $lc_crstype blog posting/user notification change log." ,
1.487 wenzelju 6768: icon => 'document-properties.png',
1.473 amueller 6769: }]}
1.193 albertel 6770: );
1.414 droeschl 6771: $r->print(&Apache::lonhtmlcommon::generate_menu(@menu));
1.539 raeburn 6772: $r->print('</form>');
1.507 www 6773: &endSettingsScreen($r);
1.539 raeburn 6774: $r->print(&Apache::loncommon::end_page());
1.193 albertel 6775: return;
6776: }
1.414 droeschl 6777:
1.416 jms 6778:
6779:
1.560 damieng 6780: ##################################################
6781: # PORTFOLIO METADATA
6782: ##################################################
6783:
1.563 damieng 6784: # Prints HTML to edit an item of portfolio metadata. The HTML contains several td elements (no tr).
6785: # It looks like field titles are not localized.
6786: #
6787: # @param {Apache2::RequestRec} $r - the Apache request
6788: # @param {string} $field_name - metadata field name
6789: # @param {string} $field_text - metadata field title, in English unless manually added
6790: # @param {boolean} $added_flag - true if the field was manually added
1.252 banghart 6791: sub output_row {
1.347 banghart 6792: my ($r, $field_name, $field_text, $added_flag) = @_;
1.252 banghart 6793: my $output;
1.263 banghart 6794: my $options=$env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.options'};
6795: my $values=$env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.values'};
1.337 banghart 6796: if (!defined($options)) {
1.254 banghart 6797: $options = 'active,stuadd';
1.261 banghart 6798: $values = '';
1.252 banghart 6799: }
1.337 banghart 6800: if (!($options =~ /deleted/)) {
6801: my @options= ( ['active', 'Show to student'],
1.418 schafran 6802: ['stuadd', 'Provide text area for students to type metadata'],
1.351 banghart 6803: ['choices','Provide choices for students to select from']);
1.473 amueller 6804: # ['onlyone','Student may select only one choice']);
1.337 banghart 6805: if ($added_flag) {
6806: push @options,['deleted', 'Delete Metadata Field'];
6807: }
1.351 banghart 6808: $output = &Apache::loncommon::start_data_table_row();
1.451 bisitz 6809: $output .= '<td><strong>'.$field_text.':</strong></td>';
1.351 banghart 6810: $output .= &Apache::loncommon::end_data_table_row();
1.337 banghart 6811: foreach my $opt (@options) {
1.560 damieng 6812: my $checked = ($options =~ m/$opt->[0]/) ? ' checked="checked" ' : '' ;
6813: $output .= &Apache::loncommon::continue_data_table_row();
6814: $output .= '<td>'.(' ' x 5).'<label>
6815: <input type="checkbox" name="'.
6816: $field_name.'_'.$opt->[0].'" value="yes"'.$checked.' />'.
6817: &mt($opt->[1]).'</label></td>';
6818: $output .= &Apache::loncommon::end_data_table_row();
6819: }
1.351 banghart 6820: $output .= &Apache::loncommon::continue_data_table_row();
1.451 bisitz 6821: $output .= '<td>'.(' ' x 10).'<input name="'.$field_name.'_values" type="text" value="'.$values.'" size="80" /></td>';
1.351 banghart 6822: $output .= &Apache::loncommon::end_data_table_row();
6823: my $multiple_checked;
6824: my $single_checked;
6825: if ($options =~ m/onlyone/) {
1.422 bisitz 6826: $multiple_checked = '';
1.423 bisitz 6827: $single_checked = ' checked="checked"';
1.351 banghart 6828: } else {
1.423 bisitz 6829: $multiple_checked = ' checked="checked"';
1.422 bisitz 6830: $single_checked = '';
1.351 banghart 6831: }
1.560 damieng 6832: $output .= &Apache::loncommon::continue_data_table_row();
6833: $output .= '<td>'.(' ' x 10).'
6834: <input type="radio" name="'.$field_name.'_onlyone" value="multiple"'.$multiple_checked .' />
6835: '.&mt('Student may select multiple choices from list').'</td>';
6836: $output .= &Apache::loncommon::end_data_table_row();
6837: $output .= &Apache::loncommon::continue_data_table_row();
6838: $output .= '<td>'.(' ' x 10).'
6839: <input type="radio" name="'.$field_name.'_onlyone" value="single"'.$single_checked.' />
6840: '.&mt('Student may select only one choice from list').'</td>';
6841: $output .= &Apache::loncommon::end_data_table_row();
1.252 banghart 6842: }
6843: return ($output);
6844: }
1.416 jms 6845:
6846:
1.560 damieng 6847: # UI to order portfolio metadata fields.
1.563 damieng 6848: # Currently useless because addmetafield does not work.
6849: #
6850: # @param {Apache2::RequestRec} $r - the Apache request
1.340 banghart 6851: sub order_meta_fields {
6852: my ($r)=@_;
6853: my $idx = 1;
6854: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
6855: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 6856: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};;
1.341 banghart 6857: $r->print(&Apache::loncommon::start_page('Order Metadata Fields'));
1.560 damieng 6858: &Apache::lonhtmlcommon::add_breadcrumb(
6859: {href=>'/adm/parmset?action=addmetadata',
1.473 amueller 6860: text=>"Add Metadata Field"});
1.560 damieng 6861: &Apache::lonhtmlcommon::add_breadcrumb(
6862: {href=>"/adm/parmset?action=setrestrictmeta",
6863: text=>"Restrict Metadata"},
6864: {text=>"Order Metadata"});
1.345 banghart 6865: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Order Metadata'));
1.531 raeburn 6866: &startSettingsScreen($r,'parmset',$crstype);
1.340 banghart 6867: if ($env{'form.storeorder'}) {
6868: my $newpos = $env{'form.newpos'} - 1;
6869: my $currentpos = $env{'form.currentpos'} - 1;
6870: my @neworder = ();
1.548 raeburn 6871: my @oldorder = split(/,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'});
1.340 banghart 6872: my $i;
1.341 banghart 6873: if ($newpos > $currentpos) {
1.340 banghart 6874: # moving stuff up
6875: for ($i=0;$i<$currentpos;$i++) {
1.560 damieng 6876: $neworder[$i]=$oldorder[$i];
1.340 banghart 6877: }
6878: for ($i=$currentpos;$i<$newpos;$i++) {
1.560 damieng 6879: $neworder[$i]=$oldorder[$i+1];
1.340 banghart 6880: }
6881: $neworder[$newpos]=$oldorder[$currentpos];
6882: for ($i=$newpos+1;$i<=$#oldorder;$i++) {
1.560 damieng 6883: $neworder[$i]=$oldorder[$i];
1.340 banghart 6884: }
6885: } else {
6886: # moving stuff down
1.473 amueller 6887: for ($i=0;$i<$newpos;$i++) {
6888: $neworder[$i]=$oldorder[$i];
6889: }
6890: $neworder[$newpos]=$oldorder[$currentpos];
6891: for ($i=$newpos+1;$i<$currentpos+1;$i++) {
6892: $neworder[$i]=$oldorder[$i-1];
6893: }
6894: for ($i=$currentpos+1;$i<=$#oldorder;$i++) {
6895: $neworder[$i]=$oldorder[$i];
6896: }
1.340 banghart 6897: }
1.560 damieng 6898: my $ordered_fields = join ",", @neworder;
1.343 banghart 6899: my $put_result = &Apache::lonnet::put('environment',
1.560 damieng 6900: {'metadata.addedorder'=>$ordered_fields},$dom,$crs);
6901: &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.metadata.addedorder' => $ordered_fields});
1.340 banghart 6902: }
1.357 raeburn 6903: my $fields = &get_added_meta_fieldnames($env{'request.course.id'});
1.341 banghart 6904: my $ordered_fields;
1.548 raeburn 6905: my @fields_in_order = split(/,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'});
1.340 banghart 6906: if (!@fields_in_order) {
6907: # no order found, pick sorted order then create metadata.addedorder key.
1.548 raeburn 6908: foreach my $key (sort(keys(%$fields))) {
1.340 banghart 6909: push @fields_in_order, $key;
1.341 banghart 6910: $ordered_fields = join ",", @fields_in_order;
1.340 banghart 6911: }
1.341 banghart 6912: my $put_result = &Apache::lonnet::put('environment',
1.446 bisitz 6913: {'metadata.addedorder'=>$ordered_fields},$dom,$crs);
6914: }
1.340 banghart 6915: $r->print('<table>');
6916: my $num_fields = scalar(@fields_in_order);
6917: foreach my $key (@fields_in_order) {
6918: $r->print('<tr><td>');
6919: $r->print('<form method="post" action="">');
1.537 bisitz 6920: $r->print('<select name="newpos" onchange="this.form.submit()">');
1.340 banghart 6921: for (my $i = 1;$i le $num_fields;$i ++) {
6922: if ($i eq $idx) {
6923: $r->print('<option value="'.$i.'" SELECTED>('.$i.')</option>');
6924: } else {
6925: $r->print('<option value="'.$i.'">'.$i.'</option>');
6926: }
6927: }
6928: $r->print('</select></td><td>');
6929: $r->print('<input type="hidden" name="currentpos" value="'.$idx.'" />');
6930: $r->print('<input type="hidden" name="storeorder" value="true" />');
6931: $r->print('</form>');
6932: $r->print($$fields{$key}.'</td></tr>');
6933: $idx ++;
6934: }
6935: $r->print('</table>');
1.507 www 6936: &endSettingsScreen($r);
1.340 banghart 6937: return 'ok';
6938: }
1.416 jms 6939:
6940:
1.563 damieng 6941: # Returns HTML with a Continue button redirecting to the initial portfolio metadata screen.
6942: # @returns {string}
1.359 banghart 6943: sub continue {
6944: my $output;
6945: $output .= '<form action="" method="post">';
6946: $output .= '<input type="hidden" name="action" value="setrestrictmeta" />';
1.586 raeburn 6947: $output .= '<input type="submit" value="'.&mt('Continue').'" />';
1.359 banghart 6948: return ($output);
6949: }
1.416 jms 6950:
6951:
1.563 damieng 6952: # UI to add a metadata field.
6953: # Currenly does not work because of an HTML error (the field is not visible).
6954: #
6955: # @param {Apache2::RequestRec} $r - the Apache request
1.334 banghart 6956: sub addmetafield {
6957: my ($r)=@_;
1.414 droeschl 6958: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=addmetadata',
1.473 amueller 6959: text=>"Add Metadata Field"});
1.334 banghart 6960: $r->print(&Apache::loncommon::start_page('Add Metadata Field'));
6961: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Add Metadata Field'));
1.335 banghart 6962: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
6963: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 6964: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
6965: &startSettingsScreen($r,'parmset',$crstype);
1.339 banghart 6966: if (exists($env{'form.undelete'})) {
1.358 banghart 6967: my @meta_fields = &Apache::loncommon::get_env_multiple('form.undeletefield');
1.339 banghart 6968: foreach my $meta_field(@meta_fields) {
6969: my $options = $env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.options'};
6970: $options =~ s/deleted//;
6971: $options =~ s/,,/,/;
6972: my $put_result = &Apache::lonnet::put('environment',
6973: {'metadata.'.$meta_field.'.options'=>$options},$dom,$crs);
1.446 bisitz 6974:
1.586 raeburn 6975: $r->print(&mt('Undeleted Metadata Field [_1] with result [_2]',
6976: '<strong>'.$env{'course.'.$env{'request.course.id'}.'.metadata.'.$meta_field.'.added'}.
6977: '</strong>',$put_result).
6978: '<br />');
1.339 banghart 6979: }
1.359 banghart 6980: $r->print(&continue());
1.339 banghart 6981: } elsif (exists($env{'form.fieldname'})) {
1.335 banghart 6982: my $meta_field = $env{'form.fieldname'};
6983: my $display_field = $env{'form.fieldname'};
6984: $meta_field =~ s/\W/_/g;
1.338 banghart 6985: $meta_field =~ tr/A-Z/a-z/;
1.335 banghart 6986: my $put_result = &Apache::lonnet::put('environment',
6987: {'metadata.'.$meta_field.'.values'=>"",
6988: 'metadata.'.$meta_field.'.added'=>"$display_field",
6989: 'metadata.'.$meta_field.'.options'=>""},$dom,$crs);
1.586 raeburn 6990: $r->print(&mt('Added new Metadata Field [_1] with result [_2]',
6991: '<strong>'.$env{'form.fieldname'}.'</strong>',$put_result).
6992: '<br />');
1.359 banghart 6993: $r->print(&continue());
1.335 banghart 6994: } else {
1.357 raeburn 6995: my $fields = &get_deleted_meta_fieldnames($env{'request.course.id'});
1.339 banghart 6996: if ($fields) {
1.586 raeburn 6997: $r->print(&mt('You may undelete previously deleted fields.').
6998: '<br />'.
6999: &mt('Check those you wish to undelete and click Undelete.').
7000: '<br />');
1.339 banghart 7001: $r->print('<form method="post" action="">');
7002: foreach my $key(keys(%$fields)) {
1.581 raeburn 7003: $r->print('<label><input type="checkbox" name="undeletefield" value="'.$key.'" />'.$$fields{$key}.'</label><br /');
1.339 banghart 7004: }
1.586 raeburn 7005: $r->print('<input type="submit" name="undelete" value="'.&mt('Undelete').'" />');
1.339 banghart 7006: $r->print('</form>');
7007: }
1.586 raeburn 7008: $r->print('<hr />'.
7009: &mt('[_1]Or[_2] you may enter a new metadata field name.',
7010: '<strong>','</strong>').
1.581 raeburn 7011: '<form method="post" action="/adm/parmset?action=addmetadata">');
1.335 banghart 7012: $r->print('<input type="text" name="fieldname" /><br />');
1.586 raeburn 7013: $r->print('<input type="submit" value="'.&mt('Add Metadata Field').'" />');
1.581 raeburn 7014: $r->print('</form>');
1.334 banghart 7015: }
1.507 www 7016: &endSettingsScreen($r);
1.334 banghart 7017: }
1.416 jms 7018:
7019:
7020:
1.560 damieng 7021: # Display or save portfolio metadata.
1.563 damieng 7022: #
7023: # @param {Apache2::RequestRec} $r - the Apache request
1.259 banghart 7024: sub setrestrictmeta {
1.240 banghart 7025: my ($r)=@_;
1.242 banghart 7026: my $next_meta;
1.244 banghart 7027: my $output;
1.245 banghart 7028: my $item_num;
1.246 banghart 7029: my $put_result;
1.414 droeschl 7030: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setrestrictmeta',
1.473 amueller 7031: text=>"Restrict Metadata"});
1.280 albertel 7032: $r->print(&Apache::loncommon::start_page('Restrict Metadata'));
1.298 albertel 7033: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Restrict Metadata'));
1.240 banghart 7034: my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
7035: my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.531 raeburn 7036: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
7037: &startSettingsScreen($r,'parmset',$crstype);
1.259 banghart 7038: my $key_base = $env{'course.'.$env{'request.course.id'}.'.'};
1.252 banghart 7039: my $save_field = '';
1.586 raeburn 7040: my %lt = &Apache::lonlocal::texthash(
7041: addm => 'Add Metadata Field',
7042: ordm => 'Order Metadata Fields',
7043: save => 'Save',
7044: );
1.259 banghart 7045: if ($env{'form.restrictmeta'}) {
1.254 banghart 7046: foreach my $field (sort(keys(%env))) {
1.252 banghart 7047: if ($field=~m/^form.(.+)_(.+)$/) {
1.254 banghart 7048: my $options;
1.252 banghart 7049: my $meta_field = $1;
7050: my $meta_key = $2;
1.253 banghart 7051: if ($save_field ne $meta_field) {
1.252 banghart 7052: $save_field = $meta_field;
1.473 amueller 7053: if ($env{'form.'.$meta_field.'_stuadd'}) {
7054: $options.='stuadd,';
7055: }
7056: if ($env{'form.'.$meta_field.'_choices'}) {
7057: $options.='choices,';
7058: }
7059: if ($env{'form.'.$meta_field.'_onlyone'} eq 'single') {
7060: $options.='onlyone,';
7061: }
7062: if ($env{'form.'.$meta_field.'_active'}) {
7063: $options.='active,';
7064: }
7065: if ($env{'form.'.$meta_field.'_deleted'}) {
7066: $options.='deleted,';
7067: }
1.259 banghart 7068: my $name = $save_field;
1.560 damieng 7069: $put_result = &Apache::lonnet::put('environment',
7070: {'metadata.'.$meta_field.'.options'=>$options,
7071: 'metadata.'.$meta_field.'.values'=>$env{'form.'.$meta_field.'_values'},
7072: },$dom,$crs);
1.252 banghart 7073: }
7074: }
7075: }
7076: }
1.296 albertel 7077: &Apache::lonnet::coursedescription($env{'request.course.id'},
1.473 amueller 7078: {'freshen_cache' => 1});
1.335 banghart 7079: # Get the default metadata fields
1.258 albertel 7080: my %metadata_fields = &Apache::lonmeta::fieldnames('portfolio');
1.335 banghart 7081: # Now get possible added metadata fields
1.357 raeburn 7082: my $added_metadata_fields = &get_added_meta_fieldnames($env{'request.course.id'});
1.347 banghart 7083: $output .= &Apache::loncommon::start_data_table();
1.258 albertel 7084: foreach my $field (sort(keys(%metadata_fields))) {
1.265 banghart 7085: if ($field ne 'courserestricted') {
1.586 raeburn 7086: $output.= &output_row($r,$field,$metadata_fields{$field});
1.560 damieng 7087: }
1.255 banghart 7088: }
1.351 banghart 7089: my $buttons = (<<ENDButtons);
1.586 raeburn 7090: <input type="submit" name="restrictmeta" value="$lt{'save'}" />
1.351 banghart 7091: </form><br />
7092: <form method="post" action="/adm/parmset?action=addmetadata" name="form1">
1.586 raeburn 7093: <input type="submit" name="restrictmeta" value="$lt{'addm'}" />
1.351 banghart 7094: </form>
7095: <br />
7096: <form method="post" action="/adm/parmset?action=ordermetadata" name="form2">
1.586 raeburn 7097: <input type="submit" name="restrictmeta" value="$lt{'ordm'}" />
1.351 banghart 7098: ENDButtons
1.337 banghart 7099: my $added_flag = 1;
1.335 banghart 7100: foreach my $field (sort(keys(%$added_metadata_fields))) {
1.586 raeburn 7101: $output.= &output_row($r,$field,$$added_metadata_fields{$field},$added_flag);
1.335 banghart 7102: }
1.347 banghart 7103: $output .= &Apache::loncommon::end_data_table();
1.446 bisitz 7104: $r->print(<<ENDenv);
1.259 banghart 7105: <form method="post" action="/adm/parmset?action=setrestrictmeta" name="form">
1.244 banghart 7106: $output
1.351 banghart 7107: $buttons
1.340 banghart 7108: </form>
1.244 banghart 7109: ENDenv
1.507 www 7110: &endSettingsScreen($r);
1.280 albertel 7111: $r->print(&Apache::loncommon::end_page());
1.240 banghart 7112: return 'ok';
7113: }
1.416 jms 7114:
7115:
1.563 damieng 7116: # Returns metadata fields that have been manually added.
7117: #
7118: # @param {string} $cid - course id
7119: # @returns {hash reference} - hash field name -> field title (not localized)
1.335 banghart 7120: sub get_added_meta_fieldnames {
1.357 raeburn 7121: my ($cid) = @_;
1.335 banghart 7122: my %fields;
7123: foreach my $key(%env) {
1.357 raeburn 7124: if ($key =~ m/\Q$cid\E\.metadata\.(.+)\.added$/) {
1.335 banghart 7125: my $field_name = $1;
7126: my ($display_field_name) = $env{$key};
7127: $fields{$field_name} = $display_field_name;
7128: }
7129: }
7130: return \%fields;
7131: }
1.416 jms 7132:
7133:
1.563 damieng 7134: # Returns metadata fields that have been manually added and deleted.
7135: #
7136: # @param {string} $cid - course id
7137: # @returns {hash reference} - hash field name -> field title (not localized)
1.339 banghart 7138: sub get_deleted_meta_fieldnames {
1.357 raeburn 7139: my ($cid) = @_;
1.339 banghart 7140: my %fields;
7141: foreach my $key(%env) {
1.357 raeburn 7142: if ($key =~ m/\Q$cid\E\.metadata\.(.+)\.added$/) {
1.339 banghart 7143: my $field_name = $1;
7144: if ($env{'course.'.$env{'request.course.id'}.'.metadata.'.$field_name.'.options'} =~ m/deleted/) {
7145: my ($display_field_name) = $env{$key};
7146: $fields{$field_name} = $display_field_name;
7147: }
7148: }
7149: }
7150: return \%fields;
7151: }
1.560 damieng 7152:
7153:
7154: ##################################################
7155: # PARAMETER SETTINGS DEFAULT ACTIONS
7156: ##################################################
7157:
7158: # UI to change parameter setting default actions
1.563 damieng 7159: #
7160: # @param {Apache2::RequestRec} $r - the Apache request
1.220 www 7161: sub defaultsetter {
1.280 albertel 7162: my ($r) = @_;
7163:
1.414 droeschl 7164: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setdefaults',
1.473 amueller 7165: text=>"Set Defaults"});
1.531 raeburn 7166: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
7167: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
7168: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.446 bisitz 7169: my $start_page =
1.531 raeburn 7170: &Apache::loncommon::start_page('Parameter Setting Default Actions');
1.298 albertel 7171: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Defaults');
1.507 www 7172: $r->print($start_page.$breadcrumbs);
1.531 raeburn 7173: &startSettingsScreen($r,'parmset',$crstype);
1.507 www 7174: $r->print('<form method="post" action="/adm/parmset?action=setdefaults" name="defaultform">');
1.280 albertel 7175:
1.221 www 7176: my @ids=();
7177: my %typep=();
7178: my %keyp=();
7179: my %allparms=();
7180: my %allparts=();
7181: my %allmaps=();
7182: my %mapp=();
7183: my %symbp=();
7184: my %maptitles=();
7185: my %uris=();
7186: my %keyorder=&standardkeyorder();
7187: my %defkeytype=();
7188:
1.446 bisitz 7189: &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
1.473 amueller 7190: \%mapp, \%symbp,\%maptitles,\%uris,
7191: \%keyorder,\%defkeytype);
1.224 www 7192: if ($env{'form.storerules'}) {
1.560 damieng 7193: my %newrules=();
7194: my @delrules=();
7195: my %triggers=();
7196: foreach my $key (keys(%env)) {
1.225 albertel 7197: if ($key=~/^form\.(\w+)\_action$/) {
1.560 damieng 7198: my $tempkey=$1;
7199: my $action=$env{$key};
1.226 www 7200: if ($action) {
1.560 damieng 7201: $newrules{$tempkey.'_action'}=$action;
7202: if ($action ne 'default') {
7203: my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/);
7204: $triggers{$whichparm}.=$tempkey.':';
7205: }
7206: $newrules{$tempkey.'_type'}=$defkeytype{$tempkey};
7207: if (&isdateparm($defkeytype{$tempkey})) {
7208: $newrules{$tempkey.'_days'}=$env{'form.'.$tempkey.'_days'};
7209: $newrules{$tempkey.'_hours'}=$env{'form.'.$tempkey.'_hours'};
7210: $newrules{$tempkey.'_min'}=$env{'form.'.$tempkey.'_min'};
7211: $newrules{$tempkey.'_sec'}=$env{'form.'.$tempkey.'_sec'};
7212: } else {
7213: $newrules{$tempkey.'_value'}=$env{'form.'.$tempkey.'_value'};
7214: $newrules{$tempkey.'_triggervalue'}=$env{'form.'.$tempkey.'_triggervalue'};
7215: }
7216: } else {
7217: push(@delrules,$tempkey.'_action');
7218: push(@delrules,$tempkey.'_type');
7219: push(@delrules,$tempkey.'_hours');
7220: push(@delrules,$tempkey.'_min');
7221: push(@delrules,$tempkey.'_sec');
7222: push(@delrules,$tempkey.'_value');
7223: }
1.473 amueller 7224: }
7225: }
1.560 damieng 7226: foreach my $key (keys(%allparms)) {
7227: $newrules{$key.'_triggers'}=$triggers{$key};
1.473 amueller 7228: }
1.560 damieng 7229: &Apache::lonnet::put('parmdefactions',\%newrules,$cdom,$cnum);
7230: &Apache::lonnet::del('parmdefactions',\@delrules,$cdom,$cnum);
7231: &resetrulescache();
1.224 www 7232: }
1.227 www 7233: my %lt=&Apache::lonlocal::texthash('days' => 'Days',
1.473 amueller 7234: 'hours' => 'Hours',
7235: 'min' => 'Minutes',
7236: 'sec' => 'Seconds',
7237: 'yes' => 'Yes',
7238: 'no' => 'No');
1.222 www 7239: my @standardoptions=('','default');
7240: my @standarddisplay=('',&mt('Default value when manually setting'));
7241: my @dateoptions=('','default');
7242: my @datedisplay=('',&mt('Default value when manually setting'));
7243: foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
1.560 damieng 7244: unless ($tempkey) { next; }
7245: push @standardoptions,'when_setting_'.$tempkey;
7246: push @standarddisplay,&mt('Automatically set when setting ').$tempkey;
7247: if (&isdateparm($defkeytype{$tempkey})) {
7248: push @dateoptions,'later_than_'.$tempkey;
7249: push @datedisplay,&mt('Automatically set later than ').$tempkey;
7250: push @dateoptions,'earlier_than_'.$tempkey;
7251: push @datedisplay,&mt('Automatically set earlier than ').$tempkey;
7252: }
1.222 www 7253: }
1.563 damieng 7254: $r->print(&mt('Manual setting rules apply to all interfaces.').'<br />'.
7255: &mt('Automatic setting rules apply to table mode interfaces only.'));
1.318 albertel 7256: $r->print("\n".&Apache::loncommon::start_data_table().
1.473 amueller 7257: &Apache::loncommon::start_data_table_header_row().
7258: "<th>".&mt('Rule for parameter').'</th><th>'.
7259: &mt('Action').'</th><th>'.&mt('Value').'</th>'.
7260: &Apache::loncommon::end_data_table_header_row());
1.221 www 7261: foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
1.560 damieng 7262: unless ($tempkey) { next; }
7263: $r->print("\n".&Apache::loncommon::start_data_table_row().
7264: "<td>".$allparms{$tempkey}."\n<br />(".$tempkey.')</td><td>');
7265: my $action=&rulescache($tempkey.'_action');
7266: $r->print('<select name="'.$tempkey.'_action">');
7267: if (&isdateparm($defkeytype{$tempkey})) {
7268: for (my $i=0;$i<=$#dateoptions;$i++) {
7269: if ($dateoptions[$i]=~/\_$tempkey$/) { next; }
7270: $r->print("\n<option value='$dateoptions[$i]'".
7271: ($dateoptions[$i] eq $action?' selected="selected"':'').
7272: ">$datedisplay[$i]</option>");
7273: }
7274: } else {
7275: for (my $i=0;$i<=$#standardoptions;$i++) {
7276: if ($standardoptions[$i]=~/\_$tempkey$/) { next; }
7277: $r->print("\n<option value='$standardoptions[$i]'".
7278: ($standardoptions[$i] eq $action?' selected="selected"':'').
7279: ">$standarddisplay[$i]</option>");
7280: }
1.473 amueller 7281: }
1.560 damieng 7282: $r->print('</select>');
7283: unless (&isdateparm($defkeytype{$tempkey})) {
7284: $r->print("\n<br />".&mt('Triggering value(s) of other parameter (optional, comma-separated):').
7285: '<input type="text" size="20" name="'.$tempkey.'_triggervalue" value="'.&rulescache($tempkey.'_triggervalue').'" />');
1.473 amueller 7286: }
1.560 damieng 7287: $r->print("\n</td><td>\n");
1.222 www 7288:
1.221 www 7289: if (&isdateparm($defkeytype{$tempkey})) {
1.560 damieng 7290: my $days=&rulescache($tempkey.'_days');
7291: my $hours=&rulescache($tempkey.'_hours');
7292: my $min=&rulescache($tempkey.'_min');
7293: my $sec=&rulescache($tempkey.'_sec');
7294: $r->print(<<ENDINPUTDATE);
7295: <input name="$tempkey\_days" type="text" size="4" value="$days" />$lt{'days'}<br />
7296: <input name="$tempkey\_hours" type="text" size="4" value="$hours" />$lt{'hours'}<br />
7297: <input name="$tempkey\_min" type="text" size="4" value="$min" />$lt{'min'}<br />
7298: <input name="$tempkey\_sec" type="text" size="4" value="$sec" />$lt{'sec'}
1.564 raeburn 7299: ENDINPUTDATE
1.560 damieng 7300: } elsif ($defkeytype{$tempkey} eq 'string_yesno') {
7301: my $yeschecked='';
7302: my $nochecked='';
7303: if (&rulescache($tempkey.'_value') eq 'yes') { $yeschecked=' checked="checked"'; }
7304: if (&rulescache($tempkey.'_value') eq 'no') { $nochecked=' checked="checked"'; }
7305:
7306: $r->print(<<ENDYESNO);
7307: <label><input type="radio" name="$tempkey\_value" value="yes"$yeschecked /> $lt{'yes'}</label><br />
7308: <label><input type="radio" name="$tempkey\_value" value="no"$nochecked /> $lt{'no'}</label>
1.564 raeburn 7309: ENDYESNO
1.221 www 7310: } else {
1.560 damieng 7311: $r->print('<input type="text" size="20" name="'.$tempkey.'_value" value="'.&rulescache($tempkey.'_value').'" />');
7312: }
1.318 albertel 7313: $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.221 www 7314: }
1.318 albertel 7315: $r->print(&Apache::loncommon::end_data_table().
1.473 amueller 7316: "\n".'<input type="submit" name="storerules" value="'.
1.507 www 7317: &mt('Save').'" /></form>'."\n");
7318: &endSettingsScreen($r);
7319: $r->print(&Apache::loncommon::end_page());
1.220 www 7320: return;
7321: }
1.193 albertel 7322:
1.560 damieng 7323: ##################################################
7324: # PARAMETER CHANGES LOG
7325: ##################################################
7326:
1.563 damieng 7327: # Returns some info for a parameter log entry.
7328: # Returned entries:
7329: # $realm - HTML title for the parameter level and resource
7330: # $section - parameter section
7331: # $name - parameter name
7332: # $part - parameter part
7333: # $what - $part.'.'.$name
7334: # $middle - resource symb ?
7335: # $uname - user name (same as given)
7336: # $udom - user domain (same as given)
7337: # $issection - section or group name
7338: # $realmdescription - title for the parameter level and resource (without using HTML)
7339: #
7340: # @param {string} $key - parameter log key
7341: # @param {string} $uname - user name
7342: # @param {string} $udom - user domain
7343: # @param {boolean} $typeflag - .type log entry
7344: # @returns {Array}
1.290 www 7345: sub components {
1.581 raeburn 7346: my ($key,$uname,$udom,$typeflag)=@_;
1.330 albertel 7347:
7348: if ($typeflag) {
1.560 damieng 7349: $key=~s/\.type$//;
1.290 www 7350: }
1.330 albertel 7351:
7352: my ($middle,$part,$name)=
1.572 damieng 7353: ($key=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s\-]+)\.(\w+)$/);
1.291 www 7354: my $issection;
1.330 albertel 7355:
1.290 www 7356: my $section=&mt('All Students');
7357: if ($middle=~/^\[(.*)\]/) {
1.560 damieng 7358: $issection=$1;
7359: $section=&mt('Group/Section').': '.$issection;
7360: $middle=~s/^\[(.*)\]//;
1.290 www 7361: }
7362: $middle=~s/\.+$//;
7363: $middle=~s/^\.+//;
1.291 www 7364: if ($uname) {
1.560 damieng 7365: $section=&mt('User').": ".&Apache::loncommon::plainname($uname,$udom);
7366: $issection='';
1.291 www 7367: }
1.316 albertel 7368: my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
1.446 bisitz 7369: my $realmdescription=&mt('all resources');
1.556 raeburn 7370: if ($middle=~/^(.+)\_\_\_\((all|rec)\)$/) {
7371: my $mapurl = $1;
7372: my $maplevel = $2;
7373: my $leveltitle = &mt('Folder/Map');
7374: if ($maplevel eq 'rec') {
7375: $leveltitle = &mt('Recursive');
7376: }
1.560 damieng 7377: $realm='<span class="LC_parm_scope_folder">'.$leveltitle.
7378: ': '.&Apache::lonnet::gettitle($mapurl).' <span class="LC_parm_folder"><br />('.
7379: $mapurl.')</span></span>';
7380: $realmdescription=&mt('folder').' '.&Apache::lonnet::gettitle($mapurl);
7381: } elsif ($middle) {
7382: my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
7383: $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').
7384: ': '.&Apache::lonnet::gettitle($middle).' <br /><span class="LC_parm_symb">('.$url.
7385: ' in '.$map.' id: '.$id.')</span></span>';
7386: $realmdescription=&mt('resource').' '.&Apache::lonnet::gettitle($middle);
1.290 www 7387: }
1.291 www 7388: my $what=$part.'.'.$name;
1.330 albertel 7389: return ($realm,$section,$name,$part,
1.473 amueller 7390: $what,$middle,$uname,$udom,$issection,$realmdescription);
1.290 www 7391: }
1.293 www 7392:
1.563 damieng 7393: my %standard_parms; # hash parameter name -> parameter title (not localized)
7394: my %standard_parms_types; # hash parameter name -> parameter type
1.416 jms 7395:
1.563 damieng 7396: # Reads parameter info from packages.tab into %standard_parms.
1.328 albertel 7397: sub load_parameter_names {
1.583 raeburn 7398: open(my $config,"<","$Apache::lonnet::perlvar{'lonTabDir'}/packages.tab");
1.328 albertel 7399: while (my $configline=<$config>) {
1.560 damieng 7400: if ($configline !~ /\S/ || $configline=~/^\#/) { next; }
7401: chomp($configline);
7402: my ($short,$plain)=split(/:/,$configline);
7403: my (undef,$name,$type)=split(/\&/,$short,3);
7404: if ($type eq 'display') {
7405: $standard_parms{$name} = $plain;
1.469 raeburn 7406: } elsif ($type eq 'type') {
1.560 damieng 7407: $standard_parms_types{$name} = $plain;
1.469 raeburn 7408: }
1.328 albertel 7409: }
7410: close($config);
7411: $standard_parms{'int_pos'} = 'Positive Integer';
7412: $standard_parms{'int_zero_pos'} = 'Positive Integer or Zero';
1.575 raeburn 7413: $standard_parms{'scoreformat'} = 'Format for display of score';
1.328 albertel 7414: }
7415:
1.563 damieng 7416: # Returns a parameter title for standard parameters, the name for others.
7417: #
7418: # @param {string} $name - parameter name
7419: # @returns {string}
1.292 www 7420: sub standard_parameter_names {
7421: my ($name)=@_;
1.328 albertel 7422: if (!%standard_parms) {
1.560 damieng 7423: &load_parameter_names();
1.328 albertel 7424: }
1.292 www 7425: if ($standard_parms{$name}) {
1.560 damieng 7426: return $standard_parms{$name};
1.446 bisitz 7427: } else {
1.560 damieng 7428: return $name;
1.292 www 7429: }
7430: }
1.290 www 7431:
1.563 damieng 7432: # Returns a parameter type for standard parameters, undef for others.
7433: #
7434: # @param {string} $name - parameter name
7435: # @returns {string}
1.469 raeburn 7436: sub standard_parameter_types {
7437: my ($name)=@_;
7438: if (!%standard_parms_types) {
7439: &load_parameter_names();
7440: }
7441: if ($standard_parms_types{$name}) {
7442: return $standard_parms_types{$name};
7443: }
7444: return;
7445: }
1.309 www 7446:
1.563 damieng 7447: # Returns a parameter level title (not localized) from the parameter level name.
7448: #
7449: # @param {string} $name - parameter level name (recognized: resourcelevel|maplevel|maplevelrecurse|courselevel)
7450: # @returns {string}
1.557 raeburn 7451: sub standard_parameter_levels {
7452: my ($name)=@_;
7453: my %levels = (
7454: 'resourcelevel' => 'a single resource',
7455: 'maplevel' => 'the enclosing map/folder',
7456: 'maplevelrecurse' => 'the enclosing map/folder (recursive into sub-folders)',
7457: 'courselevel' => 'the general (course) level',
7458: );
7459: if ($levels{$name}) {
7460: return $levels{$name};
7461: }
7462: return;
7463: }
7464:
1.560 damieng 7465: # Display log for parameter changes, blog postings, user notification changes.
1.563 damieng 7466: #
7467: # @param {Apache2::RequestRec} $r - the Apache request
1.285 albertel 7468: sub parm_change_log {
1.568 raeburn 7469: my ($r,$parm_permission)=@_;
1.531 raeburn 7470: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
7471: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.569 raeburn 7472: my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
1.414 droeschl 7473: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable',
1.473 amueller 7474: text=>"Parameter Change Log"});
1.522 raeburn 7475: my $js = '<script type="text/javascript">'."\n".
7476: '// <![CDATA['."\n".
7477: &Apache::loncommon::display_filter_js('parmslog')."\n".
7478: '// ]]>'."\n".
7479: '</script>'."\n";
7480: $r->print(&Apache::loncommon::start_page('Parameter Change Log',$js));
1.327 albertel 7481: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Parameter Change Log'));
1.531 raeburn 7482: &startSettingsScreen($r,'parmset',$crstype);
7483: my %parmlog=&Apache::lonnet::dump('nohist_parameterlog',$cdom,$cnum);
1.311 albertel 7484:
1.301 www 7485: if ((keys(%parmlog))[0]=~/^error\:/) { undef(%parmlog); }
1.311 albertel 7486:
1.522 raeburn 7487: $r->print('<div class="LC_left_float">'.
7488: '<fieldset><legend>'.&mt('Display of Changes').'</legend>'.
7489: '<form action="/adm/parmset?action=parameterchangelog"
1.327 albertel 7490: method="post" name="parameterlog">');
1.446 bisitz 7491:
1.311 albertel 7492: my %saveable_parameters = ('show' => 'scalar',);
7493: &Apache::loncommon::store_course_settings('parameter_log',
7494: \%saveable_parameters);
7495: &Apache::loncommon::restore_course_settings('parameter_log',
7496: \%saveable_parameters);
1.522 raeburn 7497: $r->print(&Apache::loncommon::display_filter('parmslog').' '."\n".
7498: '<input type="submit" value="'.&mt('Display').'" />'.
7499: '</form></fieldset></div><br clear="all" />');
1.301 www 7500:
1.568 raeburn 7501: my $readonly = 1;
7502: if ($parm_permission->{'edit'}) {
7503: undef($readonly);
7504: }
1.531 raeburn 7505: my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
1.301 www 7506: $r->print(&Apache::loncommon::start_data_table().&Apache::loncommon::start_data_table_header_row().
1.473 amueller 7507: '<th>'.&mt('Time').'</th><th>'.&mt('User').'</th><th>'.&mt('Extent').'</th><th>'.&mt('Users').'</th><th>'.
1.568 raeburn 7508: &mt('Parameter').'</th><th>'.&mt('Part').'</th><th>'.&mt('New Value').'</th>');
7509: unless ($readonly) {
7510: $r->print('<th>'.&mt('Announce').'</th>');
7511: }
7512: $r->print(&Apache::loncommon::end_data_table_header_row());
1.309 www 7513: my $shown=0;
1.349 www 7514: my $folder='';
7515: if ($env{'form.displayfilter'} eq 'currentfolder') {
1.560 damieng 7516: my $last='';
7517: if (tie(my %hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db',
7518: &GDBM_READER(),0640)) {
7519: $last=$hash{'last_known'};
7520: untie(%hash);
7521: }
7522: if ($last) { ($folder) = &Apache::lonnet::decode_symb($last); }
7523: }
1.595 raeburn 7524: my $numgroups = 0;
7525: my @groups;
7526: if ($env{'request.course.groups'} ne '') {
7527: @groups = split(/:/,$env{'request.course.groups'});
7528: $numgroups = scalar(@groups);
7529: }
1.560 damieng 7530: foreach my $id (sort {
7531: if ($parmlog{$b}{'exe_time'} ne $parmlog{$a}{'exe_time'}) {
7532: return $parmlog{$b}{'exe_time'} <=>$parmlog{$a}{'exe_time'}
7533: }
7534: my $aid = (split('00000',$a))[-1];
7535: my $bid = (split('00000',$b))[-1];
7536: return $bid<=>$aid;
1.473 amueller 7537: } (keys(%parmlog))) {
1.294 www 7538: my @changes=keys(%{$parmlog{$id}{'logentry'}});
1.560 damieng 7539: my $count = 0;
7540: my $time =
7541: &Apache::lonlocal::locallocaltime($parmlog{$id}{'exe_time'});
7542: my $plainname =
7543: &Apache::loncommon::plainname($parmlog{$id}{'exe_uname'},
7544: $parmlog{$id}{'exe_udom'});
7545: my $about_me_link =
7546: &Apache::loncommon::aboutmewrapper($plainname,
7547: $parmlog{$id}{'exe_uname'},
7548: $parmlog{$id}{'exe_udom'});
7549: my $send_msg_link='';
1.568 raeburn 7550: if ((!$readonly) &&
7551: (($parmlog{$id}{'exe_uname'} ne $env{'user.name'})
1.560 damieng 7552: || ($parmlog{$id}{'exe_udom'} ne $env{'user.domain'}))) {
7553: $send_msg_link ='<br />'.
7554: &Apache::loncommon::messagewrapper(&mt('Send message'),
7555: $parmlog{$id}{'exe_uname'},
7556: $parmlog{$id}{'exe_udom'});
7557: }
7558: my $row_start=&Apache::loncommon::start_data_table_row();
7559: my $makenewrow=0;
7560: my %istype=();
7561: my $output;
7562: foreach my $changed (reverse(sort(@changes))) {
7563: my $value=$parmlog{$id}{'logentry'}{$changed};
7564: my $typeflag = ($changed =~/\.type$/ &&
7565: !exists($parmlog{$id}{'logentry'}{$changed.'.type'}));
1.330 albertel 7566: my ($realm,$section,$parmname,$part,$what,$middle,$uname,$udom,$issection,$realmdescription)=
1.581 raeburn 7567: &components($changed,$parmlog{$id}{'uname'},$parmlog{$id}{'udom'},$typeflag);
1.560 damieng 7568: if ($env{'request.course.sec'} ne '') {
1.595 raeburn 7569: next if (($issection ne '') && (!(($issection eq $env{'request.course.sec'}) ||
7570: ($numgroups && (grep(/^\Q$issection\E$/,@groups))))));
1.560 damieng 7571: if ($uname ne '') {
7572: my $stusection = &Apache::lonnet::getsection($uname,$udom,$env{'request.course.id'});
7573: next if (($stusection ne '-1') && ($stusection ne $env{'request.course.sec'}));
7574: }
7575: }
7576: if ($env{'form.displayfilter'} eq 'currentfolder') {
7577: if ($folder) {
7578: if ($middle!~/^\Q$folder\E/) { next; }
7579: }
7580: }
7581: if ($typeflag) {
7582: $istype{$parmname}=$value;
7583: if (!$env{'form.includetypes'}) { next; }
7584: }
7585: $count++;
7586: if ($makenewrow) {
7587: $output .= $row_start;
7588: } else {
7589: $makenewrow=1;
7590: }
1.470 raeburn 7591: my $parmitem = &standard_parameter_names($parmname);
1.560 damieng 7592: $output .='<td>'.$realm.'</td><td>'.$section.'</td><td>'.
7593: &mt($parmitem).'</td><td>'.
7594: ($part?&mt('Part: [_1]',$part):&mt('All Parts')).'</td><td>';
7595: my $stillactive=0;
7596: if ($parmlog{$id}{'delflag'}) {
7597: $output .= &mt('Deleted');
7598: } else {
7599: if ($typeflag) {
1.470 raeburn 7600: my $parmitem = &standard_parameter_names($value);
7601: $parmitem = &mt($parmitem);
1.560 damieng 7602: $output .= &mt('Type: [_1]',$parmitem);
7603: } else {
1.584 raeburn 7604: my $toolsymb;
7605: if ($middle =~ /ext\.tool$/) {
7606: $toolsymb = $middle;
7607: }
1.560 damieng 7608: my ($level,@all)=&parmval_by_symb($what,$middle,
1.584 raeburn 7609: &Apache::lonnet::metadata($middle,$what,$toolsymb),
1.560 damieng 7610: $uname,$udom,$issection,$issection,$courseopt);
1.469 raeburn 7611: my $showvalue = $value;
7612: if ($istype{$parmname} eq '') {
7613: my $type = &standard_parameter_types($parmname);
7614: if ($type ne '') {
7615: if (&isdateparm($type)) {
7616: $showvalue =
7617: &Apache::lonlocal::locallocaltime($value);
7618: }
7619: }
7620: } else {
1.560 damieng 7621: if (&isdateparm($istype{$parmname})) {
7622: $showvalue = &Apache::lonlocal::locallocaltime($value);
7623: }
1.469 raeburn 7624: }
7625: $output .= $showvalue;
1.560 damieng 7626: if ($value ne $all[$level]) {
7627: $output .= '<br /><span class="LC_warning">'.&mt('Not active anymore').'</span>';
7628: } else {
7629: $stillactive=1;
7630: }
7631: }
1.473 amueller 7632: }
1.568 raeburn 7633: $output .= '</td>';
7634:
7635: unless ($readonly) {
7636: $output .= '<td>';
7637: if ($stillactive) {
7638: my $parmitem = &standard_parameter_names($parmname);
7639: $parmitem = &mt($parmitem);
7640: my $title=&mt('Changed [_1]',$parmitem);
7641: my $description=&mt('Changed [_1] for [_2] to [_3]',
7642: $parmitem,$realmdescription,
7643: (&isdateparm($istype{$parmname})?&Apache::lonlocal::locallocaltime($value):$value));
7644: if (($uname) && ($udom)) {
7645: $output .=
7646: &Apache::loncommon::messagewrapper('Notify User',
7647: $uname,$udom,$title,
7648: $description);
7649: } else {
7650: $output .=
7651: &Apache::lonrss::course_blog_link($id,$title,
7652: $description);
7653: }
1.560 damieng 7654: }
1.568 raeburn 7655: $output .= '</td>';
1.560 damieng 7656: }
1.568 raeburn 7657: $output .= &Apache::loncommon::end_data_table_row();
1.473 amueller 7658: }
1.560 damieng 7659: if ($env{'form.displayfilter'} eq 'containing') {
7660: my $wholeentry=$about_me_link.':'.
7661: $parmlog{$id}{'exe_uname'}.':'.$parmlog{$id}{'exe_udom'}.':'.
7662: $output;
7663: if ($wholeentry!~/\Q$env{'form.containingphrase'}\E/i) { next; }
1.473 amueller 7664: }
1.349 www 7665: if ($count) {
1.560 damieng 7666: $r->print($row_start.'<td rowspan="'.$count.'">'.$time.'</td>
7667: <td rowspan="'.$count.'">'.$about_me_link.
7668: '<br /><tt>'.$parmlog{$id}{'exe_uname'}.
7669: ':'.$parmlog{$id}{'exe_udom'}.'</tt>'.
7670: $send_msg_link.'</td>'.$output);
7671: $shown++;
7672: }
7673: if (!($env{'form.show'} eq &mt('all')
7674: || $shown<=$env{'form.show'})) { last; }
1.286 www 7675: }
1.301 www 7676: $r->print(&Apache::loncommon::end_data_table());
1.507 www 7677: &endSettingsScreen($r);
1.284 www 7678: $r->print(&Apache::loncommon::end_page());
7679: }
7680:
1.560 damieng 7681: ##################################################
7682: # MISC !
7683: ##################################################
7684:
1.563 damieng 7685: # Stores slot information.
1.560 damieng 7686: # Used by table UI
1.563 damieng 7687: # FIXME: I don't understand how this can work when the symb is not defined (if only a map was selected)
7688: #
7689: # @param {string} $slot_name - slot name
7690: # @param {string} $cdom - course domain
7691: # @param {string} $cnum - course number
7692: # @param {string} $symb - resource symb
7693: # @param {string} $uname - user name
7694: # @param {string} $udom - user domain
7695: # @returns {string} - 'ok' or error name
1.437 raeburn 7696: sub update_slots {
7697: my ($slot_name,$cdom,$cnum,$symb,$uname,$udom) = @_;
7698: my %slot=&Apache::lonnet::get_slot($slot_name);
7699: if (!keys(%slot)) {
7700: return 'error: slot does not exist';
7701: }
7702: my $max=$slot{'maxspace'};
7703: if (!defined($max)) { $max=99999; }
7704:
7705: my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
7706: "^$slot_name\0");
7707: my ($tmp)=%consumed;
7708: if ($tmp=~/^error: 2 / ) {
7709: return 'error: unable to determine current slot status';
7710: }
7711: my $last=0;
7712: foreach my $key (keys(%consumed)) {
7713: my $num=(split('\0',$key))[1];
7714: if ($num > $last) { $last=$num; }
7715: if ($consumed{$key}->{'name'} eq $uname.':'.$udom) {
7716: return 'ok';
7717: }
7718: }
7719:
7720: if (scalar(keys(%consumed)) >= $max) {
7721: return 'error: no space left in slot';
7722: }
7723: my $wanted=$last+1;
7724:
7725: my %reservation=('name' => $uname.':'.$udom,
7726: 'timestamp' => time,
7727: 'symb' => $symb);
7728:
7729: my $success=&Apache::lonnet::newput('slot_reservations',
7730: {"$slot_name\0$wanted" =>
7731: \%reservation},
7732: $cdom, $cnum);
1.438 raeburn 7733: if ($success eq 'ok') {
7734: my %storehash = (
7735: symb => $symb,
7736: slot => $slot_name,
7737: action => 'reserve',
7738: context => 'parameter',
7739: );
1.526 raeburn 7740: &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,
1.524 raeburn 7741: '',$uname,$udom,$cnum,$cdom);
1.438 raeburn 7742:
1.526 raeburn 7743: &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash,
1.524 raeburn 7744: '',$uname,$udom,$uname,$udom);
1.438 raeburn 7745: }
1.437 raeburn 7746: return $success;
7747: }
7748:
1.563 damieng 7749: # Deletes a slot reservation.
1.560 damieng 7750: # Used by table UI
1.563 damieng 7751: # FIXME: I don't understand how this can work when the symb is not defined (if only a map was selected)
7752: #
7753: # @param {string} $slot_name - slot name
7754: # @param {string} $cdom - course domain
7755: # @param {string} $cnum - course number
7756: # @param {string} $uname - user name
7757: # @param {string} $udom - user domain
7758: # @param {string} $symb - resource symb
7759: # @returns {string} - 'ok' or error name
1.437 raeburn 7760: sub delete_slots {
7761: my ($slot_name,$cdom,$cnum,$uname,$udom,$symb) = @_;
7762: my $delresult;
7763: my %consumed = &Apache::lonnet::dump('slot_reservations',$cdom,
7764: $cnum, "^$slot_name\0");
7765: if (&Apache::lonnet::error(%consumed)) {
7766: return 'error: unable to determine current slot status';
7767: }
7768: my ($tmp)=%consumed;
7769: if ($tmp=~/^error: 2 /) {
7770: return 'error: unable to determine current slot status';
7771: }
7772: foreach my $key (keys(%consumed)) {
7773: if ($consumed{$key}->{'name'} eq $uname.':'.$udom) {
7774: my $num=(split('\0',$key))[1];
7775: my $entry = $slot_name.'\0'.$num;
7776: $delresult = &Apache::lonnet::del('slot_reservations',[$entry],
7777: $cdom,$cnum);
7778: if ($delresult eq 'ok') {
7779: my %storehash = (
7780: symb => $symb,
7781: slot => $slot_name,
7782: action => 'release',
7783: context => 'parameter',
7784: );
1.526 raeburn 7785: &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,
1.524 raeburn 7786: 1,$uname,$udom,$cnum,$cdom);
1.526 raeburn 7787: &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash,
1.524 raeburn 7788: 1,$uname,$udom,$uname,$udom);
1.437 raeburn 7789: }
7790: }
7791: }
7792: return $delresult;
7793: }
7794:
1.563 damieng 7795: # Returns true if there is a current course.
1.560 damieng 7796: # Used by handler
1.563 damieng 7797: #
7798: # @returns {boolean}
1.355 albertel 7799: sub check_for_course_info {
7800: my $navmap = Apache::lonnavmaps::navmap->new();
7801: return 1 if ($navmap);
7802: return 0;
7803: }
7804:
1.563 damieng 7805: # Returns the current course host and host LON-CAPA version.
7806: #
7807: # @returns {Array} - (course hostname, major version number, minor version number)
1.514 raeburn 7808: sub parameter_release_vars {
1.504 raeburn 7809: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
7810: my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};
7811: my $chostname = &Apache::lonnet::hostname($chome);
7812: my ($cmajor,$cminor) =
7813: split(/\./,&Apache::lonnet::get_server_loncaparev($cdom,$chome));
7814: return ($chostname,$cmajor,$cminor);
7815: }
7816:
1.563 damieng 7817: # Checks if the course host version can handle a parameter required version,
7818: # and if it does, stores the release needed for the course.
7819: #
7820: # @param {string} $name - parameter name
7821: # @param {string} $value - parameter value
7822: # @param {string} $valmatch - name of the test used for checking the value
7823: # @param {string} $namematch - name of the test used for checking the name
7824: # @param {string} $needsrelease - version needed by the parameter, major.minor
7825: # @param {integer} $cmajor - course major version number
7826: # @param {integer} $cminor - course minor version number
7827: # @returns {boolean} - true if a newer version is needed
1.514 raeburn 7828: sub parameter_releasecheck {
1.557 raeburn 7829: my ($name,$value,$valmatch,$namematch,$needsrelease,$cmajor,$cminor) = @_;
1.504 raeburn 7830: my $needsnewer;
7831: my ($needsmajor,$needsminor) = split(/\./,$needsrelease);
7832: if (($cmajor < $needsmajor) ||
7833: ($cmajor == $needsmajor && $cminor < $needsminor)) {
7834: $needsnewer = 1;
1.557 raeburn 7835: } elsif ($name) {
7836: if ($valmatch) {
7837: &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:'.$name.'::'.$valmatch.':'});
7838: } elsif ($value) {
7839: &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:'.$name.':'.$value.'::'});
7840: }
7841: } elsif ($namematch) {
7842: &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter::::'.$namematch});
1.504 raeburn 7843: }
7844: return $needsnewer;
7845: }
7846:
1.568 raeburn 7847: sub get_permission {
7848: my %permission;
7849: my $allowed = 0;
7850: return (\%permission,$allowed) unless ($env{'request.course.id'});
7851: if ((&Apache::lonnet::allowed('opa',$env{'request.course.id'})) ||
7852: (&Apache::lonnet::allowed('opa',$env{'request.course.id'}.'/'.
7853: $env{'request.course.sec'}))) {
7854: %permission= (
7855: 'edit' => 1,
7856: 'set' => 1,
7857: 'setoverview' => 1,
7858: 'addmetadata' => 1,
7859: 'ordermetadata' => 1,
7860: 'setrestrictmeta' => 1,
7861: 'newoverview' => 1,
7862: 'setdefaults' => 1,
7863: 'settable' => 1,
7864: 'parameterchangelog' => 1,
7865: 'cleanparameters' => 1,
7866: 'dateshift1' => 1,
7867: 'dateshift2' => 1,
7868: 'helper' => 1,
7869: );
7870: } elsif ((&Apache::lonnet::allowed('vpa',$env{'request.course.id'})) ||
7871: (&Apache::lonnet::allowed('vpa',$env{'request.course.id'}.'/'.
7872: $env{'request.course.sec'}))) {
7873: %permission = (
7874: 'set' => 1,
7875: 'settable' => 1,
7876: 'newoverview' => 1,
7877: 'setoverview' => 1,
7878: 'parameterchangelog' => 1,
7879: );
7880: }
7881: foreach my $perm (values(%permission)) {
7882: if ($perm) { $allowed=1; last; }
7883: }
7884: return (\%permission,$allowed);
7885: }
7886:
1.560 damieng 7887: ##################################################
7888: # HANDLER
7889: ##################################################
7890:
7891: # Main handler for lonparmset.
7892: # Sub called based on request parameters action and command:
7893: # no command or action: print_main_menu
7894: # command 'set': assessparms (direct access to table mode for a resource)
7895: # (this can also be accessed simply with the symb parameter)
7896: # action 'setoverview': overview (display all existing parameter settings)
7897: # action 'addmetadata': addmetafield (called to add a portfolio metadata field)
7898: # action 'ordermetadata': order_meta_fields (called to order portfolio metadata fields)
7899: # action 'setrestrictmeta': setrestrictmeta (display or save portfolio metadata)
7900: # action 'newoverview': newoverview (overview mode)
7901: # action 'setdefaults': defaultsetter (UI to change parameter setting default actions)
7902: # action 'settable': assessparms (table mode)
7903: # action 'parameterchangelog': parm_change_log (display log for parameter changes,
7904: # blog postings, user notification changes)
7905: # action 'cleanparameters': clean_parameters (unused)
7906: # action 'dateshift1': date_shift_one (overview mode, shift all dates)
7907: # action 'dateshift2': date_shift_two (overview mode, shift all dates)
1.30 www 7908: sub handler {
1.43 albertel 7909: my $r=shift;
1.30 www 7910:
1.376 albertel 7911: &reset_caches();
7912:
1.414 droeschl 7913: &Apache::loncommon::content_type($r,'text/html');
7914: $r->send_http_header;
7915: return OK if $r->header_only;
7916:
1.193 albertel 7917: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.473 amueller 7918: ['action','state',
1.205 www 7919: 'pres_marker',
7920: 'pres_value',
1.206 www 7921: 'pres_type',
1.506 www 7922: 'filter','part',
1.390 www 7923: 'udom','uname','symb','serial','timebase']);
1.131 www 7924:
1.83 bowersj2 7925:
1.193 albertel 7926: &Apache::lonhtmlcommon::clear_breadcrumbs();
1.194 albertel 7927: &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/parmset",
1.507 www 7928: text=>"Content and Problem Settings",
1.473 amueller 7929: faq=>10,
7930: bug=>'Instructor Interface',
1.442 droeschl 7931: help =>
7932: 'Parameter_Manager,Course_Environment,Parameter_Helper,Parameter_Overview,Table_Mode'});
1.203 www 7933:
1.30 www 7934: # ----------------------------------------------------- Needs to be in a course
1.568 raeburn 7935: my ($parm_permission,$allowed) = &get_permission();
1.355 albertel 7936: my $exists = &check_for_course_info();
7937:
1.568 raeburn 7938: if ($env{'request.course.id'} && $allowed && $exists) {
1.193 albertel 7939: #
7940: # Main switch on form.action and form.state, as appropriate
7941: #
7942: # Check first if coming from someone else headed directly for
7943: # the table mode
1.568 raeburn 7944: if (($parm_permission->{'set'}) &&
7945: ((($env{'form.command'} eq 'set') && ($env{'form.url'})
7946: && (!$env{'form.dis'})) || ($env{'form.symb'}))) {
7947: &assessparms($r,$parm_permission);
1.193 albertel 7948: } elsif (! exists($env{'form.action'})) {
7949: &print_main_menu($r,$parm_permission);
1.568 raeburn 7950: } elsif (!$parm_permission->{$env{'form.action'}}) {
7951: &print_main_menu($r,$parm_permission);
1.414 droeschl 7952: } elsif ($env{'form.action'} eq 'setoverview') {
1.568 raeburn 7953: &overview($r,$parm_permission);
1.560 damieng 7954: } elsif ($env{'form.action'} eq 'addmetadata') {
7955: &addmetafield($r);
7956: } elsif ($env{'form.action'} eq 'ordermetadata') {
7957: &order_meta_fields($r);
1.414 droeschl 7958: } elsif ($env{'form.action'} eq 'setrestrictmeta') {
1.560 damieng 7959: &setrestrictmeta($r);
1.414 droeschl 7960: } elsif ($env{'form.action'} eq 'newoverview') {
1.568 raeburn 7961: &newoverview($r,$parm_permission);
1.414 droeschl 7962: } elsif ($env{'form.action'} eq 'setdefaults') {
1.560 damieng 7963: &defaultsetter($r);
7964: } elsif ($env{'form.action'} eq 'settable') {
1.568 raeburn 7965: &assessparms($r,$parm_permission);
1.414 droeschl 7966: } elsif ($env{'form.action'} eq 'parameterchangelog') {
1.568 raeburn 7967: &parm_change_log($r,$parm_permission);
1.414 droeschl 7968: } elsif ($env{'form.action'} eq 'cleanparameters') {
1.560 damieng 7969: &clean_parameters($r);
1.414 droeschl 7970: } elsif ($env{'form.action'} eq 'dateshift1') {
1.390 www 7971: &date_shift_one($r);
1.414 droeschl 7972: } elsif ($env{'form.action'} eq 'dateshift2') {
1.390 www 7973: &date_shift_two($r);
1.446 bisitz 7974: }
1.43 albertel 7975: } else {
1.1 www 7976: # ----------------------------- Not in a course, or not allowed to modify parms
1.560 damieng 7977: if ($exists) {
7978: $env{'user.error.msg'}=
7979: "/adm/parmset:opa:0:0:Cannot modify assessment parameters";
7980: } else {
7981: $env{'user.error.msg'}=
7982: "/adm/parmset::0:1:Course environment gone, reinitialize the course";
7983: }
7984: return HTTP_NOT_ACCEPTABLE;
1.43 albertel 7985: }
1.376 albertel 7986: &reset_caches();
7987:
1.43 albertel 7988: return OK;
1.1 www 7989: }
7990:
7991: 1;
7992: __END__
7993:
7994:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>