File:  [LON-CAPA] / rat / lonpageflip.pm
Revision 1.45: download - view: text, annotated - select for diffs
Wed Sep 17 18:16:39 2003 UTC (20 years, 8 months ago) by albertel
Branches: MAIN
CVS tags: HEAD
- stupid typo
- removing the blind acceptance of the answers target as a form parameter

    1: # The LearningOnline Network with CAPA
    2: #
    3: # Page flip handler
    4: #
    5: # $Id: lonpageflip.pm,v 1.45 2003/09/17 18:16:39 albertel Exp $
    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: # (Page Handler
   30: #
   31: # (TeX Content Handler
   32: #
   33: # 05/29/00,05/30 Gerd Kortemeyer)
   34: # 08/30,08/31,09/06,09/14,09/15,09/16,09/19,09/20,09/21,09/23,
   35: # 10/02 Gerd Kortemeyer)
   36: #
   37: # 10/03,10/05,10/06,10/07,10/09,10/10,10/11,10/16,10/17,
   38: # 11/14,11/16,
   39: # 10/01/01,05/01,05/28,07/05 Gerd Kortemeyer
   40: 
   41: package Apache::lonpageflip;
   42: 
   43: use strict;
   44: use Apache::Constants qw(:common :http REDIRECT);
   45: use Apache::lonnet();
   46: use HTML::TokeParser;
   47: use GDBM_File;
   48: 
   49: # ========================================================== Module Global Hash
   50:   
   51: my %hash;
   52: 
   53: sub cleanup {
   54:     if (tied(%hash)){
   55: 	&Apache::lonnet::logthis('Cleanup pageflip: hash');
   56:         unless (untie(%hash)) {
   57: 	    &Apache::lonnet::logthis('Failed cleanup pageflip: hash');
   58:         }
   59:     }
   60: }
   61: 
   62: sub addrid {
   63:     my ($current,$new,$condid)=@_;
   64:     unless ($condid) { $condid=0; }
   65: 
   66: 	if ($current) {
   67: 	    $current.=','.$new;
   68:         } else {
   69:             $current=''.$new;
   70:         }
   71: 
   72:     return $current;
   73: }
   74: 
   75: sub fullmove {
   76:     my ($rid,$mapurl,$direction)=@_;
   77:     if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'.db',
   78:                         &GDBM_READER(),0640)) {
   79: 	($rid,$mapurl)=&move($rid,$mapurl,$direction);
   80:         untie(%hash);
   81:     }
   82:     return($rid,$mapurl);
   83: }
   84: 
   85: sub move {
   86:     my ($rid,$mapurl,$direction)=@_;
   87:     my $startoutrid=$rid;
   88: 
   89:     my $next='';
   90: 
   91:               my $mincond=1;
   92:               my $posnext='';
   93:               if ($direction eq 'forward') {
   94: # --------------------------------------------------------------------- Forward
   95:                   while ($hash{'type_'.$rid} eq 'finish') {
   96: 	             $rid=$hash{'ids_'.$hash{'map_id_'.(split(/\./,$rid))[0]}};
   97:                   }
   98:                   map {
   99:                       my $thiscond=
  100:       &Apache::lonnet::directcondval($hash{'condid_'.$hash{'undercond_'.$_}});
  101:                       if ($thiscond>=$mincond) {
  102: 		          if ($posnext) {
  103: 		             $posnext.=','.$_.':'.$thiscond;
  104:                           } else {
  105:                              $posnext=$_.':'.$thiscond;
  106: 		          }
  107:                           if ($thiscond>$mincond) { $mincond=$thiscond; }
  108: 	              }
  109:                   } split(/\,/,$hash{'to_'.$rid});
  110:                   map {
  111:                       my ($linkid,$condval)=split(/\:/,$_);
  112:                       if ($condval>=$mincond) {
  113: 		          $next=&addrid($next,$hash{'goesto_'.$linkid},
  114:                                 $hash{'condid_'.$hash{'undercond_'.$linkid}});
  115:                       }
  116:                   } split(/\,/,$posnext);
  117:                   if ($hash{'is_map_'.$next}) {
  118: # This jumps to the beginning of a new map (going down level)
  119:                       if (
  120:       $hash{'map_type_'.$hash{'map_pc_'.$hash{'src_'.$next}}} eq 'sequence') {
  121: 			  $mapurl=$hash{'src_'.$next};
  122: 			  $next=$hash{'map_start_'.$hash{'src_'.$next}};
  123:                      }
  124:                   } elsif 
  125:                     ((split(/\./,$startoutrid))[0]!=(split(/\./,$next))[0]) {
  126: # This comes up from a map (coming up one level);
  127: 		      $mapurl=$hash{'map_id_'.(split(/\./,$next))[0]};
  128:                   }
  129:               } elsif ($direction eq 'back') {
  130: # ------------------------------------------------------------------- Backwards
  131:                  while ($hash{'type_'.$rid} eq 'start') {
  132: 	             $rid=$hash{'ids_'.$hash{'map_id_'.(split(/\./,$rid))[0]}};
  133: 		 }
  134:                   map {
  135:                       my $thiscond=
  136:       &Apache::lonnet::directcondval($hash{'condid_'.$hash{'undercond_'.$_}});
  137:                       if ($thiscond>=$mincond) {
  138: 		          if ($posnext) {
  139: 		             $posnext.=','.$_.':'.$thiscond;
  140:                           } else {
  141:                              $posnext=$_.':'.$thiscond;
  142: 		          }
  143:                           if ($thiscond>$mincond) { $mincond=$thiscond; }
  144: 	              }
  145:                   } split(/\,/,$hash{'from_'.$rid});
  146:                   map {
  147:                       my ($linkid,$condval)=split(/\:/,$_);
  148:                       if ($condval>=$mincond) {
  149: 		          $next=&addrid($next,$hash{'comesfrom_'.$linkid},
  150:                                 $hash{'condid_'.$hash{'undercond_'.$linkid}});
  151:                       }
  152:                   } split(/\,/,$posnext);
  153:                   if ($hash{'is_map_'.$next}) {
  154: # This jumps to the end of a new map (going down one level)
  155:                       if (
  156:       $hash{'map_type_'.$hash{'map_pc_'.$hash{'src_'.$next}}} eq 'sequence') {
  157: 			  $mapurl=$hash{'src_'.$next};
  158: 			  $next=$hash{'map_finish_'.$hash{'src_'.$next}};
  159:                      }
  160:                   } elsif 
  161:                     ((split(/\./,$startoutrid))[0]!=(split(/\./,$next))[0]) {
  162: # This comes back up from a map (going up one level);
  163: 		      $mapurl=$hash{'map_id_'.(split(/\./,$next))[0]};
  164:                   }
  165: 	      }
  166:               return ($next,$mapurl);
  167: }
  168: 
  169: # ================================================================ Main Handler
  170: 
  171: sub handler {
  172:    my $r=shift;
  173: 
  174: # ------------------------------------------- Set document type for header only
  175: 
  176:   if ($r->header_only) {
  177:      $r->content_type('text/html');
  178:      $r->send_http_header;
  179:      return OK;
  180:   }
  181: 
  182:   my %cachehash=(); 
  183:   my $multichoice=0;
  184:   my %multichoicehash=();
  185:   my $redirecturl='';
  186:   my $next='';
  187:   my @possibilities=();
  188:    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['postdata']);
  189:   if (($ENV{'form.postdata'})&&($ENV{'request.course.fn'})) {
  190:       $ENV{'form.postdata'}=~/(\w+)\:(.*)/;
  191:       my $direction=$1;
  192:       my $currenturl=$2;
  193:       if ($direction eq 'return') {
  194: # -------------------------------------------------------- Return to last known
  195:          my $last;
  196:          if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'_symb.db',
  197:                     &GDBM_READER(),0640)) {
  198: 	     $last=$hash{'last_known'};
  199:              untie(%hash);
  200:          }
  201:          my $newloc;
  202:          if (($last) && (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'.db',
  203:                         &GDBM_READER(),0640))) {
  204:             my ($murl,$fn)=&Apache::lonnet::decode_symb($last);
  205:             my $id;
  206:             ($murl,$id,$fn)=&Apache::lonnet::decode_symb(&Apache::lonnet::symbread($fn));
  207: 	    $newloc=$hash{'src_'.
  208:                 $hash{'map_pc_'.&Apache::lonnet::clutter($murl)}.'.'.$id};
  209:             unless ($newloc) { $newloc='/adm/noidea.html'; }
  210:             untie %hash;
  211:          } else {
  212: 	    $newloc='/adm/noidea.html';
  213:          }  
  214: 	 $r->content_type('text/html');
  215:          $r->header_out(Location => 
  216: 			'http://'.$ENV{'HTTP_HOST'}.$newloc);
  217:                                
  218:          return REDIRECT;
  219:       }
  220:       $currenturl=~s/^http\:\/\///;
  221:       $currenturl=~s/^[^\/]+//;
  222: #
  223: # Is the current URL on the map? If not, start with last known URL
  224: #
  225:       unless (&Apache::lonnet::is_on_map($currenturl)) {
  226: 	 my $last;
  227:          if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'_symb.db',
  228:                     &GDBM_READER(),0640)) {
  229: 	     $last=$hash{'last_known'};
  230:              untie(%hash);
  231:          }
  232:          if ($last) {
  233: 	     $currenturl=&Apache::lonnet::clutter((&Apache::lonnet::decode_symb($last))[1]);
  234: 	 } else {
  235: 	     $r->content_type('text/html');
  236:              $r->header_out(Location => 
  237:                                'http://'.$ENV{'HTTP_HOST'}.'/adm/noidea.html');
  238:              return REDIRECT;
  239:          }
  240:       }
  241: # ------------------------------------------- Do we have any idea where we are?
  242:       my $position;
  243:       if ($position=Apache::lonnet::symbread($currenturl)) {
  244: # ------------------------------------------------------------------------- Yes
  245: 	  my ($startoutmap,$mapnum,$thisurl)=&Apache::lonnet::decode_symb($position);
  246:           $cachehash{$startoutmap}{$thisurl}=$mapnum;
  247:           $cachehash{$startoutmap}{'last_known'}=
  248:                                        &Apache::lonnet::declutter($currenturl);
  249: 
  250: # ============================================================ Tie the big hash
  251:           if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'.db',
  252:                         &GDBM_READER(),0640)) {
  253:               my $rid=$hash{'map_pc_'.&Apache::lonnet::clutter($startoutmap)}.
  254:                       '.'.$mapnum;
  255: 
  256: # ------------------------------------------------- Move forward, backward, etc
  257:               my $endupmap;
  258:               ($next,$endupmap)=&move($rid,$startoutmap,$direction);
  259: # -------------------------------------- Do we have one and only one empty URL?
  260:               my $safecount=0;
  261:               while (($next) && ($next!~/\,/) && 
  262:                      ((!$hash{'src_'.$next}) || ($hash{'randomout_'.$next}))
  263:                      && ($safecount<10000)) {
  264:                   ($next,$endupmap)=&move($next,$endupmap,$direction);
  265:                   $safecount++;
  266:               }
  267: # We are now at at least one non-empty URL
  268: # ----------------------------------------------------- Check out possibilities
  269:               if ($next) {
  270:                   @possibilities=split(/\,/,$next);
  271:                   if ($#possibilities==0) {
  272: # ---------------------------------------------- Only one possibility, redirect
  273: 	              $redirecturl=$hash{'src_'.$next};
  274:                       $cachehash{$endupmap}
  275:                                 {&Apache::lonnet::declutter($redirecturl)}
  276: 		                                 =(split(/\./,$next))[1];
  277:                   } else {
  278: # ------------------------ There are multiple possibilities for a next resource
  279:                       $multichoice=1;
  280:                       map {
  281: 			  $multichoicehash{'src_'.$_}=$hash{'src_'.$_};
  282:                           $multichoicehash{'title_'.$_}=$hash{'title_'.$_};
  283:                           $multichoicehash{'type_'.$_}=$hash{'type_'.$_};
  284:                           (my $first, my $second) = $_ =~ /(\d+).(\d+)/;
  285:                           my $symbSrc = Apache::lonnet::declutter($hash{'src_'.$_});
  286:                           $multichoicehash{'symb_'.$_} = 
  287:                               Apache::lonnet::declutter($hash{'map_id_'.$first}.'___'.
  288:                                                         $second.'___'.$symbSrc);
  289:                                                          
  290:                           my ($choicemap,$choiceres)=split(/\./,$_);
  291:                           $cachehash
  292: 			 {&Apache::lonnet::declutter($hash{'src_'.$choicemap})}
  293:                          {&Apache::lonnet::declutter(
  294: 						      $multichoicehash
  295:                                                          {'src_'.$_}
  296:                                                        )}
  297: 		                                 =$choiceres;
  298:                       } @possibilities;
  299:                   }
  300: 	      } else {
  301: # -------------------------------------------------------------- No place to go
  302:                   $multichoice=-1;
  303:               }
  304: # ----------------- The program must come past this point to untie the big hash
  305: 	      untie(%hash);
  306: # --------------------------------------------------------- Store position info
  307:               $cachehash{$startoutmap}{'last_direction'}=$direction;
  308:               foreach my $thismap (keys %cachehash) {
  309:                  &Apache::lonnet::symblist($thismap,%{$cachehash{$thismap}});
  310: 	      }
  311: # ============================================== Do not return before this line
  312:               if ($redirecturl) {
  313: # ----------------------------------------------------- There is a URL to go to
  314: 		  if ($direction eq 'forward') {
  315:                      &Apache::lonnet::linklog($currenturl,$redirecturl);
  316: 		  }
  317: 		  if ($direction eq 'back') {
  318:                      &Apache::lonnet::linklog($redirecturl,$currenturl);
  319: 		  }
  320: # ------------------------------------------------- Check for critical messages
  321: 		  if ((time-$ENV{'user.criticalcheck.time'})>300) {
  322:                      my @what=&Apache::lonnet::dump
  323:                                   ('critical',$ENV{'user.domain'},
  324:                                               $ENV{'user.name'});
  325:                      if ($what[0]) {
  326: 	                if (($what[0] ne 'con_lost') && 
  327:                             ($what[0]!~/^error\:/)) {
  328: 	                   $redirecturl='/adm/email?critical=display';
  329:                         }
  330:                      }
  331:                      &Apache::lonnet::appenv('user.criticalcheck.time'=>time);
  332: 		  }
  333: 
  334: 		  $r->content_type('text/html');
  335:                   $r->header_out(Location => 
  336:                                 'http://'.$ENV{'HTTP_HOST'}.$redirecturl);
  337:                   return REDIRECT;
  338: 	      } else {
  339: # --------------------------------------------------------- There was a problem
  340:                   $r->content_type('text/html');
  341:                   $r->send_http_header;
  342:                   if ($#possibilities>0) {
  343: 		      my $bodytag=
  344:                              &Apache::loncommon::bodytag('Multiple Resources');
  345:                      $r->print(<<ENDSTART);
  346: <head><title>Choose Next Location</title></head>
  347: $bodytag
  348: <h3>There are several possibilities of where to go next</h3>
  349: <p>
  350: Please click on the the resource you intend to access:
  351: <p>
  352: <table border=2>
  353: <tr><th>Title</th><th>Type</th></tr>
  354: ENDSTART
  355:                      foreach (@possibilities) {
  356:                         $r->print(
  357:                               '<tr><td><a href="'.
  358:                               $multichoicehash{'src_'.$_}.'?symb=' .
  359:                                   Apache::lonnet::escape($multichoicehash{'symb_'.$_}).'">'.
  360:                               $multichoicehash{'title_'.$_}.
  361:                               '</a></td><td>'.$multichoicehash{'type_'.$_}.
  362: 			      '</td></tr>');
  363:                      }
  364:                      $r->print('</table></body></html>');
  365: 		     return OK;
  366:                   } else {
  367: 		      my $bodytag=&Apache::loncommon::bodytag('No Resource');
  368:                      $r->print(<<ENDNONE);
  369: <head><title>No Resource</title></head>
  370: $bodytag
  371: <h3>Next resource could not be identified.</h3>
  372: <p>You probably are at the <b>beginning</b> or the <b>end</b> of the 
  373: course.</p>
  374: <ul>
  375: <li><a href="/adm/flip?postdata=return:">Go Back</a></li>
  376: <li><a href="/adm/navmaps">Navigate Course Content</a></li>
  377: </ul>
  378: </body>
  379: </html>
  380: ENDNONE
  381:                      return OK;
  382: 	         }
  383: 	     }
  384: 	  } else {
  385: # ------------------------------------------------- Problem, could not tie hash
  386:               $ENV{'user.error.msg'}="/adm/flip:bre:0:1:Course Data Missing";
  387:               return HTTP_NOT_ACCEPTABLE; 
  388:           }
  389:       } else {
  390: # ---------------------------------------- No, could not determine where we are
  391: 	  if ( &Apache::lonnet::mod_perl_version() == 2 ) {
  392: 	      &Apache::lonnet::cleanenv();
  393: 	  }
  394: 	  $r->internal_redirect('/adm/ambiguous');
  395:       }
  396:   } else {
  397: # -------------------------- Class was not initialized or page fliped strangely
  398:       $ENV{'user.error.msg'}="/adm/flip:bre:0:0:Choose Course";
  399:       return HTTP_NOT_ACCEPTABLE; 
  400:   } 
  401: }
  402: 
  403: 1;
  404: __END__
  405: 
  406: 
  407: 
  408: 
  409: 
  410: 
  411: 

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.