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

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.16    ! gci         5: # $Id: londocsgci.pm,v 1.15 2010/11/16 02:28:10 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.15      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','023','024','025','026','027');
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.').
1.16    ! gci       222:                     '<br /><br /><form name="changetest" method="post" action="/adm/coursedocs">'.
1.5       gci       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');
1.16    ! gci       229:       my $hide_timezone = 1;
1.5       gci       230:       my $startform =
                    231:           &Apache::lonhtmlcommon::date_setter($formname,'opendate',
1.16    ! gci       232:                                               $crsparms->{'opendate'},'','','',
        !           233:                                               '','','','','',$hide_timezone);
1.5       gci       234:       my $endform =
                    235:           &Apache::lonhtmlcommon::date_setter($formname,'duedate',
1.16    ! gci       236:                                               $crsparms->{'duedate'},'','','',
        !           237:                                               '','','','','',$hide_timezone);
        !           238:       my $includeempty = 1;
        !           239:       my $timezone = &Apache::lonlocal::gettimezone();
        !           240:       my $tzform = &Apache::loncommon::select_timezone('timezone',$timezone,
        !           241:                                                        undef,$includeempty);
1.5       gci       242:       $r->print('<p><fieldset><legend>'.&mt('Test Availability').'</legend>'.
                    243:                 &mt('Open and close dates for test items for the concept test are currently set as follows:').
1.16    ! gci       244:                 '<br /><br />'.
1.5       gci       245:                 '<form name="'.$formname.'" method="post" '.
                    246:                 'action="/adm/coursedocs">'.
                    247:                 &Apache::lonhtmlcommon::start_pick_box().
1.16    ! gci       248:                 &Apache::lonhtmlcommon::row_title(&mt('Time zone')).
        !           249:                 $tzform.
        !           250:                 &Apache::lonhtmlcommon::row_closure(1).         
1.5       gci       251:                 &Apache::lonhtmlcommon::row_title(&mt('Open date')).
                    252:                 $startform.
1.6       gci       253:                 &Apache::lonhtmlcommon::row_closure(1).
1.5       gci       254:                 &Apache::lonhtmlcommon::row_title(&mt('Close date')).
                    255:                 $endform.
1.10      gci       256:                 &Apache::lonhtmlcommon::row_closure(1).
                    257:                 &Apache::lonhtmlcommon::end_pick_box().'<br />'. 
1.5       gci       258:                 '<input type="hidden" name="phase" value="storeparms" />'.
                    259:                 '<input type="submit" value="'.$datebutton.'" />'.
                    260:                 '</form></fieldset></p>');
1.1       gci       261:    }
1.3       gci       262: }
                    263: 
                    264: sub editor {
1.5       gci       265:     my ($r,$context,$cdom,$cnum)=@_;
                    266:     my %chosenitems=();
                    267:     my $havedev = 0;
                    268:     foreach my $item (@chosen) {
                    269:         $chosenitems{$item}=1;
                    270:     }
                    271:     my @devitems = &get_development_questions($cdom,$cnum);
                    272:     &Apache::lonnet::appenv({'request.gcicontext' => 'buildtest'});
                    273:     $r->print('<form name="selecteditems" method="post" action="/adm/coursedocs"
                    274:               onsubmit="return validTestCheck()">');
                    275:     $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 />');
                    276:     $r->print('<ul>'.
                    277:               '<li>'.&mt('Tests will contain a minimum of [_1] questions from the GCI 2 Inventory.',"<b>$reqnum</b>").'</li>'.
                    278:               '<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>'.
                    279:               '<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>'.
                    280:               '</ul>');
                    281:     my $mandleg = &mt('Mandatory Questions');
                    282:     $r->print(&display_questions(\@mandprobs,'mandatory',$mandleg,\%chosenitems));
                    283:     for (my $i=0; $i<@bins; $i++) {
                    284:         my $num = $i+1;
                    285:         my $legend = &mt('Bin [_1]',$num);
                    286:         my $catname = 'bin'.$i;
                    287:         $r->print(&display_questions($bins[$i],$catname,$legend,\%chosenitems));
                    288:     }
                    289:     my $optleg = &mt('Optional Questions');
                    290:     $r->print(&display_questions(\@optional,'optional',$optleg,\%chosenitems));
                    291:     my $devleg = &mt('Development Questions');
                    292:     $r->print(&display_questions(\@devitems,'development',$devleg,\%chosenitems));
                    293:     $r->print('<input type="hidden" name="phase" value="storemap" />'.
                    294:               '<input type="hidden" name="context" value="'.$context.'" />'.
1.14      gci       295:               '<input type="hidden" name="concepttest" value="'.$env{'form.concepttest'}.'" />'.
1.5       gci       296:               '<input type="submit" value="'.&mt('Store Problem Selection').'" />'.
                    297:               '</form>');
                    298:     &Apache::lonnet::delenv('request.gcicontext');
                    299: }
                    300: 
                    301: sub display_questions {
                    302:     my ($questions,$catname,$catlegend,$chosenitems) = @_;
                    303:     return unless((ref($questions) eq 'ARRAY') && (ref($chosenitems) eq 'HASH'));
                    304:     my $total = 0;
                    305:     foreach my $item (@{$questions}) {
                    306:         if ($chosenitems->{$item}) {
                    307:             $total ++;
                    308:         }
                    309:     }
                    310:     my $fieldid = 'GCI_'.$catname.'_q';
                    311:     my $titleid = 'GCI_'.$catname.'_t';
                    312:     my $countid = 'GCI_'.$catname.'_count';
                    313:     my $output = '<fieldset>';
                    314:     my %fixed = (
                    315:         mandatory   => 4,
                    316:         development => 2, 
                    317:     );
                    318:     if (($catname eq 'mandatory') || ($catname eq 'development')) {
                    319:         $output .= '<legend>'.&mt('[_1] [_2] selected automatically',$catlegend,
                    320:                    '<input type="text" name="'.$countid.'" size="1" '.
                    321:                    'value="'.$fixed{$catname}.'" readonly="readonly" />').'</legend>';
                    322:     } else {
                    323:         $output .= '<legend>'.&mt('[_1]: currently [_2] selected',$catlegend,
1.10      gci       324:                    '<input type="text" name="'.$countid.'" id="'.$countid.'" size="1" value="'.
1.5       gci       325:                    $total.'" readonly="readonly" />').'</legend>';
                    326:     }
                    327:     $output .= '<span id="'.$titleid.'">'.
                    328:               '<a href="javascript:showQuestions('."'$fieldid','$titleid'".')">'.
                    329:               &mt('Show').'</a> ...</span><br />'.
1.13      gci       330:               '<div id="'.$fieldid.'" style="display: none">'.
1.5       gci       331:               &Apache::loncommon::start_data_table().
                    332:               &Apache::loncommon::start_data_table_header_row();
                    333:     unless (($catname eq 'development') || ($catname eq 'mandatory')) {
                    334:         $output .= '<th>'.&mt('Select').'</th>';
                    335:     }
                    336:     $output .= '<th>'.&mt('Problem').
                    337:                '</th><th>'.&mt('Preview').'</th>'.
                    338:                &Apache::loncommon::end_data_table_header_row();
                    339:     foreach my $item (@{$questions}) {
1.8       gci       340:         my $url = &fullurl($item,$catname);
1.5       gci       341:         my $title = &Apache::lonnet::metadata($url,'title');
                    342:         $output .= &Apache::loncommon::start_data_table_row().'<td>';
1.8       gci       343:         if ($catname eq 'mandatory') {
1.5       gci       344:             $output .= '<input type="hidden" name="item'.$item.'" value="checked" />';
1.8       gci       345:         } elsif ($catname eq 'development') {
                    346:             $output .= '<input type="hidden" name="pilot'.$item.'" value="checked" />';
1.5       gci       347:         } else {
1.10      gci       348:             $output .= '<input type="checkbox" name="item'.$item.'" id="item'.$item.'"';
1.5       gci       349:             if ($chosenitems->{$item}) { $output .= ' checked="checked"'; }
1.6       gci       350:             $output .= ' onclick="countChecked('."'$catname'".');';
                    351:             my $binname;
                    352:             if ($prereqs{$item}) {
                    353:                 for (my $i=0; $i<@bincats; $i++) {
                    354:                     if ($bincats[$i] eq $probcat{$prereqs{$item}}) {
                    355:                         $binname = 'bin'.$i; 
                    356:                         last;
                    357:                     }
                    358:                 }
                    359:                 $output .= 'checkPrereqs('."'dep','$item','$prereqs{$item}','$binname'".');';
                    360:             } elsif ($revreqs{$item}) {
                    361:                 for (my $i=0; $i<@bincats; $i++) {
                    362:                     if ($bincats[$i] eq $probcat{$item}) {
                    363:                         $binname = 'bin'.$i;
                    364:                         last;
                    365:                     }
                    366:                 }
                    367:                 $output .= 'checkPrereqs('."'pre','$revreqs{$item}','$item','$binname'".');';
                    368:             }
                    369:             $output .= '" />'.
1.5       gci       370:                        '<input type="hidden" name="container'.$item.'" value="'.
                    371:                        $catname.'"></td><td>';
                    372:         }
                    373:         $output .= '<b>'.$title.'</b></td>';
                    374:         my $content=&Apache::lonindexer::showpreview($url);
1.12      gci       375:         my $startformtag = '<form name="lonhomework" enctype="multipart/form-data" method="post" action="'.$url.'?inhibitmenu=yes" >';
                    376:         my $endtag = '<table><tr><td><input onmouseup="javascript:setSubmittedPart';
                    377:         $content =~ s/^\Q$startformtag\E//;
                    378:         $content =~ s/\Q$endtag\E.+$//s;
1.5       gci       379:         $output .= '<td> '.($content eq '' ? '&nbsp;':$content).' </td>'."\n".
                    380:                    &Apache::loncommon::end_data_table_row();
                    381:     }
                    382:     $output .= &Apache::loncommon::end_data_table().
                    383:                '</div></fieldset><br />';
                    384:     return $output;
                    385: }
                    386: 
                    387: sub get_development_questions {
                    388:     my ($cdom,$cnum) = @_;
                    389:     my $cid = $cdom.'_'.$cnum;
                    390:     my %courseenv = &Apache::lonnet::userenvironment($cdom,$cnum,
                    391:                         ('internal.courseowner'));
                    392:     my $seed = $courseenv{'internal.courseowner'};
                    393:     my $rndseed=&Apache::lonnet::rndseed($seed,$cid,$cdom,$cnum);
                    394:     &Apache::lonnet::setup_random_from_rndseed($rndseed);
                    395:     my @devitems = &Math::Random::random_permutation(@development);
                    396:     return ($devitems[0],$devitems[1]); 
1.1       gci       397: }
                    398: 
                    399: sub evaluate {
                    400:    if ($env{'form.phase'} eq 'storemap') {
                    401:       @chosen=();
                    402:       foreach my $item (@allprobs) {
                    403:          if ($env{'form.item'.$item}) {
                    404:             push(@chosen,$item);
                    405:          }
                    406:       }
                    407:    }
                    408: }
                    409: 
                    410: sub mapread_gci {
                    411:     my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'};
                    412:     my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'};
                    413:     return
1.5       gci       414:       &LONCAPA::map::mapread('/uploaded/'.$coursedom.'/'.$coursenum.'/default_1261144274.sequence');
1.1       gci       415: }
                    416: 
                    417: sub storemap_gci {
1.5       gci       418:     my ($coursedom,$coursenum) = @_;
                    419:     if (($coursedom !~ /^$match_domain$/) || ($coursenum !~ /^$match_courseid$/)) { 
                    420:         $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'};
                    421:         $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'};
                    422:     }
                    423:     return ('unauthorized',2) if (($coursedom eq '') || ($coursedom eq '') ||
                    424:                    (!&Apache::lonnet::allowed('mdc',$coursedom.'_'.$coursenum)));
1.1       gci       425:     my ($outtext,$errtext)=
1.5       gci       426:         &LONCAPA::map::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/default_1261144274.sequence',1);
1.1       gci       427:     if ($errtext) { return ($errtext,2); }
                    428:     return ($errtext,0);
                    429: }
                    430: 
                    431: sub chosen_to_map {
                    432:    my %chosenproblems=();
                    433:    foreach my $item (@chosen) {
                    434:       $chosenproblems{$item}=1;
                    435:    }
                    436:    @LONCAPA::map::order=();
                    437:    @LONCAPA::map::resources=();
1.5       gci       438:    my $counter = 0;
1.8       gci       439:    my $residx;
1.1       gci       440:    for (my $idx=0;$idx<=$#allprobs;$idx++) {
1.8       gci       441:        $residx=$idx+1;
1.1       gci       442:        if ($chosenproblems{$allprobs[$idx]}) {
1.6       gci       443:           my $url  = &LONCAPA::map::qtunescape(&fullurl($allprobs[$idx]));
                    444:           if (($revreqs{$allprobs[$idx]}) && 
                    445:               ($chosenproblems{$revreqs{$allprobs[$idx]}})) {
1.7       gci       446:               my $probnum = '_'.$allprobs[$idx].'_'.$revreqs{$allprobs[$idx]};
1.6       gci       447:               $url = &LONCAPA::map::qtunescape(&fullurl($probnum));
                    448:           } elsif ($prereqs{$allprobs[$idx]}) {
                    449:               next;
                    450:           }
1.1       gci       451:           push(@LONCAPA::map::order,$residx);
1.5       gci       452:           $counter ++;
                    453: 	  my $name = &LONCAPA::map::qtunescape('Problem '.$counter);
1.1       gci       454: 	  $LONCAPA::map::resources[$residx]=join(':', ($name, $url, 'false', 'normal', 'res'));
                    455:        }
                    456:     }
1.8       gci       457:     foreach my $devitem (@development) {
                    458:         if ($env{'form.pilot'.$devitem}) {
                    459:             my $url = &LONCAPA::map::qtunescape(&fullurl($devitem,'development'));
                    460:             $residx ++;
                    461:             push(@LONCAPA::map::order,$residx);
                    462:             $counter ++;
                    463:             my $name = &LONCAPA::map::qtunescape('Problem '.$counter);
                    464:             $LONCAPA::map::resources[$residx]=join(':', ($name, $url, 'false', 'normal', 'res'));
                    465:         }
                    466:     }
1.1       gci       467: }
                    468: 
                    469: sub map_to_chosen {
                    470:     @chosen=();
                    471:     foreach my $idx (@LONCAPA::map::order) {
1.6       gci       472:        my ($title,$url)=split(':',$LONCAPA::map::resources[$idx]);
                    473:        my $item;
1.5       gci       474:        unless ($url eq '') {
1.6       gci       475:            $item = &item_from_url($url);
                    476:            if (($item =~ /^(\d+)_(\d+)$/) && ($prereqs{$2} eq $1)) {
                    477:                push(@chosen,($1,$2));
                    478:            } else {
                    479:                push(@chosen,$item);
                    480:            }
1.5       gci       481:        }
                    482:     }
                    483:     if (($env{'form.concepttest'} eq 'defchosen') || 
                    484:         ((@chosen == 0) && ($env{'form.concepttest'} eq 'editmyown'))) {
                    485:         @chosen = @defchosen;
1.1       gci       486:     }
                    487: }
                    488: 
                    489: sub store {
1.5       gci       490:    my ($caller,$cdom,$cnum)=@_;
                    491:    if ($env{'form.concepttest'} eq 'defchosen') {
                    492:        @chosen = @defchosen;
                    493:    }
1.1       gci       494:    my @errors=&checkvalid();
1.5       gci       495:    if (@errors > 0) {
                    496:        if (($caller eq 'requestcrs') && ($env{'form.concepttest'} eq 'defchosen')) {
1.6       gci       497:            return &mt('Invalid concept test.');
1.5       gci       498:        } else {
1.6       gci       499:            my $errormsg = '<span class="LC_warning">'.&mt('Invalid concept test:');
                    500:            if (@errors > 1) {
                    501:                $errormsg .= '<ul><li>'.join('</li><li>',@errors).'</li></ul>';
                    502:            } else {
                    503:                $errormsg .= '<br />'.$errors[0];
                    504:            }
                    505:            $errormsg .= '</span>';
                    506:            return $errormsg;
1.5       gci       507:        }
                    508:    }
1.1       gci       509:    &chosen_to_map();
1.5       gci       510:    my ($err,$errnum) = &storemap_gci($cdom,$cnum);
                    511:    if ($caller eq 'requestcrs') {
                    512:        if ($errnum == 0) {
                    513:            return; 
                    514:        } else {
                    515:            return 'An error occurred when storing the concept test';
                    516:        }
                    517:    }
1.3       gci       518:    if ($env{'form.phase'} eq 'storemap') {
1.5       gci       519:       if ($errnum == 0) {
                    520:          &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
                    521:          return '<p>'.&mt('You have successfully assembled a valid test.').'</p>'.
                    522:                 '<p><a href="/adm/navmaps">'.&mt('Display Table of Contents').
                    523:                 '</a>'.('&nbsp;' x4).'<a href="/adm/menu">'.&mt('Return to Main Menu').'</a></p>';
                    524:       } else {
                    525:           return '<div class="LC_error">'.&mt('An error occurred when storing your concept test: [_1].',$err).'</div>';
1.3       gci       526:       }
1.1       gci       527:    }
1.5       gci       528:    return;
1.1       gci       529: }
                    530: 
                    531: sub load {
                    532:    &mapread_gci();
                    533:    &map_to_chosen();
1.5       gci       534:    if (@chosen > 0) {
                    535:        my @errors=&checkvalid();
                    536:        if ($#errors>1) { @chosen=@defchosen; }
                    537:    }
                    538: }
                    539: 
                    540: sub current_parms {
                    541:     my ($cdom,$cnum) = @_;
                    542:     my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
                    543:     my (%crsparms,%ineffect,%parmlev);
                    544:     foreach my $item ('opendate','duedate') {
                    545:         $crsparms{$item} = $courseopt->{$env{'request.course.id'}.'.0.'.$item};
                    546:         my ($result,@outpar) =
                    547:             &Apache::lonparmset::parmval('0.'.$item,'0.0',undef,undef,
                    548:                                          $cdom,undef,undef,$courseopt);
                    549:         if ($result) {
                    550:             $ineffect{$item} = $outpar[$result];
                    551:             $parmlev{$item} = $result;
                    552:         }
                    553:     }
                    554:     return (\%crsparms,\%ineffect,\%parmlev);
                    555: }
                    556: 
                    557: sub store_dates_parms {
                    558:     my ($cdom,$cnum) = @_;
                    559:     my $topsymb = '___0___uploaded/'.$cdom.'/'.$cnum.'/default.sequence';
1.16    ! gci       560:     my $tz_change; 
        !           561:     my $timezone =  &Apache::lonlocal::gettimezone();
        !           562:     if ($env{'form.timezone'} ne '') {
        !           563:         if (&Apache::lonlocal::gettimezone($env{'form.timezone'}) ne 'local') {
        !           564:             if ($timezone ne $env{'form.timezone'}) {
        !           565:                 $tz_change = 1;
        !           566:                 $timezone = $env{'form.timezone'};
        !           567:             }
        !           568:         }
        !           569:     }
1.5       gci       570:     my ($opendate,$duedate) = 
1.16    ! gci       571:         &Apache::lonuserutils::get_dates_from_form('opendate','duedate',$timezone);
1.5       gci       572:     my %dates = (
                    573:                   opendate => {
                    574:                                value => $opendate,
                    575:                                type  => 'date_start',
                    576:                               },
                    577:                   duedate => {
                    578:                                value => $duedate,
                    579:                                type  => 'date_end',
                    580:                              },
                    581:                 );
                    582:     my %parmresult;
                    583:     foreach my $date (keys(%dates)) {
                    584:         $parmresult{$date} =
                    585:             &Apache::lonparmset::storeparm_by_symb($topsymb,
                    586:                                    '0_'.$date,14,$dates{$date}{'value'},
                    587:                                    $dates{$date}{'type'},undef,$cdom);
                    588:     }
1.16    ! gci       589:     if ($tz_change) {
        !           590:         &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.timezone' => $timezone});
        !           591:     }
1.5       gci       592:     my $output = &mt('Open and Close dates set for test items').'<ul>'.
                    593:                  '<li>'.&mt('Concept Test Questions open:').' '.
1.16    ! gci       594:                         &Apache::lonlocal::locallocaltime($opendate,$timezone).'</li>'.
1.5       gci       595:                  '<li>'.&mt('Concept Test Questions close:').' '.
1.16    ! gci       596:                         &Apache::lonlocal::locallocaltime($duedate,$timezone).'</li>'.
1.5       gci       597:                  '</ul>';
                    598:     return $output;
                    599: }
                    600: 
                    601: sub get_submissions_count {
                    602:     my ($cdom,$cnum) = @_;
                    603:     my $navmap = Apache::lonnavmaps::navmap->new();
                    604:     if (!defined($navmap)) {
                    605:         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>';
                    606:         return $itemserror;
                    607:     }
                    608:     my @allres=$navmap->retrieveResources('/uploaded/'.$cdom.'/'.$cnum.'/default_1261144274.sequence',sub {if ($_[0]->is_problem) { $_[0]->parts();} return 1;});
                    609:     my (%resourcetracker,$submissioncount);
                    610:     my %resourcetracker =  &Apache::lonnet::dump('nohist_resourcetracker',
                    611:                                                  $cdom,$cnum);
                    612:     foreach my $resource (@allres) {
                    613:         my $symb = $resource->symb();
                    614:         my @parts = @{$resource->parts()};
                    615:         foreach my $part (@parts) {
                    616:             if ($resource->handgrade($part) eq 'yes') {
                    617:                 next;
                    618:             }
                    619:             if ($resource->is_survey($part)) {
                    620:                 next;
                    621:             }
                    622:             if (exists($resourcetracker{$symb."\0".$part."\0users"})) {
                    623:                 $submissioncount += $resourcetracker{$symb."\0".$part."\0users"};
                    624:             }
                    625:         }
                    626:     }
                    627:     return $submissioncount;
                    628: }
                    629: 
                    630: sub builder_javascript {
                    631:     my %lt = &Apache::lonlocal::texthash(
                    632:                                           show => 'Show',
                    633:                                           hide => 'Hide',
                    634:                                         );
1.6       gci       635:     my $prereqjs = "
                    636: function checkPrereqs(caller,item,prereq,binname) {
                    637:     var changedPrereq = 0;
1.10      gci       638:     element = document.getElementById('item'+item);
                    639:     if (element.checked == false) {
1.6       gci       640:         return;
                    641:     } else {
1.10      gci       642:         prereqelement = document.getElementById('item'+prereq);
                    643:         if (!prereqelement.checked) {
                    644:             prereqelement.checked = true;
1.6       gci       645:             changedPrereq = 1;
                    646:             countChecked(binname);
                    647:         }
                    648:     }
                    649: ";
                    650:     
                    651:     my ($hasdep,$prereq,$hasdeptitle,$prereqtitle) = ('','','','');
                    652:     foreach my $item (sort(keys(%prereqs))) {
                    653:         $hasdep .= "'$item',";
                    654:         $prereq .= "'$prereqs{$item}',";
                    655:         my $url = &fullurl($item);
                    656:         $hasdeptitle .= "'".&Apache::lonnet::metadata($url,'title')."',";
                    657:         my $purl = &fullurl($prereqs{$item});
                    658:         $prereqtitle .= "'".&Apache::lonnet::metadata($purl,'title')."',";
                    659:     }
                    660:     $hasdep =~ s/,$//;
                    661:     $prereq =~ s/,$//;
                    662:     $hasdeptitle =~ s/,$//;
                    663:     $prereqtitle =~ s/,$//;
                    664: 
                    665:     $prereqjs .= <<"ENDFN";
                    666: 
                    667:     var hasDeps = Array($hasdep);
                    668:     var preReqs = Array($prereq);
                    669:     var hasDepTitles = Array($hasdeptitle);
                    670:     var preReqTitles = Array($prereqtitle);
                    671:     for (var i=0; i<hasDeps.length; i++) {
                    672:         if (hasDeps[i] == item) {
                    673:             var msg = hasDepTitles[i]+' question has a prerequisite: '+preReqTitles[i]+'.\\nThe two questions will appear together in a composite question.';
                    674:             if (changedPrereq == 1) {
                    675:                 msg = msg+'\\n\\nAs the prerequisite was not checked, inclusion of '+hasDepTitles[i]+' has now caused '+preReqTitles[i]+' to also be checked automatically.';
                    676:             }
                    677:             if (caller == 'pre') {
                    678:                 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.'
                    679:             }
                    680:             alert(msg);
                    681:             break;
                    682:         }
                    683:     }
                    684:     return;
                    685: }
                    686: 
                    687: ENDFN
                    688: 
1.5       gci       689:     return <<ENDJS;
                    690: function showQuestions(content,title) {
                    691:     document.getElementById(content).style.display = "";
                    692:     document.getElementById(title).innerHTML='<a href="javascript:hideQuestions('+"'"+content+"','"+title+"'"+');">$lt{'hide'}</a> ...';
                    693:     return;
                    694: }
                    695: 
                    696: function hideQuestions(content,title) {
                    697:     document.getElementById(content).style.display = "none";
                    698:     document.getElementById(title).innerHTML='<a href="javascript:showQuestions('+"'"+content+"','"+title+"'"+')">$lt{'show'}</a> ...';
                    699:     return;
                    700: }
                    701: 
                    702: function countChecked(binname) {
                    703:     var count = 0;
                    704:     for (var i=0; i<document.selecteditems.elements.length; i++) {
                    705:         if (document.selecteditems.elements[i].type == "hidden") {
                    706:             if (document.selecteditems.elements[i].value == binname) {
                    707:                 var itemname = document.selecteditems.elements[i].name;
                    708:                 var itemnum = itemname.substr(9);
1.10      gci       709:                 element = document.getElementById('item'+itemnum);
                    710:                 if (element.checked) {
1.5       gci       711:                     count ++;
                    712:                 }
                    713:             }
                    714:         }
                    715:     }
1.10      gci       716:     countelement = document.getElementById('GCI_'+binname+'_count');
                    717:     countelement.value = count;
1.5       gci       718: }
                    719: 
                    720: function validTestCheck() {
                    721:     var empty = '';
                    722:     for (var i=0; i<11; i++) {
                    723:         var binname = 'GCI_bin'+i+'_count';
                    724:         var j = i+1;
1.10      gci       725:         countelement = document.getElementById(binname);        
                    726:         if (countelement.value < 1) {
1.5       gci       727:             empty = empty +' '+j;
                    728:         }
                    729:     }
                    730:     if (empty != "") {
                    731:         alert("Current test invalid - select at least one item from the following bin(s): "+empty);
                    732:         return false;
                    733:     }
                    734:     return true;
                    735: }
                    736: 
                    737: function setDocsPhase() {
                    738:     if (document.choices.concepttest.length) {
                    739:         for (var i=0; i<document.choices.concepttest.length; i++) {
                    740:             if (document.choices.concepttest[i].checked) {
                    741:                 if (document.choices.concepttest[i].value == 'defchosen') {
                    742:                     document.choices.phase.value = 'storemap';
                    743:                 }
                    744:             }
                    745:         }
                    746:     }
                    747:     return;
                    748: }
                    749: 
1.6       gci       750: $prereqjs
                    751: 
1.5       gci       752: ENDJS
                    753: 
1.1       gci       754: }
                    755: 
                    756: } #end scope variables
                    757: 
                    758: 1;
                    759: __END__
                    760: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.