Diff for /loncom/interface/lonnavmaps.pm between versions 1.315 and 1.324

version 1.315, 2005/02/05 06:52:50 version 1.324, 2005/04/15 21:08:37
Line 30 Line 30
 package Apache::lonnavmaps;  package Apache::lonnavmaps;
   
 use strict;  use strict;
   use GDBM_File;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lonmenu();  use Apache::lonmenu();
Line 38  use Apache::lonlocal; Line 39  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
 use POSIX qw (floor strftime);  use POSIX qw (floor strftime);
 use Data::Dumper; # for debugging, not always   use Data::Dumper; # for debugging, not always 
   use Time::HiRes qw( gettimeofday tv_interval );
   
 # symbolic constants  # symbolic constants
 sub SYMB { return 1; }  sub SYMB { return 1; }
Line 108  sub launch_win { Line 110  sub launch_win {
 }  }
   
 sub close {  sub close {
     if ($ENV{'environment.remotenavmap'} ne 'on') { return ''; }      if ($env{'environment.remotenavmap'} ne 'on') { return ''; }
     return(<<ENDCLOSE);      return(<<ENDCLOSE);
 <script type="text/javascript">  <script type="text/javascript">
 window.status='Accessing Nav Control';  window.status='Accessing Nav Control';
Line 122  ENDCLOSE Line 124  ENDCLOSE
 }  }
   
 sub update {  sub update {
     if ($ENV{'environment.remotenavmap'} ne 'on') { return ''; }      if ($env{'environment.remotenavmap'} ne 'on') { return ''; }
     if (!$ENV{'request.course.id'}) { return ''; }      if (!$env{'request.course.id'}) { return ''; }
     if ($ENV{'REQUEST_URI'}=~m|^/adm/navmaps|) { return ''; }      if ($ENV{'REQUEST_URI'}=~m|^/adm/navmaps|) { return ''; }
     return(<<ENDUPDATE);      return(<<ENDUPDATE);
 <form name="navform"></form>  <form name="navform"></form>
Line 142  sub handler { Line 144  sub handler {
   
 sub real_handler {  sub real_handler {
     my $r = shift;      my $r = shift;
       #my $t0=[&gettimeofday()];
     # Handle header-only request      # Handle header-only request
     if ($r->header_only) {      if ($r->header_only) {
         if ($ENV{'browser.mathml'}) {          if ($env{'browser.mathml'}) {
             &Apache::loncommon::content_type($r,'text/xml');              &Apache::loncommon::content_type($r,'text/xml');
         } else {          } else {
             &Apache::loncommon::content_type($r,'text/html');              &Apache::loncommon::content_type($r,'text/html');
Line 155  sub real_handler { Line 157  sub real_handler {
     }      }
   
     # Send header, don't cache this page      # Send header, don't cache this page
     if ($ENV{'browser.mathml'}) {      if ($env{'browser.mathml'}) {
         &Apache::loncommon::content_type($r,'text/xml');          &Apache::loncommon::content_type($r,'text/xml');
     } else {      } else {
         &Apache::loncommon::content_type($r,'text/html');          &Apache::loncommon::content_type($r,'text/html');
Line 184  MENU Line 186  MENU
      $navstatus       $navstatus
 MENU  MENU
  }   }
    my $html=&Apache::lonxml::xmlbegin();
  $r->print(<<"ENDSUBM");   $r->print(<<"ENDSUBM");
  <html>   $html
         <head>          <head>
   <script type="text/javascript">    <script type="text/javascript">
      function submitthis() {       function submitthis() {
Line 210  ENDSUBM Line 213  ENDSUBM
   
     if (!defined($navmap)) {      if (!defined($navmap)) {
         my $requrl = $r->uri;          my $requrl = $r->uri;
         $ENV{'user.error.msg'} = "$requrl:bre:0:0:Course not initialized";          $env{'user.error.msg'} = "$requrl:bre:0:0:Course not initialized";
         return HTTP_NOT_ACCEPTABLE;          return HTTP_NOT_ACCEPTABLE;
     }      }
       my $html=&Apache::lonxml::xmlbegin();
     $r->print("<html><head>\n");      $r->print("$html<head>\n");
     $r->print("<title>".&mt('Navigate Course Contents')."</title>");      $r->print("<title>".&mt('Navigate Course Contents')."</title>");
 # ------------------------------------------------------------ Get query string  # ------------------------------------------------------------ Get query string
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['register','sort','showOnlyHomework','postsymb']);      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['register','sort','showOnlyHomework','postsymb']);
Line 223  ENDSUBM Line 226  ENDSUBM
     my $addentries='';      my $addentries='';
     my $more_unload;      my $more_unload;
     my $body_only='';      my $body_only='';
     if ($ENV{'environment.remotenavmap'} eq 'on') {      if ($env{'environment.remotenavmap'} eq 'on') {
  $r->print('<script type="text/javascript">   $r->print('<script type="text/javascript">
                       function collapse() {                        function collapse() {
                          this.document.location="/adm/navmaps?collapseExternal";                           this.document.location="/adm/navmaps?collapseExternal";
Line 233  ENDSUBM Line 236  ENDSUBM
 # $more_unload="collapse()"  # $more_unload="collapse()"
  $body_only=1;   $body_only=1;
     }      }
     if ($ENV{'form.register'}) {      if ($env{'form.register'}) {
  $addentries=' onLoad="'.&Apache::lonmenu::loadevents().   $addentries=' onLoad="'.&Apache::lonmenu::loadevents().
     '" onUnload="'.&Apache::lonmenu::unloadevents().';'.      '" onUnload="'.&Apache::lonmenu::unloadevents().';'.
     $more_unload.'"';      $more_unload.'"';
Line 246  ENDSUBM Line 249  ENDSUBM
     $r->print('</head>'.      $r->print('</head>'.
               &Apache::loncommon::bodytag('Navigate Course Contents','',                &Apache::loncommon::bodytag('Navigate Course Contents','',
   $addentries,$body_only,'',    $addentries,$body_only,'',
   $ENV{'form.register'}));    $env{'form.register'}));
     $r->print('<script>window.focus();</script>');      $r->print('<script>window.focus();</script>');
             
     $r->rflush();      $r->rflush();
Line 277  ENDSUBM Line 280  ENDSUBM
         if ($sequenceCount == 1) {          if ($sequenceCount == 1) {
             # The automatic iterator creation in the render call               # The automatic iterator creation in the render call 
             # will pick this up. We know the condition because              # will pick this up. We know the condition because
             # the defined($ENV{'form.filter'}) also ensures this              # the defined($env{'form.filter'}) also ensures this
             # is a fresh call.              # is a fresh call.
             $ENV{'form.filter'} = "$sequenceId";              $env{'form.filter'} = "$sequenceId";
         }          }
     }      }
   
Line 294  ENDSUBM Line 297  ENDSUBM
           </script>');            </script>');
     }      }
   
     if ($ENV{'environment.remotenavmap'} ne 'on') {      if ($env{'environment.remotenavmap'} ne 'on') {
  $r->print(&launch_win('link','yes',\%toplinkitems));   $r->print(&launch_win('link','yes',\%toplinkitems));
     }       } 
     if ($ENV{'environment.remotenavmap'} eq 'on') {      if ($env{'environment.remotenavmap'} eq 'on') {
  &add_linkitem(\%toplinkitems,'closenav','collapse()',   &add_linkitem(\%toplinkitems,'closenav','collapse()',
       "Close navigation window");        "Close navigation window");
     }       } 
Line 324  ENDSUBM Line 327  ENDSUBM
                     pop @$stack; # last resource in the stack is the problem                      pop @$stack; # last resource in the stack is the problem
                                  # itself, which we don't need in the map stack                                   # itself, which we don't need in the map stack
                     my @mapPcs = map {$_->map_pc()} @$stack;                      my @mapPcs = map {$_->map_pc()} @$stack;
                     $ENV{'form.filter'} = join(',', @mapPcs);                      $env{'form.filter'} = join(',', @mapPcs);
   
                     # Mark as both "here" and "jump"                      # Mark as both "here" and "jump"
                     $ENV{'form.postsymb'} = $curRes->symb();                      $env{'form.postsymb'} = $curRes->symb();
                 }                  }
             }              }
         }          }
Line 348  ENDSUBM Line 351  ENDSUBM
   
     # Display only due homework.      # Display only due homework.
     my $showOnlyHomework = 0;      my $showOnlyHomework = 0;
     if ($ENV{'form.showOnlyHomework'} eq "1") {      if ($env{'form.showOnlyHomework'} eq "1") {
         $showOnlyHomework = 1;          $showOnlyHomework = 1;
         $suppressEmptySequences = 1;          $suppressEmptySequences = 1;
         $filterFunc = sub { my $res = shift;           $filterFunc = sub { my $res = shift; 
                             return $res->completable() || $res->is_map();                              return $res->completable() || $res->is_map();
                         };                          };
  &add_linkitem(\%toplinkitems,'everything',   &add_linkitem(\%toplinkitems,'everything',
      'location.href="navmaps?sort='.$ENV{'form.sort'}.'"',       'location.href="navmaps?sort='.$env{'form.sort'}.'"',
       "Show Everything");        "Show Everything");
         $r->print("<p><font size='+2'>".&mt("Uncompleted Homework")."</font></p>");          $r->print("<p><font size='+2'>".&mt("Uncompleted Homework")."</font></p>");
         $ENV{'form.filter'} = '';          $env{'form.filter'} = '';
         $ENV{'form.condition'} = 1;          $env{'form.condition'} = 1;
  $resource_no_folder_link = 1;   $resource_no_folder_link = 1;
     } else {      } else {
  &add_linkitem(\%toplinkitems,'uncompleted',   &add_linkitem(\%toplinkitems,'uncompleted',
       'location.href="navmaps?sort='.$ENV{'form.sort'}.        'location.href="navmaps?sort='.$env{'form.sort'}.
           '&showOnlyHomework=1"',            '&showOnlyHomework=1"',
       "Show Only Uncompleted Homework");        "Show Only Uncompleted Homework");
     }      }
   
     my %selected=($ENV{'form.sort'} => 'selected=on');      my %selected=($env{'form.sort'} => 'selected=on');
     my $sort_html=("<form>      my $sort_html=("<form>
                  <nobr>                   <nobr>
                     <input type=\"hidden\" name=\"showOnlyHomework\" value=\"".$ENV{'form.showOnlyHomework'}."\" />                      <input type=\"hidden\" name=\"showOnlyHomework\" value=\"".$env{'form.showOnlyHomework'}."\" />
                     <input type=\"submit\" value=\"".&mt('Sort by:')."\" />                      <input type=\"submit\" value=\"".&mt('Sort by:')."\" />
                     <select name=\"sort\">                      <select name=\"sort\">
                        <option value=\"default\" $selected{'default'}>".&mt('Default')."</option>                         <option value=\"default\" $selected{'default'}>".&mt('Default')."</option>
Line 383  ENDSUBM Line 386  ENDSUBM
                </form>");                 </form>");
     # renderer call      # renderer call
     my $renderArgs = { 'cols' => [0,1,2,3],      my $renderArgs = { 'cols' => [0,1,2,3],
        'sort' => $ENV{'form.sort'},         'sort' => $env{'form.sort'},
                        'url' => '/adm/navmaps',                         'url' => '/adm/navmaps',
                        'navmap' => $navmap,                         'navmap' => $navmap,
                        'suppressNavmap' => 1,                         'suppressNavmap' => 1,
Line 405  ENDSUBM Line 408  ENDSUBM
             $r->print("<p><font size='+1'>This course is empty.</font></p>");              $r->print("<p><font size='+1'>This course is empty.</font></p>");
         }          }
     }      }
       #my $td=&tv_interval($t0);
       #$r->print("<br />$td");
   
     $r->print("</body></html>");      $r->print("</body></html>");
     $r->rflush();      $r->rflush();
Line 560  sub lastTry { Line 565  sub lastTry {
         $res->duedate($part) > time();          $res->duedate($part) > time();
 }  }
   
 # This puts a human-readable name on the ENV variable.  # This puts a human-readable name on the env variable.
   
 sub advancedUser {  sub advancedUser {
     return $ENV{'request.role.adv'};      return $env{'request.role.adv'};
 }  }
   
   
Line 866  automatically. Line 871  automatically.
   
 =over 4  =over 4
   
 =item * B<iterator>: default: constructs one from %ENV  =item * B<iterator>: default: constructs one from %env
   
 A reference to a fresh ::iterator to use from the navmaps. The  A reference to a fresh ::iterator to use from the navmaps. The
 rendering will reflect the options passed to the iterator, so you can  rendering will reflect the options passed to the iterator, so you can
 use that to just render a certain part of the course, if you like. If  use that to just render a certain part of the course, if you like. If
 one is not passed, the renderer will attempt to construct one from  one is not passed, the renderer will attempt to construct one from
 ENV{'form.filter'} and ENV{'form.condition'} information, plus the  env{'form.filter'} and env{'form.condition'} information, plus the
 'iterator_map' parameter if any.  'iterator_map' parameter if any.
   
 =item * B<iterator_map>: default: not used  =item * B<iterator_map>: default: not used
Line 882  instruct the renderer to render only a p Line 887  instruct the renderer to render only a p
 the source of the map you want to process, like  the source of the map you want to process, like
 '/res/103/jerf/navmap.course.sequence'.  '/res/103/jerf/navmap.course.sequence'.
   
 =item * B<navmap>: default: constructs one from %ENV  =item * B<navmap>: default: constructs one from %env
   
 A reference to a navmap, used only if an iterator is not passed in. If  A reference to a navmap, used only if an iterator is not passed in. If
 this is necessary to make an iterator but it is not passed in, a new  this is necessary to make an iterator but it is not passed in, a new
 one will be constructed based on ENV info. This is useful to do basic  one will be constructed based on env info. This is useful to do basic
 error checking before passing it off to render.  error checking before passing it off to render.
   
 =item * B<r>: default: must be passed in  =item * B<r>: default: must be passed in
Line 912  then only one line will be displayed for Line 917  then only one line will be displayed for
 all parts will always be displayed. If showParts is 0, this is  all parts will always be displayed. If showParts is 0, this is
 ignored.  ignored.
   
 =item * B<jumpCount>: default: determined from %ENV  =item * B<jumpCount>: default: determined from %env
   
 A string identifying the URL to place the anchor 'curloc' at.  A string identifying the URL to place the anchor 'curloc' at.
 It is the responsibility of the renderer user to  It is the responsibility of the renderer user to
 ensure that the #curloc is in the URL. By default, determined through  ensure that the #curloc is in the URL. By default, determined through
 the use of the ENV{} 'jump' information, and should normally "just  the use of the env{} 'jump' information, and should normally "just
 work" correctly.  work" correctly.
   
 =item * B<here>: default: empty string  =item * B<here>: default: empty string
Line 945  are allowing the user to open and close Line 950  are allowing the user to open and close
   
 Describes the currently-open row number to cause the browser to jump  Describes the currently-open row number to cause the browser to jump
 to, because the user just opened that folder. By default, pulled from  to, because the user just opened that folder. By default, pulled from
 the Jump information in the ENV{'form.*'}.  the Jump information in the env{'form.*'}.
   
 =item * B<printKey>: default: false  =item * B<printKey>: default: false
   
Line 1055  sub render_resource { Line 1060  sub render_resource {
             $icon = $params->{'indentString'};              $icon = $params->{'indentString'};
         }          }
     } else {      } else {
  $icon = "<img src='".&Apache::loncommon::lonhttpdurl(&Apache::loncommon::icon($resource->src))."' alt='' border='0' />";   $icon = "<img src='".&Apache::loncommon::icon($resource->src)."' alt='' border='0' />";
     }      }
   
     # Display the correct map icon to open or shut map      # Display the correct map icon to open or shut map
Line 1138  sub render_resource { Line 1143  sub render_resource {
     }      }
   
     my $target;      my $target;
     if ($ENV{'environment.remotenavmap'} eq 'on') {      if ($env{'environment.remotenavmap'} eq 'on') {
  $target=' target="loncapaclient" ';   $target=' target="loncapaclient" ';
     }      }
     if (!$params->{'resource_nolink'} && !$resource->is_sequence() && !$resource->is_empty_sequence) {      if (!$params->{'resource_nolink'} && !$resource->is_sequence() && !$resource->is_empty_sequence) {
Line 1385  sub render { Line 1390  sub render {
     # marker      # marker
     my $filterHash = {};      my $filterHash = {};
     # Figure out what we're not displaying      # Figure out what we're not displaying
     foreach (split(/\,/, $ENV{"form.filter"})) {      foreach (split(/\,/, $env{"form.filter"})) {
         if ($_) {          if ($_) {
             $filterHash->{$_} = "1";              $filterHash->{$_} = "1";
         }          }
Line 1405  sub render { Line 1410  sub render {
     }      }
   
     my $condition = 0;      my $condition = 0;
     if ($ENV{'form.condition'}) {      if ($env{'form.condition'}) {
         $condition = 1;          $condition = 1;
     }      }
   
     if (!$ENV{'form.folderManip'} && !defined($args->{'iterator'})) {      if (!$env{'form.folderManip'} && !defined($args->{'iterator'})) {
         # Step 1: Check to see if we have a navmap          # Step 1: Check to see if we have a navmap
         if (!defined($navmap)) {          if (!defined($navmap)) {
             $navmap = Apache::lonnavmaps::navmap->new();              $navmap = Apache::lonnavmaps::navmap->new();
Line 1419  sub render { Line 1424  sub render {
         # Step two: Locate what kind of here marker is necessary          # Step two: Locate what kind of here marker is necessary
         # Determine where the "here" marker is and where the screen jumps to.          # Determine where the "here" marker is and where the screen jumps to.
   
         if ($ENV{'form.postsymb'}) {          if ($env{'form.postsymb'}) {
             $here = $jump = &Apache::lonnet::symbclean($ENV{'form.postsymb'});              $here = $jump = &Apache::lonnet::symbclean($env{'form.postsymb'});
         } elsif ($ENV{'form.postdata'}) {          } elsif ($env{'form.postdata'}) {
             # couldn't find a symb, is there a URL?              # couldn't find a symb, is there a URL?
             my $currenturl = $ENV{'form.postdata'};              my $currenturl = $env{'form.postdata'};
             #$currenturl=~s/^http\:\/\///;              #$currenturl=~s/^http\:\/\///;
             #$currenturl=~s/^[^\/]+//;              #$currenturl=~s/^[^\/]+//;
                           
             $here = $jump = &Apache::lonnet::symbread($currenturl);              $here = $jump = &Apache::lonnet::symbread($currenturl);
         }          } else {
       my $last;
       if (tie(my %hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db',
                       &GDBM_READER(),0640)) {
    $last=$hash{'last_known'};
    untie(%hash);
       }
       if ($last) { $here = $jump = $last; }
    }
   
         # Step three: Ensure the folders are open          # Step three: Ensure the folders are open
         my $mapIterator = $navmap->getIterator(undef, undef, undef, 1);          my $mapIterator = $navmap->getIterator(undef, undef, undef, 1);
Line 1455  sub render { Line 1468  sub render {
         }                      }            
     }              }        
   
     if ( !defined($args->{'iterator'}) && $ENV{'form.folderManip'} ) { # we came from a user's manipulation of the nav page      if ( !defined($args->{'iterator'}) && $env{'form.folderManip'} ) { # we came from a user's manipulation of the nav page
         # If this is a click on a folder or something, we want to preserve the "here"          # If this is a click on a folder or something, we want to preserve the "here"
         # from the querystring, and get the new "jump" marker          # from the querystring, and get the new "jump" marker
         $here = $ENV{'form.here'};          $here = $env{'form.here'};
         $jump = $ENV{'form.jump'};          $jump = $env{'form.jump'};
     }       } 
           
     my $it = $args->{'iterator'};      my $it = $args->{'iterator'};
     if (!defined($it)) {      if (!defined($it)) {
         # Construct a default iterator based on $ENV{'form.'} information          # Construct a default iterator based on $env{'form.'} information
                   
         # Step 1: Check to see if we have a navmap          # Step 1: Check to see if we have a navmap
         if (!defined($navmap)) {          if (!defined($navmap)) {
Line 1575  END Line 1588  END
     my @allres=$navmap->retrieveResources();      my @allres=$navmap->retrieveResources();
     foreach my $resource (@allres) {      foreach my $resource (@allres) {
  if ($resource->hasDiscussion()) {   if ($resource->hasDiscussion()) {
     my $ressymb;      $haveDisc .= $resource->wrap_symb().':';
     if ($resource->symb() =~ m-(___adm/\w+/\w+)/(\d+)/bulletinboard$-) {  
  $ressymb = 'bulletin___'.$2.$1.'/'.$2.'/bulletinboard';  
     } else {  
  $ressymb = $resource->symb();  
     }  
     $haveDisc .= $ressymb.':';  
     $totdisc ++;      $totdisc ++;
  }   }
     }      }
Line 1599  END Line 1606  END
     if ($args->{'caller'} eq 'navmapsdisplay') {      if ($args->{'caller'} eq 'navmapsdisplay') {
         $result .= '<table><tr><td>'.          $result .= '<table><tr><td>'.
                    &Apache::loncommon::help_open_menu('','Navigation Screen','Navigation_Screen','',undef,'RAT').'</td>';                     &Apache::loncommon::help_open_menu('','Navigation Screen','Navigation_Screen','',undef,'RAT').'</td>';
  if ($ENV{'environment.remotenavmap'} ne 'on') {   if ($env{'environment.remotenavmap'} ne 'on') {
     $result .= '<td>&nbsp;</td>';       $result .= '<td>&nbsp;</td>'; 
         } else {          } else {
     $result .= '</tr><tr>';       $result .= '</tr><tr>'; 
         }          }
  $result.=&show_linkitems($args->{'linkitems'});   $result.=&show_linkitems($args->{'linkitems'});
         if ($args->{'sort_html'}) {          if ($args->{'sort_html'}) {
     if ($ENV{'environment.remotenavmap'} ne 'on') {      if ($env{'environment.remotenavmap'} ne 'on') {
  $result.='<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>'.   $result.='<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>'.
     '<td align="right">'.$args->{'sort_html'}.'</td></tr>';      '<td align="right">'.$args->{'sort_html'}.'</td></tr>';
     } else {      } else {
Line 2057  See iterator documentation below. Line 2064  See iterator documentation below.
   
 use strict;  use strict;
 use GDBM_File;  use GDBM_File;
   use Apache::lonnet;
   
 sub new {  sub new {
     # magic invocation to create a class instance      # magic invocation to create a class instance
Line 2076  sub new { Line 2084  sub new {
   
     my %navmaphash;      my %navmaphash;
     my %parmhash;      my %parmhash;
     my $courseFn = $ENV{"request.course.fn"};      my $courseFn = $env{"request.course.fn"};
     if (!(tie(%navmaphash, 'GDBM_File', "${courseFn}.db",      if (!(tie(%navmaphash, 'GDBM_File', "${courseFn}.db",
               &GDBM_READER(), 0640))) {                &GDBM_READER(), 0640))) {
         return undef;          return undef;
Line 2102  sub generate_course_user_opt { Line 2110  sub generate_course_user_opt {
     my $self = shift;      my $self = shift;
     if ($self->{COURSE_USER_OPT_GENERATED}) { return; }      if ($self->{COURSE_USER_OPT_GENERATED}) { return; }
   
     my $uname=$ENV{'user.name'};      my $uname=$env{'user.name'};
     my $udom=$ENV{'user.domain'};      my $udom=$env{'user.domain'};
     my $uhome=$ENV{'user.home'};      my $uhome=$env{'user.home'};
     my $cid=$ENV{'request.course.id'};      my $cid=$env{'request.course.id'};
     my $chome=$ENV{'course.'.$cid.'.home'};      my $chome=$env{'course.'.$cid.'.home'};
     my ($cdom,$cnum)=split(/\_/,$cid);      my ($cdom,$cnum)=split(/\_/,$cid);
           
     my $userprefix=$uname.'_'.$udom.'_';      my $userprefix=$uname.'_'.$udom.'_';
Line 2114  sub generate_course_user_opt { Line 2122  sub generate_course_user_opt {
     my %courserdatas; my %useropt; my %courseopt; my %userrdatas;      my %courserdatas; my %useropt; my %courseopt; my %userrdatas;
     unless ($uhome eq 'no_host') {       unless ($uhome eq 'no_host') { 
 # ------------------------------------------------- Get coursedata (if present)  # ------------------------------------------------- Get coursedata (if present)
  unless ((time-$courserdatas{$cid.'.last_cache'})<240) {   my $reply=&Apache::lonnet::reply('dump:'.$cdom.':'.$cnum.
     my $reply=&Apache::lonnet::reply('dump:'.$cdom.':'.$cnum.   ':resourcedata',$chome);
      ':resourcedata',$chome);   # Check for network failure
     # Check for network failure   if ( $reply =~ /no.such.host/i || $reply =~ /con_lost/i) {
     if ( $reply =~ /no.such.host/i || $reply =~ /con_lost/i) {      $self->{NETWORK_FAILURE} = 1;
  $self->{NETWORK_FAILURE} = 1;   } elsif ($reply!~/^error\:/) {
     } elsif ($reply!~/^error\:/) {      $courserdatas{$cid}=$reply;
  $courserdatas{$cid}=$reply;      $courserdatas{$cid.'.last_cache'}=time;
  $courserdatas{$cid.'.last_cache'}=time;  
     }  
  }   }
  foreach (split(/\&/,$courserdatas{$cid})) {   foreach (split(/\&/,$courserdatas{$cid})) {
     my ($name,$value)=split(/\=/,$_);      my ($name,$value)=split(/\=/,$_);
Line 2131  sub generate_course_user_opt { Line 2137  sub generate_course_user_opt {
  &Apache::lonnet::unescape($value);   &Apache::lonnet::unescape($value);
  }   }
 # --------------------------------------------------- Get userdata (if present)  # --------------------------------------------------- Get userdata (if present)
  unless ((time-$userrdatas{$uname.'___'.$udom.'.last_cache'})<240) {   my $reply=&Apache::lonnet::reply('dump:'.$udom.':'.$uname.':resourcedata',$uhome);
     my $reply=&Apache::lonnet::reply('dump:'.$udom.':'.$uname.':resourcedata',$uhome);   if ($reply!~/^error\:/) {
     if ($reply!~/^error\:/) {      $userrdatas{$uname.'___'.$udom}=$reply;
  $userrdatas{$uname.'___'.$udom}=$reply;      $userrdatas{$uname.'___'.$udom.'.last_cache'}=time;
  $userrdatas{$uname.'___'.$udom.'.last_cache'}=time;   }
     }   # check to see if network failed
     # check to see if network failed   elsif ( $reply=~/no.such.host/i || $reply=~/con.*lost/i )
     elsif ( $reply=~/no.such.host/i || $reply=~/con.*lost/i )   {
     {      $self->{NETWORK_FAILURE} = 1;
  $self->{NETWORK_FAILURE} = 1;  
     }  
  }   }
  foreach (split(/\&/,$userrdatas{$uname.'___'.$udom})) {   foreach (split(/\&/,$userrdatas{$uname.'___'.$udom})) {
     my ($name,$value)=split(/\=/,$_);      my ($name,$value)=split(/\=/,$_);
Line 2162  sub generate_email_discuss_status { Line 2166  sub generate_email_discuss_status {
     my $symb = shift;      my $symb = shift;
     if ($self->{EMAIL_DISCUSS_GENERATED}) { return; }      if ($self->{EMAIL_DISCUSS_GENERATED}) { return; }
   
     my $cid=$ENV{'request.course.id'};      my $cid=$env{'request.course.id'};
     my ($cdom,$cnum)=split(/\_/,$cid);      my ($cdom,$cnum)=split(/\_/,$cid);
           
     my %emailstatus = &Apache::lonnet::dump('email_status');      my %emailstatus = &Apache::lonnet::dump('email_status');
     my $logoutTime = $emailstatus{'logout'};      my $logoutTime = $emailstatus{'logout'};
     my $courseLeaveTime = $emailstatus{'logout_'.$ENV{'request.course.id'}};      my $courseLeaveTime = $emailstatus{'logout_'.$env{'request.course.id'}};
     $self->{LAST_CHECK} = (($courseLeaveTime > $logoutTime) ?      $self->{LAST_CHECK} = (($courseLeaveTime > $logoutTime) ?
    $courseLeaveTime : $logoutTime);     $courseLeaveTime : $logoutTime);
     my %discussiontime = &Apache::lonnet::dump('discussiontimes',       my %discussiontime = &Apache::lonnet::dump('discussiontimes', 
        $cdom, $cnum);         $cdom, $cnum);
     my %lastread = &Apache::lonnet::dump('nohist_'.$cid.'_discuss',      my %lastread = &Apache::lonnet::dump('nohist_'.$cid.'_discuss',
                                         $ENV{'user.domain'},$ENV{'user.name'},'lastread');                                          $env{'user.domain'},$env{'user.name'},'lastread');
     my %lastreadtime = ();      my %lastreadtime = ();
     foreach (keys %lastread) {      foreach (keys %lastread) {
         my $key = $_;          my $key = $_;
Line 2184  sub generate_email_discuss_status { Line 2188  sub generate_email_discuss_status {
     my %feedback=();      my %feedback=();
     my %error=();      my %error=();
     my $keys = &Apache::lonnet::reply('keys:'.      my $keys = &Apache::lonnet::reply('keys:'.
       $ENV{'user.domain'}.':'.        $env{'user.domain'}.':'.
       $ENV{'user.name'}.':nohist_email',        $env{'user.name'}.':nohist_email',
       $ENV{'user.home'});        $env{'user.home'});
           
     foreach my $msgid (split(/\&/, $keys)) {      foreach my $msgid (split(/\&/, $keys)) {
  $msgid=&Apache::lonnet::unescape($msgid);   $msgid=&Apache::lonnet::unescape($msgid);
Line 2220  sub get_user_data { Line 2224  sub get_user_data {
     if ($self->{RETRIEVED_USER_DATA}) { return; }      if ($self->{RETRIEVED_USER_DATA}) { return; }
   
     # Retrieve performance data on problems      # Retrieve performance data on problems
     my %student_data = Apache::lonnet::currentdump($ENV{'request.course.id'},      my %student_data = Apache::lonnet::currentdump($env{'request.course.id'},
    $ENV{'user.domain'},     $env{'user.domain'},
    $ENV{'user.name'});     $env{'user.name'});
     $self->{STUDENT_DATA} = \%student_data;      $self->{STUDENT_DATA} = \%student_data;
   
     $self->{RETRIEVED_USER_DATA} = 1;      $self->{RETRIEVED_USER_DATA} = 1;
Line 2247  sub navhash { Line 2251  sub navhash {
 # Checks to see if coursemap is defined, matching test in old lonnavmaps  # Checks to see if coursemap is defined, matching test in old lonnavmaps
 sub courseMapDefined {  sub courseMapDefined {
     my $self = shift;      my $self = shift;
     my $uri = &Apache::lonnet::clutter($ENV{'request.course.uri'});      my $uri = &Apache::lonnet::clutter($env{'request.course.uri'});
   
     my $firstres = $self->navhash("map_start_$uri");      my $firstres = $self->navhash("map_start_$uri");
     my $lastres = $self->navhash("map_finish_$uri");      my $lastres = $self->navhash("map_finish_$uri");
Line 2267  sub getIterator { Line 2271  sub getIterator {
 sub hasDiscussion {  sub hasDiscussion {
     my $self = shift;      my $self = shift;
     my $symb = shift;      my $symb = shift;
       
     $self->generate_email_discuss_status();      $self->generate_email_discuss_status();
   
     if (!defined($self->{DISCUSSION_TIME})) { return 0; }      if (!defined($self->{DISCUSSION_TIME})) { return 0; }
   
     #return defined($self->{DISCUSSION_TIME}->{$symb});      #return defined($self->{DISCUSSION_TIME}->{$symb});
   
 # backward compatibility (bulletin boards used to be 'wrapped')      # backward compatibility (bulletin boards used to be 'wrapped')
     my $ressymb = $symb;      my $ressymb = $self->wrap_symb($symb);
     if ($ressymb =~ m|adm/(\w+)/(\w+)/(\d+)/bulletinboard$|) {  
         unless ($ressymb =~ m|adm/wrapper/adm|) {  
             $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard';  
         }  
     }  
   
     if ( defined ( $self->{LAST_READ}->{$ressymb} ) ) {      if ( defined ( $self->{LAST_READ}->{$ressymb} ) ) {
         return $self->{DISCUSSION_TIME}->{$ressymb} > $self->{LAST_READ}->{$ressymb};          return $self->{DISCUSSION_TIME}->{$ressymb} > $self->{LAST_READ}->{$ressymb};
     } else {      } else {
Line 2290  sub hasDiscussion { Line 2287  sub hasDiscussion {
     }      }
 }  }
   
   sub wrap_symb {
       my $self = shift;
       my $symb = shift;
       if ($symb =~ m-___(adm/\w+/\w+/)(\d+)(/bulletinboard)$-) {
           unless ($symb =~ m|adm/wrapper/adm|) {
               $symb = 'bulletin___'.$2.'___adm/wrapper/'.$1.$2.$3;
           }
       }
       return $symb;
   }
   
 # Private method: Does the given resource (as a symb string) have  # Private method: Does the given resource (as a symb string) have
 # current feedback? Returns the string in the feedback hash, which  # current feedback? Returns the string in the feedback hash, which
 # will be false if it does not exist.  # will be false if it does not exist.
   
 sub getFeedback {   sub getFeedback { 
     my $self = shift;      my $self = shift;
     my $symb = shift;      my $symb = shift;
Line 2388  resource in the navmap. Line 2397  resource in the navmap.
 sub firstResource {  sub firstResource {
     my $self = shift;      my $self = shift;
     my $firstResource = $self->navhash('map_start_' .      my $firstResource = $self->navhash('map_start_' .
                      &Apache::lonnet::clutter($ENV{'request.course.uri'}));                       &Apache::lonnet::clutter($env{'request.course.uri'}));
     return $self->getById($firstResource);      return $self->getById($firstResource);
 }  }
   
Line 2404  in the navmap. Line 2413  in the navmap.
 sub finishResource {  sub finishResource {
     my $self = shift;      my $self = shift;
     my $firstResource = $self->navhash('map_finish_' .      my $firstResource = $self->navhash('map_finish_' .
                      &Apache::lonnet::clutter($ENV{'request.course.uri'}));                       &Apache::lonnet::clutter($env{'request.course.uri'}));
     return $self->getById($firstResource);      return $self->getById($firstResource);
 }  }
   
Line 2431  sub parmval_real { Line 2440  sub parmval_real {
     # Make sure the {USER_OPT} and {COURSE_OPT} hashes are populated      # Make sure the {USER_OPT} and {COURSE_OPT} hashes are populated
     $self->generate_course_user_opt();      $self->generate_course_user_opt();
   
     my $cid=$ENV{'request.course.id'};      my $cid=$env{'request.course.id'};
     my $csec=$ENV{'request.course.sec'};      my $csec=$env{'request.course.sec'};
     my $uname=$ENV{'user.name'};      my $uname=$env{'user.name'};
     my $udom=$ENV{'user.domain'};      my $udom=$env{'user.domain'};
   
     unless ($symb) { return ''; }      unless ($symb) { return ''; }
     my $result='';      my $result='';
Line 2553  want to know is if I<any> resources matc Line 2562  want to know is if I<any> resources matc
 parameter will allow you to avoid potentially expensive enumeration of  parameter will allow you to avoid potentially expensive enumeration of
 all matching resources.  all matching resources.
   
 =item * B<hasResource>(map, filterFunc, recursive):  =item * B<hasResource>(map, filterFunc, recursive, showall):
   
 Convience method for  Convience method for
   
  scalar(retrieveResources($map, $filterFunc, $recursive, 1)) > 0   scalar(retrieveResources($map, $filterFunc, $recursive, 1, $showall)) > 0
   
 which will tell whether the map has resources matching the description  which will tell whether the map has resources matching the description
 in the filter function.  in the filter function.
Line 2640  sub hasResource { Line 2649  sub hasResource {
     my $map = shift;      my $map = shift;
     my $filterFunc = shift;      my $filterFunc = shift;
     my $recursive = shift;      my $recursive = shift;
       my $showall = shift;
           
     return scalar($self->retrieveResources($map, $filterFunc, $recursive, 1)) > 0;      return scalar($self->retrieveResources($map, $filterFunc, $recursive, 1, $showall)) > 0;
 }  }
   
 1;  1;
   
 package Apache::lonnavmaps::iterator;  package Apache::lonnavmaps::iterator;
 use WeakRef;  use WeakRef;
   use Apache::lonnet;
   
 =pod  =pod
   
 =back  =back
Line 3127  sub populateStack { Line 3139  sub populateStack {
   
 package Apache::lonnavmaps::DFSiterator;  package Apache::lonnavmaps::DFSiterator;
 use WeakRef;  use WeakRef;
   use Apache::lonnet;
   
 # Not documented in the perldoc: This is a simple iterator that just walks  # Not documented in the perldoc: This is a simple iterator that just walks
 #  through the nav map and presents the resources in a depth-first search  #  through the nav map and presents the resources in a depth-first search
 #  fashion, ignorant of conditionals, randomized resources, etc. It presents  #  fashion, ignorant of conditionals, randomized resources, etc. It presents
Line 3512  sub symb { Line 3526  sub symb {
         . '___' . $second . '___' . $symbSrc;          . '___' . $second . '___' . $symbSrc;
     return &Apache::lonnet::symbclean($symb);      return &Apache::lonnet::symbclean($symb);
 }  }
   sub wrap_symb {
       my $self = shift;
       return $self->{NAV_MAP}->wrap_symb($self->symb());
   }
 sub title {   sub title { 
     my $self=shift;       my $self=shift; 
     if ($self->{ID} eq '0.0') {      if ($self->{ID} eq '0.0') {
  # If this is the top-level map, return the title of the course   # If this is the top-level map, return the title of the course
  # since this map can not be titled otherwise.   # since this map can not be titled otherwise.
  return $ENV{'course.'.$ENV{'request.course.id'}.'.description'};   return $env{'course.'.$env{'request.course.id'}.'.description'};
     }      }
     return $self->navHash("title_", 1); }      return $self->navHash("title_", 1); }
 # considered private and undocumented  # considered private and undocumented
Line 3851  sub weight { Line 3869  sub weight {
     my $self = shift; my $part = shift;      my $self = shift; my $part = shift;
     if (!defined($part)) { $part = '0'; }      if (!defined($part)) { $part = '0'; }
     return &Apache::lonnet::EXT('resource.'.$part.'.weight',      return &Apache::lonnet::EXT('resource.'.$part.'.weight',
  $self->symb(), $ENV{'user.domain'},   $self->symb(), $env{'user.domain'},
  $ENV{'user.name'},    $env{'user.name'}, 
  $ENV{'request.course.sec'});   $env{'request.course.sec'});
 }  }
 sub part_display {  sub part_display {
     my $self= shift(); my $partID = shift();      my $self= shift(); my $partID = shift();

Removed from v.1.315  
changed lines
  Added in v.1.324


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