Diff for /loncom/lonmap.pm between versions 1.1 and 1.2

version 1.1, 2011/09/07 10:58:36 version 1.2, 2011/09/13 10:27:52
Line 38  use Error qw(:try); Line 38  use Error qw(:try);
 use HTML::TokeParser;  use HTML::TokeParser;
   
   
 use Apache::LONCAPA;  use LONCAPA;
 use Apache::lonnet;  use Apache::lonnet;
   
 #------------- File scoped variables:  #------------- File scoped variables:
Line 56  my %randompickseed; Line 56  my %randompickseed;
 my %randomorder;  my %randomorder;
 my %encurl;  my %encurl;
 my %hiddenurl;  my %hiddenurl;
   my %parmhash;
 my @cond; # Array of conditions.  my @cond; # Array of conditions.
   my $retfrid;
 #  #
 #  Other stuff we make global (sigh) so that it does not need  #  Other stuff we make global (sigh) so that it does not need
 #  to be passed around all the time:  #  to be passed around all the time:
Line 128  sub simplify { Line 129  sub simplify {
 sub merge_conditions {  sub merge_conditions {
     my $hash = shift;      my $hash = shift;
   
     for (my $i = 0; i < scalar(@cond); i++) {      for (my $i = 0; $i < scalar(@cond); $i++) {
  $hash->{'condition' . '.' . $i} = $cond[$i];   $hash->{'condition' . '.' . $i} = $cond[$i];
     }      }
 }  }
Line 181  sub count_mapalias { Line 182  sub count_mapalias {
 #  result string.'  #  result string.'
 #  #
 #  Parameters:  #  Parameters:
 #     none  #     hash - Reference to the hash we are trying t build up.
 #  Implicit inputs  #  Implicit inputs
 #     %mapalias - a hash that is indexed by map aliases and contains for each key  #     %mapalias - a hash that is indexed by map aliases and contains for each key
 #                 an array of the resource id's the alias 'points to'.  #                 an array of the resource id's the alias 'points to'.
Line 191  sub count_mapalias { Line 192  sub count_mapalias {
 #  #
 #  #
 sub get_mapalias_errors {  sub get_mapalias_errors {
       my $hash = shift;
     my $error_text;      my $error_text;
     foreach my $mapalias (sort(keys(%mapalias_cache))) {      foreach my $mapalias (sort(keys(%mapalias_cache))) {
  next if (scalar(@{ $mapalias_cache{$mapalias} } ) == 1);   next if (scalar(@{ $mapalias_cache{$mapalias} } ) == 1);
Line 199  sub get_mapalias_errors { Line 201  sub get_mapalias_errors {
     join('</li><li>',       join('</li><li>', 
  map {   map {
      my $id = $_;       my $id = $_;
      if (exists($hash{'src_'.$id})) {       if (exists($hash->{'src_'.$id})) {
  $count++;   $count++;
      }       }
      my ($mapid) = split(/\./,$id);       my ($mapid) = split(/\./,$id);
      &mt('Resource "[_1]" <br /> in Map "[_2]"',       &mt('Resource "[_1]" <br /> in Map "[_2]"',
  $hash{'title_'.$id},   $hash->{'title_'.$id},
  $hash{'title_'.$hash{'ids_'.$hash{'map_id_'.$mapid}}});   $hash->{'title_'.$hash->{'ids_'.$hash->{'map_id_'.$mapid}}});
  } (@{ $mapalias_cache{$mapalias} }));   } (@{ $mapalias_cache{$mapalias} }));
  next if ($count < 2);   next if ($count < 2);
  $error_text .= '<div class="LC_error">'.   $error_text .= '<div class="LC_error">'.
Line 229  sub clear_mapalias_count { Line 231  sub clear_mapalias_count {
 #  #
   
 #  #
   #  Put a version into a src element of a hash or url:
   #
   #  Parameters:
   #     uri - URI into which the version must be added.
   #    hash - Reference to the hash being built up.
   #    short- Short coursename.
   #
   
   sub putinversion {
       my ($uri, $hash, $short) = @_;
       my $key=$short.'_'.&Apache::lonnet::clutter($uri);
       if ($hash->{'version_'.$uri}) {
    my $version=$hash->{'version_'.$uri};
    if ($version eq 'mostrecent') { return $uri; }
    if ($version eq &Apache::lonnet::getversion(
    &Apache::lonnet::filelocation('',$uri))) 
                { return $uri; }
    $uri=~s/\.(\w+)$/\.$version\.$1/;
       }
       &Apache::lonnet::do_cache_new('courseresversion',$key,&Apache::lonnet::declutter($uri),600);
       return $uri;
   }
   
   
   #
 #  Create hash entries for each version of the course.  #  Create hash entries for each version of the course.
 # Parameters:  # Parameters:
 #   $cenv    - Reference to a course environment from lonnet::coursedescription.  #   $cenv    - Reference to a course environment from lonnet::coursedescription.
Line 291  sub vesiontrack { Line 318  sub vesiontrack {
         unless ($hash->{'version_'.$uri}) {          unless ($hash->{'version_'.$uri}) {
     $hash->{'version_'.$uri}=$version;      $hash->{'version_'.$uri}=$version;
  } elsif ($version!=$hash->{'version_'.$uri}) {   } elsif ($version!=$hash->{'version_'.$uri}) {
     throw Error::Simple(&versionerror($uri,$hash{'version_'.$uri},$version));      throw Error::Simple(&versionerror($uri, $hash->{'version_'.$uri}, $version));
         }          }
     }      }
     return $uri;      return $uri;
Line 410  sub hiddenurls { Line 437  sub hiddenurls {
 #         #       
   
 sub accinit {  sub accinit {
     my ($uri,$short,$fn)=@_;      my ($uri, $short, $fn, $hash)=@_;
     my %acchash=();      my %acchash=();
     my %captured=();      my %captured=();
     my $condcounter=0;      my $condcounter=0;
Line 542  sub accinit { Line 569  sub accinit {
 #    new value indicating how far the map has been traversed (the sofar).  #    new value indicating how far the map has been traversed (the sofar).
 #  #
 sub traceroute {  sub traceroute {
     my ($sofar,$rid,$beenhere,$encflag,$hdnflag)=@_;      my ($sofar, $rid, $beenhere, $encflag, $hdnflag, $hash)=@_;
     my $newsofar=$sofar=simplify($sofar);      my $newsofar=$sofar=simplify($sofar);
   
     unless ($beenhere=~/\&\Q$rid\E\&/) {      unless ($beenhere=~/\&\Q$rid\E\&/) {
Line 608  sub traceroute { Line 635  sub traceroute {
  $further=simplify('('.'_'.$rid.')&('.   $further=simplify('('.'_'.$rid.')&('.
   $hash->{'condid_'.$hash->{'undercond_'.$id}}.')');    $hash->{'condid_'.$hash->{'undercond_'.$id}}.')');
     } else {      } else {
  $errtext.=&mt('<br />Undefined condition ID: [_1]',$hash->{'undercond_'.$id});   my $errtext.=&mt('<br />Undefined condition ID: [_1]',$hash->{'undercond_'.$id});
  throw Error::Simple($errtext);   throw Error::Simple($errtext);
     }      }
                 }                  }
Line 1128  sub read_map { Line 1155  sub read_map {
     # Check for duplication: A map may only be included once.      # Check for duplication: A map may only be included once.
   
     if($hash->{'map_pc_' . $uri}) {      if($hash->{'map_pc_' . $uri}) {
  throw Error::Simple('Duplicate map: ' $uri);   throw Error::Simple('Duplicate map: ', $uri);
     }      }
     # count the map number and save it locally so that we don't lose it      # count the map number and save it locally so that we don't lose it
     # when we recurse.      # when we recurse.
Line 1151  sub read_map { Line 1178  sub read_map {
  my $parent_no = $1;       # Parent's map number.   my $parent_no = $1;       # Parent's map number.
  if (defined($hash->{'map_hierarchy_' . $parent_no})) {   if (defined($hash->{'map_hierarchy_' . $parent_no})) {
     $hash->{'map_hierarchy_' . $lmap_no} =      $hash->{'map_hierarchy_' . $lmap_no} =
  $hash->{'map_hierarchy_' . $parent_no} . ',' $parent_no;   $hash->{'map_hierarchy_' . $parent_no} . ',' . $parent_no;
  } else {   } else {
     # Only 1 level deep ..nothing to append to:      # Only 1 level deep ..nothing to append to:
   
Line 1165  sub read_map { Line 1192  sub read_map {
   
     my $filename = &Apache::lonnet::filelocation('', &append_version($uri, $hash));      my $filename = &Apache::lonnet::filelocation('', &append_version($uri, $hash));
     my $ispage = ($filename =~/\.page$/);      my $ispage = ($filename =~/\.page$/);
     unless ($ispage || ($filname =~ /\.sequence$/)) {      unless ($ispage || ($filename =~ /\.sequence$/)) {
  throw Error::Simple(&mt("<br />Invalid map: <tt>[_1]</tt>", $filename));   throw Error::Simple(&mt("<br />Invalid map: <tt>[_1]</tt>", $filename));
     }      }
   
     $filename =~ /\.(\w+)$/;      $filename =~ /\.(\w+)$/;
   
     $hash->{'map_type_'.$lpc}=$1;      $hash->{'map_type_'.$lmap_no}=$1;
   
     # Repcopy the file and get its contents...report errors if we can't      # Repcopy the file and get its contents...report errors if we can't
         
Line 1192  sub read_map { Line 1219  sub read_map {
     # tags.. this is because there is no body to a <param> tag.      # tags.. this is because there is no body to a <param> tag.
     #      #
   
     my $parser  = HTML::TokeParser->new($\contents);      my $parser  = HTML::TokeParser->new(\$contents);
     $parser->attr_encoded(1); # Don't interpret entities in attributes (leave &xyz; alone).      $parser->attr_encoded(1); # Don't interpret entities in attributes (leave &xyz; alone).
   
     while (my $token = $parser->get_token()) {      while (my $token = $parser->get_token()) {
Line 1207  sub read_map { Line 1234  sub read_map {
     # resources, they are also not processed if random order is turned on.      # resources, they are also not processed if random order is turned on.
     #      #
   
     $parser = HTML::TokeParser->new($\contents); # no way to reset the existing parser      $parser = HTML::TokeParser->new(\$contents); # no way to reset the existing parser
     $parser->attr_encoded(1);      $parser->attr_encoded(1);
   
     my $linkpc=0;      my $linkpc=0;
Line 1220  sub read_map { Line 1247  sub read_map {
  # Resource   # Resource
   
  if ($token->[1] eq 'resource') {   if ($token->[1] eq 'resource') {
     my $resource_id = &parse_resource($token,$lpc,$ispage,$uri, $hash);      my $resource_id = &parse_resource($token,$lmap_no,$ispage,$uri, $hash);
     if (defined $resource_id) {      if (defined $resource_id) {
  push(@map_ids, $resource_id);    push(@map_ids, $resource_id); 
     }      }
Line 1228  sub read_map { Line 1255  sub read_map {
        # Link         # Link
   
  } elsif ($token->[1] eq 'link' && !$randomize) {   } elsif ($token->[1] eq 'link' && !$randomize) {
     &make_link(++$linkpc,$lpc,$token->[2]->{'to'},      &make_link(++$linkpc,$lmap_no,$token->[2]->{'to'},
        $token->[2]->{'from'},         $token->[2]->{'from'},
        $token->[2]->{'condition'}, $hash); # note ..condition may be undefined.         $token->[2]->{'condition'}, $hash); # note ..condition may be undefined.
   
  # condition   # condition
   
  } elsif ($token->[1] eq 'condition' && !$randomize) {   } elsif ($token->[1] eq 'condition' && !$randomize) {
     &parse_condition($token,$lpc, $hash);      &parse_condition($token,$lmap_no, $hash);
  }   }
     }      }
   
Line 1279  sub read_map { Line 1306  sub read_map {
   
   
  my $from = shift(@map_ids);   my $from = shift(@map_ids);
  my $from_rid = $lpc.'.'.$from;   my $from_rid = $lmap_no.'.'.$from;
  $hash->{'map_start_'.$uri} = $from_rid;   $hash->{'map_start_'.$uri} = $from_rid;
  $hash->{'type_'.$from_rid}='start';   $hash->{'type_'.$from_rid}='start';
   
Line 1288  sub read_map { Line 1315  sub read_map {
  # if randomorder was set.  This means that for an instructor to choose   # if randomorder was set.  This means that for an instructor to choose
   
  while (my $to = shift(@map_ids)) {   while (my $to = shift(@map_ids)) {
     &make_link(++$linkpc,$lpc,$to,$from);      &make_link(++$linkpc,$lmap_no,$to,$from);
     my $to_rid =  $lpc.'.'.$to;      my $to_rid =  $lmap_no.'.'.$to;
     $hash->{'type_'.$to_rid}='normal';      $hash->{'type_'.$to_rid}='normal';
     $from = $to;      $from = $to;
     $from_rid = $to_rid;      $from_rid = $to_rid;
Line 1308  sub read_map { Line 1335  sub read_map {
     while (my $token = $parser->get_token) {      while (my $token = $parser->get_token) {
  next if ($token->[0] ne 'S');   next if ($token->[0] ne 'S');
  if ($token->[1] eq 'param') {   if ($token->[1] eq 'param') {
     &parse_mapalias_param($token,$lpc, $hash);        &parse_mapalias_param($token,$lmap_no, $hash);  
  }    } 
     }      }
   
Line 1342  sub loadmap { Line 1369  sub loadmap {
     %randompickseed = ();      %randompickseed = ();
     %encurl         = ();      %encurl         = ();
     %hiddenurl      = ();      %hiddenurl      = ();
       %parmhash       = ();
     @cond           = ();      @cond           = ();
       $retfrid        = '';
   
       
     #       # 
   
     $username   = $uname;      $username   = $uname;
Line 1357  sub loadmap { Line 1387  sub loadmap {
  # Get the information we need about the course.   # Get the information we need about the course.
  # Return without filling in anything if we can't get any info:   # Return without filling in anything if we can't get any info:
   
  my %cenv = &Apache::lonnet::coursedesription($short_name,   my %cenv = &Apache::lonnet::coursedescription($short_name,
      {'freshen_cache' => 1,       {'freshen_cache' => 1,
       'user'          => $uname});         'user'          => $uname}); 
  unless ($cenv{'url'}) {    unless ($cenv{'url'}) { 
Line 1374  sub loadmap { Line 1404  sub loadmap {
   
  # Figure out the map filename's URI, and set up some starting points for the map.   # Figure out the map filename's URI, and set up some starting points for the map.
   
  $course_uri = $cenv->{'url'};   my $course_uri = $cenv{'url'};
  $map_uri    = &Apache::lonnet::clutter($course_uri);   my $map_uri    = &Apache::lonnet::clutter($course_uri);
   
  $target_hash->{'src_0.0'}            = &versiontrack($map_uri, $target_hash);    $target_hash->{'src_0.0'}            = &versiontrack($map_uri, $target_hash); 
  $target_hash->{'title_0.0'}          = &Apache::lonnet::metadata($course_uri, 'title');   $target_hash->{'title_0.0'}          = &Apache::lonnet::metadata($course_uri, 'title');
  $target_hash->{'ids_'.$file_map_uri} = '0.0';   $target_hash->{'ids_'.$map_uri} = '0.0';
  $target_hash->{'is_map_0.0'}         = 1;   $target_hash->{'is_map_0.0'}         = 1;
         &read_map($course_uri, '0.0', &hash);          &read_map($course_uri, '0.0', &hash);
   
  #    # 
   
  if (defined($hash->{'map_start_'.$uri})) {   if (defined($target_hash->{'map_start_'.$map_uri})) {
   
     &traceroute('0',$hash->{'map_start_'.$course_uri},'&', $hash);      &traceroute('0',$target_hash->{'map_start_'.$course_uri},'&', $target_hash);
     &accinit($course_uri, $short_name, $fn, $hash);      &accinit($course_uri, $short_name, $filepath, $target_hash);
     &hiddenurls($hash);      &hiddenurls($target_hash);
    }
    my $errors = &get_mapalias_errors($target_hash);
    if ($errors ne "") {
       throw Error::Simple("Map alias errors: ", $errors);
    }
   
    # Put the versions in to src:
   
    foreach my $key (keys(%$target_hash)) {
       if ($key =~ /^src_/) {
    $target_hash->{$key} = 
       &putinversion($target_hash->{$key}, $target_hash, $short_name);
       } elsif ($key =~ /^(map_(?:start|finish|pc)_)(.*)/) {
    my ($type, $url) = ($1,$2);
    my $value = $target_hash->{$key};
    $target_hash->{$type.&putinversion($url, $target_hash, $short_name)}=$value;
       }
  }   }
   
  # Merge in the child hashes in case the caller wants that information as well.   # Merge in the child hashes in case the caller wants that information as well.
   
   
  &merge_hash($hash, 'randompick', \%randompick);   &merge_hash($target_hash, 'randompick', \%randompick);
  &merge_hash($hash, 'randompickseed', \%randompick);   &merge_hash($target_hash, 'randompickseed', \%randompick);
  &merge_hash($hash, 'randomorder', \%randomorder);   &merge_hash($target_hash, 'randomorder', \%randomorder);
  &merge_hash($hash, 'encurl', \%encurl);   &merge_hash($target_hash, 'encurl', \%encurl);
  &merge_hash($hash, 'hiddenurl', \%hiddenurl);   &merge_hash($target_hash, 'hiddenurl', \%hiddenurl);
  &merge_conditions($hash);   &merge_hash($target_hash, 'param', \%parmhash);
    &merge_conditions($target_hash);
     }      }
     otherwise {      otherwise {
  my $e = shift;   my $e = shift;

Removed from v.1.1  
changed lines
  Added in v.1.2


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