Diff for /loncom/interface/lonnavmaps.pm between versions 1.144 and 1.156

version 1.144, 2003/02/20 22:08:55 version 1.156, 2003/03/13 17:05:36
Line 38 Line 38
 # YEAR=2002  # YEAR=2002
 # 1/1 Gerd Kortemeyer  # 1/1 Gerd Kortemeyer
 # Oct-Nov Jeremy Bowers  # Oct-Nov Jeremy Bowers
   # YEAR=2003
   # Jeremy Bowers ... lots of days
   
 package Apache::lonnavmaps;  package Apache::lonnavmaps;
   
 use strict;  use strict;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
 use Apache::loncommon();  use Apache::loncommon();
   use Apache::lonmenu();
 use POSIX qw (floor strftime);  use POSIX qw (floor strftime);
   
 my %navmaphash;  my %navmaphash;
Line 152  sub real_handler { Line 155  sub real_handler {
     }      }
   
     $r->print("<html><head>\n");      $r->print("<html><head>\n");
     $r->print("<title>Navigate Course Contents</title></head>");      $r->print("<title>Navigate Course Contents</title>");
   # ------------------------------------------------------------ Get query string
       &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['register']);
   # ----------------------------------------------------- Force menu registration
       my $addentries='';
       if ($ENV{'form.register'}) {
          $addentries=' onLoad="'.&Apache::lonmenu::loadevents().
      '" onUnload="'.&Apache::lonmenu::unloadevents().'"';
          $r->print(&Apache::lonmenu::registerurl(1));
       }
   
     # Header      # Header
     $r->print(&Apache::loncommon::bodytag('Navigate Course Contents','',      $r->print('</head>'.
                                           ''));                &Apache::loncommon::bodytag('Navigate Course Contents','',
                                       $addentries,'','',$ENV{'form.register'}));
     $r->print('<script>window.focus();</script>');      $r->print('<script>window.focus();</script>');
   
     $r->rflush();      $r->rflush();
Line 175  sub real_handler { Line 188  sub real_handler {
         return OK;          return OK;
     }      }
   
       # See if there's only one map in the top-level... if so,
       # automatically display it
       my $iterator = $navmap->getIterator(undef, undef, undef, 0);
       my $depth = 1;
       $iterator->next();
       my $curRes = $iterator->next();
       my $sequenceCount = 0;
       my $sequenceId;
       while ($depth > 0) {
           if ($curRes == $iterator->BEGIN_MAP()) { $depth++; }
           if ($curRes == $iterator->END_MAP()) { $depth--; }
   
           if (ref($curRes) && $curRes->is_sequence()) {
               $sequenceCount++;
               $sequenceId = $curRes->map_pc();
           }
   
           $curRes = $iterator->next();
       }
   
       if ($sequenceCount == 1) {
           # The automatic iterator creation in the render call 
           # will pick this up.
           $ENV{'form.filter'} = "$sequenceId";
       }
   
     # renderer call      # renderer call
     my $render = render({ 'cols' => [0,1,2,3],      my $render = render({ 'cols' => [0,1,2,3],
                           'url' => '/adm/navmaps',                            'url' => '/adm/navmaps',
                           'printKey' => 1,                            'suppressNavmap' => 1,
                           'r' => $r});                            'r' => $r});
   
     $navmap->untieHashes();      $navmap->untieHashes();
Line 525  Most of these parameters are only useful Line 564  Most of these parameters are only useful
   
 =item * B<printCloseAll>: If true, print the "Close all folders" or "open all folders" links. Default is true.  =item * B<printCloseAll>: If true, print the "Close all folders" or "open all folders" links. Default is true.
   
 =item * B<filterFunc>: A function that takes the resource object as its only parameter and returns a true or false value. If true, the resource is displayed. If false, it is simply skipped in the display. By default, all resources are showne.  =item * B<filterFunc>: A function that takes the resource object as its only parameter and returns a true or false value. If true, the resource is displayed. If false, it is simply skipped in the display. By default, all resources are shown.
   
   =item * B<suppressNavmaps>: If true, will not display Navigate Content resources. Default to false.
   
 =back  =back
   
Line 533  Most of these parameters are only useful Line 574  Most of these parameters are only useful
   
 In addition to the parameters you can pass to the renderer, which will be passed through unchange to the column renderers, the renderer will generate the following information which your renderer may find useful:  In addition to the parameters you can pass to the renderer, which will be passed through unchange to the column renderers, the renderer will generate the following information which your renderer may find useful:
   
   If you want to know how many rows were printed, the 'counter' element of the hash passed into the render function will contain the count. You may want to check whether any resources were printed at all.
   
 =over 4  =over 4
   
 =back  =back
Line 577  sub render_resource { Line 620  sub render_resource {
     my $icon = "<img src='/adm/lonIcons/html.gif' alt='' border='0' />";      my $icon = "<img src='/adm/lonIcons/html.gif' alt='' border='0' />";
           
     if ($resource->is_problem()) {      if ($resource->is_problem()) {
         if ($part eq "0" || $params->{'condensed'}) {          if ($part eq "" || $params->{'condensed'}) {
             $icon = '<img src="/adm/lonIcons/problem.gif" alt="" border="0" />';              $icon = '<img src="/adm/lonIcons/problem.gif" alt="" border="0" />';
         } else {          } else {
             $icon = $params->{'indentString'};              $icon = $params->{'indentString'};
Line 649  sub render_resource { Line 692  sub render_resource {
         $curMarkerEnd = '<font color="red" size="+2">&lt;</font>';          $curMarkerEnd = '<font color="red" size="+2">&lt;</font>';
     }      }
   
     if ($resource->is_problem() && $part ne "0" &&       if ($resource->is_problem() && $part ne "" && 
         !$params->{'condensed'}) {          !$params->{'condensed'}) {
         $partLabel = " (Part $part)";          $partLabel = " (Part $part)";
         $title = "";          $title = "";
Line 802  sub render { Line 845  sub render {
     my $here;      my $here;
     my $jump;      my $jump;
     my $currentJumpIndex = setDefault($args->{'currentJumpIndex'}, 0);          my $currentJumpIndex = setDefault($args->{'currentJumpIndex'}, 0);    
       my $suppressNavmap = setDefault($args->{'suppressNavmap'}, 0);
     my $currentJumpDelta = 2; # change this to change how many resources are displayed      my $currentJumpDelta = 2; # change this to change how many resources are displayed
                              # before the current resource when using #current                               # before the current resource when using #current
   
Line 941  sub render { Line 985  sub render {
         # See if we're being passed a specific map          # See if we're being passed a specific map
         if ($args->{'iterator_map'}) {          if ($args->{'iterator_map'}) {
             my $map = $args->{'iterator_map'};              my $map = $args->{'iterator_map'};
             $map = &Apache::lonnet::clutter($map);              $map = $navmap->getResourceByUrl($map);
             $map = $navmap->{NAV_HASH}->{'ids_' . $map};  
             $map = $navmap->getById($map);  
             my $firstResource = $map->map_start();              my $firstResource = $map->map_start();
             my $finishResource = $map->map_finish();              my $finishResource = $map->map_finish();
   
Line 1065  sub render { Line 1107  sub render {
   
         # If this has been filtered out, continue on          # If this has been filtered out, continue on
         if (!(&$filterFunc($curRes))) {          if (!(&$filterFunc($curRes))) {
             $curRes = $it->next();  
             $args->{'isNewBranch'} = 0; # Don't falsely remember this              $args->{'isNewBranch'} = 0; # Don't falsely remember this
             next;              next;
         }           } 
   
           # If we're suppressing navmaps and this is a navmap, continue on
           if ($suppressNavmap && $curRes->src() =~ /^\/adm\/navmaps/) {
               next;
           }
   
         # Does it have multiple parts?          # Does it have multiple parts?
         $args->{'multipart'} = 0;          $args->{'multipart'} = 0;
         $args->{'condensed'} = 0;          $args->{'condensed'} = 0;
Line 1120  sub render { Line 1166  sub render {
                                           
                 }                  }
             }              }
               
         } else {  
             # Not showing parts  
             @parts = ("0"); # show main part only  
         }          }
               
         # If the multipart problem was condensed, "forget" it was multipart          # If the multipart problem was condensed, "forget" it was multipart
         if (scalar(@parts) == 1) {          if (scalar(@parts) == 1) {
             $args->{'multipart'} = 0;              $args->{'multipart'} = 0;
         }          }
   
         # In the event of a network error, display one part.  
         # If this is a single part, we can at least show the correct  
         # status, but if it's multipart, we're lost, since we can't  
         # retreive the metadata to count the parts  
         if ($curRes->{RESOURCE_ERROR}) {  
             @parts = ("0");  
         }  
   
         # Now, we've decided what parts to show. Loop through them and          # Now, we've decided what parts to show. Loop through them and
         # show them.          # show them.
         foreach my $part (@parts) {          foreach my $part ('', @parts) {
               if ($part eq '0') {
                   next;
               }
             $rownum ++;              $rownum ++;
             my $backgroundColor = $backgroundColors[$rownum % scalar(@backgroundColors)];              my $backgroundColor = $backgroundColors[$rownum % scalar(@backgroundColors)];
                           
Line 1181  sub render { Line 1218  sub render {
             $result .= "    </tr>\n";              $result .= "    </tr>\n";
             $args->{'isNewBranch'} = 0;              $args->{'isNewBranch'} = 0;
         }          }
           
         if ($r && $rownum % 20 == 0) {          if ($r && $rownum % 20 == 0) {
             $r->print($result);              $r->print($result);
             $result = "";              $result = "";
             $r->rflush();              $r->rflush();
         }          }
               } continue {
         $curRes = $it->next();          $curRes = $it->next();
     }      }
           
Line 1613  sub parmval_real { Line 1650  sub parmval_real {
     return '';      return '';
 }  }
   
   =pod 
   
   =item * B<getResourceByUrl>(url): Retrieves a resource object by URL of the resource. If passed a resource object, it will simply return it, so it is safe to use this method in code like "$res = $navmap->getResourceByUrl($res)", if you're not sure if $res is already an object, or just a URL. If the resource appears multiple times in the course, only the first instance will be returned. As a result, this is probably useful only for maps.
   
   =item * B<retrieveResources>(map, filterFunc, recursive, bailout): The map is a specification of a map to retreive the resources from, either as a url or as an object. The filterFunc is a reference to a function that takes a resource object as its one argument and returns true if the resource should be included, or false if it should not be. If recursive is true, the map will be recursively examined, otherwise it will not be. If bailout is true, the function will return as soon as it finds a resource, if false it will finish. By default, the map is the top-level map of the course, filterFunc is a function that always returns 1, recursive is true, bailout is false. The resources will be returned in a list reference containing the resource objects for the corresponding resources, with B<no structure information> in the list; regardless of branching, recursion, etc., it will be a flat list. 
   
   Thus, this is suitable for cases where you don't want the structure, just a list of all resources. It is also suitable for finding out how many resources match a given description; for this use, if all you want to know is if I<any> resources match the description, the bailout parameter will allow you to avoid potentially expensive enumeration of all matching resources.
   
   =item * B<hasResources>(map, filterFunc, recursive): Convience method for 
   
    scalar(retrieveResources($map, $filterFunc, $recursive, 1)) > 0
   
   which will tell whether the map has resources matching the description in the filter function.
   
   =cut
   
   sub getResourceByUrl {
       my $self = shift;
       my $resUrl = shift;
   
       if (ref($resUrl)) { return $resUrl; }
   
       $resUrl = &Apache::lonnet::clutter($resUrl);
       my $resId = $self->{NAV_HASH}->{'ids_' . $resUrl};
       if ($resId =~ /,/) {
           $resId = (split (/,/, $resId))[0];
       }
       if (!$resId) { return ''; }
       return $self->getById($resId);
   }
   
   sub retrieveResources {
       my $self = shift;
       my $map = shift;
       my $filterFunc = shift;
       if (!defined ($filterFunc)) {
           $filterFunc = sub {return 1;};
       }
       my $recursive = shift;
       if (!defined($recursive)) { $recursive = 1; }
       my $bailout = shift;
       if (!defined($bailout)) { $bailout = 0; }
   
       # Create the necessary iterator.
       if (!ref($map)) { # assume it's a url of a map.
           $map = $self->getMapByUrl($map);
       }
   
       # Check the map's validity.
       if (!$map || !$map->is_map()) {
           # Oh, to throw an exception.... how I'd love that!
           return ();
       }
   
       # Get an iterator.
       my $it = $self->getIterator($map->map_start(), $map->map_finish(),
                                   !$recursive);
   
       my @resources = ();
   
       # Run down the iterator and collect the resources.
       my $depth = 1;
       $it->next();
       my $curRes = $it->next();
   
       while ($depth > 0) {
           if ($curRes == $it->BEGIN_MAP()) {
               $depth++;
           }
           if ($curRes == $it->END_MAP()) {
               $depth--;
           }
           
           if (ref($curRes)) {
               if (!&$filterFunc($curRes)) {
                   next;
               }
   
               push @resources, $curRes;
   
               if ($bailout) {
                   return @resources;
               }
           }
   
           $curRes = $it->next();
       }
   
       return @resources;
   }
   
   sub hasResource {
       my $self = shift;
       my $map = shift;
       my $filterFunc = shift;
       my $recursive = shift;
       
       return scalar($self->retrieveResources($map, $filterFunc, $recursive, 1)) > 0;
   }
   
 1;  1;
   
 package Apache::lonnavmaps::iterator;  package Apache::lonnavmaps::iterator;
Line 2580  sub countParts { Line 2717  sub countParts {
 sub extractParts {   sub extractParts { 
     my $self = shift;      my $self = shift;
           
     return if ($self->{PARTS});      return if (defined($self->{PARTS}));
     return if ($self->ext);      return if ($self->ext);
   
     $self->{PARTS} = [];      $self->{PARTS} = [];
   
     # Retrieve part count, if this is a problem      # Retrieve part count, if this is a problem
     if ($self->is_problem()) {      if ($self->is_problem()) {
         my $metadata = &Apache::lonnet::metadata($self->src(), 'allpossiblekeys');          my $metadata = &Apache::lonnet::metadata($self->src(), 'packages');
         if (!$metadata) {          if (!$metadata) {
             $self->{RESOURCE_ERROR} = 1;              $self->{RESOURCE_ERROR} = 1;
             $self->{PARTS} = [];              $self->{PARTS} = [];
             return;              return;
         }          }
           
         foreach (split(/\,/,$metadata)) {          foreach (split(/\,/,$metadata)) {
             if ($_ =~ /^parameter\_(.*)\_opendate$/) {              if ($_ =~ /^part_(.*)$/) {
                 push @{$self->{PARTS}}, $1;                  my $part = $1;
                   # check to see if part is turned off.
                   if (! Apache::loncommon::check_if_partid_hidden($part, $self->symb())) {
                       push @{$self->{PARTS}}, $1;
                   }
             }              }
         }          }
                   
                   
         # Is this possible to do in one line? - Jeremy  
         my @sortedParts = sort @{$self->{PARTS}};          my @sortedParts = sort @{$self->{PARTS}};
         $self->{PARTS} = \@sortedParts;          $self->{PARTS} = \@sortedParts;
     }      }

Removed from v.1.144  
changed lines
  Added in v.1.156


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