Annotation of modules/gci/londocsgci.pm, revision 1.13

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>