Diff for /rat/lonpageflip.pm between versions 1.3 and 1.52

version 1.3, 2000/10/07 22:30:30 version 1.52, 2005/03/01 00:22:57
Line 2 Line 2
 #  #
 # Page flip handler  # Page flip handler
 #  #
 # (Page Handler  # $Id$
 #  #
 # (TeX Content Handler  # Copyright Michigan State University Board of Trustees
 #  #
 # 05/29/00,05/30 Gerd Kortemeyer)  # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
 # 08/30,08/31,09/06,09/14,09/15,09/16,09/19,09/20,09/21,09/23,  #
 # 10/02 Gerd Kortemeyer)  # LON-CAPA is free software; you can redistribute it and/or modify
   # it under the terms of the GNU General Public License as published by
   # the Free Software Foundation; either version 2 of the License, or
   # (at your option) any later version.
   #
   # LON-CAPA is distributed in the hope that it will be useful,
   # but WITHOUT ANY WARRANTY; without even the implied warranty of
   # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   # GNU General Public License for more details.
   #
   # You should have received a copy of the GNU General Public License
   # along with LON-CAPA; if not, write to the Free Software
   # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   #
   # /home/httpd/html/adm/gpl.txt
   #
   # http://www.lon-capa.org/
 #  #
 # 10/03,10/05,10/06,10/07 Gerd Kortemeyer  
   
 package Apache::lonpageflip;  package Apache::lonpageflip;
   
 use strict;  use strict;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http REDIRECT);
 use Apache::lonnet();  use Apache::lonnet();
 use HTML::TokeParser;  use HTML::TokeParser;
 use GDBM_File;  use GDBM_File;
Line 24  use GDBM_File; Line 39  use GDBM_File;
       
 my %hash;  my %hash;
   
   sub cleanup {
       if (tied(%hash)){
    &Apache::lonnet::logthis('Cleanup pageflip: hash');
           unless (untie(%hash)) {
       &Apache::lonnet::logthis('Failed cleanup pageflip: hash');
           }
       }
   }
   
 sub addrid {  sub addrid {
     my ($current,$new)=@_;      my ($current,$new,$condid)=@_;
     if (&Apache::lonnet::allowed('bre',$hash{'src_'.$new})) {      unless ($condid) { $condid=0; }
   
  if ($current) {   if ($current) {
     $current.=','.$new;      $current.=','.$new;
         } else {          } else {
             $current=''.$new;              $current=''.$new;
         }          }
     }  
     return $current;      return $current;
 }  }
   
   sub fullmove {
       my ($rid,$mapurl,$direction)=@_;
       if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'.db',
                           &GDBM_READER(),0640)) {
    ($rid,$mapurl)=&move($rid,$mapurl,$direction);
           untie(%hash);
       }
       return($rid,$mapurl);
   }
   
   sub hash_src {
       my ($id)=@_;
       if ($hash{'encrypted_'.$id}) {
    return &Apache::lonenc::encrypted($hash{'src_'.$id});
       }
       return $hash{'src_'.$id};
   }
   
   sub move {
       my ($rid,$mapurl,$direction)=@_;
       my $startoutrid=$rid;
   
       my $next='';
   
                 my $mincond=1;
                 my $posnext='';
                 if ($direction eq 'forward') {
   # --------------------------------------------------------------------- Forward
                     while ($hash{'type_'.$rid} eq 'finish') {
                $rid=$hash{'ids_'.$hash{'map_id_'.(split(/\./,$rid))[0]}};
                     }
                     map {
                         my $thiscond=
         &Apache::lonnet::directcondval($hash{'condid_'.$hash{'undercond_'.$_}});
                         if ($thiscond>=$mincond) {
             if ($posnext) {
                $posnext.=','.$_.':'.$thiscond;
                             } else {
                                $posnext=$_.':'.$thiscond;
             }
                             if ($thiscond>$mincond) { $mincond=$thiscond; }
                 }
                     } split(/\,/,$hash{'to_'.$rid});
                     map {
                         my ($linkid,$condval)=split(/\:/,$_);
                         if ($condval>=$mincond) {
             $next=&addrid($next,$hash{'goesto_'.$linkid},
                                   $hash{'condid_'.$hash{'undercond_'.$linkid}});
                         }
                     } split(/\,/,$posnext);
                     if ($hash{'is_map_'.$next}) {
   # This jumps to the beginning of a new map (going down level)
                         if (
         $hash{'map_type_'.$hash{'map_pc_'.$hash{'src_'.$next}}} eq 'sequence') {
     $mapurl=$hash{'src_'.$next};
     $next=$hash{'map_start_'.$hash{'src_'.$next}};
                        } elsif (
   # This jumps back up from an empty sequence, to a page up one level
                            $hash{'map_type_'.$hash{'map_pc_'.$hash{'src_'.$next}}} eq 'page') {
                            $mapurl=$hash{'map_id_'.(split(/\./,$next))[0]};
                        }
                     } elsif 
                       ((split(/\./,$startoutrid))[0]!=(split(/\./,$next))[0]) {
   # This comes up from a map (coming up one level);
         $mapurl=$hash{'map_id_'.(split(/\./,$next))[0]};
                     }
                 } elsif ($direction eq 'back') {
   # ------------------------------------------------------------------- Backwards
                    while ($hash{'type_'.$rid} eq 'start') {
                $rid=$hash{'ids_'.$hash{'map_id_'.(split(/\./,$rid))[0]}};
    }
                     map {
                         my $thiscond=
         &Apache::lonnet::directcondval($hash{'condid_'.$hash{'undercond_'.$_}});
                         if ($thiscond>=$mincond) {
             if ($posnext) {
                $posnext.=','.$_.':'.$thiscond;
                             } else {
                                $posnext=$_.':'.$thiscond;
             }
                             if ($thiscond>$mincond) { $mincond=$thiscond; }
                 }
                     } split(/\,/,$hash{'from_'.$rid});
                     map {
                         my ($linkid,$condval)=split(/\:/,$_);
                         if ($condval>=$mincond) {
             $next=&addrid($next,$hash{'comesfrom_'.$linkid},
                                   $hash{'condid_'.$hash{'undercond_'.$linkid}});
                         }
                     } split(/\,/,$posnext);
                     if ($hash{'is_map_'.$next}) {
   # This jumps to the end of a new map (going down one level)
                         if (
         $hash{'map_type_'.$hash{'map_pc_'.$hash{'src_'.$next}}} eq 'sequence') {
     $mapurl=$hash{'src_'.$next};
     $next=$hash{'map_finish_'.$hash{'src_'.$next}};
                         } elsif (
         $hash{'map_type_'.$hash{'map_pc_'.$hash{'src_'.$next}}} eq 'page') {
   # This jumps back up from an empty sequence, to a page up one level
                             $mapurl=$hash{'map_id_'.(split(/\./,$next))[0]};
                         }
                     } elsif 
                       ((split(/\./,$startoutrid))[0]!=(split(/\./,$next))[0]) {
   # This comes back up from a map (going up one level);
         $mapurl=$hash{'map_id_'.(split(/\./,$next))[0]};
                     }
         }
                 return ($next,$mapurl);
   }
   
 # ================================================================ Main Handler  # ================================================================ Main Handler
   
 sub handler {  sub handler {
Line 44  sub handler { Line 179  sub handler {
 # ------------------------------------------- Set document type for header only  # ------------------------------------------- Set document type for header only
   
   if ($r->header_only) {    if ($r->header_only) {
      $r->content_type('text/html');        &Apache::loncommon::content_type($r,'text/html');
      $r->send_http_header;        $r->send_http_header;
      return OK;        return OK;
   }    }
   
     my %cachehash=(); 
 # --------BEGIN DEBUG ONLY TRASH    my $multichoice=0;
     $r->content_type('text/html');    my %multichoicehash=();
      $r->send_http_header;    my $redirecturl='';
     my $next='';
   $r->print('<html><body>');    my @possibilities=();
 # --------END DEBUG ONLY TRASH     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['postdata']);
   
   my %cachehash=();  
   my $redir=0;  
   
   if (($ENV{'form.postdata'})&&($ENV{'request.course.fn'})) {    if (($ENV{'form.postdata'})&&($ENV{'request.course.fn'})) {
       $ENV{'form.postdata'}=~/(\w+)\:(.*)/;        $ENV{'form.postdata'}=~/(\w+)\:(.*)/;
       my $direction=$1;        my $direction=$1;
       my $currenturl=$2;        my $currenturl=$2;
       my $redirecturl=$currenturl;        if ($currenturl=~m|^/enc/|) {
     $currenturl=&Apache::lonenc::unencrypted($currenturl);
         }
         $currenturl=~s/\.\d+\.(\w+)$/\.$1/;
         if ($direction eq 'return') {
   # -------------------------------------------------------- Return to last known
            my $last;
            if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'_symb.db',
                       &GDBM_READER(),0640)) {
        $last=$hash{'last_known'};
                untie(%hash);
            }
            my $newloc;
            if (($last) && (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'.db',
                           &GDBM_READER(),0640))) {
               my ($murl,$id,$fn)=&Apache::lonnet::decode_symb($last);
       $id=$hash{'map_pc_'.&Apache::lonnet::clutter($murl)}.'.'.$id;
       $newloc=$hash{'src_'.$id};
       if ($newloc) {
    if ($hash{'encrypted_'.$id}) { $newloc=&Apache::lonenc::encrypted($newloc); }
         
       } else {
    $newloc='/adm/noidea.html';
       }
               untie %hash;
            } else {
       $newloc='/adm/noidea.html';
            }  
    &Apache::loncommon::content_type($r,'text/html');
            $r->header_out(Location => 
    'http://'.$ENV{'HTTP_HOST'}.$newloc);
                                  
            return REDIRECT;
         }
       $currenturl=~s/^http\:\/\///;        $currenturl=~s/^http\:\/\///;
       $currenturl=~s/^[^\/]+//;        $currenturl=~s/^[^\/]+//;
   #
   # Is the current URL on the map? If not, start with last known URL
   #
         unless (&Apache::lonnet::is_on_map($currenturl)) {
    my $last;
            if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'_symb.db',
                       &GDBM_READER(),0640)) {
        $last=$hash{'last_known'};
                untie(%hash);
            }
            if ($last) {
        $currenturl=&Apache::lonnet::clutter((&Apache::lonnet::decode_symb($last))[2]);
    } else {
        &Apache::loncommon::content_type($r,'text/html');
                $r->header_out(Location => 
                                  'http://'.$ENV{'HTTP_HOST'}.'/adm/noidea.html');
                return REDIRECT;
            }
         }
 # ------------------------------------------- Do we have any idea where we are?  # ------------------------------------------- Do we have any idea where we are?
       my $position;        my $position;
       if ($position=Apache::lonnet::symbread($currenturl)) {        if ($position=Apache::lonnet::symbread($currenturl)) {
 # ------------------------------------------------------------------------- Yes  # ------------------------------------------------------------------------- Yes
   my ($mapurl,$mapnum,$thisurl)=split(/\_\_\_/,$position);    my ($startoutmap,$mapnum,$thisurl)=&Apache::lonnet::decode_symb($position);
           $cachehash{$thisurl}=$mapnum;            $cachehash{$startoutmap}{$thisurl}=[$thisurl,$mapnum];
             $cachehash{$startoutmap}{'last_known'}=
                                [&Apache::lonnet::declutter($currenturl),$mapnum];
   
   # ============================================================ Tie the big hash
           if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'.db',            if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'.db',
                         &GDBM_READER,0640)) {                          &GDBM_READER(),0640)) {
               my $rid=$hash{'map_pc_/res/'.$mapurl}.'.'.$mapnum;                my $rid=$hash{'map_pc_'.&Apache::lonnet::clutter($startoutmap)}.
               my $next='';                        '.'.$mapnum;
               if ($direction eq 'forward') {  
                  map {  # ------------------------------------------------- Move forward, backward, etc
     $next=&addrid($next,$hash{'goesto_'.$_});                my $endupmap;
                   } split(/\,/,$hash{'to_'.$rid});                ($next,$endupmap)=&move($rid,$startoutmap,$direction);
                   my @possibilities=split(/,/,$next);  # -------------------------------------- Do we have one and only one empty URL?
                   if ($#possibilities==1) {                my $safecount=0;
               my $goto=$possibilities[0];                while (($next) && ($next!~/\,/) && 
   }                       ((!$hash{'src_'.$next}) || 
               } elsif ($direction eq 'back') {        ((!$ENV{'request.role.adv'}) && $hash{'randomout_'.$next}))
       } elsif ($direction eq 'up') {                       && ($safecount<10000)) {
               } elsif ($direction eq 'down') {                    ($next,$endupmap)=&move($next,$endupmap,$direction);
                     $safecount++;
               }                }
   # We are now at at least one non-empty URL
   # ----------------------------------------------------- Check out possibilities
                 if ($next) {
                     @possibilities=split(/\,/,$next);
                     if ($#possibilities==0) {
   # ---------------------------------------------- Only one possibility, redirect
                 $redirecturl=&hash_src($next);
                         $cachehash{$endupmap}{$redirecturl}=
     [$redirecturl,(split(/\./,$next))[1]];
                     } else {
   # ------------------------ There are multiple possibilities for a next resource
                         $multichoice=1;
                         map {
     $multichoicehash{'src_'.$_}=$hash{'src_'.$_};
                             $multichoicehash{'title_'.$_}=$hash{'title_'.$_};
                             $multichoicehash{'type_'.$_}=$hash{'type_'.$_};
                             (my $first, my $second) = $_ =~ /(\d+).(\d+)/;
                             my $symbSrc = Apache::lonnet::declutter($hash{'src_'.$_});
                             $multichoicehash{'symb_'.$_} = 
                                 Apache::lonnet::declutter($hash{'map_id_'.$first}.'___'.
                                                           $second.'___'.$symbSrc);
                                                            
                             my ($choicemap,$choiceres)=split(/\./,$_);
     my $map=&Apache::lonnet::declutter($hash{'src_'.$choicemap});
     my $url=$multichoicehash{'src_'.$_};
                             $cachehash{$map}{$url}=[$url,$choiceres];
                         } @possibilities;
                     }
         } else {
   # -------------------------------------------------------------- No place to go
                     $multichoice=-1;
                 }
   # ----------------- The program must come past this point to untie the big hash
       untie(%hash);        untie(%hash);
               $r->print($rid.' - '.$next);  # --------------------------------------------------------- Store position info
                 $cachehash{$startoutmap}{'last_direction'}=[$direction,'notasymb'];
                 foreach my $thismap (keys %cachehash) {
     my $mapnum=$cachehash{$thismap}->{'mapnum'};
     delete($cachehash{$thismap}->{'mapnum'});
     &Apache::lonnet::symblist($thismap,
       %{$cachehash{$thismap}});
         }
   # ============================================== Do not return before this line
                 if ($redirecturl) {
   # ----------------------------------------------------- There is a URL to go to
     if ($direction eq 'forward') {
                        &Apache::lonnet::linklog($currenturl,$redirecturl);
     }
     if ($direction eq 'back') {
                        &Apache::lonnet::linklog($redirecturl,$currenturl);
     }
   # ------------------------------------------------- Check for critical messages
     if ((time-$ENV{'user.criticalcheck.time'})>300) {
                        my @what=&Apache::lonnet::dump
                                     ('critical',$ENV{'user.domain'},
                                                 $ENV{'user.name'});
                        if ($what[0]) {
                   if (($what[0] ne 'con_lost') && 
                               ($what[0]!~/^error\:/)) {
                      $redirecturl='/adm/email?critical=display';
                           }
                        }
                        &Apache::lonnet::appenv('user.criticalcheck.time'=>time);
     }
   
     &Apache::loncommon::content_type($r,'text/html');
                     $r->header_out(Location => 
                                   'http://'.$ENV{'HTTP_HOST'}.$redirecturl);
                     return REDIRECT;
         } else {
   # --------------------------------------------------------- There was a problem
                     &Apache::loncommon::content_type($r,'text/html');
                     $r->send_http_header;
                     if ($#possibilities>0) {
         my $bodytag=
                                &Apache::loncommon::bodytag('Multiple Resources');
                        $r->print(<<ENDSTART);
   <head><title>Choose Next Location</title></head>
   $bodytag
   <h3>There are several possibilities of where to go next</h3>
   <p>
   Please click on the the resource you intend to access:
   <p>
   <table border=2>
   <tr><th>Title</th><th>Type</th></tr>
   ENDSTART
                        foreach (@possibilities) {
                           $r->print(
                                 '<tr><td><a href="'.
                                 $multichoicehash{'src_'.$_}.'?symb=' .
                                     Apache::lonnet::escape($multichoicehash{'symb_'.$_}).'">'.
                                 $multichoicehash{'title_'.$_}.
                                 '</a></td><td>'.$multichoicehash{'type_'.$_}.
         '</td></tr>');
                        }
                        $r->print('</table></body></html>');
        return OK;
                     } else {
         my $bodytag=&Apache::loncommon::bodytag('No Resource');
                        $r->print(<<ENDNONE);
   <head><title>No Resource</title></head>
   $bodytag
   <h3>Next resource could not be identified.</h3>
   <p>You probably are at the <b>beginning</b> or the <b>end</b> of the 
   course.</p>
   <ul>
   <li><a href="/adm/flip?postdata=return:">Go Back</a></li>
   <li><a href="/adm/navmaps">Navigate Course Content</a></li>
   </ul>
   </body>
   </html>
   ENDNONE
                        return OK;
            }
        }
     } else {
   # ------------------------------------------------- Problem, could not tie hash
                 $ENV{'user.error.msg'}="/adm/flip:bre:0:1:Course Data Missing";
                 return HTTP_NOT_ACCEPTABLE; 
           }            }
       } else {        } else {
 # -------------------------------------------------------------------------- No  # ---------------------------------------- No, could not determine where we are
   $r->print('No idea '.$currenturl);    if ( &Apache::lonnet::mod_perl_version() == 2 ) {
         &Apache::lonnet::cleanenv();
     }
     $r->internal_redirect('/adm/ambiguous');
       }        }
 # -------------------------- Class was not initialized or page fliped strangely  
   } else {    } else {
   # -------------------------- Class was not initialized or page fliped strangely
       $ENV{'user.error.msg'}="/adm/flip:bre:0:0:Choose Course";        $ENV{'user.error.msg'}="/adm/flip:bre:0:0:Choose Course";
       return HTTP_NOT_ACCEPTABLE;         return HTTP_NOT_ACCEPTABLE; 
   }     } 
   
   
   
   
 # ------TRASH BELOW  
 # --------------------------- TRASH  
   
   $r->print('</body></html>');  
   return OK;  
   
   
 # ========================================================= TOTAL TRASH  
   
 #                  &Apache::lonnet::symblist($requrl,%symbhash);  
   
 }  }
   
 1;  1;

Removed from v.1.3  
changed lines
  Added in v.1.52


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