Diff for /loncom/interface/lonnavmaps.pm between versions 1.481 and 1.506

version 1.481, 2012/03/05 11:15:37 version 1.506, 2015/04/13 16:46:43
Line 164  If true, the resource's folder will not Line 164  If true, the resource's folder will not
 it. Default is false. True implies printCloseAll is false, since you  it. Default is false. True implies printCloseAll is false, since you
 can't close or open folders when this is on anyhow.  can't close or open folders when this is on anyhow.
   
   =item * B<map_no_edit_link>:
   
   If true, the title of the folder or page will not be followed by an
   icon/link to direct editing of a folder or composite page, originally
   added via the Course Editor.
   
 =back  =back
   
 =item * B<Apache::lonnavmaps::communication_status>:  =item * B<Apache::lonnavmaps::communication_status>:
Line 225  automatically. Line 231  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
Line 484  use POSIX qw (floor strftime); Line 490  use POSIX qw (floor strftime);
 use Time::HiRes qw( gettimeofday tv_interval );  use Time::HiRes qw( gettimeofday tv_interval );
 use LONCAPA;  use LONCAPA;
 use DateTime();  use DateTime();
   use HTML::Entities;
   
 # For debugging  # For debugging
   
 # use Data::Dumper;  #use Data::Dumper;
   
   
 # symbolic constants  # symbolic constants
Line 612  sub getDescription { Line 619  sub getDescription {
         return &mt("Having technical difficulties; please check status later");           return &mt("Having technical difficulties; please check status later"); 
     }      }
     if ($status == $res->NOTHING_SET) {      if ($status == $res->NOTHING_SET) {
         return &Apache::lonhtmlcommon::direct_parm_link(&mt("Not currently assigned.",$res->symb(),'opendate'),$part);          return &Apache::lonhtmlcommon::direct_parm_link(&mt('Not currently assigned'),$res->symb(),'opendate',$part);
     }      }
     if ($status == $res->OPEN_LATER) {      if ($status == $res->OPEN_LATER) {
         return &mt("Open [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($open,'start'),$res->symb(),'opendate',$part));          return &mt("Open [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($open,'start'),$res->symb(),'opendate',$part));
Line 691  sub getDescription { Line 698  sub getDescription {
         my $maxtries = $res->maxtries($part);          my $maxtries = $res->maxtries($part);
         my $triesString = "";          my $triesString = "";
         if ($tries && $maxtries) {          if ($tries && $maxtries) {
             $triesString = '<font size="-1"><i>('.&mt('[_1] of [quant,_2,try,tries] used',$tries,$maxtries).')</i></font>';              $triesString = '<span class="LC_fontsize_medium"><i>('.&mt('[_1] of [quant,_2,try,tries] used',$tries,$maxtries).')</i></span>';
             if ($maxtries > 1 && $maxtries - $tries == 1) {              if ($maxtries > 1 && $maxtries - $tries == 1) {
                 $triesString = "<b>$triesString</b>";                  $triesString = "<b>$triesString</b>";
             }              }
Line 980  sub render_resource { Line 987  sub render_resource {
         }          }
         if ((&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) &&          if ((&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) &&
             ($resource->symb=~/\_\_\_[^\_]+\_\_\_uploaded/)) {              ($resource->symb=~/\_\_\_[^\_]+\_\_\_uploaded/)) {
             my $icon = &Apache::loncommon::lonhttpdurl('/res/adm/pages').'/editmap.png';              if (!$params->{'map_no_edit_link'}) {
             $editmapLink='&nbsp;'.                  my $icon = &Apache::loncommon::lonhttpdurl('/res/adm/pages').'/editmap.png';
                          '<a href="/adm/coursedocs?command=direct&symb='.&escape($resource->symb()).'">'.                  $editmapLink='&nbsp;'.
                            '<a href="/adm/coursedocs?command=directnav&amp;symb='.&escape($resource->symb()).'">'.
                          '<img src="'.$icon.'" alt="'.&mt('Edit Content').'" title="'.&mt('Edit Content').'" />'.                           '<img src="'.$icon.'" alt="'.&mt('Edit Content').'" title="'.&mt('Edit Content').'" />'.
                          '</a>';                           '</a>';
               }
         }          }
     }      }
   
Line 995  sub render_resource { Line 1004  sub render_resource {
         $nonLinkedText .= ' <span class="LC_info">('.&mt('conditionally hidden').')</span> ';          $nonLinkedText .= ' <span class="LC_info">('.&mt('conditionally hidden').')</span> ';
     }      }
     if (($resource->is_practice()) && ($resource->is_raw_problem())) {      if (($resource->is_practice()) && ($resource->is_raw_problem())) {
         $nonLinkedText .=' <font color="green"><b>'.&mt('not graded').'</b></font>';          $nonLinkedText .=' <span class="LC_info"><b>'.&mt('not graded').'</b></span>';
     }      }
   
     # We're done preparing and finally ready to start the rendering      # We're done preparing and finally ready to start the rendering
Line 1039  sub render_resource { Line 1048  sub render_resource {
     }      }
   
     if (!$params->{'resource_nolink'} && !$resource->is_sequence() && !$resource->is_empty_sequence) {      if (!$params->{'resource_nolink'} && !$resource->is_sequence() && !$resource->is_empty_sequence) {
         $result .= "$curMarkerBegin<a href=\"$link\">$title$partLabel</a>$curMarkerEnd$nonLinkedText</td>";          $result .= "$curMarkerBegin<a href=\"$link\">$title$partLabel</a>$curMarkerEnd$editmapLink$nonLinkedText</td>";
     } else {      } else {
         $result .= "$curMarkerBegin$linkopen$title$partLabel</a>$curMarkerEnd$editmapLink$nonLinkedText</td>";          $result .= "$curMarkerBegin$linkopen$title$partLabel</a>$curMarkerEnd$editmapLink$nonLinkedText</td>";
     }      }
Line 1128  sub render_long_status { Line 1137  sub render_long_status {
         $params->{'multipart'} && $part eq "0";          $params->{'multipart'} && $part eq "0";
                                   
     my $color;      my $color;
       my $info = '';
     if ($resource->is_problem() || $resource->is_practice()) {      if ($resource->is_problem() || $resource->is_practice()) {
         $color = $colormap{$resource->status};          $color = $colormap{$resource->status};
           
         if (dueInLessThan24Hours($resource, $part) ||          if (dueInLessThan24Hours($resource, $part)) {
             lastTry($resource, $part)) {  
             $color = $hurryUpColor;              $color = $hurryUpColor;
         }              $info = ' title="'.&mt('Due in less than 24 hours!').'"';
           } elsif (lastTry($resource, $part)) {
               unless (($resource->problemstatus($part) eq 'no') ||
                       ($resource->problemstatus($part) eq 'no_feedback_ever')) {
                   $color = $hurryUpColor;
                   $info = ' title="'.&mt('One try remaining!').'"';
               }
            }
     }      }
           
     if ($resource->kind() eq "res" &&      if ($resource->kind() eq "res" &&
         $resource->is_raw_problem() &&          $resource->is_raw_problem() &&
         !$firstDisplayed) {          !$firstDisplayed) {
         if ($color) {$result .= "<font color=\"$color\"><b>"; }          if ($color) {$result .= '<span style="color:'.$color.'"'.$info.'><b>'; }
         $result .= getDescription($resource, $part);          $result .= getDescription($resource, $part);
         if ($color) {$result .= "</b></font>"; }          if ($color) {$result .= "</b></span>"; }
     }      }
     if ($resource->is_map() && &advancedUser() && $resource->randompick()) {      if ($resource->is_map() && &advancedUser() && $resource->randompick()) {
         $result .= &mt('(randomly select [_1])', $resource->randompick());          $result .= &mt('(randomly select [_1])', $resource->randompick());
Line 1224  sub render_parts_summary_status { Line 1240  sub render_parts_summary_status {
     }      }
     $return.= $td . $totalParts . ' parts: ';      $return.= $td . $totalParts . ' parts: ';
     foreach my $status (@statuses) {      foreach my $status (@statuses) {
  if ($overallstatus{$status}) {          if ($overallstatus{$status}) {
     $return.="<font color='" . $statusColors{$status} .              $return.='<span style="color:' . $statusColors{$status}
  "'>" . $overallstatus{$status} . ' '                     . '">' . $overallstatus{$status} . ' '
  . $statusStrings{$status} . "</font>";                     . $statusStrings{$status} . '</span>';
  }          }
     }      }
     $return.= $endtd;      $return.= $endtd;
     return $return;      return $return;
Line 1398  sub render { Line 1414  sub render {
         }          }
     }      }
   
   
     # (re-)Locate the jump point, if any      # (re-)Locate the jump point, if any
     # Note this does not take filtering or hidden into account... need      # Note this does not take filtering or hidden into account... need
     # to be fixed?      # to be fixed?
Line 1482  sub render { Line 1497  sub render {
       'document.clearbubbles.submit()',        'document.clearbubbles.submit()',
       'Mark all posts read');        'Mark all posts read');
  my $time=time;   my $time=time;
           my $querystr = &HTML::Entities::encode($ENV{'QUERY_STRING'},'<>&"');
  $result .= (<<END);   $result .= (<<END);
     <form name="clearbubbles" method="post" action="/adm/feedback">      <form name="clearbubbles" method="post" action="/adm/feedback">
  <input type="hidden" name="navurl" value="$ENV{'QUERY_STRING'}" />   <input type="hidden" name="navurl" value="$querystr" />
  <input type="hidden" name="navtime" value="$time" />   <input type="hidden" name="navtime" value="$time" />
 END  END
         if ($env{'form.register'}) {          if ($env{'form.register'}) {
Line 1655  END Line 1671  END
     $curRes = shift(@resources);      $curRes = shift(@resources);
  } else {   } else {
     $curRes = $it->next($closeAllPages);      $curRes = $it->next($closeAllPages);
   
  }   }
  if (!$curRes) { last; }   if (!$curRes) { last; }
   
Line 1827  END Line 1842  END
     }      }
  }   }
     }      }
   
       $result.=&Apache::loncommon::end_data_table();
           
     # Print out the part that jumps to #curloc if it exists      # Print out the part that jumps to #curloc if it exists
     # delay needed because the browser is processing the jump before      # delay needed because the browser is processing the jump before
Line 1843  if (location.href.indexOf('#curloc')==-1 Line 1860  if (location.href.indexOf('#curloc')==-1
 ");  ");
     }      }
   
     $result.=&Apache::loncommon::end_data_table();  
   
     if ($r) {      if ($r) {
         $r->print($result);          $r->print($result);
         $result = "";          $result = "";
Line 1875  sub show_linkitems_toolbar { Line 1890  sub show_linkitems_toolbar {
                           '<td class="LC_middle">'.&mt('Tools:').'</td>';                            '<td class="LC_middle">'.&mt('Tools:').'</td>';
             }              }
             $result .= '<td align="left">'."\n".              $result .= '<td align="left">'."\n".
                        '<span class="LC_nobreak">'."\n".  
                        '<ul id="LC_toolbar">';                         '<ul id="LC_toolbar">';
             my @linkorder = ('firsthomework','everything','uncompleted',              my @linkorder = ('firsthomework','everything','uncompleted',
                              'changefolder','clearbubbles','edittoplevel');                               'changefolder','clearbubbles','edittoplevel');
Line 1903  sub show_linkitems_toolbar { Line 1917  sub show_linkitems_toolbar {
                 }                  }
             }              }
             $result .= '</ul>'.              $result .= '</ul>'.
                        '</span></td>';                         '</td>';
             if (($numlinks==1) && (exists($args->{'linkitems'}{'edittoplevel'}))) {              if (($numlinks==1) && (exists($args->{'linkitems'}{'edittoplevel'}))) {
                 $result .= '<td><a href="'.$args->{'linkitems'}{'edittoplevel'}{'cmd'}.'">'.                  $result .= '<td><a href="'.$args->{'linkitems'}{'edittoplevel'}{'cmd'}.'">'.
                            &mt('Content Editor').'</a></td>';                             &mt('Content Editor').'</a></td>';
Line 2006  sub new { Line 2020  sub new {
     my $proto = shift;      my $proto = shift;
     my $class = ref($proto) || $proto;      my $class = ref($proto) || $proto;
     my $self = {};      my $self = {};
     bless($self); # So we can call change_user if neceesary      bless($self); # So we can call change_user if necessary
   
     $self->{USERNAME} = shift || $env{'user.name'};      $self->{USERNAME} = shift || $env{'user.name'};
     $self->{DOMAIN}   = shift || $env{'user.domain'};      $self->{DOMAIN}   = shift || $env{'user.domain'};
       $self->{CODE}     = shift;
       $self->{NOHIDE} = shift;
   
   
   
Line 2023  sub new { Line 2039  sub new {
   
     # We can only tie the nav hash as done below if the username/domain      # We can only tie the nav hash as done below if the username/domain
     # match the env one. Otherwise change_user does everything we need...since we can't      # match the env one. Otherwise change_user does everything we need...since we can't
     # assume there are course hashes for the specific requested user@domamin:      # assume there are course hashes for the specific requested user:domain
       # Note: change_user is also called if we need the nav hash when printing CODEd 
       # assignments or printing an exam, in which the enclosing folder for the items in
       # the exam has hidden set.
     #      #
   
     if ( ($self->{USERNAME} eq $env{'user.name'}) && ($self->{DOMAIN} eq $env{'user.domain'})) {      if (($self->{USERNAME} eq $env{'user.name'}) && ($self->{DOMAIN} eq $env{'user.domain'}) &&
            !$self->{CODE} && !$self->{NOHIDE}) {
   
  # tie the nav hash   # tie the nav hash
   
Line 2049  sub new { Line 2069  sub new {
  $self->{PARM_HASH} = \%parmhash;   $self->{PARM_HASH} = \%parmhash;
  $self->{PARM_CACHE} = {};   $self->{PARM_CACHE} = {};
     } else {      } else {
  $self->change_user($self->{USERNAME}, $self->{DOMAIN});   $self->change_user($self->{USERNAME}, $self->{DOMAIN},  $self->{CODE}, $self->{NOHIDE});
     }      }
   
     my $d = Data::Dumper->new([$self]);  
   
     return $self;      return $self;
 }  }
   
Line 2064  sub new { Line 2082  sub new {
 # Parameters:  # Parameters:
 #    user  - New user.  #    user  - New user.
 #    domain- Domain the user belongs to.  #    domain- Domain the user belongs to.
   #    code  - Anonymous CODE in use.
 # Implicit inputs:  # Implicit inputs:
 #     #   
 sub change_user {  sub change_user {
     my $self = shift;      my $self = shift;
     $self->{USERNAME} = shift;      $self->{USERNAME} = shift;
     $self->{DOMAIN}   = shift;      $self->{DOMAIN}   = shift;
       $self->{CODE}     = shift;
       $self->{NOHIDE}   = shift;
   
     # If the hashes are already tied make sure to break that bond:      # If the hashes are already tied make sure to break that bond:
   
Line 2085  sub change_user { Line 2106  sub change_user {
     my ($cdom, $cnum) = split(/\_/, $env{'request.course.id'});      my ($cdom, $cnum) = split(/\_/, $env{'request.course.id'});
   
     my %big_hash;      my %big_hash;
     &Apache::lonmap::loadmap($cnum, $cdom, $self->{USERNAME}, $self->{DOMAIN}, \%big_hash);      &Apache::lonmap::loadmap($cnum, $cdom, $self->{USERNAME}, $self->{DOMAIN}, $self->{CODE}, $self->{NOHIDE}, \%big_hash);
     $self->{NAV_HASH} = \%big_hash;      $self->{NAV_HASH} = \%big_hash;
   
   
Line 2096  sub change_user { Line 2117  sub change_user {
     $self->{PARM_CACHE} = {};      $self->{PARM_CACHE} = {};
           
     my %parm_hash = {};      my %parm_hash = {};
     foreach my $key (keys %big_hash) {      foreach my $key (keys(%big_hash)) {
  if ($key =~ /^param\./) {   if ($key =~ /^param\./) {
     my $param_key = $key;      my $param_key = $key;
     $param_key =~ s/^param\.//;      $param_key =~ s/^param\.//;
Line 2105  sub change_user { Line 2126  sub change_user {
     }      }
   
     $self->{PARM_HASH} = \%parm_hash;      $self->{PARM_HASH} = \%parm_hash;
      
   
   
       }
 }   
   
 sub generate_course_user_opt {  sub generate_course_user_opt {
     my $self = shift;      my $self = shift;
Line 2151  sub generate_course_user_opt { Line 2169  sub generate_course_user_opt {
     return;      return;
 }  }
   
   
   
 sub generate_email_discuss_status {  sub generate_email_discuss_status {
     my $self = shift;      my $self = shift;
     my $symb = shift;      my $symb = shift;
Line 2170  sub generate_email_discuss_status { Line 2190  sub generate_email_discuss_status {
     my %lastread = &Apache::lonnet::dump('nohist_'.$cid.'_discuss',      my %lastread = &Apache::lonnet::dump('nohist_'.$cid.'_discuss',
                                         $self->{DOMAIN},$self->{USERNAME},'lastread');                                          $self->{DOMAIN},$self->{USERNAME},'lastread');
     my %lastreadtime = ();      my %lastreadtime = ();
     foreach my $key (keys %lastread) {      foreach my $key (keys(%lastread)) {
         my $shortkey = $key;          my $shortkey = $key;
         $shortkey =~ s/_lastread$//;          $shortkey =~ s/_lastread$//;
         $lastreadtime{$shortkey} = $lastread{$key};          $lastreadtime{$shortkey} = $lastread{$key};
Line 2564  sub parmval { Line 2584  sub parmval {
     return $result->[0];      return $result->[0];
 }  }
   
   
 sub parmval_real {  sub parmval_real {
     my $self = shift;      my $self = shift;
     my ($what,$symb,$recurse) = @_;      my ($what,$symb,$recurse) = @_;
   
   
     # 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();
   
Line 2596  sub parmval_real { Line 2618  sub parmval_real {
     my $mapparm=$mapname.'___(all).'.$what;      my $mapparm=$mapname.'___(all).'.$what;
     my $usercourseprefix=$cid;      my $usercourseprefix=$cid;
   
   
   
     my $grplevel=$usercourseprefix.'.['.$cgroup.'].'.$what;      my $grplevel=$usercourseprefix.'.['.$cgroup.'].'.$what;
     my $grplevelr=$usercourseprefix.'.['.$cgroup.'].'.$symbparm;      my $grplevelr=$usercourseprefix.'.['.$cgroup.'].'.$symbparm;
     my $grplevelm=$usercourseprefix.'.['.$cgroup.'].'.$mapparm;      my $grplevelm=$usercourseprefix.'.['.$cgroup.'].'.$mapparm;
   
   
     my $seclevel= $usercourseprefix.'.['.$csec.'].'.$what;      my $seclevel= $usercourseprefix.'.['.$csec.'].'.$what;
     my $seclevelr=$usercourseprefix.'.['.$csec.'].'.$symbparm;      my $seclevelr=$usercourseprefix.'.['.$csec.'].'.$symbparm;
     my $seclevelm=$usercourseprefix.'.['.$csec.'].'.$mapparm;      my $seclevelm=$usercourseprefix.'.['.$csec.'].'.$mapparm;
   
   
     my $courselevel= $usercourseprefix.'.'.$what;      my $courselevel= $usercourseprefix.'.'.$what;
     my $courselevelr=$usercourseprefix.'.'.$symbparm;      my $courselevelr=$usercourseprefix.'.'.$symbparm;
     my $courselevelm=$usercourseprefix.'.'.$mapparm;      my $courselevelm=$usercourseprefix.'.'.$mapparm;
   
   
     my $useropt = $self->{USER_OPT};      my $useropt = $self->{USER_OPT};
     my $courseopt = $self->{COURSE_OPT};      my $courseopt = $self->{COURSE_OPT};
     my $parmhash = $self->{PARM_HASH};      my $parmhash = $self->{PARM_HASH};
Line 2674  sub parmval_real { Line 2701  sub parmval_real {
     if (defined($pack_def)) { return [$pack_def,'resource']; }      if (defined($pack_def)) { return [$pack_def,'resource']; }
     return [''];      return [''];
 }  }
   #
   #  Determines the open/close dates for printing a map that
   #  encloses a resource.
   #
   sub map_printdates {
       my ($self, $res, $part) = @_;
   
   
   
   
   
       my $opendate = $self->get_mapparam($res->symb(), "$part.printstartdate");
       my $closedate= $self->get_mapparam($res->symb(), "$part.printenddate");
   
   
       return ($opendate, $closedate);
   }
   
   sub get_mapparam {
       my ($self, $symb, $what) = @_;
   
       # Ensure the course option hash is populated:
   
       $self->generate_course_user_opt();
   
       # Get the course id and section if there is one.
   
       my $cid=$env{'request.course.id'};
       my $csec=$env{'request.course.sec'};
       my $cgroup='';
       my @cgrps=split(/:/,$env{'request.course.groups'});
       if (@cgrps > 0) {
           @cgrps = sort(@cgrps);
           $cgroup = $cgrps[0];
       } 
       my $uname=$self->{USERNAME};
       my $udom=$self->{DOMAIN};
   
       unless ($symb) { return ['']; }
       my $result='';
   
   
       # Figure out which map we are in.
   
       my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb);
       $mapname = &Apache::lonnet::deversion($mapname);
   
   
       my $rwhat=$what;
       $what=~s/^parameter\_//;
       $what=~s/\_/\./;
   
       # Build the hash keys for the lookup:
   
       my $symbparm=$symb.'.'.$what;
       my $mapparm=$mapname.'___(all).'.$what;
       my $usercourseprefix=$cid;
   
   
       my $grplevel    = "$usercourseprefix.[$cgroup].$mapparm";
       my $seclevel    = "$usercourseprefix.[$csec].$mapparm";
       my $courselevel = "$usercourseprefix.$mapparm";
   
   
       # Get handy references to the hashes we need in $self:
   
       my $useropt = $self->{USER_OPT};
       my $courseopt = $self->{COURSE_OPT};
       my $parmhash = $self->{PARM_HASH};
   
       # Check per user 
   
   
   
       if ($uname and defined($useropt)) {
    if (defined($$useropt{$courselevel})) {
       return $$useropt{$courselevel};
    }
       }
   
       # Check course -- group
   
   
   
       if ($cgroup ne '' and defined ($courseopt)) {
    if (defined($$courseopt{$grplevel})) {
       return $$courseopt{$grplevel};
    }
       }
   
       # Check course -- section
   
   
   
   
   
       if ($csec and defined($courseopt)) {
    if (defined($$courseopt{$seclevel})) {
       return $$courseopt{$seclevel};
    }
       }
       # Check the map parameters themselves:
   
       my $thisparm = $$parmhash{$symbparm};
       if (defined($thisparm)) {
    return $thisparm;
       }
   
   
       # Additional course parameters:
   
       if (defined($courseopt)) {
    if (defined($$courseopt{$courselevel})) {
       return $$courseopt{$courselevel};
    }
       }
       return undef; # Unefined if we got here.
   }
   
   sub course_printdates {
       my ($self, $symb,  $part) = @_;
   
   
       my $opendate  = $self->getcourseparam($symb, $part . '.printstartdate');
       my $closedate = $self->getcourseparam($symb, $part . '.printenddate');
       return ($opendate, $closedate);
   
   }
   
   sub getcourseparam {
       my ($self, $symb, $what) = @_;
   
       $self->generate_course_user_opt(); # If necessary populate the hashes.
   
       my $uname = $self->{USERNAME};
       my $udom  = $self->{DOMAIN};
       
       # Course, section, group ids come from the env:
   
       my $cid   = $env{'request.course.id'};
       my $csec  = $env{'request.course.sec'};
       my $cgroup = ''; # Assume no group
   
       my @cgroups = split(/:/, $env{'request.course.groups'});
       if(@cgroups > 0) {
    @cgroups = sort(@cgroups);
    $cgroup  = $cgroups[0]; # There is a course group. 
      }
       my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb);
       $mapname = &Apache::lonnet::deversion($mapname);
   
       #
       # Make the various lookup keys:
       #
   
       $what=~s/^parameter\_//;
       $what=~s/\_/\./;
   
   
       my $symbparm = $symb . '.' . $what;
       my $mapparm=$mapname.'___(all).'.$what;
   
       # Local refs to the hashes we're going to look at:
   
       my $useropt   = $self->{USER_OPT};
       my $courseopt = $self->{COURSE_OPT};
   
       # 
       # We want the course level stuff from the way
       # parmval_real operates 
       # TODO: Fator some of this stuff out of
       # both parmval_real and here
       #
       my $courselevel = $cid . '.' .  $what;
       my $grplevel    = $cid . '.[' . $cgroup   . ']' . $what;
       my $seclevel    = $cid . '.[' . $csec     . ']' . $what;
   
   
       # Try for the user's course level option:
   
       if ($uname and defined($useropt)) {
    if (defined($$useropt{$courselevel})) {
       return $$useropt{$courselevel};
    }
       }
       # Try for the group's course level option:
   
       if ($uname ne '' and defined($courseopt)) {
    if (defined($$courseopt{$grplevel})) {
       return $$courseopt{$grplevel};
    }
       }
   
       #  Try for section level parameters:
   
       if ($csec and defined($courseopt)) {
    if (defined($$courseopt{$seclevel})) {
       return $$courseopt{$seclevel};
    }
       }
       # Try for 'additional' course parameterse:
   
       if (defined($courseopt)) {
    if (defined($$courseopt{$courselevel})) {
       return $$courseopt{$courselevel};
    }
       }
       return undef;
   
   }
   
   
 =pod  =pod
   
Line 2689  resource appears multiple times in the c Line 2927  resource appears multiple times in the c
 will be returned (useful for maps), unless the multiple parameter has  will be returned (useful for maps), unless the multiple parameter has
 been included, in which case all instances are returned in an array.  been included, in which case all instances are returned in an array.
   
 =item * B<retrieveResources>(map, filterFunc, recursive, bailout, showall):  =item * B<retrieveResources>(map, filterFunc, recursive, bailout, showall, noblockcheck):
   
 The map is a specification of a map to retreive the resources from,  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  either as a url or as an object. The filterFunc is a reference to a
Line 2698  true if the resource should be included, Line 2936  true if the resource should be included,
 be. If recursive is true, the map will be recursively examined,  be. If recursive is true, the map will be recursively examined,
 otherwise it will not be. If bailout is true, the function will return  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. If showall is  as soon as it finds a resource, if false it will finish. If showall is
 true it will not hide maps that contain nothing but one other map. By  true it will not hide maps that contain nothing but one other map. The 
 default, the map is the top-level map of the course, filterFunc is a  noblockcheck arg is propagated to become the sixth arg in the call to
 function that always returns 1, recursive is true, bailout is false,  lonnet::allowed when checking a resource's availability during collection
 showall is false. The resources will be returned in a list containing  of resources using the iterator. noblockcheck needs to be true if 
 the resource objects for the corresponding resources, with B<no  retrieveResources() was called by a routine that itself was called by 
 structure information> in the list; regardless of branching,  lonnet::allowed, in order to avoid recursion.  By default the map  
 recursion, etc., it will be a flat list.  is the top-level map of the course, filterFunc is a function that 
   always returns 1, recursive is true, bailout is false, showall is
   false. The resources will be returned in a list 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,  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  just a list of all resources. It is also suitable for finding out how
Line 2771  sub retrieveResources { Line 3014  sub retrieveResources {
     my $bailout = shift;      my $bailout = shift;
     if (!defined($bailout)) { $bailout = 0; }      if (!defined($bailout)) { $bailout = 0; }
     my $showall = shift;      my $showall = shift;
       my $noblockcheck = shift;
     # Create the necessary iterator.      # Create the necessary iterator.
     if (!ref($map)) { # assume it's a url of a map.      if (!ref($map)) { # assume it's a url of a map.
         $map = $self->getResourceByUrl($map);          $map = $self->getResourceByUrl($map);
Line 2800  sub retrieveResources { Line 3044  sub retrieveResources {
     # Run down the iterator and collect the resources.      # Run down the iterator and collect the resources.
     my $curRes;      my $curRes;
   
     while ($curRes = $it->next()) {      while ($curRes = $it->next(undef,$noblockcheck)) {
         if (ref($curRes)) {          if (ref($curRes)) {
             if (!&$filterFunc($curRes)) {              if (!&$filterFunc($curRes)) {
                 next;                  next;
Line 2951  Note that inside of the loop, it's frequ Line 3195  Note that inside of the loop, it's frequ
 resource objects will be references, and any non-references will   resource objects will be references, and any non-references will 
 be the tokens described above.  be the tokens described above.
   
 Also note there is some old code floating around that trys to track  The next() routine can take two (optional) arguments:
   closeAllPages - if true will not recurse down a .page
   noblockcheck - passed to browsePriv() for passing as sixth arg to
   call to lonnet::allowed. This needs to be set if retrieveResources
   was already called from another routine called within lonnet::allowed, 
   so as to prevent recursion.
   
   Also note there is some old code floating around that tries to track
 the depth of the iterator to see when it's done; do not copy that   the depth of the iterator to see when it's done; do not copy that 
 code. It is difficult to get right and harder to understand than  code. It is difficult to get right and harder to understand than
 this. They should be migrated to this new style.  this. They should be migrated to this new style.
Line 3098  sub new { Line 3349  sub new {
     if ($resourceCount == 1 && $resource->is_sequence() && !$self->{FORCE_TOP}) {       if ($resourceCount == 1 && $resource->is_sequence() && !$self->{FORCE_TOP}) { 
         my $firstResource = $resource->map_start();          my $firstResource = $resource->map_start();
         my $finishResource = $resource->map_finish();          my $finishResource = $resource->map_finish();
  my $result;   return Apache::lonnavmaps::iterator->new($self->{NAV_MAP}, $firstResource,
  my $rdump  = Data::Dumper->new([$result]);   $finishResource, $self->{FILTER},
  $result =  Apache::lonnavmaps::iterator->new($self->{NAV_MAP}, $firstResource,   $self->{ALREADY_SEEN}, 
      $finishResource, $self->{FILTER},   $self->{CONDITION},
      $self->{ALREADY_SEEN},    $self->{FORCE_TOP});
      $self->{CONDITION},  
      $self->{FORCE_TOP});  
  return $result;  
              
           
     }      }
   
     # Set up some bookkeeping information.      # Set up some bookkeeping information.
Line 3126  sub new { Line 3372  sub new {
     $self->{ALREADY_SEEN}->{$self->{FIRST_RESOURCE}->{ID}} = 1;      $self->{ALREADY_SEEN}->{$self->{FIRST_RESOURCE}->{ID}} = 1;
   
     bless ($self);      bless ($self);
     my $selfDump = Data::Dumper->new([$self]);  
   
     return $self;      return $self;
 }  }
   
 sub next {  sub next {
     my $self = shift;      my $self = shift;
     my $closeAllPages=shift;      my $closeAllPages=shift;
       my $noblockcheck = shift;
     if ($self->{FINISHED}) {      if ($self->{FINISHED}) {
  return END_ITERATOR();   return END_ITERATOR();
     }      }
Line 3143  sub next { Line 3388  sub next {
     if ($self->{RETURN_0} && !$self->{HAVE_RETURNED_0}) {      if ($self->{RETURN_0} && !$self->{HAVE_RETURNED_0}) {
         $self->{HAVE_RETURNED_0} = 1;          $self->{HAVE_RETURNED_0} = 1;
  my $nextTopLevel = $self->{NAV_MAP}->getById('0.0');   my $nextTopLevel = $self->{NAV_MAP}->getById('0.0');
   
         return $self->{NAV_MAP}->getById('0.0');          return $self->{NAV_MAP}->getById('0.0');
     }      }
     if ($self->{RETURN_0} && !$self->{HAVE_RETURNED_0_BEGIN_MAP}) {      if ($self->{RETURN_0} && !$self->{HAVE_RETURNED_0_BEGIN_MAP}) {
Line 3169  sub next { Line 3413  sub next {
     if (defined($self->{FORCE_NEXT})) {      if (defined($self->{FORCE_NEXT})) {
         my $tmp = $self->{FORCE_NEXT};          my $tmp = $self->{FORCE_NEXT};
         $self->{FORCE_NEXT} = undef;          $self->{FORCE_NEXT} = undef;
   
         return $tmp;          return $tmp;
     }      }
   
Line 3285  sub next { Line 3528  sub next {
     # If this is a blank resource, don't actually return it.      # If this is a blank resource, don't actually return it.
     # Should you ever find you need it, make sure to add an option to the code      # Should you ever find you need it, make sure to add an option to the code
     #  that you can use; other things depend on this behavior.      #  that you can use; other things depend on this behavior.
     my $browsePriv = $self->{HERE}->browsePriv();      my $browsePriv = $self->{HERE}->browsePriv($noblockcheck);
     if (!$self->{HERE}->src() ||       if (!$self->{HERE}->src() || 
         (!($browsePriv eq 'F') && !($browsePriv eq '2')) ) {          (!($browsePriv eq 'F') && !($browsePriv eq '2')) ) {
         return $self->next($closeAllPages);          return $self->next($closeAllPages);
     }      }
   
     my $hereResource = $self->{HERE};  
   
     return $self->{HERE};      return $self->{HERE};
   
 }  }
Line 3459  sub next { Line 3700  sub next {
     my $nextUnfiltered;      my $nextUnfiltered;
     if ($self->{DIRECTION} == FORWARD()) {      if ($self->{DIRECTION} == FORWARD()) {
         $nextUnfiltered = $self->{HERE}->getNext();          $nextUnfiltered = $self->{HERE}->getNext();
   
     } else {      } else {
         $nextUnfiltered = $self->{HERE}->getPrevious();          $nextUnfiltered = $self->{HERE}->getPrevious();
     }      }
Line 4012  resource of the map. Line 4252  resource of the map.
   
 Returns a string with the type of the map in it.  Returns a string with the type of the map in it.
   
 =item *B<map_hierarchy>:  =item * B<map_hierarchy>:
   
 Returns a string with a comma-separated ordered list of map_pc IDs  Returns a string with a comma-separated ordered list of map_pc IDs
 for the hierarchy of maps containing a map, with the top level  for the hierarchy of maps containing a map, with the top level
Line 4083  their code.) Line 4323  their code.)
   
 =over 4  =over 4
   
   
 =item * B<printable>  =item * B<printable>
   
 returns true if the current date is such that the   returns true if the current date is such that the 
 specified resource part is printable.  specified resource part is printable.
   
   
 =item * B<resprintable>  =item * B<resprintable>
   
 Returns true if all parts in the resource are printable making the  Returns true if all parts in the resource are printable making the
Line 4146  Get the weight for the problem. Line 4388  Get the weight for the problem.
   
 =cut  =cut
   
 sub printable {  
   
     my ($self, $part) = @_;  
   
     # Get the print open/close dates for the resource.  
   
     my $start = $self->parmval("prinstartdate", $part);  sub printable {
     my $end   = $self->parmval("printenddate", $part);  
       my ($self, $part) = @_;
   
     #  The following cases apply:      #  The following cases apply:
     #  - No dates set: Printable.      #  - If a start date is not set, it is replaced by the open date.
       #  - Ditto for start/open replaced by content open.
       #  - If neither start nor printdates are set the part is printable.
     #  - Start date set but no end date: Printable if now >= start date.      #  - Start date set but no end date: Printable if now >= start date.
     #  - End date set but no start date: Printable if now <= end date.      #  - End date set but no start date: Printable if now <= end date.
     #  - both defined: printable if start <= now <= end      #  - both defined: printable if start <= now <= end
     #      #
   
       # Get the print open/close dates for the resource.
   
       my $start = $self->parmval("printstartdate", $part);
       my $end   = $self->parmval("printenddate", $part);
   
       if (!$start) {
    $start = $self->parmval("opendate", $part);
       }
       if (!$start) {
    $start = $self->parmval("contentopen", $part);
       }
   
   
     my $now  = time();      my $now  = time();
   
   
     my $startok = 1;      my $startok = 1;
     my $endok   = 1;      my $endok   = 1;
   
Line 4183  sub resprintable { Line 4440  sub resprintable {
     my $partsref = $self->parts();      my $partsref = $self->parts();
     my @parts    = @$partsref;      my @parts    = @$partsref;
   
     if ((!defined(@parts)) || (scalar(@parts) == 0)) {      if (!@parts) {
  return $self->printable(0);   return $self->printable(0);
     } else {      } else {
  foreach my $part  (@parts) {   foreach my $part  (@parts) {
Line 4631  sub extractParts { Line 4888  sub extractParts {
     }      }
  }   }
     }      }
     my @sortedParts = sort keys %parts;      my @sortedParts = sort(keys(%parts));
     $self->{PARTS} = \@sortedParts;      $self->{PARTS} = \@sortedParts;
         }          }
                   
Line 4652  sub extractParts { Line 4909  sub extractParts {
         # So we have to use our knowlege of part names to figure out           # So we have to use our knowlege of part names to figure out 
         # where the part names begin and end, and even then, it is possible          # where the part names begin and end, and even then, it is possible
         # to construct ambiguous situations.          # to construct ambiguous situations.
         foreach my $data (split /,/, $metadata) {          foreach my $data (split(/,/, $metadata)) {
             if ($data =~ /^([a-zA-Z]+)response_(.*)/              if ($data =~ /^([a-zA-Z]+)response_(.*)/
  || $data =~ /^(Task)_(.*)/) {   || $data =~ /^(Task)_(.*)/) {
                 my $responseType = $1;                  my $responseType = $1;
                 my $partStuff = $2;                  my $partStuff = $2;
                 my $partIdSoFar = '';                  my $partIdSoFar = '';
                 my @partChunks = split /_/, $partStuff;                  my @partChunks = split(/_/, $partStuff);
                 my $i = 0;                  my $i = 0;
                 for ($i = 0; $i < scalar(@partChunks); $i++) {                  for ($i = 0; $i < scalar(@partChunks); $i++) {
                     if ($partIdSoFar) { $partIdSoFar .= '_'; }                      if ($partIdSoFar) { $partIdSoFar .= '_'; }
Line 5159  sub check_for_slot { Line 5416  sub check_for_slot {
                         } else {                          } else {
                             if ($ip ne '') {                              if ($ip ne '') {
                                 if (!&Apache::loncommon::check_ip_acc($ip)) {                                  if (!&Apache::loncommon::check_ip_acc($ip)) {
                                     return (RESERVED_LOCATION,$ip,$slot_name);                                      return (RESERVED_LOCATION,$end,$slot_name);
                                 }                                  }
                             }                              }
                             my @proctors;                              my @proctors;
Line 5402  sub getPrevious { Line 5659  sub getPrevious {
     my $self = shift;      my $self = shift;
     my @branches;      my @branches;
     my $from = $self->from();      my $from = $self->from();
     foreach my $branch ( split /,/, $from) {      foreach my $branch ( split(/,/, $from)) {
         my $choice = $self->{NAV_MAP}->getById($branch);          my $choice = $self->{NAV_MAP}->getById($branch);
         my $prev = $choice->comesfrom();          my $prev = $choice->comesfrom();
         $prev = $self->{NAV_MAP}->getById($prev);          $prev = $self->{NAV_MAP}->getById($prev);
Line 5414  sub getPrevious { Line 5671  sub getPrevious {
   
 sub browsePriv {  sub browsePriv {
     my $self = shift;      my $self = shift;
       my $noblockcheck = shift;
     if (defined($self->{BROWSE_PRIV})) {      if (defined($self->{BROWSE_PRIV})) {
         return $self->{BROWSE_PRIV};          return $self->{BROWSE_PRIV};
     }      }
   
     $self->{BROWSE_PRIV} = &Apache::lonnet::allowed('bre',$self->src(),      $self->{BROWSE_PRIV} = &Apache::lonnet::allowed('bre',$self->src(),
     $self->symb());      $self->symb(),undef,
                                                       undef,$noblockcheck);
 }  }
   
 =pod  =pod

Removed from v.1.481  
changed lines
  Added in v.1.506


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