Diff for /loncom/interface/lonnavmaps.pm between versions 1.288 and 1.306

version 1.288, 2004/09/13 20:06:57 version 1.306, 2004/12/02 22:50:16
Line 33  use strict; Line 33  use strict;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lonmenu();  use Apache::lonmenu();
   use Apache::lonenc();
 use Apache::lonlocal;  use Apache::lonlocal;
   use Apache::lonnet;
 use POSIX qw (floor strftime);  use POSIX qw (floor strftime);
 use Data::Dumper; # for debugging, not always used  use Data::Dumper; # for debugging, not always 
   
 # symbolic constants  # symbolic constants
 sub SYMB { return 1; }  sub SYMB { return 1; }
Line 119  window.status='Done.'; Line 121  window.status='Done.';
 ENDCLOSE  ENDCLOSE
 }  }
   
 sub nav_control_js {  
     my $nav=($ENV{'environment.remotenavmap'} eq 'on');  
     return (<<NAVCONTROL);  
     var w_loncapanav_flag="$nav";  
   
   
 function gonav(url) {  
    if (w_loncapanav_flag != 1) {  
       go(url);  
    }  else {  
       navwindow=window.open(url,  
                   "loncapanav","height=600,width=400,scrollbars=1");   
    }  
 }  
 NAVCONTROL  
 }  
   
 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 ''; }
Line 370  ENDSUBM Line 355  ENDSUBM
                             return $res->completable() || $res->is_map();                              return $res->completable() || $res->is_map();
                         };                          };
  &add_linkitem(\%toplinkitems,'everything',   &add_linkitem(\%toplinkitems,'everything',
      'location.href="locatnavmaps?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'} = '';
Line 392  ENDSUBM Line 377  ENDSUBM
                        <option value=\"default\" $selected{'default'}>".&mt('Default')."</option>                         <option value=\"default\" $selected{'default'}>".&mt('Default')."</option>
                        <option value=\"title\"   $selected{'title'}  >".&mt('Title')."</option>                         <option value=\"title\"   $selected{'title'}  >".&mt('Title')."</option>
                        <option value=\"duedate\" $selected{'duedate'}>".&mt('Duedate')."</option>                         <option value=\"duedate\" $selected{'duedate'}>".&mt('Duedate')."</option>
                          <option value=\"discussion\" $selected{'discussion'}>".&mt('Has Discussion')."</option>
                     </select>                      </select>
                  </nobr>                   </nobr>
                </form>");                 </form>");
Line 409  ENDSUBM Line 395  ENDSUBM
                        'caller' => 'navmapsdisplay',                         'caller' => 'navmapsdisplay',
                        'linkitems' => \%toplinkitems};                         'linkitems' => \%toplinkitems};
     my $render = render($renderArgs);      my $render = render($renderArgs);
     $navmap->untieHashes();  
   
     # If no resources were printed, print a reassuring message so the      # If no resources were printed, print a reassuring message so the
     # user knows there was no error.      # user knows there was no error.
Line 459  sub getLinkForResource { Line 444  sub getLinkForResource {
     foreach $res (@$stack) {      foreach $res (@$stack) {
         if (defined($res)) {          if (defined($res)) {
     if ($res->is_page()) {      if ($res->is_page()) {
  return $res->src();   return $res->link();
     }      }
             # in case folder was skipped over as "only sequence"              # in case folder was skipped over as "only sequence"
     my ($map,$id,$src)=&Apache::lonnet::decode_symb($res->symb());      my ($map,$id,$src)=&Apache::lonnet::decode_symb($res->symb());
Line 478  sub getLinkForResource { Line 463  sub getLinkForResource {
         if (defined($_)) { $res = $_; }          if (defined($_)) { $res = $_; }
     }      }
   
     return $res->src();      return $res->link();
 }  }
   
 # Convenience function: This separates the logic of how to create  # Convenience function: This separates the logic of how to create
Line 1026  sub render_resource { Line 1011  sub render_resource {
     my $nonLinkedText = ''; # stuff after resource title not in link      my $nonLinkedText = ''; # stuff after resource title not in link
   
     my $link = $params->{"resourceLink"};      my $link = $params->{"resourceLink"};
   
       #  The URL part is not escaped at this point, but the symb is... 
       #  The stuff to the left of the ? must have ' replaced by \' since
       #  it will be quoted with ' in the href.
   
       my ($left,$right) = split(/\?/, $link);
       $left =~ s/'/\\'/g;
       $link = $left.'?'.$right;
   
     my $src = $resource->src();      my $src = $resource->src();
     my $it = $params->{"iterator"};      my $it = $params->{"iterator"};
     my $filter = $it->{FILTER};      my $filter = $it->{FILTER};
Line 1034  sub render_resource { Line 1028  sub render_resource {
   
     my $partLabel = "";      my $partLabel = "";
     my $newBranchText = "";      my $newBranchText = "";
           my $location=&Apache::loncommon::lonhttpdurl("/adm/lonIcons");
     # If this is a new branch, label it so      # If this is a new branch, label it so
     if ($params->{'isNewBranch'}) {      if ($params->{'isNewBranch'}) {
         $newBranchText = "<img src='/adm/lonIcons/branch.gif' border='0' />";          $newBranchText = "<img src='$location/branch.gif' border='0' />";
     }      }
   
     # links to open and close the folder      # links to open and close the folder
   
       
     my $linkopen = "<a href='$link'>";      my $linkopen = "<a href='$link'>";
   
   
     my $linkclose = "</a>";      my $linkclose = "</a>";
   
     # Default icon: unknown page      # Default icon: unknown page
     my $icon = "<img src='/adm/lonIcons/unknown.gif' alt='' border='0' />";      my $icon = "<img src='$location/unknown.gif' alt='' border='0' />";
           
     if ($resource->is_problem()) {      if ($resource->is_problem()) {
         if ($part eq '0' || $params->{'condensed'}) {          if ($part eq '0' || $params->{'condensed'}) {
             $icon = '<img src="/adm/lonIcons/problem.gif" alt="" border="0" />';              $icon ='<img src="'.$location.'/problem.gif" alt="" border="0" />';
         } else {          } else {
             $icon = $params->{'indentString'};              $icon = $params->{'indentString'};
         }          }
     } else {      } else {
  $icon = "<img src='".&Apache::loncommon::icon($resource->src).   $icon = "<img src='".&Apache::loncommon::lonhttpdurl(&Apache::loncommon::icon($resource->src))."' alt='' border='0' />";
     "' alt='' border='0' />";  
     }      }
   
     # Display the correct map icon to open or shut map      # Display the correct map icon to open or shut map
Line 1070  sub render_resource { Line 1067  sub render_resource {
   
         if (!$params->{'resource_no_folder_link'}) {          if (!$params->{'resource_no_folder_link'}) {
             $icon = "navmap.$folderType." . ($nowOpen ? 'closed' : 'open') . '.gif';              $icon = "navmap.$folderType." . ($nowOpen ? 'closed' : 'open') . '.gif';
             $icon = "<img src='/adm/lonIcons/$icon' alt='' border='0' />";              $icon = "<img src='$location/$icon' alt='' border='0' />";
   
             $linkopen = "<a href='" . $params->{'url'} . '?' .               $linkopen = "<a href='" . $params->{'url'} . '?' . 
                 $params->{'queryString'} . '&filter=';                  $params->{'queryString'} . '&filter=';
Line 1083  sub render_resource { Line 1080  sub render_resource {
                 '&jump=' .                  '&jump=' .
                 &Apache::lonnet::escape($resource->symb()) .                   &Apache::lonnet::escape($resource->symb()) . 
                 "&folderManip=1'>";                  "&folderManip=1'>";
   
         } else {          } else {
             # Don't allow users to manipulate folder              # Don't allow users to manipulate folder
             $icon = "navmap.$folderType." . ($nowOpen ? 'closed' : 'open') .              $icon = "navmap.$folderType." . ($nowOpen ? 'closed' : 'open') .
                 '.nomanip.gif';                  '.nomanip.gif';
             $icon = "<img src='/adm/lonIcons/$icon' alt='' border='0' />";              $icon = "<img src='$location/$icon' alt='' border='0' />";
   
             $linkopen = "";              $linkopen = "";
             $linkclose = "";              $linkclose = "";
Line 1110  sub render_resource { Line 1108  sub render_resource {
     }      }
   
     # Decide what to display      # Decide what to display
   
     $result .= "$newBranchText$linkopen$icon$linkclose";      $result .= "$newBranchText$linkopen$icon$linkclose";
           
     my $curMarkerBegin = '';      my $curMarkerBegin = '';
Line 1155  sub render_communication_status { Line 1154  sub render_communication_status {
     my $link = $params->{"resourceLink"};      my $link = $params->{"resourceLink"};
     my $linkopen = "<a href='$link'>";      my $linkopen = "<a href='$link'>";
     my $linkclose = "</a>";      my $linkclose = "</a>";
       my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc");
     if ($resource->hasDiscussion()) {      if ($resource->hasDiscussion()) {
         $discussionHTML = $linkopen .          $discussionHTML = $linkopen .
             '<img border="0" src="/adm/lonMisc/chat.gif" />' .              '<img border="0" src="'.$location.'/chat.gif" />' .
             $linkclose;              $linkclose;
     }      }
           
Line 1168  sub render_communication_status { Line 1167  sub render_communication_status {
             if ($_) {              if ($_) {
                 $feedbackHTML .= '&nbsp;<a href="/adm/email?display='                  $feedbackHTML .= '&nbsp;<a href="/adm/email?display='
                     . &Apache::lonnet::escape($_) . '">'                      . &Apache::lonnet::escape($_) . '">'
                     . '<img src="/adm/lonMisc/feedback.gif" '                      . '<img src="'.$location.'/feedback.gif" '
                     . 'border="0" /></a>';                      . 'border="0" /></a>';
             }              }
         }          }
Line 1183  sub render_communication_status { Line 1182  sub render_communication_status {
                 $errorcount++;                  $errorcount++;
                 $errorHTML .= '&nbsp;<a href="/adm/email?display='                  $errorHTML .= '&nbsp;<a href="/adm/email?display='
                     . &Apache::lonnet::escape($_) . '">'                      . &Apache::lonnet::escape($_) . '">'
                     . '<img src="/adm/lonMisc/bomb.gif" '                      . '<img src="'.$location.'/bomb.gif" '
                     . 'border="0" /></a>';                      . 'border="0" /></a>';
             }              }
         }          }
Line 1212  sub render_quick_status { Line 1211  sub render_quick_status {
         my $icon = $statusIconMap{$resource->simpleStatus($part)};          my $icon = $statusIconMap{$resource->simpleStatus($part)};
         my $alt = $iconAltTags{$icon};          my $alt = $iconAltTags{$icon};
         if ($icon) {          if ($icon) {
             $result .= "<td width='30' valign='center' width='50' align='right'>$linkopen<img width='25' height='25' src='/adm/lonIcons/$icon' border='0' alt='$alt' />$linkclose</td>\n";      my $location=
    &Apache::loncommon::lonhttpdurl("/adm/lonIcons/$icon");
               $result .= "<td width='30' valign='center' width='50' align='right'>$linkopen<img width='25' height='25' src='$location' border='0' alt='$alt' />$linkclose</td>\n";
         } else {          } else {
             $result .= "<td width='30'>&nbsp;</td>\n";              $result .= "<td width='30'>&nbsp;</td>\n";
         }          }
Line 1343  sub setDefault { Line 1344  sub setDefault {
     return $val;      return $val;
 }  }
   
   sub cmp_title {
       my ($atitle,$btitle) = (lc($_[0]->compTitle),lc($_[1]->compTitle));
       $atitle=~s/^\s*//;
       $btitle=~s/^\s*//;
       return $atitle cmp $btitle;
   }
   
 sub render {  sub render {
     my $args = shift;      my $args = shift;
     &Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING});      &Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING});
     my $result = '';      my $result = '';
   
     # Configure the renderer.      # Configure the renderer.
     my $cols = $args->{'cols'};      my $cols = $args->{'cols'};
     if (!defined($cols)) {      if (!defined($cols)) {
Line 1410  sub render { Line 1417  sub render {
         # 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 = $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'};
Line 1428  sub render { Line 1435  sub render {
         # We only need to do this if we need to open the maps to show the          # We only need to do this if we need to open the maps to show the
         # current position. This will change the counter so we can't count          # current position. This will change the counter so we can't count
         # for the jump marker with this loop.          # for the jump marker with this loop.
         while (($curRes = $mapIterator->next()) && !$found) {          while ($here && ($curRes = $mapIterator->next()) && !$found) {
             if (ref($curRes) && $curRes->symb() eq $here) {              if (ref($curRes) && $curRes->symb() eq $here) {
                 my $mapStack = $mapIterator->getStack();                  my $mapStack = $mapIterator->getStack();
                                   
Line 1504  sub render { Line 1511  sub render {
     my $printKey = $args->{'printKey'};      my $printKey = $args->{'printKey'};
     my $printCloseAll = $args->{'printCloseAll'};      my $printCloseAll = $args->{'printCloseAll'};
     if (!defined($printCloseAll)) { $printCloseAll = 1; }      if (!defined($printCloseAll)) { $printCloseAll = 1; }
       
     # Print key?      # Print key?
     if ($printKey) {      if ($printKey) {
         $result .= '<table border="0" cellpadding="2" cellspacing="0">';          $result .= '<table border="0" cellpadding="2" cellspacing="0">';
         my $date=localtime;          my $date=localtime;
         $result.='<tr><td align="right" valign="bottom">Key:&nbsp;&nbsp;</td>';          $result.='<tr><td align="right" valign="bottom">Key:&nbsp;&nbsp;</td>';
    my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc");
         if ($navmap->{LAST_CHECK}) {          if ($navmap->{LAST_CHECK}) {
             $result .=               $result .= 
                 '<img src="/adm/lonMisc/chat.gif"> '.&mt('New discussion since').' '.                  '<img src="'.$location.'/chat.gif"> '.&mt('New discussion since').' '.
                 strftime("%A, %b %e at %I:%M %P", localtime($navmap->{LAST_CHECK})).                  strftime("%A, %b %e at %I:%M %P", localtime($navmap->{LAST_CHECK})).
                 '</td><td align="center" valign="bottom">&nbsp;&nbsp;'.                  '</td><td align="center" valign="bottom">&nbsp;&nbsp;'.
                 '<img src="/adm/lonMisc/feedback.gif"> '.&mt('New message (click to open)').'<p>'.                  '<img src="'.$location.'/feedback.gif"> '.&mt('New message (click to open)').'<p>'.
                 '</td>';                   '</td>'; 
         } else {          } else {
             $result .= '<td align="center" valign="bottom">&nbsp;&nbsp;'.              $result .= '<td align="center" valign="bottom">&nbsp;&nbsp;'.
                 '<img src="/adm/lonMisc/chat.gif"> '.&mt('Discussions').'</td><td align="center" valign="bottom">'.                  '<img src="'.$location.'/chat.gif"> '.&mt('Discussions').'</td><td align="center" valign="bottom">'.
                 '&nbsp;&nbsp;<img src="/adm/lonMisc/feedback.gif"> '.&mt('New message (click to open)').                  '&nbsp;&nbsp;<img src="'.$location.'/feedback.gif"> '.&mt('New message (click to open)').
                 '</td>';                   '</td>'; 
         }          }
   
Line 1549  sub render { Line 1557  sub render {
   
     # Check for any unread discussions in all resources.      # Check for any unread discussions in all resources.
     if ($args->{'caller'} eq 'navmapsdisplay') {      if ($args->{'caller'} eq 'navmapsdisplay') {
  my $totdisc = 0;   &add_linkitem($args->{'linkitems'},'clearbubbles',
  my $haveDisc = '';        'document.clearbubbles.submit()',
  my @allres=$navmap->retrieveResources();        'Mark all posts read');
  foreach my $resource (@allres) {   my $time=time;
     if ($resource->hasDiscussion()) {   $result .= (<<END);
  my $ressymb;      <form name="clearbubbles" method="post" action="/adm/feedback">
  if ($resource->symb() =~ m-(___adm/\w+/\w+)/(\d+)/bulletinboard$-) {   <input type="hidden" name="navurl" value="$ENV{'QUERY_STRING'}" />
     $ressymb = 'bulletin___'.$2.$1.'/'.$2.'/bulletinboard';   <input type="hidden" name="navtime" value="$time" />
  } else {  END
     $ressymb = $resource->symb();          if ($args->{'sort'} eq 'discussion') { 
       my $totdisc = 0;
       my $haveDisc = '';
       my @allres=$navmap->retrieveResources();
       foreach my $resource (@allres) {
    if ($resource->hasDiscussion()) {
       my $ressymb;
       if ($resource->symb() =~ m-(___adm/\w+/\w+)/(\d+)/bulletinboard$-) {
    $ressymb = 'bulletin___'.$2.$1.'/'.$2.'/bulletinboard';
       } else {
    $ressymb = $resource->symb();
       }
       $haveDisc .= $ressymb.':';
       $totdisc ++;
  }   }
  $haveDisc .= $ressymb.':';  
  $totdisc ++;  
     }      }
  }      if ($totdisc > 0) {
  if ($totdisc > 0) {   $haveDisc =~ s/:$//;
     $haveDisc =~ s/:$//;   $result .= (<<END);
             my $navurl = $ENV{'QUERY_STRING'};   <input type="hidden" name="navmaps" value="$haveDisc" />
     &add_linkitem($args->{'linkitems'},'clearbubbles',      </form>
   'document.clearbubbles.submit()',  
   'Mark all posts read');  
             $result .= (<<END);  
  <form name="clearbubbles" method="post" action="/adm/feedback">  
  <input type="hidden" name="navurl" value="$ENV{'QUERY_STRING'}" />  
  <input type="hidden" name="navmaps" value="$haveDisc" />  
  </form>  
 END  END
               }
  }   }
    $result.='</form>';
     }      }
   
     if ($args->{'caller'} eq 'navmapsdisplay') {      if ($args->{'caller'} eq 'navmapsdisplay') {
Line 1624  END Line 1638  END
     $args->{'indentLevel'} = 0;      $args->{'indentLevel'} = 0;
     $args->{'isNewBranch'} = 0;      $args->{'isNewBranch'} = 0;
     $args->{'condensed'} = 0;          $args->{'condensed'} = 0;    
     $args->{'indentString'} = setDefault($args->{'indentString'}, "<img src='/adm/lonIcons/whitespace1.gif' width='25' height='1' alt='' border='0' />");      my $location=
    &Apache::loncommon::lonhttpdurl("/adm/lonIcons/whitespace1.gif");
       $args->{'indentString'} = setDefault($args->{'indentString'}, "<img src='$location' width='25' height='1' alt='' border='0' />");
     $args->{'displayedHereMarker'} = 0;      $args->{'displayedHereMarker'} = 0;
   
     # If we're suppressing empty sequences, look for them here. Use DFS for speed,      # If we're suppressing empty sequences, look for them here. Use DFS for speed,
Line 1685  END Line 1701  END
  return &$oldFilterFunc($res);   return &$oldFilterFunc($res);
     };      };
  @resources=$navmap->retrieveResources(undef,$filterFunc);   @resources=$navmap->retrieveResources(undef,$filterFunc);
  @resources= sort {lc($a->compTitle) cmp lc($b->compTitle)} @resources;   @resources= sort { &cmp_title($a,$b) } @resources;
     } elsif ($args->{'sort'} eq 'duedate') {      } elsif ($args->{'sort'} eq 'duedate') {
  @resources=$navmap->retrieveResources(undef,   my $oldFilterFunc = $filterFunc;
        sub { shift->is_problem(); });   my $filterFunc= 
  @resources= sort      sub {
  {   my ($res)=@_;
    if (!$res->is_problem()) { return 0;}
    return &$oldFilterFunc($res);
       };
    @resources=$navmap->retrieveResources(undef,$filterFunc);
    @resources= sort {
     if ($a->duedate ne $b->duedate) {      if ($a->duedate ne $b->duedate) {
         return $a->duedate cmp $b->duedate;          return $a->duedate cmp $b->duedate;
     } else {  
  lc($a->compTitle) cmp lc($b->compTitle)  
     }      }
       my $value=&cmp_title($a,$b);
       return $value;
  } @resources;   } @resources;
       } elsif ($args->{'sort'} eq 'discussion') {
    my $oldFilterFunc = $filterFunc;
    my $filterFunc= 
       sub {
    my ($res)=@_;
    if (!$res->hasDiscussion() &&
       !$res->getFeedback() &&
       !$res->getErrors()) { return 0;}
    return &$oldFilterFunc($res);
       };
    @resources=$navmap->retrieveResources(undef,$filterFunc);
    @resources= sort { &cmp_title($a,$b) } @resources;
     } else {      } else {
  #unknow sort mechanism or default   #unknow sort mechanism or default
  undef($args->{'sort'});   undef($args->{'sort'});
Line 1838  END Line 1871  END
             my $srcHasQuestion = $src =~ /\?/;              my $srcHasQuestion = $src =~ /\?/;
             $args->{"resourceLink"} = $src.              $args->{"resourceLink"} = $src.
                 ($srcHasQuestion?'&':'?') .                  ($srcHasQuestion?'&':'?') .
                 'symb=' . &Apache::lonnet::escape($curRes->symb()).                  'symb=' . &Apache::lonnet::escape($curRes->shown_symb()).
  $anchor;   $anchor;
   
             # Now, display each column.              # Now, display each column.
Line 1906  if (location.href.indexOf('#curloc')==-1 Line 1939  if (location.href.indexOf('#curloc')==-1
         $r->rflush();          $r->rflush();
     }      }
                   
     if ($mustCloseNavMap) { $navmap->untieHashes(); }   
   
     return $result;      return $result;
 }  }
   
Line 1947  ENDBLOCK Line 1978  ENDBLOCK
     $result .= '</select>&nbsp;<input type="button" name="chgnav"      $result .= '</select>&nbsp;<input type="button" name="chgnav"
                    value="Go" onClick="javascript:changeNavDisplay()" />                     value="Go" onClick="javascript:changeNavDisplay()" />
                 </nobr></form></td>'."\n";                  </nobr></form></td>'."\n";
   
     return $result;      return $result;
 }  }
   
Line 2007  successful, or B<undef> if not. Line 2039  successful, or B<undef> if not.
   
 =back  =back
   
 When you are done with the $navmap object, you I<must> call   
 $navmap->untieHashes(), or you'll prevent the current user from using that   
 course until the web server is restarted. (!)  
   
 =head2 Methods  =head2 Methods
   
 =over 4  =over 4
Line 2156  sub generate_email_discuss_status { Line 2184  sub generate_email_discuss_status {
           
     foreach my $msgid (split(/\&/, $keys)) {      foreach my $msgid (split(/\&/, $keys)) {
  $msgid=&Apache::lonnet::unescape($msgid);   $msgid=&Apache::lonnet::unescape($msgid);
  my $plain=&Apache::lonnet::unescape(&Apache::lonnet::unescape($msgid));   if ((!$emailstatus{$msgid}) || ($emailstatus{$msgid} eq 'new')) {
  if ($plain=~/(Error|Feedback) \[([^\]]+)\]/) {      my $plain=
     my ($what,$url)=($1,$2);   &Apache::lonnet::unescape(&Apache::lonnet::unescape($msgid));
     my %status=      if ($plain=~/(Error|Feedback) \[([^\]]+)\]/) {
  &Apache::lonnet::get('email_status',[$msgid]);   my ($what,$url)=($1,$2);
     if ($status{$msgid}=~/^error\:/) {   
  $status{$msgid}='';   
     }  
       
     if (($status{$msgid} eq 'new') ||   
  (!$status{$msgid})) {   
  if ($what eq 'Error') {   if ($what eq 'Error') {
     $error{$url}.=','.$msgid;       $error{$url}.=','.$msgid; 
  } else {   } else {
Line 2176  sub generate_email_discuss_status { Line 2198  sub generate_email_discuss_status {
  }   }
     }      }
           
       #url's of resources that have feedbacks
     $self->{FEEDBACK} = \%feedback;      $self->{FEEDBACK} = \%feedback;
     $self->{ERROR_MSG} = \%error; # what is this? JB      #or errors
       $self->{ERROR_MSG} = \%error;
     $self->{DISCUSSION_TIME} = \%discussiontime;      $self->{DISCUSSION_TIME} = \%discussiontime;
     $self->{EMAIL_STATUS} = \%emailstatus;      $self->{EMAIL_STATUS} = \%emailstatus;
     $self->{LAST_READ} = \%lastreadtime;      $self->{LAST_READ} = \%lastreadtime;
Line 2231  sub getIterator { Line 2255  sub getIterator {
     return $iterator;      return $iterator;
 }  }
   
 # unties the hash when done  
 sub untieHashes {  
     my $self = shift;  
     untie %{$self->{NAV_HASH}};  
     untie %{$self->{PARM_HASH}};  
 }  
   
 # Private method: Does the given resource (as a symb string) have  # Private method: Does the given resource (as a symb string) have
 # current discussion? Returns 0 if chat/mail data not extracted.  # current discussion? Returns 0 if chat/mail data not extracted.
 sub hasDiscussion {  sub hasDiscussion {
Line 2618  sub hasResource { Line 2635  sub hasResource {
 1;  1;
   
 package Apache::lonnavmaps::iterator;  package Apache::lonnavmaps::iterator;
   use WeakRef;
 =pod  =pod
   
 =back  =back
Line 2758  sub new { Line 2775  sub new {
     my $class = ref($proto) || $proto;      my $class = ref($proto) || $proto;
     my $self = {};      my $self = {};
   
     $self->{NAV_MAP} = shift;      weaken($self->{NAV_MAP} = shift);
     return undef unless ($self->{NAV_MAP});      return undef unless ($self->{NAV_MAP});
   
     # Handle the parameters      # Handle the parameters
Line 3094  sub populateStack { Line 3111  sub populateStack {
 1;  1;
   
 package Apache::lonnavmaps::DFSiterator;  package Apache::lonnavmaps::DFSiterator;
   use WeakRef;
 # 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 3122  sub new { Line 3139  sub new {
     my $class = ref($proto) || $proto;      my $class = ref($proto) || $proto;
     my $self = {};      my $self = {};
   
     $self->{NAV_MAP} = shift;      weaken($self->{NAV_MAP} = shift);
     return undef unless ($self->{NAV_MAP});      return undef unless ($self->{NAV_MAP});
   
     $self->{FIRST_RESOURCE} = shift || $self->{NAV_MAP}->firstResource();      $self->{FIRST_RESOURCE} = shift || $self->{NAV_MAP}->firstResource();
Line 3276  sub populateStack { Line 3293  sub populateStack {
 1;  1;
   
 package Apache::lonnavmaps::resource;  package Apache::lonnavmaps::resource;
   use WeakRef;
 use Apache::lonnet;  use Apache::lonnet;
   
 =pod  =pod
Line 3358  sub new { Line 3375  sub new {
     my $class = ref($proto) || $proto;      my $class = ref($proto) || $proto;
     my $self = {};      my $self = {};
   
     $self->{NAV_MAP} = shift;      weaken($self->{NAV_MAP} = shift);
     $self->{ID} = shift;      $self->{ID} = shift;
   
     # Store this new resource in the parent nav map's cache.      # Store this new resource in the parent nav map's cache.
Line 3446  Returns the title of the resource. Line 3463  Returns the title of the resource.
 # These info functions can be used directly, as they don't return  # These info functions can be used directly, as they don't return
 # resource information.  # resource information.
 sub comesfrom { my $self=shift; return $self->navHash("comesfrom_", 1); }  sub comesfrom { my $self=shift; return $self->navHash("comesfrom_", 1); }
   sub encrypted { my $self=shift; return $self->navHash("encrypted_", 1); }
 sub ext { my $self=shift; return $self->navHash("ext_", 1) eq 'true:'; }  sub ext { my $self=shift; return $self->navHash("ext_", 1) eq 'true:'; }
 sub from { my $self=shift; return $self->navHash("from_", 1); }  sub from { my $self=shift; return $self->navHash("from_", 1); }
 # considered private and undocumented  # considered private and undocumented
Line 3457  sub randompick { Line 3475  sub randompick {
     return $self->{NAV_MAP}->{PARM_HASH}->{$self->symb .      return $self->{NAV_MAP}->{PARM_HASH}->{$self->symb .
                                                '.0.parameter_randompick'};                                                 '.0.parameter_randompick'};
 }  }
   sub link {
       my $self=shift;
       if ($self->encrypted()) { return &Apache::lonenc::encrypted($self->src); }
       return $self->src;
   }
 sub src {   sub src { 
     my $self=shift;      my $self=shift;
     return $self->navHash("src_", 1);      return $self->navHash("src_", 1);
 }  }
   sub shown_symb {
       my $self=shift;
       if ($self->encrypted()) {return &Apache::lonenc::encrypted($self->symb());}
       return $self->symb();
   }
 sub symb {  sub symb {
     my $self=shift;      my $self=shift;
     (my $first, my $second) = $self->{ID} =~ /(\d+).(\d+)/;      (my $first, my $second) = $self->{ID} =~ /(\d+).(\d+)/;
Line 3479  sub title { Line 3507  sub title {
     return $self->navHash("title_", 1); }      return $self->navHash("title_", 1); }
 # considered private and undocumented  # considered private and undocumented
 sub to { my $self=shift; return $self->navHash("to_", 1); }  sub to { my $self=shift; return $self->navHash("to_", 1); }
   sub condition {
       my $self=shift;
       my $undercond=$self->navHash("undercond_", 1);
       if (!defined($undercond)) { return 1; };
       my $condid=$self->navHash("condid_$undercond");
       if (!defined($condid)) { return 1; };
       my $condition=&Apache::lonnet::directcondval($condid);
       return $condition;
   }
   
 sub compTitle {  sub compTitle {
     my $self = shift;      my $self = shift;
     my $title = $self->title();      my $title = $self->title();
Line 3900  Returns the number of parts of the probl Line 3938  Returns the number of parts of the probl
 for single part problems, returns 1. For multipart, it returns the  for single part problems, returns 1. For multipart, it returns the
 number of parts in the problem, not including psuedo-part 0.   number of parts in the problem, not including psuedo-part 0. 
   
   =item * B<countResponses>():
   
   Returns the total number of responses in the problem a student can answer.
   
   =item * B<responseTypes>():
   
   Returns a hash whose keys are the response types.  The values are the number 
   of times each response type is used.  This is for the I<entire> problem, not 
   just a single part.
   
 =item * B<multipart>():  =item * B<multipart>():
   
 Returns true if the problem is multipart, false otherwise. Use this instead  Returns true if the problem is multipart, false otherwise. Use this instead
Line 3946  sub countParts { Line 3994  sub countParts {
     return scalar(@{$parts}); # + $delta;      return scalar(@{$parts}); # + $delta;
 }  }
   
   sub countResponses {
       my $self = shift;
       my $count;
       foreach my $part (@{$self->parts()}) {
           $count+= scalar($self->responseIds($part));
       }
       return $count;
   }
   
   sub responseTypes {
       my $self = shift;
       my %responses;
       foreach my $part ($self->parts()) {
           foreach my $responsetype ($self->responseType($part)) {
               $responses{$responsetype}++ if (defined($responsetype));
           }
       }
       return %responses;
   }
   
 sub multipart {  sub multipart {
     my $self = shift;      my $self = shift;
     return $self->countParts() > 1;      return $self->countParts() > 1;
Line 4622  sub getNext { Line 4690  sub getNext {
     my $to = $self->to();      my $to = $self->to();
     foreach my $branch ( split(/,/, $to) ) {      foreach my $branch ( split(/,/, $to) ) {
         my $choice = $self->{NAV_MAP}->getById($branch);          my $choice = $self->{NAV_MAP}->getById($branch);
           if (!$choice->condition()) { next; }
         my $next = $choice->goesto();          my $next = $choice->goesto();
         $next = $self->{NAV_MAP}->getById($next);          $next = $self->{NAV_MAP}->getById($next);
   

Removed from v.1.288  
changed lines
  Added in v.1.306


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