Diff for /rat/lonsequence.pm between versions 1.5 and 1.58

version 1.5, 2001/11/29 19:23:49 version 1.58, 2022/10/19 18:09:03
Line 26 Line 26
 #  #
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
 #  #
 # (Handler to resolve ambiguous file locations  
 #  
 # (TeX Content Handler  
 #  
 # 05/29/00,05/30,10/11 Gerd Kortemeyer)  
 #  
 # 10/11,10/12 Gerd Kortemeyer)  
 #  
 # 10/16 Gerd Kortemeyer  
   
 package Apache::lonsequence;  package Apache::lonsequence;
   
Line 42  use strict; Line 35  use strict;
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::Constants qw(:common :http REDIRECT);  use Apache::Constants qw(:common :http REDIRECT);
 use GDBM_File;  use GDBM_File;
   use LONCAPA::map();
   use LONCAPA::ltiutils;
   use LONCAPA;
   use Apache::lonpageflip();
   use Apache::loncommon();
   use Apache::groupsort();
   use Apache::lonlocal;
   use Apache::lonnavmaps();
   use Apache::lonenc();
   use HTML::Entities();
   
   my %selhash;
   my $successtied;
   
   # ----------------------------------------- Attempt to read from resource space
   
   sub attemptread {
       my ($fn,$unsorted)=@_;
       &Apache::lonnet::repcopy($fn);
       if (-e $fn) {
    return &LONCAPA::map::attemptread($fn,$unsorted);
       } else {
           return ();
       }
   }
   
   sub mapread {
       my $fn=shift;
       &Apache::lonnet::repcopy($fn);
       if (-e $fn) {
    return &LONCAPA::map::mapread($fn,'');
       } else {
           return ();
       }
   }
   
   # ---------------------------------------------------------------- View Handler
   
 # ----------------------------------------------------------- Could not resolve  sub viewmap {
       my ($r,$url)=@_;
   
 sub getlost {      my $js;
     my ($r,$errmsg)=@_;      if ($env{'form.forceselect'}) {
     $r->content_type('text/html');   $js = (<<ENDSCRIPT);
     $r->send_http_header;  <script type="text/javascript">
     $r->print(  
  '<head><title>Unknown Error</title></head><body bgcolor="#FFFFFF"><h1>'.  function select_group() {
  'LON-CAPA</h1>Could not handle sequence resource reference.<p>'.$errmsg.      window.location="/adm/groupsort?catalogmode=groupsec&mode=rat&acts="+document.forms.fileattr.acts.value;
  '</body></html>');  }
   
   function queue(val) {
       if (eval("document.forms."+val+".filelink.checked")) {
    var l=val.length;
    var v=val.substring(4,l);
    document.forms.fileattr.acts.value+='1a'+v+'b';
       }
       else {
    var l=val.length;
    var v=val.substring(4,l);
    document.forms.fileattr.acts.value+='0a'+v+'b';
       }
   }
   
   </script>
   ENDSCRIPT
       }
   
       $r->print(&Apache::loncommon::start_page('Map Contents',$js).
         '<h1>'.$url.'</h1>');
   # ------------------ This is trying to select. Provide buttons and tie %selhash
       if ($env{'form.forceselect'}) { $r->print(<<ENDSELECT);
   <form name="fileattr"><input type="hidden" name="acts" value="" />
   <input type="button" name="close" value="CLOSE" onClick="self.close()" />
   <input type="button" name="groupimport" value="GROUP IMPORT"
   onClick="javascript:select_group()" />
   </form>   
   ENDSELECT
       my $diropendb = 
     LONCAPA::tempdir() .
       "$env{'user.domain'}\_$env{'user.name'}_sel_res.db";
           if (tie(%selhash,'GDBM_File',$diropendb,&GDBM_WRCREAT(),0640)) {
       if ($env{'form.launch'} eq '1') {
          &start_fresh_session();
       }
               $successtied=1;
   
   # - Evaluate actions from previous page (both cumulatively and chronologically)
       if ($env{'form.catalogmode'} eq 'import') {
    &Apache::groupsort::update_actions_hash(\%selhash);
       }
   # -
           }
       }
   # ----------------------------- successtied is now '1' if in working selectmode
       my ($errtext,$fatal)=&mapread(&Apache::lonnet::filelocation('',$url),'');
       if ($fatal==1) {
          $r->print('<p class="LC_warning">'
                   .&mt('Map contents are not shown in order.')
                   .'</p><br />');
       }
       my $idx=0;
       foreach my $entry (&attemptread(&Apache::lonnet::filelocation('',$url))) {
    if (defined($entry)) {
               $idx++;
               if ($successtied) { 
    $r->print('<form name="form'.$idx.'">');
               }
       my ($title,$url)=split(/\:/,$entry);
       $title = &LONCAPA::map::qtescape($title);
       unless ($title) { $title=(split(/\//,$url))[-1] };
               my $enc_title = &HTML::Entities::encode($title,'\'"<>&');
       unless ($title) {
    $title='<i>'.&mt('Empty').'</i>';
    $enc_title = &mt('Empty');
       }
       $url  = &LONCAPA::map::qtescape($url);
               my $enc_url = &HTML::Entities::encode($url,'\'"<>&');
               if ($url) {
    if ($successtied) {
       my $checked='';
              if ($selhash{'store_'.$url}) {
               $checked=' checked="checked"';
              }
              $selhash{"pre_${idx}_link"}=$url;
              $selhash{"pre_${idx}_title"}=$title;
       
       $url  = &HTML::Entities::encode($url, '\'"<>&');
       $r->print(<<ENDCHECKBOX);
   <input type='checkbox' name='filelink' 
   value='$enc_url' onClick='javascript:queue("form$idx")'$checked />
   <input type='hidden' name='title' value='$enc_title' />
   ENDCHECKBOX
                   }
    $r->print('<a href="'.$enc_url.'">');
               }
               $r->print($enc_title);
               if ($url) { $r->print('</a>'); }
               if ($successtied) {
    $r->print('</form>');
               } else {
    $r->print('<br />');
               }
           }
       }
       $r->print(&Apache::loncommon::end_page());
       if ($successtied) {
    untie %selhash;
       }
 }  }
   
   # ----------------------------------------------------------- Clean out selhash
   sub start_fresh_session {
       foreach my $item (keys(%selhash)) {
    if ($item =~ /^pre_/) {
       delete $selhash{$item};
    }
    if ($item =~ /^store/) {
       delete $selhash{$item};
    }
       }
   }
   
   
 # ================================================================ Main Handler  # ================================================================ Main Handler
   
 sub handler {  sub handler {
    my $r=shift;     my $r=shift;
   
    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 $requrl=$r->uri;
      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                             ['forceselect','launch','navmap']);
   
      if (($env{'request.course.fn'}) && ($env{'form.navmap'}) && ($env{'request.course.id'})) {
          my $crstype = &Apache::loncommon::course_type();
          unless (($crstype eq 'Placement') && (!$env{'request.role.adv'})) {
   
              # Check for critical messages and redirect if present.
              my ($redirect,$url) = &Apache::loncommon::critical_redirect(300,'contents');
              if ($redirect) {
                  &Apache::loncommon::content_type($r,'text/html');
                  $r->header_out(Location => $url);
                  return REDIRECT;
              }
   
              # Check if course needs to be re-initialized
              my $loncaparev = $r->dir_config('lonVersion');
              my ($result,@reinit) = &Apache::loncommon::needs_coursereinit($loncaparev);
   
              if ($result eq 'switch') {
                  &Apache::loncommon::content_type($r,'text/html');
                  $r->send_http_header;
                  $r->print(&Apache::loncommon::check_release_result(@reinit));
                  return OK;
              }
              my ($cnum,$cdom);
              if ($result) {
                  $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                  $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
              }
              if (($result eq 'main') || ($result eq 'both')) {
                  my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum");
                  if ($ferr) {
                      my $requrl = $r->uri;
                      $env{'user.error.msg'}="$requrl:bre:0:0:Course not initialized";
                      $env{'user.reinit'} = 1;
                      return HTTP_NOT_ACCEPTABLE;
                  }
              }
              if (($result eq 'both') || ($result eq 'supp')) {
                  my $possdel;
                  if ($result eq 'supp') {
                      $possdel = 1;
                  }
                  my ($supplemental,$refs_updated) = &Apache::lonnet::get_supplemental($cnum,$cdom,'',$possdel);
                  unless ($refs_updated) {
                      &Apache::loncommon::set_supp_httprefs($cnum,$cdom,$supplemental,$possdel);
                  }
              }
              &Apache::loncommon::content_type($r,'text/html');
              $r->send_http_header;
   
              my $mapurl = &Apache::lonnet::declutter($requrl);
              my $maptitle = &Apache::lonnet::gettitle($mapurl);
              my @crumbs = ({text => $maptitle, no_mt => 1});
              my $args = {'bread_crumbs' => \@crumbs,
                          'bread_crumbs_nomenu' => 1};
   
              # Create the nav map
              my $navmap = Apache::lonnavmaps::navmap->new();
   
              if (ref($navmap)) {
                  # renderer call
                  if (&Apache::lonnet::is_on_map($requrl)) {
                      my ($ltiscope,$ltiuri);
                      if (($env{'request.lti.login'}) && ($env{'request.lti.uri'})) {
                          my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                          my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                          ($ltiscope,$ltiuri) = &LONCAPA::ltiutils::lti_provider_scope($env{'request.lti.uri'},$cdom,$cnum);
                      }
                      @crumbs = ();
                      unless ($ltiscope eq 'resource') {
                          unless ($ltiscope eq 'map') {
                              @crumbs = ({text  => $crstype.' Contents',
                                          href  => "javascript:gopost('/adm/navmaps','')"});
                          }
                          my $res = $navmap->getResourceByUrl($mapurl);
                          if (ref($res)) {
                              my $symb = $res->symb();
                              if ($symb) {
                                  my ($parent) = &Apache::lonnet::decode_symb($res->symb());
                                  if (($parent ne $env{'course.'.$env{'request.course.id'}.'.url'}) &&
                                      !(($ltiscope eq 'map') && ($requrl eq $ltiuri))) {
                                      my @mapcrumbs = $navmap->recursed_crumbs($parent);
                                      if (@mapcrumbs) {
                                          push(@crumbs,@mapcrumbs);
                                      }
                                  }
                                  $env{'request.symb'} = $symb;
                              }
                          }
                      }
                      push(@crumbs,{text => $maptitle, no_mt => 1});
                      $args = {'bread_crumbs' => \@crumbs,
                               'bread_crumbs_nomenu' => 1,
                               'no_auto_mt_title' => 1};
                      $r->print(&Apache::loncommon::start_page($maptitle,undef,$args));
   
                      my $renderArgs = { 'cols'                    => [0,1,2,3],
                                         'url'                     => $mapurl,
                                         'navmap'                  => $navmap,
                                         'suppressNavmap'          => 1,
                                         'suppressEmptySequences'  => 1,
                                         'filterFunc'              => undef,
                                         'resource_no_folder_link' => 1,
                                         'r'                       => $r,
                                         'caller'                  => 'sequence',
                                         'notools'                 => 1,
                                         'iterator_map'            => $mapurl,
                                       };
   
                      my $render = &Apache::lonnavmaps::render($renderArgs);
   
                      # If no resources were found let the user know.
                      if ($renderArgs->{'counter'} == 0) {
                          $r->print('<p class="LC_info">'.
                                    &mt('No items found in folder').
                                    '</p>');
                      }
                      $r->print(&Apache::loncommon::end_page());
                  } else {
                      $r->print(&Apache::loncommon::start_page($maptitle,undef,$args).
                                '<p class="LC_info">'.
                                &mt('Folder no longer appears to be a part of the course').
                                '</p>'.
                                &Apache::loncommon::end_page());
                  }
              } else {
                  $r->print(&Apache::loncommon::start_page($maptitle,undef,$args).
                            '<p class="LC_warning">'.
                            &mt('Error: could not determine contents of folder').
                            '</p>'.
                            &Apache::loncommon::end_page());
              }
              $r->rflush();
              return OK;
          }
      }
   
    my %hash;     my %hash;
    my %bighash;     my %bighash;
    my $requrl=$r->uri;  
   
      $successtied=0;
 # ------------------------------------------------------------ Tie symb db file  # ------------------------------------------------------------ Tie symb db file
   if ($ENV{'request.course.fn'}) {    my $disurl='';
     my $dismapid='';
     my $exitdisid = '';
     my $arrow_dir = '';
     my $is_encrypted = '';
   
     if (($env{'request.course.fn'}) && (!$env{'form.forceselect'})) {
        my $last;         my $last;
        if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'_symb.db',         if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db',
                     &GDBM_READER,0640)) {                      &GDBM_READER(),0640)) {
    $last=$hash{'last_direction'};     $last=$hash{'last_direction'};
            untie(%hash);             untie(%hash);
        }         }
        my $direction='';         my $direction='';
        my $prevmap='';         my $prevmap='';
        if ($last) {         if ($last) {
   ($prevmap,$direction)=(split(/\_\_\_/,$last));     ($prevmap,undef,$direction)=&Apache::lonnet::decode_symb($last);
        }         }
 # ------------------------------------------------------------- Tie big db file  # ------------------------------------------------------------- Tie big db file
        if (tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db',         if (tie(%bighash,'GDBM_File',$env{'request.course.fn'}.'.db',
                     &GDBM_READER,0640)) {                      &GDBM_READER(),0640)) {
    my $disid='';     my $disid='';
            my $whatend='';             my $randomout ='';
   
            if ($direction eq 'back') {             if ($direction eq 'back') {
        $disid=$bighash{'map_finish_'.$requrl};         $disid=$bighash{'map_finish_'.$requrl};
                $whatend='End';  
            } else {             } else {
                $disid=$bighash{'map_start_'.$requrl};                 $disid=$bighash{'map_start_'.$requrl};
                $whatend='Beginning';             }
            }   
            my $disurl='';  
            my $dismapid='';  
            if ($disid) {             if ($disid) {
        $disurl=$bighash{'src_'.$disid};         $disurl=$bighash{'src_'.$disid};
                $dismapid=(split(/\./,$disid))[1];                 $dismapid=(split(/\./,$disid))[1];
            }         if (!$env{'request.role.adv'}) {
            my $symb='';     $randomout = $bighash{'randomout_'.$disid};
            my $sequencetitle='';                     $is_encrypted = $bighash{'encrypted_'.$disid};
            unless($disurl) {  
                if ($symb=&Apache::lonnet::symbread()) {  
    my ($mapurl,$mapid)=split(/\_\_\_/,$symb);  
                    $sequencetitle=$bighash{'title_'.  
           $bighash{'map_pc_/res/'.$mapurl}.'.'.  
   $mapid};  
                }                 }
              } elsif (tie(%hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db',
                       &GDBM_READER(),0640)) {
                  $last=$hash{'last_known'};
                  untie(%hash);
            }             }
   
   
   # ----------- If this is an empty one, or hidden, skip to next non-empty or non-hidden one
              while ( ((!$disurl) && ($disid)) || ($randomout && $disid) ) {
          $direction=($direction?$direction:'forward');
                  ($disid,$requrl)=
                            &Apache::lonpageflip::fullmove($disid,
                              &Apache::lonnet::declutter($requrl),$direction);
                  if ($disid) {
              $disurl=$bighash{'src_'.$disid};
                      $dismapid=(split(/\./,$disid))[1];
      if (!$env{'request.role.adv'}) {
          $randomout = $bighash{'randomout_'.$disid};
                          $is_encrypted = $bighash{'encrypted_'.$disid};
                      }
                  }
       }
              $exitdisid = $disid;
              $arrow_dir = $direction;
   
 # --------------------------------------- Untie hash, make sure to come by here  # --------------------------------------- Untie hash, make sure to come by here
            untie(%bighash);             untie(%bighash);
            if ($disurl) {         }
      }
   
   # now either disurl is set (going to first page), or we need another display
      if ($disurl) {
 # -------------------------------------------------- Has first or last resource  # -------------------------------------------------- Has first or last resource
                &Apache::lonnet::symblist($requrl,$disurl => $dismapid,        my $showdisurl = $disurl;
                    'last_known' => &Apache::lonnet::declutter($disurl));         if ($is_encrypted) {
        $r->content_type('text/html');            $showdisurl = &Apache::lonenc::encrypted($disurl);
                $r->header_out(Location => 'http://'.$ENV{'HTTP_HOST'}.$disurl);        }
                return REDIRECT;        if ($disurl =~ m{^/adm/navmaps(\?|$)}) {
            } else {            &Apache::lonnet::symblist($requrl,$disurl => [$disurl,$dismapid]);
 # ---------- Does not have first or last resource, try to find out where we are        } else {
                unless ($symb) {            &Apache::lonnet::symblist($requrl,$disurl => [$disurl,$dismapid],
    $r->internal_redirect('/adm/ambiguous');                                      'last_known' => [$disurl,$dismapid]);
                }        }
                $r->content_type('text/html');        &Apache::loncommon::content_type($r,'text/html');
                $r->send_http_header;        $r->header_out(Location => &Apache::lonnet::absolute_url().
                $r->print(<<ENDSYMB);                                   $showdisurl);
 <html><body bgcolor="#FFFFFF">        return REDIRECT;
 <h2>$whatend of</h2>     } else {
 <h1>$sequencetitle</h1>         &Apache::loncommon::content_type($r,'text/html');
 </body></html>         $r->send_http_header;
 ENDSYMB         if ($exitdisid eq '' && $arrow_dir ne '') {
                return OK             my %lt =&Apache::lonlocal::texthash(
                      'nere' => 'Next resource could not be displayed',
                      'goba' => 'Go Back',
                      'nacc' => 'Course Contents',
                             );
              if (&Apache::loncommon::course_type() eq 'Community') {
                  $lt{'nav'} = &mt('Community Contents');
              }
              my $warnmsg;
              if ($arrow_dir eq 'forward') {
                  $warnmsg = &mt('As all folders and sequences '
                                .'following the current resource were empty, '
                                .'you have now reached the end of the course.');
              } elsif ($arrow_dir eq 'back') {
                  $warnmsg = &mt('As all folders and sequences '
                                .'preceding the current resource were empty, '
                                .'you have now reached the beginning of the course.');
            }             }
              my $start_page=
          &Apache::loncommon::start_page('Empty Folder/Sequence');
              my $end_page=
          &Apache::loncommon::end_page();
              $r->print(<<ENDNONE);
   $start_page
   <h3>$lt{'nere'}</h3>
   <p>$warnmsg</p>
   <ul>
     <li><a href="javascript:history.go(-1)">$lt{'goba'}</a></li>
     <li><a href="/adm/navmaps">$lt{'nacc'}</a></li>
   </ul>
   $end_page
   ENDNONE
        } else {         } else {
           &getlost($r,'Could not access course structure.');             &viewmap($r,$requrl);
           return OK;  
        }         }
    } else {         return OK;
       $ENV{'user.error.msg'}="$requrl:bre:0:0:Course not initialized";  
       return HTTP_NOT_ACCEPTABLE;   
    }     }
   
    return OK;  
 }  }
   
 1;  1;
 __END__  __END__
   
   =head1 NAME
   
   Apache::lonsequence
   
   =head1 SYNOPSIS
   
   Handler for showing sequence objects of
   educational resources.
   
   This is part of the LearningOnline Network with CAPA project
   described at http://www.lon-capa.org.
   
   =head1 SUBROUTINES
   
   =over
   
   =item handler()
   
   =item viewmap()
   
   =item attemptread()
   
   =item mapread()
   
   =item start_fresh_session()
   
   =back
   
   =cut
   
   
   

Removed from v.1.5  
changed lines
  Added in v.1.58


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