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