Annotation of modules/gci/londocsgci.pm, revision 1.6
1.1 gci 1: # The LearningOnline Network
2: # Custom Edit Course Routines for Assembly of Valid Concept Tests from
3: # Geoscience Concept Inventory.
4: #
1.6 ! gci 5: # $Id: londocsgci.pm,v 1.5 2009/12/20 04:32:03 gci Exp $
1.1 gci 6: #
7: # Copyright Michigan State University Board of Trustees
8: #
9: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
10: #
11: # LON-CAPA is free software; you can redistribute it and/or modify
12: # it under the terms of the GNU General Public License as published by
13: # the Free Software Foundation; either version 2 of the License, or
14: # (at your option) any later version.
15: #
16: # LON-CAPA is distributed in the hope that it will be useful,
17: # but WITHOUT ANY WARRANTY; without even the implied warranty of
18: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19: # GNU General Public License for more details.
20: #
21: # You should have received a copy of the GNU General Public License
22: # along with LON-CAPA; if not, write to the Free Software
23: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24: #
25: # /home/httpd/html/adm/gpl.txt
26: #
27: # http://www.lon-capa.org/
28: #
29:
30:
31: package Apache::londocsgci;
32:
33: use strict;
34:
35: use Apache::lonnet;
36: use Apache::loncommon;
37: use LONCAPA::map();
38: use Apache::lonindexer;
39: use Apache::lonlocal;
40: use LONCAPA qw(:DEFAULT :match);
41:
42: { #scope variables
43:
44: my $path;
45: my $version;
46: my $reqnum;
1.6 ! gci 47: my @mandcats;
! 48: my @bincats;
1.1 gci 49: my @categories;
50: my @allprobs;
51: my %probcat;
52: my %prereqs;
1.6 ! gci 53: my %revreqs;
1.1 gci 54: my @defchosen;
55: my @chosen;
1.5 gci 56: my @mandprobs;
57: my @bins;
58: my @optional;
1.3 gci 59: my %mandatory;
1.5 gci 60: my @development;
61: my %developmentitems;
1.1 gci 62:
63: sub setdefaults {
64: $path='/res/gci/gci';
65: $version='GCIv2-1-1';
66: $reqnum=15;
1.5 gci 67: @allprobs=('01','02','37','2004_73','03','04','05','06','07',
1.1 gci 68: '08','10',
69: '09',
70: '11','12','13','14','15','16','17',
71: '18','69',
72: '19','20',
73: '21','22','23','24','25','26','27','28','29','30',
1.5 gci 74: '31','32','33','34','35','36','38',
1.1 gci 75: '39A','39B',
76: '40',
77: '41','42','43','44','45','46','47','48','49','50',
78: '51',
79: '52','57',
80: '53','54','55','56','58',
81: '60',
82: '61','62','63','64','65','66','67','68','70',
1.5 gci 83: '71');
84: @bins = ( ['03','04','06'],
85: ['07','08','09'],
86: ['10','12','13','14','15','16','17'],
87: ['18','19','20','21','22','23','24','25'],
88: ['26','27','28','30'],
89: ['32','33','34','35','36'],
90: ['38','39A','39B','40','41','42','43','44','45','46'],
91: ['47','48','49','50','51','52','53'],
92: ['54','55','56','57','58','60','61','62'],
93: ['63','64','65'],
94: ['66','67','68','69','70','71']);
95: @optional = ('05','11','29','31');
1.6 ! gci 96: @mandcats = ('M1','M2','M3','M4');
! 97: @bincats = ('A','B','C','D','E','F','G','H','I','J','K');
! 98: @categories=(@mandcats,@bincats);
! 99: %probcat =('01' => 'M1' ,'02' => 'M2' ,'37' => 'M3' ,'2004_73' => 'M4' ,
1.5 gci 100: '03' => 'A' ,'04' => 'A','05' => '' ,'06' => 'A' ,'07' => 'B' ,
101: '08' => 'B' ,'09' => 'B' ,'10' => 'C' ,'11' => '' ,'12' => 'C' ,
102: '13' => 'C' ,'14' => 'C' ,'15' => 'C' ,'16' => 'C' ,'17' => 'C' ,'18' => 'D' ,'19' => 'D' ,'20' => 'D' ,
1.1 gci 103: '21' => 'D' ,'22' => 'D' ,'23' => 'D' ,'24' => 'D' ,'25' => 'D' ,'26' => 'E' ,'27' => 'E' ,'28' => 'E' ,'29' => '' ,'30' => 'E' ,
1.5 gci 104: '31' => '' ,'32' => 'F' ,'33' => 'F' ,'34' => 'F' ,'35' => 'F' ,'36' => 'F' ,'38' => 'G' ,
1.1 gci 105: '39A'=> 'G' ,'39B'=> 'G' ,
106: '40' => 'G' ,
107: '41' => 'G' ,'42' => 'G' ,'43' => 'G' ,'44' => 'G' ,'45' => 'G' ,'46' => 'G' ,'47' => 'H' ,'48' => 'H' ,'49' => 'H' ,'50' => 'H' ,
108: '51' => 'H' ,'52' => 'H' ,'53' => 'H' ,'54' => 'I' ,'55' => 'I' ,'56' => 'I' ,'57' => 'I' ,'58' => 'I' ,
109: '60' => 'I' ,
110: '61' => 'I' ,'62' => 'I' ,'63' => 'J' ,'64' => 'J' ,'65' => 'J' ,'66' => 'K' ,'67' => 'K' ,'68' => 'K' ,'69' => 'K' ,'70' => 'K' ,
1.5 gci 111: '71' => 'K');
1.6 ! gci 112: %mandatory=('01' => 1 ,'02' => 1,'37' => 1, '2004_73' => 1);
! 113: @mandprobs = ('01','02','37','2004_73');
! 114: %prereqs=('10' => '08', '57' => '52', '69' => '18');
! 115: foreach my $item (keys(%prereqs)) {
! 116: $revreqs{$prereqs{$item}} = $item;
! 117: }
! 118: @defchosen=('01','02','03','07','12','18','26','32','37','38','47','54','63','66','2004_73');
! 119: @development = ('100','101','102');
! 120: %developmentitems = ('100' => 1, '101' => '1', '102' => '1');
1.1 gci 121: }
122:
123: sub checkvalid {
124: my %covered=();
125: my %chosenproblems=();
126: my @errors=();
127: my $num=$#chosen+1;
128: if ($num<$reqnum) {
129: push(@errors,&mt('Test requires at least [_1] items, but has only [_2].',$reqnum,$num));
130: }
131: foreach my $item (@chosen) {
132: $chosenproblems{$item}=1;
133: $covered{$probcat{$item}}=1;
134: }
135: foreach my $cat (@categories) {
136: unless ($covered{$cat}) {
1.3 gci 137: push(@errors,&mt('Bin [_1] not covered.',$cat));
1.1 gci 138: }
139: }
140: foreach my $item (@chosen) {
141: if ($prereqs{$item}) {
142: unless ($chosenproblems{$prereqs{$item}}) {
1.6 ! gci 143: my $url = &fullurl($item);
! 144: my $title = &Apache::lonnet::metadata($url,'title');
! 145: my $prerequrl = &fullurl($prereqs{$item});
! 146: my $prereqtitle = &Apache::lonnet::metadata($prerequrl,'title');
! 147: push(@errors,&mt('[_1] requires [_2].',"'$title'","'$prereqtitle'"));
1.1 gci 148: }
149: }
150: }
151: return @errors;
152: }
153:
154: sub fullurl {
155: my ($item)=@_;
1.6 ! gci 156: unless ($item=~/^\_/) { $item='_'.$item; }
1.1 gci 157: return $path.'/'.$version.'/GCI'.$item.'.problem';
158: }
159:
1.6 ! gci 160: sub item_from_url {
! 161: my ($url)=@_;
! 162: if ($url =~ m{\Q$path\E/\Q$version\E/GCI_([^.]+)\.problem$}) {
! 163: return $1;
! 164: }
! 165: }
! 166:
1.3 gci 167: sub validcheck {
1.1 gci 168: my ($r)=@_;
169: my @errors=&checkvalid();
170: if ($#errors>-1) {
171: $r->print('<span class="LC_error">'.&mt('Your test is not yet valid.').'</span><p>'.&mt('The following issues must be addressed before you can use the test:').'<ul>');
172: foreach my $message (@errors) {
173: $r->print('<li>'.$message.'</li>');
174: }
175: $r->print('</ul></p>');
1.3 gci 176: return 0;
177: }
178: return 1;
179: }
180:
181: sub listresources {
1.5 gci 182: my ($r,$context,$cdom,$cnum)=@_;
183: my $numchosen = scalar(@chosen);
184: unless ($numchosen > 0) {
185: $r->print('<h3>'.&mt('Create a Concept Test').'</h3>'.
186: '<p>'.&mt('Choose how the test should be built:').'<br />'.
187: '<form name="choices" method="post" action="/adm/coursedocs" onsubmit="javascript:setDocsPhase();">'.
188: '<label><input type="radio" name="concepttest" value="defchosen" />'.&mt('Have a valid test built automatically by the WebCenter.').'</label><br />'.
189: '<label><input type="radio" name="concepttest" value="editmyown" checked="checked" />'.&mt('Make your own selection of questions from the Geoscience Concept Inventory.').'</label><br /><br />'.
190: '<input type="hidden" name="phase" value="" />'.
191: '<input type="submit" name="choosetest" value="'.&mt('Next').'"></p>');
192: return;
193: }
194: if ((!&validcheck($r)) || ($env{'form.concepttest'} eq 'editmyown')) {
195: &editor($r,$context,$cdom,$cnum);
1.3 gci 196: } else {
1.5 gci 197: my $numsub = &get_submissions_count($cdom,$cnum);
198: unless ($env{'form.phase'} eq 'storemap') {
199: $r->print('<p>'.&mt('This course contains a valid concept test which includes [quant,_1,question].',$numchosen).' <a href="/adm/navmaps" target="_coursecontents">'.&mt('Display Contents').'</a><br />');
200: }
201: if ($numsub > 0) {
202: $r->print(&mt('As there are existing student submissions, modification of the [_1]contents[_2] of the Concept Test will result in loss of student performance data, and is [_3]not[_4] permitted.','<i>','</i>','<b>','</b>').'<br />'.&mt('Modification of open and close dates [_1]is[_2] permitted.','<b>','</b>').'</p>');
203: } else {
204: $r->print('<fieldset><legend>'.&mt('Modify Test').'</legend>'.
205: &mt('Currently no student submissions have been recorded, so you may modify the contents of the Concept Test.').
206: '<br /><form name="changetest" method="post" action="/adm/coursedocs">'.
207: '<input type="hidden" name="concepttest" value="editmyown" />'.
208: '<input type="submit" name="modifytest" value="'.&mt('Edit Concept Test').'" /></form></fieldset></p>');
1.3 gci 209: }
1.5 gci 210: my ($crsparms,$ineffect,$parmlev) = ¤t_parms($cdom,$cnum);
211: my $formname = 'datesform';
212: my $datebutton = &mt('Save');
213: my $startform =
214: &Apache::lonhtmlcommon::date_setter($formname,'opendate',
215: $crsparms->{'opendate'});
216: my $endform =
217: &Apache::lonhtmlcommon::date_setter($formname,'duedate',
218: $crsparms->{'duedate'});
219: $r->print('<p><fieldset><legend>'.&mt('Test Availability').'</legend>'.
220: &mt('Open and close dates for test items for the concept test are currently set as follows:').
221: '<br />'.
222: '<form name="'.$formname.'" method="post" '.
223: 'action="/adm/coursedocs">'.
224: &Apache::lonhtmlcommon::start_pick_box().
225: &Apache::lonhtmlcommon::row_title(&mt('Open date')).
226: $startform.
1.6 ! gci 227: &Apache::lonhtmlcommon::row_closure(1).
1.5 gci 228: &Apache::lonhtmlcommon::row_title(&mt('Close date')).
229: $endform.
230: &Apache::lonhtmlcommon::end_pick_box().'<br />'.
231: '<input type="hidden" name="phase" value="storeparms" />'.
232: '<input type="submit" value="'.$datebutton.'" />'.
233: '</form></fieldset></p>');
1.1 gci 234: }
1.3 gci 235: }
236:
237: sub editor {
1.5 gci 238: my ($r,$context,$cdom,$cnum)=@_;
239: my %chosenitems=();
240: my $havedev = 0;
241: foreach my $item (@chosen) {
242: $chosenitems{$item}=1;
243: }
244: my @devitems = &get_development_questions($cdom,$cnum);
245: &Apache::lonnet::appenv({'request.gcicontext' => 'buildtest'});
246: $r->print('<form name="selecteditems" method="post" action="/adm/coursedocs"
247: onsubmit="return validTestCheck()">');
248: $r->print(&mt('Select test items from the numbered bins below and then press [_1]"Store Problem Selection"[_2] at the bottom of the page.','<i>','</i>').'<br />');
249: $r->print('<ul>'.
250: '<li>'.&mt('Tests will contain a minimum of [_1] questions from the GCI 2 Inventory.',"<b>$reqnum</b>").'</li>'.
251: '<li>'.&mt('Tests must contain [_1]four[_2] mandatory questions and at least one item from each of [_1]eleven[_2] other bins.','<b>','</b>').'</li>'.
252: '<li>'.&mt('All tests conclude with [_1]two[_2] questions selected by the system (at random) from a pool of development questions being piloted by the GCI team.','<b>','</b>').'</li>'.
253: '</ul>');
254: my $mandleg = &mt('Mandatory Questions');
255: $r->print(&display_questions(\@mandprobs,'mandatory',$mandleg,\%chosenitems));
256: for (my $i=0; $i<@bins; $i++) {
257: my $num = $i+1;
258: my $legend = &mt('Bin [_1]',$num);
259: my $catname = 'bin'.$i;
260: $r->print(&display_questions($bins[$i],$catname,$legend,\%chosenitems));
261: }
262: my $optleg = &mt('Optional Questions');
263: $r->print(&display_questions(\@optional,'optional',$optleg,\%chosenitems));
264: my $devleg = &mt('Development Questions');
265: $r->print(&display_questions(\@devitems,'development',$devleg,\%chosenitems));
266: $r->print('<input type="hidden" name="phase" value="storemap" />'.
267: '<input type="hidden" name="context" value="'.$context.'" />'.
268: '<input type="submit" value="'.&mt('Store Problem Selection').'" />'.
269: '</form>');
270: &Apache::lonnet::delenv('request.gcicontext');
271: }
272:
273: sub display_questions {
274: my ($questions,$catname,$catlegend,$chosenitems) = @_;
275: return unless((ref($questions) eq 'ARRAY') && (ref($chosenitems) eq 'HASH'));
276: my $total = 0;
277: foreach my $item (@{$questions}) {
278: if ($chosenitems->{$item}) {
279: $total ++;
280: }
281: }
282: my $fieldid = 'GCI_'.$catname.'_q';
283: my $titleid = 'GCI_'.$catname.'_t';
284: my $countid = 'GCI_'.$catname.'_count';
285: my $output = '<fieldset>';
286: my %fixed = (
287: mandatory => 4,
288: development => 2,
289: );
290: if (($catname eq 'mandatory') || ($catname eq 'development')) {
291: $output .= '<legend>'.&mt('[_1] [_2] selected automatically',$catlegend,
292: '<input type="text" name="'.$countid.'" size="1" '.
293: 'value="'.$fixed{$catname}.'" readonly="readonly" />').'</legend>';
294: } else {
295: $output .= '<legend>'.&mt('[_1]: currently [_2] selected',$catlegend,
296: '<input type="text" name="'.$countid.'" size="1" value="'.
297: $total.'" readonly="readonly" />').'</legend>';
298: }
299: $output .= '<span id="'.$titleid.'">'.
300: '<a href="javascript:showQuestions('."'$fieldid','$titleid'".')">'.
301: &mt('Show').'</a> ...</span><br />'.
302: '<div id="'.$fieldid.'">'.
303: &Apache::loncommon::start_data_table().
304: &Apache::loncommon::start_data_table_header_row();
305: unless (($catname eq 'development') || ($catname eq 'mandatory')) {
306: $output .= '<th>'.&mt('Select').'</th>';
307: }
308: $output .= '<th>'.&mt('Problem').
309: '</th><th>'.&mt('Preview').'</th>'.
310: &Apache::loncommon::end_data_table_header_row();
311: foreach my $item (@{$questions}) {
312: my $url = &fullurl($item);
313: my $title = &Apache::lonnet::metadata($url,'title');
314: $output .= &Apache::loncommon::start_data_table_row().'<td>';
315: if (($catname eq 'mandatory') || ($catname eq 'development')) {
316: $output .= '<input type="hidden" name="item'.$item.'" value="checked" />';
317: } else {
318: $output .= '<input type="checkbox" name="item'.$item.'"';
319: if ($chosenitems->{$item}) { $output .= ' checked="checked"'; }
1.6 ! gci 320: $output .= ' onclick="countChecked('."'$catname'".');';
! 321: my $binname;
! 322: if ($prereqs{$item}) {
! 323: for (my $i=0; $i<@bincats; $i++) {
! 324: if ($bincats[$i] eq $probcat{$prereqs{$item}}) {
! 325: $binname = 'bin'.$i;
! 326: last;
! 327: }
! 328: }
! 329: $output .= 'checkPrereqs('."'dep','$item','$prereqs{$item}','$binname'".');';
! 330: } elsif ($revreqs{$item}) {
! 331: for (my $i=0; $i<@bincats; $i++) {
! 332: if ($bincats[$i] eq $probcat{$item}) {
! 333: $binname = 'bin'.$i;
! 334: last;
! 335: }
! 336: }
! 337: $output .= 'checkPrereqs('."'pre','$revreqs{$item}','$item','$binname'".');';
! 338: }
! 339: $output .= '" />'.
1.5 gci 340: '<input type="hidden" name="container'.$item.'" value="'.
341: $catname.'"></td><td>';
342: }
343: $output .= '<b>'.$title.'</b></td>';
344: my $content=&Apache::lonindexer::showpreview($url);
345: $output .= '<td> '.($content eq '' ? ' ':$content).' </td>'."\n".
346: &Apache::loncommon::end_data_table_row();
347: }
348: $output .= &Apache::loncommon::end_data_table().
349: '</div></fieldset><br />';
350: return $output;
351: }
352:
353: sub get_development_questions {
354: my ($cdom,$cnum) = @_;
355: my $cid = $cdom.'_'.$cnum;
356: my %courseenv = &Apache::lonnet::userenvironment($cdom,$cnum,
357: ('internal.courseowner'));
358: my $seed = $courseenv{'internal.courseowner'};
359: my $rndseed=&Apache::lonnet::rndseed($seed,$cid,$cdom,$cnum);
360: &Apache::lonnet::setup_random_from_rndseed($rndseed);
361: my @devitems = &Math::Random::random_permutation(@development);
362: return ($devitems[0],$devitems[1]);
1.1 gci 363: }
364:
365: sub evaluate {
366: if ($env{'form.phase'} eq 'storemap') {
367: @chosen=();
368: foreach my $item (@allprobs) {
369: if ($env{'form.item'.$item}) {
370: push(@chosen,$item);
371: }
372: }
373: }
374: }
375:
376: sub mapread_gci {
377: my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'};
378: my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'};
379: return
1.5 gci 380: &LONCAPA::map::mapread('/uploaded/'.$coursedom.'/'.$coursenum.'/default_1261144274.sequence');
1.1 gci 381: }
382:
383: sub storemap_gci {
1.5 gci 384: my ($coursedom,$coursenum) = @_;
385: if (($coursedom !~ /^$match_domain$/) || ($coursenum !~ /^$match_courseid$/)) {
386: $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'};
387: $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'};
388: }
389: return ('unauthorized',2) if (($coursedom eq '') || ($coursedom eq '') ||
390: (!&Apache::lonnet::allowed('mdc',$coursedom.'_'.$coursenum)));
1.1 gci 391: my ($outtext,$errtext)=
1.5 gci 392: &LONCAPA::map::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/default_1261144274.sequence',1);
1.1 gci 393: if ($errtext) { return ($errtext,2); }
394: return ($errtext,0);
395: }
396:
397: sub chosen_to_map {
398: my %chosenproblems=();
399: foreach my $item (@chosen) {
400: $chosenproblems{$item}=1;
401: }
402: @LONCAPA::map::order=();
403: @LONCAPA::map::resources=();
1.5 gci 404: my $counter = 0;
1.1 gci 405: for (my $idx=0;$idx<=$#allprobs;$idx++) {
406: my $residx=$idx+1;
407: if ($chosenproblems{$allprobs[$idx]}) {
1.6 ! gci 408: my $url = &LONCAPA::map::qtunescape(&fullurl($allprobs[$idx]));
! 409: if (($revreqs{$allprobs[$idx]}) &&
! 410: ($chosenproblems{$revreqs{$allprobs[$idx]}})) {
! 411: my $probnum = $allprobs[$idx].'_'.$revreqs{$allprobs[$idx]};
! 412: $url = &LONCAPA::map::qtunescape(&fullurl($probnum));
! 413: } elsif ($prereqs{$allprobs[$idx]}) {
! 414: next;
! 415: }
1.1 gci 416: push(@LONCAPA::map::order,$residx);
1.5 gci 417: $counter ++;
418: my $name = &LONCAPA::map::qtunescape('Problem '.$counter);
1.1 gci 419: $LONCAPA::map::resources[$residx]=join(':', ($name, $url, 'false', 'normal', 'res'));
420: }
421: }
422: }
423:
424: sub map_to_chosen {
425: @chosen=();
426: foreach my $idx (@LONCAPA::map::order) {
1.6 ! gci 427: my ($title,$url)=split(':',$LONCAPA::map::resources[$idx]);
! 428: my $item;
1.5 gci 429: unless ($url eq '') {
1.6 ! gci 430: $item = &item_from_url($url);
! 431: if (($item =~ /^(\d+)_(\d+)$/) && ($prereqs{$2} eq $1)) {
! 432: push(@chosen,($1,$2));
! 433: } else {
! 434: push(@chosen,$item);
! 435: }
1.5 gci 436: }
437: }
438: if (($env{'form.concepttest'} eq 'defchosen') ||
439: ((@chosen == 0) && ($env{'form.concepttest'} eq 'editmyown'))) {
440: @chosen = @defchosen;
1.1 gci 441: }
442: }
443:
444: sub store {
1.5 gci 445: my ($caller,$cdom,$cnum)=@_;
446: if ($env{'form.concepttest'} eq 'defchosen') {
447: @chosen = @defchosen;
448: }
1.1 gci 449: my @errors=&checkvalid();
1.5 gci 450: if (@errors > 0) {
451: if (($caller eq 'requestcrs') && ($env{'form.concepttest'} eq 'defchosen')) {
1.6 ! gci 452: return &mt('Invalid concept test.');
1.5 gci 453: } else {
1.6 ! gci 454: my $errormsg = '<span class="LC_warning">'.&mt('Invalid concept test:');
! 455: if (@errors > 1) {
! 456: $errormsg .= '<ul><li>'.join('</li><li>',@errors).'</li></ul>';
! 457: } else {
! 458: $errormsg .= '<br />'.$errors[0];
! 459: }
! 460: $errormsg .= '</span>';
! 461: return $errormsg;
1.5 gci 462: }
463: }
1.1 gci 464: &chosen_to_map();
1.5 gci 465: my ($err,$errnum) = &storemap_gci($cdom,$cnum);
466: if ($caller eq 'requestcrs') {
467: if ($errnum == 0) {
468: return;
469: } else {
470: return 'An error occurred when storing the concept test';
471: }
472: }
1.3 gci 473: if ($env{'form.phase'} eq 'storemap') {
1.5 gci 474: if ($errnum == 0) {
475: &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
476: return '<p>'.&mt('You have successfully assembled a valid test.').'</p>'.
477: '<p><a href="/adm/navmaps">'.&mt('Display Table of Contents').
478: '</a>'.(' ' x4).'<a href="/adm/menu">'.&mt('Return to Main Menu').'</a></p>';
479: } else {
480: return '<div class="LC_error">'.&mt('An error occurred when storing your concept test: [_1].',$err).'</div>';
1.3 gci 481: }
1.1 gci 482: }
1.5 gci 483: return;
1.1 gci 484: }
485:
486: sub load {
487: &mapread_gci();
488: &map_to_chosen();
1.5 gci 489: if (@chosen > 0) {
490: my @errors=&checkvalid();
491: if ($#errors>1) { @chosen=@defchosen; }
492: }
493: }
494:
495: sub current_parms {
496: my ($cdom,$cnum) = @_;
497: my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
498: my (%crsparms,%ineffect,%parmlev);
499: foreach my $item ('opendate','duedate') {
500: $crsparms{$item} = $courseopt->{$env{'request.course.id'}.'.0.'.$item};
501: my ($result,@outpar) =
502: &Apache::lonparmset::parmval('0.'.$item,'0.0',undef,undef,
503: $cdom,undef,undef,$courseopt);
504: if ($result) {
505: $ineffect{$item} = $outpar[$result];
506: $parmlev{$item} = $result;
507: }
508: }
509: return (\%crsparms,\%ineffect,\%parmlev);
510: }
511:
512: sub store_dates_parms {
513: my ($cdom,$cnum) = @_;
514: my $topsymb = '___0___uploaded/'.$cdom.'/'.$cnum.'/default.sequence';
515: my ($opendate,$duedate) =
516: &Apache::lonuserutils::get_dates_from_form('opendate','duedate');
517: my %dates = (
518: opendate => {
519: value => $opendate,
520: type => 'date_start',
521: },
522: duedate => {
523: value => $duedate,
524: type => 'date_end',
525: },
526: );
527: my %parmresult;
528: foreach my $date (keys(%dates)) {
529: $parmresult{$date} =
530: &Apache::lonparmset::storeparm_by_symb($topsymb,
531: '0_'.$date,14,$dates{$date}{'value'},
532: $dates{$date}{'type'},undef,$cdom);
533: }
534: my $output = &mt('Open and Close dates set for test items').'<ul>'.
535: '<li>'.&mt('Concept Test Questions open:').' '.
536: &Apache::lonlocal::locallocaltime($opendate).'</li>'.
537: '<li>'.&mt('Concept Test Questions close:').' '.
538: &Apache::lonlocal::locallocaltime($duedate).'</li>'.
539: '</ul>';
540: return $output;
541: }
542:
543: sub get_submissions_count {
544: my ($cdom,$cnum) = @_;
545: my $navmap = Apache::lonnavmaps::navmap->new();
546: if (!defined($navmap)) {
547: my $itemserror = '<span class="LC_warning">'.&mt('An error occurred retrieving information about the course.').'<br />'.&mt('It is recommended that you [_1]re-select the course[_2].','<a href="/adm/roles">','</a>').'</span>';
548: return $itemserror;
549: }
550: my @allres=$navmap->retrieveResources('/uploaded/'.$cdom.'/'.$cnum.'/default_1261144274.sequence',sub {if ($_[0]->is_problem) { $_[0]->parts();} return 1;});
551: my (%resourcetracker,$submissioncount);
552: my %resourcetracker = &Apache::lonnet::dump('nohist_resourcetracker',
553: $cdom,$cnum);
554: foreach my $resource (@allres) {
555: my $symb = $resource->symb();
556: my @parts = @{$resource->parts()};
557: foreach my $part (@parts) {
558: if ($resource->handgrade($part) eq 'yes') {
559: next;
560: }
561: if ($resource->is_survey($part)) {
562: next;
563: }
564: if (exists($resourcetracker{$symb."\0".$part."\0users"})) {
565: $submissioncount += $resourcetracker{$symb."\0".$part."\0users"};
566: }
567: }
568: }
569: return $submissioncount;
570: }
571:
572: sub builder_javascript {
573: my %lt = &Apache::lonlocal::texthash(
574: show => 'Show',
575: hide => 'Hide',
576: );
1.6 ! gci 577: my $prereqjs = "
! 578: function checkPrereqs(caller,item,prereq,binname) {
! 579: var changedPrereq = 0;
! 580: if (document.selecteditems.elements['item'+item].checked == false) {
! 581: return;
! 582: } else {
! 583: if (!document.selecteditems.elements['item'+prereq].checked) {
! 584: document.selecteditems.elements['item'+prereq].checked = true;
! 585: changedPrereq = 1;
! 586: countChecked(binname);
! 587: }
! 588: }
! 589: ";
! 590:
! 591: my ($hasdep,$prereq,$hasdeptitle,$prereqtitle) = ('','','','');
! 592: foreach my $item (sort(keys(%prereqs))) {
! 593: $hasdep .= "'$item',";
! 594: $prereq .= "'$prereqs{$item}',";
! 595: my $url = &fullurl($item);
! 596: $hasdeptitle .= "'".&Apache::lonnet::metadata($url,'title')."',";
! 597: my $purl = &fullurl($prereqs{$item});
! 598: $prereqtitle .= "'".&Apache::lonnet::metadata($purl,'title')."',";
! 599: }
! 600: $hasdep =~ s/,$//;
! 601: $prereq =~ s/,$//;
! 602: $hasdeptitle =~ s/,$//;
! 603: $prereqtitle =~ s/,$//;
! 604:
! 605: $prereqjs .= <<"ENDFN";
! 606:
! 607: var hasDeps = Array($hasdep);
! 608: var preReqs = Array($prereq);
! 609: var hasDepTitles = Array($hasdeptitle);
! 610: var preReqTitles = Array($prereqtitle);
! 611: for (var i=0; i<hasDeps.length; i++) {
! 612: if (hasDeps[i] == item) {
! 613: var msg = hasDepTitles[i]+' question has a prerequisite: '+preReqTitles[i]+'.\\nThe two questions will appear together in a composite question.';
! 614: if (changedPrereq == 1) {
! 615: msg = msg+'\\n\\nAs the prerequisite was not checked, inclusion of '+hasDepTitles[i]+' has now caused '+preReqTitles[i]+' to also be checked automatically.';
! 616: }
! 617: if (caller == 'pre') {
! 618: msg = msg +'\\n\\nIf you do not wish to include '+preReqTitles[i]+' you will first need to uncheck '+hasDepTitles[i]+', then uncheck '+preReqTitles[i]+' again.'
! 619: }
! 620: alert(msg);
! 621: break;
! 622: }
! 623: }
! 624: return;
! 625: }
! 626:
! 627: ENDFN
! 628:
1.5 gci 629: return <<ENDJS;
630: function showQuestions(content,title) {
631: document.getElementById(content).style.display = "";
632: document.getElementById(title).innerHTML='<a href="javascript:hideQuestions('+"'"+content+"','"+title+"'"+');">$lt{'hide'}</a> ...';
633: return;
634: }
635:
636: function hideQuestions(content,title) {
637: document.getElementById(content).style.display = "none";
638: document.getElementById(title).innerHTML='<a href="javascript:showQuestions('+"'"+content+"','"+title+"'"+')">$lt{'show'}</a> ...';
639: return;
640: }
641:
642: function setInitialVisibility() {
643: if (document.getElementById('GCI_mandatory_q') == null) {
644: return;
645: }
646: document.getElementById('GCI_mandatory_q').style.display = "none";
647: document.getElementById('GCI_bin0_q').style.display = "none";
648: document.getElementById('GCI_bin1_q').style.display = "none";
649: document.getElementById('GCI_bin2_q').style.display = "none";
650: document.getElementById('GCI_bin3_q').style.display = "none";
651: document.getElementById('GCI_bin4_q').style.display = "none";
652: document.getElementById('GCI_bin5_q').style.display = "none";
653: document.getElementById('GCI_bin6_q').style.display = "none";
654: document.getElementById('GCI_bin7_q').style.display = "none";
655: document.getElementById('GCI_bin8_q').style.display = "none";
656: document.getElementById('GCI_bin9_q').style.display = "none";
657: document.getElementById('GCI_bin10_q').style.display = "none";
658: document.getElementById('GCI_optional_q').style.display = "none";
659: document.getElementById('GCI_development_q').style.display = "none";
660: }
661:
662: function countChecked(binname) {
663: var count = 0;
664: for (var i=0; i<document.selecteditems.elements.length; i++) {
665: if (document.selecteditems.elements[i].type == "hidden") {
666: if (document.selecteditems.elements[i].value == binname) {
667: var itemname = document.selecteditems.elements[i].name;
668: var itemnum = itemname.substr(9);
669: if (document.selecteditems.elements['item'+itemnum].checked) {
670: count ++;
671: }
672: }
673: }
674: }
675: document.selecteditems.elements['GCI_'+binname+'_count'].value = count;
676: }
677:
678: function validTestCheck() {
679: var empty = '';
680: for (var i=0; i<11; i++) {
681: var binname = 'GCI_bin'+i+'_count';
682: var j = i+1;
683: if (document.selecteditems.elements[binname].value < 1) {
684: empty = empty +' '+j;
685: }
686: }
687: if (empty != "") {
688: alert("Current test invalid - select at least one item from the following bin(s): "+empty);
689: return false;
690: }
691: return true;
692: }
693:
694: function setDocsPhase() {
695: if (document.choices.concepttest.length) {
696: for (var i=0; i<document.choices.concepttest.length; i++) {
697: if (document.choices.concepttest[i].checked) {
698: if (document.choices.concepttest[i].value == 'defchosen') {
699: document.choices.phase.value = 'storemap';
700: alert("Setting value for phase to "+document.choices.phase.value);
701:
702: }
703: }
704: }
705: }
706: return;
707: }
708:
1.6 ! gci 709: $prereqjs
! 710:
1.5 gci 711: ENDJS
712:
1.1 gci 713: }
714:
715: } #end scope variables
716:
717: 1;
718: __END__
719:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>