Annotation of rat/lonuserstate.pm, revision 1.28

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Construct and maintain state and binary representation of course for user
                      3: #
1.28    ! www         4: # $Id: lonuserstate.pm,v 1.27 2002/06/05 12:52:05 www Exp $
1.25      www         5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
1.1       www        28: # (Server for RAT Maps
                     29: #
                     30: # (Edit Handler for RAT Maps
                     31: # (TeX Content Handler
                     32: #
1.26      harris41   33: # YEAR=2000
1.1       www        34: # 05/29/00,05/30 Gerd Kortemeyer)
                     35: # 7/1 Gerd Kortemeyer)
                     36: # 7/1,7/3,7/4,7/7,7/8,7/10 Gerd Kortemeyer)
                     37: #
1.9       www        38: # 7/15,7/17,7/18,8/1,8/2,8/4,8/5,8/21,8/22,8/23,8/30,
1.19      www        39: # 9/2,9/4,9/29,9/30,10/2,10/11,10/30,10/31,
1.22      www        40: # 11/1,11/2,11/14,11/16,11/22,12/28,
1.26      harris41   41: # YEAR=2001
1.24      www        42: # 07/05/01,08/30,08/31 Gerd Kortemeyer
1.26      harris41   43: # 12/16 Scott Harrison
                     44: #
                     45: ###
1.1       www        46: 
                     47: package Apache::lonuserstate;
                     48: 
1.26      harris41   49: # ------------------------------------------------- modules used by this module
1.1       www        50: use strict;
                     51: use Apache::Constants qw(:common :http);
                     52: use Apache::File;
                     53: use HTML::TokeParser;
                     54: use Apache::lonnet();
1.26      harris41   55: use Apache::loncommon();
1.1       www        56: use GDBM_File;
1.12      www        57: use Apache::lonmsg;
1.15      www        58: use Safe;
1.21      www        59: use Safe::Hole;
1.15      www        60: use Opcode;
                     61: 
1.1       www        62: # ---------------------------------------------------- Globals for this package
                     63: 
                     64: my $pc;      # Package counter
                     65: my %hash;    # The big tied hash
1.19      www        66: my %parmhash;# The hash with the parameters
1.1       www        67: my @cond;    # Array with all of the conditions
                     68: my $errtext; # variable with all errors
1.21      www        69: my $retfurl; # variable with the very first URL in the course
1.1       www        70: 
                     71: # --------------------------------------------------------- Loads map from disk
                     72: 
                     73: sub loadmap { 
                     74:     my $uri=shift;
                     75:     if ($hash{'map_pc_'.$uri}) { return OK; }
                     76: 
                     77:     $pc++;
                     78:     my $lpc=$pc;
                     79:     $hash{'map_pc_'.$uri}=$lpc;
                     80:     $hash{'map_id_'.$lpc}=$uri;
                     81: 
                     82:     my $fn='/home/httpd/html'.$uri;
                     83: 
1.10      www        84:     unless (($fn=~/\.sequence$/) ||
1.1       www        85:             ($fn=~/\.page$/)) { 
                     86:        $errtext.="Invalid map: $fn\n";
                     87:        return OK; 
                     88:     }
                     89: 
1.22      www        90:     my $ispage=($fn=~/\.page$/);
                     91: 
1.1       www        92:     unless (-e $fn) {
                     93: 	my $returned=Apache::lonnet::repcopy($fn);
                     94:         unless ($returned eq OK) {
                     95:            $errtext.="Could not import: $fn - ";
                     96:            if ($returned eq HTTP_SERVICE_UNAVAILABLE) {
                     97: 	      $errtext.="Server unavailable\n";
                     98:            }
                     99:            if ($returned eq HTTP_NOT_FOUND) {
                    100: 	      $errtext.="File not found\n";
                    101:            }
                    102:            if ($returned eq FORBIDDEN) {
                    103: 	      $errtext.="Access forbidden\n";
                    104:            }
                    105:            return OK;
                    106:        }
                    107:     }
                    108: 
                    109:     if (-e $fn) {
                    110:         my @content;
                    111:         {
                    112: 	    my $fh=Apache::File->new($fn);
                    113:             @content=<$fh>;
                    114:         }
                    115:         my $instr=join('',@content);
                    116:         my $parser = HTML::TokeParser->new(\$instr);
                    117:         my $token;
                    118: 
                    119:         my $linkpc=0;
                    120: 
                    121:         $fn=~/\.(\w+)$/;
                    122: 
                    123:         $hash{'map_type_'.$lpc}=$1;
                    124: 
                    125:         while ($token = $parser->get_token) {
                    126: 	    if ($token->[0] eq 'S') {
                    127:                 if ($token->[1] eq 'resource') {
                    128: # -------------------------------------------------------------------- Resource
                    129: 
                    130:                     my $rid=$lpc.'.'.$token->[2]->{'id'};
                    131: 
                    132:                     $hash{'kind_'.$rid}='res';
                    133:                     $hash{'title_'.$rid}=$token->[2]->{'title'};
                    134:                     my $turi=$token->[2]->{'src'};
1.22      www       135:                     unless ($ispage) {
                    136:                         $turi=~/\.(\w+)$/;
1.26      harris41  137:                         my $embstyle=&Apache::loncommon::fileembstyle($1);
1.22      www       138:                         if ($token->[2]->{'external'} eq 'true') {
                    139:                             $turi=~s/^http\:\/\//\/adm\/wrapper\/ext\//;
                    140:                         } else {
1.26      harris41  141:                            my $embstyle=&Apache::loncommon::fileembstyle($1);
1.22      www       142:                            if (($embstyle eq 'img') || ($embstyle eq 'emb')) {
                    143: 			       $turi='/adm/wrapper'.$turi;
                    144:                            }
                    145:                         }
                    146: 		    }
1.1       www       147:                     $hash{'src_'.$rid}=$turi;
                    148: 
                    149:                     if (defined($hash{'ids_'.$turi})) {
                    150:                         $hash{'ids_'.$turi}.=','.$rid;
                    151:                     } else {
                    152:                         $hash{'ids_'.$turi}=''.$rid;
                    153:                     }
                    154: 
1.22      www       155:                     if ($token->[2]->{'external'} eq 'true') {
1.1       www       156:                         $hash{'ext_'.$rid}='true:';
                    157:                     } else {
                    158:                         $hash{'ext_'.$rid}='false:';
                    159:                     }
                    160:                     if ($token->[2]->{'type'}) {
                    161: 			$hash{'type_'.$rid}=$token->[2]->{'type'};
1.2       www       162:                         if ($token->[2]->{'type'} eq 'start') {
                    163: 			    $hash{'map_start_'.$uri}="$rid";
                    164:                         }
                    165:                         if ($token->[2]->{'type'} eq 'finish') {
                    166: 			    $hash{'map_finish_'.$uri}="$rid";
                    167:                         }
1.1       www       168:                     }  else {
                    169:                         $hash{'type_'.$rid}='normal';
                    170:                     }
                    171: 
1.10      www       172:                     if (($turi=~/\.sequence$/) ||
1.1       www       173:                         ($turi=~/\.page$/)) {
1.2       www       174:                         $hash{'is_map_'.$rid}=1;
1.1       www       175:                         &loadmap($turi);
                    176:                     } 
                    177:                     
                    178:                 } elsif ($token->[1] eq 'condition') {
                    179: # ------------------------------------------------------------------- Condition
                    180: 
                    181:                     my $rid=$lpc.'.'.$token->[2]->{'id'};
                    182: 
                    183:                     $hash{'kind_'.$rid}='cond';
1.2       www       184:                     $cond[$#cond+1]=$token->[2]->{'value'};
                    185:                     $hash{'condid_'.$rid}=$#cond;
1.1       www       186:                     if ($token->[2]->{'type'}) {
1.2       www       187:                         $cond[$#cond].=':'.$token->[2]->{'type'};
1.1       www       188:                     }  else {
1.2       www       189:                         $cond[$#cond].=':normal';
1.1       www       190:                     }
                    191: 
                    192:                 } elsif ($token->[1] eq 'link') {
                    193: # ----------------------------------------------------------------------- Links
                    194: 
                    195:                     $linkpc++;
                    196:                     my $linkid=$lpc.'.'.$linkpc;
                    197: 
                    198:                     my $goesto=$lpc.'.'.$token->[2]->{'to'};
                    199:                     my $comesfrom=$lpc.'.'.$token->[2]->{'from'};
                    200:                     my $undercond=0;
                    201: 
                    202:                     if ($token->[2]->{'condition'}) {
                    203: 			$undercond=$lpc.'.'.$token->[2]->{'condition'};
                    204:                     }
                    205: 
                    206:                     $hash{'goesto_'.$linkid}=$goesto;
                    207:                     $hash{'comesfrom_'.$linkid}=$comesfrom;
                    208:                     $hash{'undercond_'.$linkid}=$undercond;
                    209: 
                    210:                     if (defined($hash{'to_'.$comesfrom})) {
                    211:                         $hash{'to_'.$comesfrom}.=','.$linkid;
                    212:                     } else {
                    213:                         $hash{'to_'.$comesfrom}=''.$linkid;
                    214:                     }
                    215:                     if (defined($hash{'from_'.$goesto})) {
                    216:                         $hash{'from_'.$goesto}.=','.$linkid;
                    217:                     } else {
                    218:                         $hash{'from_'.$goesto}=''.$linkid;
                    219:                     }
1.18      www       220:                 } elsif ($token->[1] eq 'param') {
                    221: # ------------------------------------------------------------------- Parameter
                    222: 
                    223:                     my $referid=$lpc.'.'.$token->[2]->{'to'};
1.20      www       224:                     my $part=$token->[2]->{'part'};
                    225:                     unless ($part) { $part=0; }
1.18      www       226:                     my $newparam=
                    227: 			&Apache::lonnet::escape($token->[2]->{'type'}).':'.
1.20      www       228: 			&Apache::lonnet::escape($part.'.'.
                    229:                          $token->[2]->{'name'}).'='.
1.18      www       230: 			&Apache::lonnet::escape($token->[2]->{'value'});
                    231:                     if (defined($hash{'param_'.$referid})) {
                    232:                         $hash{'param_'.$referid}.='&'.$newparam;
                    233:                     } else {
                    234:                         $hash{'param_'.$referid}=''.$newparam;
                    235:                     }
1.28    ! www       236:                     if ($token->[2]->{'name'} eq 'mapalias') {
        !           237: 			$hash{'mapalias_'.$token->[2]->{'value'}}=$referid;
        !           238:                     }
1.1       www       239:                 } 
                    240: 
                    241:             }
                    242:         }
                    243: 
                    244:     } else {
                    245:         $errtext.='Map not loaded: The file does not exist. ';
                    246:     }
                    247: }
                    248: 
1.3       www       249: # --------------------------------------------------------- Simplify expression
                    250: 
                    251: sub simplify {
                    252:    my $expression=shift;
                    253: # (8)=8
                    254:    $expression=~s/\((\d+)\)/$1/g;
                    255: # 8&8=8
1.7       www       256:    $expression=~s/(\D)(\d+)\&\2(\D)/$1$2$3/g;
1.3       www       257: # 8|8=8
1.7       www       258:    $expression=~s/(\D)(\d+)\|\2(\D)/$1$2$3/g;
1.3       www       259: # (5&3)&4=5&3&4
1.7       www       260:    $expression=~s/\((\d+)((?:\&\d+)+)\)\&(\d+\D)/$1$2\&$3/g;
1.3       www       261: # (((5&3)|(4&6)))=((5&3)|(4&6))
                    262:    $expression=~
                    263:        s/\((\(\(\d+(?:\&\d+)*\)(?:\|\(\d+(?:\&\d+)*\))+\))\)/$1/g;
                    264: # ((5&3)|(4&6))|(1&2)=(5&3)|(4&6)|(1&2)
                    265:    $expression=~
                    266:        s/\((\(\d+(?:\&\d+)*\))((?:\|\(\d+(?:\&\d+)*\))+)\)\|(\(\d+(?:\&\d+)*\))/\($1$2\|$3\)/g;
                    267:    return $expression;
                    268: }
                    269: 
1.2       www       270: # -------------------------------------------------------- Build condition hash
                    271: 
                    272: sub traceroute {
1.3       www       273:     my ($sofar,$rid,$beenhere)=@_;
                    274:     $sofar=simplify($sofar);
1.2       www       275:     unless ($beenhere=~/\&$rid\&/) {
                    276:        $beenhere.=$rid.'&';  
1.21      www       277:        if ($retfurl eq '') {
                    278:            $retfurl=$hash{'src_'.$rid};
                    279:        }
1.2       www       280:        if (defined($hash{'conditions_'.$rid})) {
1.3       www       281: 	   $hash{'conditions_'.$rid}=simplify(
                    282:            '('.$hash{'conditions_'.$rid}.')|('.$sofar.')');
1.2       www       283:        } else {
                    284:            $hash{'conditions_'.$rid}=$sofar;
                    285:        }
                    286:        if (defined($hash{'is_map_'.$rid})) {
1.3       www       287:            if (defined($hash{'map_start_'.$hash{'src_'.$rid}})) {
                    288: 	       &traceroute($sofar,$hash{'map_start_'.$hash{'src_'.$rid}},'&');
                    289:                if (defined($hash{'map_finish_'.$hash{'src_'.$rid}})) {
                    290: 		   $sofar=
                    291:                   $hash{'conditions_'.$hash{'map_finish_'.$hash{'src_'.$rid}}};
                    292:                }
1.2       www       293:            }
                    294:        }
                    295:        if (defined($hash{'to_'.$rid})) {
1.26      harris41  296:           foreach (split(/\,/,$hash{'to_'.$rid})) {
1.2       www       297: 		my $further=$sofar;
                    298:                 if ($hash{'undercond_'.$_}) {
                    299: 		   if (defined($hash{'condid_'.$hash{'undercond_'.$_}})) {
1.3       www       300:   		       $further=simplify('('.$further.')&('.
                    301:                               $hash{'condid_'.$hash{'undercond_'.$_}}.')');
1.2       www       302: 		   } else {
                    303:                        $errtext.='Undefined condition ID: '
                    304:                                  .$hash{'undercond_'.$_}.'. ';
                    305:                    }
                    306:                 }
                    307:                 &traceroute($further,$hash{'goesto_'.$_},$beenhere);
1.26      harris41  308:           }
1.2       www       309:        }
                    310:     }
                    311: }
1.1       www       312: 
1.19      www       313: # ------------------------------ Cascading conditions, quick access, parameters
1.4       www       314: 
                    315: sub accinit {
                    316:     my ($uri,$short,$fn)=@_;
                    317:     my %acchash=();
                    318:     my %captured=();
                    319:     my $condcounter=0;
1.5       www       320:     $acchash{'acc.cond.'.$short.'.0'}=0;
1.26      harris41  321:     foreach (keys %hash) {
1.4       www       322:        if ($_=~/^conditions/) {
                    323: 	  my $expr=$hash{$_};
1.26      harris41  324:          foreach ($expr=~m/(\(\(\d+(?:\&\d+)+\)(?:\|\(\d+(?:\&\d+)+\))+\))/g) {
1.4       www       325:              my $sub=$_;
                    326:              my $orig=$_;
1.13      www       327:       $sub=~/\(\((\d+\&(:?\d+\&)*)(?:\d+\&*)+\)(?:\|\(\1(?:\d+\&*)+\))+\)/;
1.4       www       328:              my $factor=$1;
1.7       www       329:              $sub=~s/$factor//g;
                    330:              $sub=~s/^\(/\($factor\(/;
1.4       www       331: 	     $sub.=')';
                    332:              $sub=simplify($sub);
                    333:              $orig=~s/(\W)/\\$1/g;
1.7       www       334:  	     $expr=~s/$orig/$sub/;
1.26      harris41  335: 	  }
1.4       www       336:           $hash{$_}=$expr;
                    337:           unless (defined($captured{$expr})) {
                    338: 	      $condcounter++;
                    339:               $captured{$expr}=$condcounter;
1.5       www       340:               $acchash{'acc.cond.'.$short.'.'.$condcounter}=$expr;
1.4       www       341:           } 
1.19      www       342:        } elsif ($_=~/^param_(\d+)\.(\d+)/) {
                    343:           my $prefix=&Apache::lonnet::declutter($hash{'map_id_'.$1}).
                    344:       '___'.$2.'___'.&Apache::lonnet::declutter($hash{'src_'.$1.'.'.$2});
1.26      harris41  345:           foreach (split(/\&/,$hash{$_})) {
1.19      www       346: 	     my ($typename,$value)=split(/\=/,$_);
                    347:              my ($type,$name)=split(/\:/,$typename);
                    348:              $parmhash{$prefix.'.'.&Apache::lonnet::unescape($name)}=
                    349:                                    &Apache::lonnet::unescape($value);
                    350: 	     $parmhash{$prefix.'.'.&Apache::lonnet::unescape($name).'.type'}=
                    351:                                    &Apache::lonnet::unescape($type);
1.26      harris41  352:           }
1.19      www       353:        }
1.26      harris41  354:     }
                    355:     foreach (keys %hash) {
1.4       www       356: 	if ($_=~/^ids/) {
1.26      harris41  357: 	  foreach (split(/\,/,$hash{$_})) {
1.13      www       358: 	    my $resid=$_;
1.4       www       359:             my $uri=$hash{'src_'.$resid};
1.22      www       360:             $uri=~s/^\/adm\/wrapper//;
1.4       www       361:             my @uriparts=split(/\//,$uri);
                    362:             my $urifile=$uriparts[$#uriparts];
                    363:             $#uriparts--;
                    364:             my $uripath=join('/',@uriparts);
1.8       www       365:             $uripath=~s/^\/res\///;
1.23      www       366:            if ($uripath) {
1.13      www       367:             my $uricond='0';
1.4       www       368:             if (defined($hash{'conditions_'.$resid})) {
1.13      www       369:  		$uricond=$captured{$hash{'conditions_'.$resid}};
1.4       www       370:             }
1.5       www       371:             if (defined($acchash{'acc.res.'.$short.'.'.$uripath})) {
1.13      www       372:                 if ($acchash{'acc.res.'.$short.'.'.$uripath}=~
                    373:                    /(\&$urifile\:[^\&]*)/) {
                    374: 		    my $replace=$1;
1.27      www       375:                     my $regexp=$replace;
                    376:                     $regexp=~s/\|/\\\|/g;
1.13      www       377:                     $acchash{'acc.res.'.$short.'.'.$uripath}
1.27      www       378:                      =~s/$regexp/$replace\|$uricond/;
1.13      www       379:                 } else {
                    380: 		   $acchash{'acc.res.'.$short.'.'.$uripath}.=
                    381:                      $urifile.':'.$uricond.'&';
                    382: 	        }
1.4       www       383:             } else {
1.13      www       384:                 $acchash{'acc.res.'.$short.'.'.$uripath}=
                    385:                  '&'.$urifile.':'.$uricond.'&';
1.23      www       386:             }
                    387:            } 
1.26      harris41  388:          }
1.13      www       389:       }
1.26      harris41  390:     }
1.24      www       391:     $acchash{'acc.res.'.$short.'.'}='&:0&';
1.8       www       392:     my $courseuri=$uri;
                    393:     $courseuri=~s/^\/res\///;
1.19      www       394:     &Apache::lonnet::delenv('(acc\.|httpref\.)');
1.4       www       395:     &Apache::lonnet::appenv(%acchash,
1.9       www       396:                             "request.course.id"  => $short,
1.8       www       397:                             "request.course.fn"  => $fn,
                    398:                             "request.course.uri" => $courseuri); 
1.4       www       399: }
                    400: 
1.1       www       401: # ---------------------------------------------------- Read map and all submaps
                    402: 
                    403: sub readmap {
1.9       www       404:    my $short=shift;
                    405:    $short=~s/^\///;
                    406:    my %cenv=&Apache::lonnet::coursedescription($short);
                    407:    my $fn=$cenv{'fn'};
                    408:    my $uri;
                    409:    $short=~s/\//\_/g;
                    410:    unless ($uri=$cenv{'url'}) { 
                    411:       &Apache::lonnet::logthis("<font color=blue>WARNING: ".
                    412:                        "Could not load course $short.</font>"); 
                    413:       return 'No course data available.';
                    414:    }
1.3       www       415:    @cond=('true:normal');
1.11      www       416:    unlink($fn.'.db');
                    417:    unlink($fn.'_symb.db');
                    418:    unlink($fn.'.state');
1.19      www       419:    unlink($fn.'parms.db');
1.21      www       420:    $retfurl='';
1.19      www       421:    if ((tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT,0640)) &&
                    422:        (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT,0640))) {
1.4       www       423:     %hash=();
1.19      www       424:     %parmhash=();
1.4       www       425:     $errtext='';
                    426:     $pc=0;
                    427:     loadmap($uri);
                    428:     if (defined($hash{'map_start_'.$uri})) {
                    429:         &traceroute('0',$hash{'map_start_'.$uri},'&');
                    430:         &accinit($uri,$short,$fn);
1.2       www       431:     }
1.19      www       432:     unless ((untie(%hash)) && (untie(%parmhash))) {
1.4       www       433:       &Apache::lonnet::logthis("<font color=blue>WARNING: ".
                    434:                        "Could not untie coursemap $fn for $uri.</font>"); 
1.1       www       435:     }
1.4       www       436:     {
                    437:      my $cfh;
                    438:      if ($cfh=Apache::File->new(">$fn.state")) {
                    439:         print $cfh join("\n",@cond);
                    440:      } else {
1.6       www       441:       &Apache::lonnet::logthis("<font color=blue>WARNING: ".
1.4       www       442:                        "Could not write statemap $fn for $uri.</font>"); 
                    443:      }
                    444:     }  
                    445:    } else {
1.6       www       446:       &Apache::lonnet::logthis("<font color=blue>WARNING: ".
1.4       www       447:                        "Could not tie coursemap $fn for $uri.</font>"); 
                    448:    }
1.12      www       449:    &Apache::lonmsg::author_res_msg($ENV{'request.course.uri'},$errtext);
1.21      www       450:    return ($retfurl,$errtext);
1.1       www       451: }
1.15      www       452: 
                    453: # ------------------------------------------------------- Evaluate state string
                    454: 
                    455: sub evalstate {
1.21      www       456: 
1.15      www       457:     my $fn=$ENV{'request.course.fn'}.'.state';
                    458:     my $state='2';
                    459:     if (-e $fn) {
                    460:        my @conditions=();
                    461:        {
                    462:         my $fh=Apache::File->new($fn);
                    463:         @conditions=<$fh>;
                    464:        }  
1.21      www       465:        my $safeeval = new Safe;
                    466:        my $safehole = new Safe::Hole;
1.15      www       467:        $safeeval->permit("entereval");
                    468:        $safeeval->permit(":base_math");
                    469:        $safeeval->deny(":base_io");
1.21      www       470:        $safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&EXT');
1.26      harris41  471:        foreach (@conditions) {
1.15      www       472: 	   my $line=$_;
                    473:            chomp($line);
                    474: 	   my ($condition,$weight)=split(/\:/,$_);
                    475:            if ($safeeval->reval($condition)) {
                    476: 	       if ($weight eq 'force') {
                    477: 		   $state.='3';
                    478:                } else {
                    479:                    $state.='2';
                    480:                }
                    481:            } else {
                    482:                if ($weight eq 'stop') {
                    483: 		   $state.='0';
                    484:                } else {
                    485:                    $state.='1';
                    486:                }
                    487:            }
1.26      harris41  488:        }
1.15      www       489:     }
                    490:     &Apache::lonnet::appenv('user.state.'.$ENV{'request.course.id'} => $state);
                    491:     return $state;
                    492: }
                    493: 
1.1       www       494: 1;
                    495: __END__
                    496: 
1.26      harris41  497: =head1 NAME
                    498: 
                    499: Apache::lonuserstate - Construct and maintain state and binary representation
                    500: of course for user
                    501: 
                    502: =head1 SYNOPSIS
                    503: 
                    504: Invoked by lonroles.pm.
                    505: 
                    506: &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
                    507: 
                    508: =head1 INTRODUCTION
                    509: 
                    510: This module constructs and maintains state and binary representation
                    511: of course for user.
                    512: 
                    513: This is part of the LearningOnline Network with CAPA project
                    514: described at http://www.lon-capa.org.
                    515: 
                    516: =head1 HANDLER SUBROUTINE
                    517: 
                    518: There is no handler subroutine.
                    519: 
                    520: =head1 OTHER SUBROUTINES
                    521: 
                    522: =over 4
                    523: 
                    524: =item *
                    525: 
                    526: loadmap() : Loads map from disk
                    527: 
                    528: =item *
                    529: 
                    530: simplify() : Simplify expression
                    531: 
                    532: =item *
                    533: 
                    534: traceroute() : Build condition hash
                    535: 
                    536: =item *
                    537: 
                    538: accinit() : Cascading conditions, quick access, parameters
1.1       www       539: 
1.26      harris41  540: =item *
1.1       www       541: 
1.26      harris41  542: readmap() : Read map and all submaps
1.1       www       543: 
1.26      harris41  544: =item *
1.1       www       545: 
1.26      harris41  546: evalstate() : Evaluate state string
1.1       www       547: 
1.26      harris41  548: =back
1.1       www       549: 
1.26      harris41  550: =cut

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.