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