Diff for /loncom/interface/lonnavmaps.pm between versions 1.509.2.14.2.7 and 1.509.2.17

version 1.509.2.14.2.7, 2023/01/20 22:51:11 version 1.509.2.17, 2024/07/03 03:07:58
Line 534  my %colormap = Line 534  my %colormap =
       $resObj->EXCUSED                => '#3333FF',        $resObj->EXCUSED                => '#3333FF',
       $resObj->PAST_DUE_ANSWER_LATER  => '',        $resObj->PAST_DUE_ANSWER_LATER  => '',
       $resObj->PAST_DUE_NO_ANSWER     => '',        $resObj->PAST_DUE_NO_ANSWER     => '',
         $resObj->PAST_DUE_ATMPT_ANS     => '',
         $resObj->PAST_DUE_ATMPT_NOANS   => '',
         $resObj->PAST_DUE_NO_ATMT_ANS   => '',
         $resObj->PAST_DUE_NO_ATMT_NOANS => '',
       $resObj->ANSWER_OPEN            => '#006600',        $resObj->ANSWER_OPEN            => '#006600',
       $resObj->OPEN_LATER             => '',        $resObj->OPEN_LATER             => '',
       $resObj->TRIES_LEFT             => '',        $resObj->TRIES_LEFT             => '',
Line 679  sub getDescription { Line 683  sub getDescription {
             return &Apache::lonhtmlcommon::direct_parm_link(&mt("Open, no due date"),$res->symb(),'duedate',$part).$slotinfo;              return &Apache::lonhtmlcommon::direct_parm_link(&mt("Open, no due date"),$res->symb(),'duedate',$part).$slotinfo;
         }          }
     }      }
     if ($status == $res->PAST_DUE_ANSWER_LATER) {      if (($status == $res->PAST_DUE_ANSWER_LATER) || ($status == $res->PAST_DUE_ATMPT_ANS) || ($status == $res->PAST_DUE_NO_ATMT_ANS)) {
         return &mt("Answer open [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($answer,'start'),$res->symb(),'answerdate',$part));          return &mt("Answer open [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($answer,'start'),$res->symb(),'answerdate',$part));
     }      }
     if ($status == $res->PAST_DUE_NO_ANSWER) {      if (($status == $res->PAST_DUE_NO_ANSWER) || ($status == $res->PAST_DUE_ATMPT_NOANS) || ($status == $res->PAST_DUE_NO_ATMT_NOANS)) {
  if ($res->is_practice()) {   if ($res->is_practice()) {
     return &mt("Closed [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'start'),$res->symb(),'answerdate,duedate',$part));      return &mt("Closed [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'start'),$res->symb(),'answerdate,duedate',$part));
  } else {   } else {
Line 945  sub render_resource { Line 949  sub render_resource {
     # links to open and close the folder      # links to open and close the folder
   
     my $whitespace = $location.'/whitespace_21.gif';      my $whitespace = $location.'/whitespace_21.gif';
     my ($nomodal,$linkopen,$linkclose);      my $linkopen = "<img src='$whitespace' alt='' />";
     unless ($resource->is_map() || $params->{'resource_nolink'}) {      my $nomodal;
         $linkopen = "<img src='$whitespace' alt='' />";      if (($params->{'modalLink'}) && (!$resource->is_sequence())) {
         $linkclose = "</a>";          if ($link =~m{^(?:|/adm/wrapper)/ext/([^#]+)}) {
         if (($params->{'modalLink'}) && (!$resource->is_sequence())) {              my $exturl = $1;
             if ($link =~m{^(?:|/adm/wrapper)/ext/([^#]+)}) {              if (($ENV{'SERVER_PORT'} == 443) && ($exturl !~ /^https:/)) {
                 my $exturl = $1;  
                 if (($ENV{'SERVER_PORT'} == 443) && ($exturl !~ /^https:/)) {  
                     $nomodal = 1;  
                 }  
             } elsif (($link eq "/public/$LONCAPA::match_domain/$LONCAPA::match_courseid/syllabus") &&  
                      ($env{'request.course.id'}) && ($ENV{'SERVER_PORT'} == 443) &&  
                      ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) {  
                 $nomodal = 1;                  $nomodal = 1;
             }              }
             my $esclink = &js_escape($link);          } elsif (($link eq "/public/$LONCAPA::match_domain/$LONCAPA::match_courseid/syllabus") &&
             if ($nomodal) {                   ($env{'request.course.id'}) && ($ENV{'SERVER_PORT'} == 443) &&
                 $linkopen .= "<a href=\"#\" onclick=\"javascript:window.open('$esclink','resourcepreview','height=400,width=500,scrollbars=1,resizable=1,menubar=0,location=1'); return false;\" />";                   ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) {
             } else {               $nomodal = 1;
                 $linkopen .= "<a href=\"$link\" onclick=\"javascript:openMyModal('$esclink',600,500,'yes','true'); return false;\">";          }
             }          my $esclink = &js_escape($link);
           if ($nomodal) {
               $linkopen .= "<a href=\"#\" onclick=\"javascript:window.open('$esclink','resourcepreview','height=400,width=500,scrollbars=1,resizable=1,menubar=0,location=1'); return false;\" />";
         } else {          } else {
             $linkopen .= "<a href=\"$link\">";              $linkopen .= "<a href=\"$link\" onclick=\"javascript:openMyModal('$esclink',600,500,'yes','true'); return false;\">";
         }          }
       } else {
           $linkopen .= "<a href=\"$link\">";
     }      }
       my $linkclose = "</a>";
   
     # Default icon: unknown page      # Default icon: unknown page
     my $icon = "<img class=\"LC_contentImage\" src='$location/unknown.gif' alt='' />";      my $icon = "<img class=\"LC_contentImage\" src='$location/unknown.gif' alt='' />";
Line 1021  sub render_resource { Line 1023  sub render_resource {
                 '&amp;jump=' .                  '&amp;jump=' .
                 &escape($resource->symb()) .                   &escape($resource->symb()) . 
                 "&amp;folderManip=1\">";                  "&amp;folderManip=1\">";
             $linkclose = '</a>';  
         } else {          } else {
             # Don't allow users to manipulate folder              # Don't allow users to manipulate folder
             $icon = "navmap.$folderType." . ($nowOpen ? 'closed' : 'open') . '.gif';              $icon = "navmap.$folderType." . ($nowOpen ? 'closed' : 'open') . '.gif';
             $icon = "<img class=\"LC_space\" src='$whitespace' alt='' />"."<img class=\"LC_contentImage\" src='$location/$icon' alt=\"".($nowOpen ? &mt('Open Folder') : &mt('Close Folder')).' '.$title."\" />";              $icon = "<img class=\"LC_space\" src='$whitespace' alt='' />"."<img class=\"LC_contentImage\" src='$location/$icon' alt=\"".($nowOpen ? &mt('Open Folder') : &mt('Close Folder')).' '.$title."\" />";
             if ($params->{'caller'} eq 'sequence') {              if ($params->{'caller'} eq 'sequence') {
                 $linkopen = "<a href=\"$link\">";                  $linkopen = "<a href=\"$link\">";
                 $linkclose = '</a>';  
             } else {              } else {
                 $linkopen = "";                  $linkopen = "";
                 $linkclose = "";                  $linkclose = "";
Line 1047  sub render_resource { Line 1048  sub render_resource {
         }          }
         if ($params->{'mapHidden'} || $resource->randomout()) {          if ($params->{'mapHidden'} || $resource->randomout()) {
             $nonLinkedText .= ' <span class="LC_warning">('.&mt('hidden').')</span> ';              $nonLinkedText .= ' <span class="LC_warning">('.&mt('hidden').')</span> ';
         } elsif ($params->{'mapUnlisted'}) {  
             $nonLinkedText .= ' <span class="LC_warning">('.&mt('unlisted').')</span> ';  
         } elsif ($params->{'mapHiddenDeepLink'} || $resource->deeplinkout()) {  
             $nonLinkedText .= ' <span class="LC_warning">('.&mt('not shown').')</span> ';  
         }          }
     } else {      } else {
         if ($resource->randomout()) {          if ($resource->randomout()) {
             $nonLinkedText .= ' <span class="LC_warning">('.&mt('hidden').')</span> ';              $nonLinkedText .= ' <span class="LC_warning">('.&mt('hidden').')</span> ';
         } elsif ($resource->deeplinkout()) {  
             $nonLinkedText .= ' <span class="LC_warning">('.&mt('not shown').')</span> ';  
         } else {  
             my $deeplink = $resource->deeplink($params->{caller});  
             if ((($deeplink eq 'absent') || ($deeplink eq 'grades')) &&  
                   &advancedUser()) {  
                 $nonLinkedText .= ' <span class="LC_warning">('.&mt('unlisted').')</span> ';  
             } elsif (($deeplink) && ($deeplink) ne 'full') {  
                 if (&advancedUser()) {  
                     $nonLinkedText .= ' <span class="LC_warning">('.&mt('deep-link access').  
                                       ')</span> ';  
                 } else {  
                     $nonLinkedText .= ' <span class="LC_warning">('.&mt('access via external site').  
                                       ')</span> ';  
                 }  
             }  
         }          }
     }      }
     if (!$resource->condval()) {      if (!$resource->condval()) {
Line 1395  sub render { Line 1376  sub render {
         # an infinite loop          # an infinite loop
         my $oldFilterFunc = $filterFunc;          my $oldFilterFunc = $filterFunc;
         $filterFunc = sub { my $res = shift; return !$res->randomout() &&           $filterFunc = sub { my $res = shift; return !$res->randomout() && 
                                 ($res->deeplink($args->{'caller'}) ne 'absent') &&  
                                 ($res->deeplink($args->{'caller'}) ne 'grades') &&  
                                 !$res->deeplinkout() &&  
                                 &$oldFilterFunc($res);};                                  &$oldFilterFunc($res);};
     }      }
   
     my $condition = 0;      my $condition = 0;
     if ($env{'form.condition'}) {      if ($env{'form.condition'}) {
         $condition = 1;          $condition = 1;
     } elsif (($env{'request.deeplink.login'}) && ($env{'request.course.id'}) && (!$userCanSeeHidden)) {  
         if (!defined($navmap)) {  
             $navmap = Apache::lonnavmaps::navmap->new();  
         }  
         if (defined($navmap)) {  
             my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};  
             my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};  
             my $symb = &Apache::loncommon::symb_from_tinyurl($env{'request.deeplink.login'},$cnum,$cdom);  
             if ($symb) {  
                 my $deeplink;  
                 my $res = $navmap->getBySymb($symb);  
                 if ($res->is_map()) {  
                     my $mapname = &Apache::lonnet::declutter($res->src());  
                     $mapname = &Apache::lonnet::deversion($mapname);  
                     $deeplink = $navmap->get_mapparam(undef,$mapname,"0.deeplink");  
                 } else {  
                     $deeplink = $res->deeplink();  
                 }  
                 if ($deeplink ne '') {  
                     if ((split(/,/,$deeplink))[1] eq 'hide') {  
                         if ($res->is_map()) {  
                             map { $filterHash->{$_} = 1 if $_ } split(/,/,$res->map_hierarchy());  
                         } else {  
                             my $mapurl = (&Apache::lonnet::decode_symb($symb))[0];  
                             my $map = $navmap->getResourceByUrl($mapurl);  
                             map { $filterHash->{$_} = 1 if $_ } split(/,/,$map->map_hierarchy());  
                         }  
                     }  
                 }  
             }  
         }  
     }      }
   
     if (!$env{'form.folderManip'} && !defined($args->{'iterator'}) && !$args->{'nocurrloc'}) {      if (!$env{'form.folderManip'} && !defined($args->{'iterator'})) {
         # Step 1: Check to see if we have a navmap          # Step 1: Check to see if we have a navmap
         if (!defined($navmap)) {          if (!defined($navmap)) {
             $navmap = Apache::lonnavmaps::navmap->new();              $navmap = Apache::lonnavmaps::navmap->new();
Line 1644  END Line 1591  END
  }   }
  $result.='</form>';   $result.='</form>';
     }      }
     if (($args->{'caller'} eq 'navmapsdisplay') && ($env{'request.course.id'})) {      if (($args->{'caller'} eq 'navmapsdisplay') &&
           ((&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) ||
            (&Apache::lonnet::allowed('cev',$env{'request.course.id'})))) {
         my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};          my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
         my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};          my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
         if ($env{'course.'.$env{'request.course.id'}.'.url'} eq          if ($env{'course.'.$env{'request.course.id'}.'.url'} eq 
             "uploaded/$cdom/$cnum/default.sequence") {              "uploaded/$cdom/$cnum/default.sequence") {
             if ((&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) ||              &add_linkitem($args->{'linkitems'},'edittoplevel',
                 (&Apache::lonnet::allowed('cev',$env{'request.course.id'}))) {                            "javascript:gocmd('/adm/coursedocs','editdocs');",
                 &add_linkitem($args->{'linkitems'},'edittoplevel',                            'Content Editor');
                               "javascript:gocmd('/adm/coursedocs','editdocs');",  
                               'Content Editor');  
             }  
             if ($counter) {  
                 &add_linkitem($args->{'linkitems'},'printout',  
                               "javascript:gopost('/adm/printout','/adm/navmaps');",  
                               'Prepare a printable document');  
             }  
         }          }
     }      }
   
Line 1705  END Line 1646  END
     # mark as hidden for users who have $userCanSeeHidden.      # mark as hidden for users who have $userCanSeeHidden.
     # Use DFS for speed, since structure actually doesn't matter,      # Use DFS for speed, since structure actually doesn't matter,
     # except what map has what resources.      # except what map has what resources.
     #  
     # To ensure the "Selected Resources from selected folder in course"  
     # printout generation option will work in sessions launched via a  
     # deep link, the value of $args->{'filterFunc'} included in the  
     # call to lonnavmaps::render() is omitted from the filter function  
     # used with the DFS Iterator when $args->{'caller'} is 'printout'.  
     #  
     # As a result $sequence->{DATA}->{HAS_VISIBLE_CHILDREN} can be  
     # set to 1 for folder(s) which include resources only accessible  
     # for sessions launched via a deep link, when the current session  
     # is of that type.  
   
     my $dfsit = Apache::lonnavmaps::DFSiterator->new($navmap,      my $dfsit = Apache::lonnavmaps::DFSiterator->new($navmap,
                                                      $it->{FIRST_RESOURCE},                                                       $it->{FIRST_RESOURCE},
                                                      $it->{FINISH_RESOURCE},                                                       $it->{FINISH_RESOURCE},
                                                      {}, undef, 1);                                                       {}, undef, 1);
   
     my $dfsFilterFunc;  
     if ($args->{'caller'} eq 'printout') {  
         $dfsFilterFunc = sub { my $res = shift; return !$res->randomout() &&  
                               ($res->deeplink($args->{'caller'}) ne 'absent') &&  
                               ($res->deeplink($args->{'caller'}) ne 'grades') &&  
                               !$res->deeplinkout();};  
     } else {  
         $dfsFilterFunc = $filterFunc;  
     }  
     my $depth = 0;      my $depth = 0;
     $dfsit->next();      $dfsit->next();
     my $curRes = $dfsit->next();      my $curRes = $dfsit->next();
Line 1749  END Line 1670  END
             } elsif ($curRes->src()) {              } elsif ($curRes->src()) {
                 # Not a sequence: if it's filtered, ignore it, otherwise                  # Not a sequence: if it's filtered, ignore it, otherwise
                 # rise up the stack and mark the sequences as having children                  # rise up the stack and mark the sequences as having children
                 if (&$dfsFilterFunc($curRes)) {                  if (&$filterFunc($curRes)) {
                     for my $sequence (@{$dfsit->getStack()}) {                      for my $sequence (@{$dfsit->getStack()}) {
                         next unless ($sequence->is_map());  
                         $sequence->{DATA}->{HAS_VISIBLE_CHILDREN} = 1;                          $sequence->{DATA}->{HAS_VISIBLE_CHILDREN} = 1;
                     }                      }
                 }                  }
Line 1874  END Line 1794  END
   
         # If this is an empty sequence and we're filtering them, continue on          # If this is an empty sequence and we're filtering them, continue on
         $args->{'mapHidden'} = 0;          $args->{'mapHidden'} = 0;
         $args->{'mapUnlisted'} = 0;  
         $args->{'mapHiddenDeepLink'} = 0;  
         if (($curRes->is_map()) && (!$curRes->{DATA}->{HAS_VISIBLE_CHILDREN})) {          if (($curRes->is_map()) && (!$curRes->{DATA}->{HAS_VISIBLE_CHILDREN})) {
             if ($args->{'suppressEmptySequences'}) {              if ($args->{'suppressEmptySequences'}) {
                 next;                  next;
Line 1888  END Line 1806  END
                     } else {                      } else {
                         next;                          next;
                     }                      }
                 } elsif ($curRes->deeplinkout) {  
                     if ($userCanSeeHidden) {  
                         $args->{'mapHiddenDeepLink'} = 1;  
                     } else {  
                         next;  
                     }  
                 } else {  
                     my $deeplink = $navmap->get_mapparam(undef,$mapname,"0.deeplink");  
                     my ($state,$others,$listed) = split(/,/,$deeplink);  
                     if (($listed eq 'absent') || ($listed eq 'grades')) {  
                         if ($userCanSeeHidden) {  
                             $args->{'mapUnlisted'} = 1;  
                         } else {  
                             next;  
                         }  
                     }  
                 }                  }
             }              }
         }          }
Line 1966  END Line 1868  END
     $args->{'condensed'} = 1;      $args->{'condensed'} = 1;
  }   }
             }              }
         }          } 
         # If deep-link parameter is set (and is not set to full) suppress link  
         # unless privileged user, tinyurl used for login resolved to a map, and  
         # the resource is within the map.  
         if ((!$curRes->deeplink($args->{'caller'})) ||  
             ($curRes->deeplink($args->{'caller'}) eq 'full') || &advancedUser()) {  
             $args->{'resource_nolink'} = 0;  
         } else {  
             $args->{'resource_nolink'} = 1;  
         }  
                           
         # 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) {
Line 2128  sub show_linkitems_toolbar { Line 2021  sub show_linkitems_toolbar {
             $result .= '<td align="left">'."\n".              $result .= '<td align="left">'."\n".
                        '<ul id="LC_toolbar">';                         '<ul id="LC_toolbar">';
             my @linkorder = ('firsthomework','everything','uncompleted',              my @linkorder = ('firsthomework','everything','uncompleted',
                              'changefolder','clearbubbles','printout','edittoplevel');                               'changefolder','clearbubbles','edittoplevel');
             foreach my $link (@linkorder) {              foreach my $link (@linkorder) {
                 if (ref($args->{'linkitems'}{$link}) eq 'HASH') {                  if (ref($args->{'linkitems'}{$link}) eq 'HASH') {
                     if ($args->{'linkitems'}{$link}{'text'} ne '') {                      if ($args->{'linkitems'}{$link}{'text'} ne '') {
Line 2541  sub getIterator { Line 2434  sub getIterator {
     my $self = shift;      my $self = shift;
     my $iterator = Apache::lonnavmaps::iterator->new($self, shift, shift,      my $iterator = Apache::lonnavmaps::iterator->new($self, shift, shift,
                                                      shift, undef, shift,                                                       shift, undef, shift,
      shift, shift, shift);       shift, shift);
     return $iterator;      return $iterator;
 }  }
   
Line 3515  getIterator behaves as follows: Line 3408  getIterator behaves as follows:
   
 =over 4  =over 4
   
 =item * B<getIterator>(firstResource, finishResource, filterHash, condition, forceTop, returnTopMap, $deeplinklisted):  =item * B<getIterator>(firstResource, finishResource, filterHash, condition, forceTop, returnTopMap):
   
 All parameters are optional. firstResource is a resource reference  All parameters are optional. firstResource is a resource reference
 corresponding to where the iterator should start. It defaults to  corresponding to where the iterator should start. It defaults to
Line 3532  that is not just a single, 'redirecting' Line 3425  that is not just a single, 'redirecting'
 will return all information, starting with the top-level map,  will return all information, starting with the top-level map,
 regardless of content. returnTopMap, if true (default false), will  regardless of content. returnTopMap, if true (default false), will
 cause the iterator to return the top-level map object (resource 0.0)  cause the iterator to return the top-level map object (resource 0.0)
 before anything else. deeplinklisted if true (default false), will  before anything else.
 check "listed" status of a resource with a deeplink, and unless "absent"  
 will exclude deeplink checking when retrieving the browsePriv from  
 lonnet::allowed().  
   
 Thus, by default, only top-level resources will be shown. Change the  Thus, by default, only top-level resources will be shown. Change the
 condition to a 1 without changing the hash, and all resources will be  condition to a 1 without changing the hash, and all resources will be
Line 3672  sub new { Line 3562  sub new {
     # have we done that yet?      # have we done that yet?
     $self->{HAVE_RETURNED_0} = 0;      $self->{HAVE_RETURNED_0} = 0;
   
     # Do we want to check the "listed" status for a resource for which  
     # deeplinking applies.  
     $self->{DEEPLINKLISTED} = shift;  
   
     # Now, we need to pre-process the map, by walking forward and backward      # Now, we need to pre-process the map, by walking forward and backward
     # over the parts of the map we're going to look at.      # over the parts of the map we're going to look at.
   
Line 3767  sub new { Line 3653  sub new {
  $finishResource, $self->{FILTER},   $finishResource, $self->{FILTER},
  $self->{ALREADY_SEEN},    $self->{ALREADY_SEEN}, 
  $self->{CONDITION},   $self->{CONDITION},
  $self->{FORCE_TOP},   $self->{FORCE_TOP});
                                                  undef,$self->{DEEPLINKLISTED});  
     }      }
   
     # Set up some bookkeeping information.      # Set up some bookkeeping information.
Line 3938  sub next { Line 3823  sub next {
                                               $finishResource, $self->{FILTER},                                                $finishResource, $self->{FILTER},
                                               $self->{ALREADY_SEEN},                                                $self->{ALREADY_SEEN},
       $self->{CONDITION},        $self->{CONDITION},
       $self->{FORCE_TOP},        $self->{FORCE_TOP});
                                               undef,$self->{DEEPLINKLISTED});  
     }      }
   
     # 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($noblockcheck,$self->{DEEPLINKLISTED});      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);
Line 4373  sub from { my $self=shift; return $self- Line 4257  sub from { my $self=shift; return $self-
 sub goesto { my $self=shift; return $self->navHash("goesto_", 1); }  sub goesto { my $self=shift; return $self->navHash("goesto_", 1); }
 sub kind { my $self=shift; return $self->navHash("kind_", 1); }  sub kind { my $self=shift; return $self->navHash("kind_", 1); }
 sub randomout { my $self=shift; return $self->navHash("randomout_", 1); }  sub randomout { my $self=shift; return $self->navHash("randomout_", 1); }
 sub deeplinkout { my $self=shift; return $self->navHash("deeplinkout_", 1); }  
 sub randompick {   sub randompick { 
     my $self = shift;      my $self = shift;
     my $randompick = $self->parmval('randompick');      my $randompick = $self->parmval('randompick');
Line 4634  sub is_task { Line 4517  sub is_task {
   
 sub is_empty_sequence {  sub is_empty_sequence {
     my $self=shift;      my $self=shift;
       my $src = $self->src();
     return !$self->is_page() && $self->navHash("is_map_", 1) && !$self->navHash("map_type_" . $self->map_pc());      return !$self->is_page() && $self->navHash("is_map_", 1) && !$self->navHash("map_type_" . $self->map_pc());
 }  }
   
Line 4954  sub duedate { Line 4838  sub duedate {
     my $date;      my $date;
     my @interval=$self->parmval("interval", $part);      my @interval=$self->parmval("interval", $part);
     my $due_date=$self->parmval("duedate", $part);      my $due_date=$self->parmval("duedate", $part);
     if ($interval[0] =~ /(\d+)/) {      if ($interval[0] =~ /\d+/) {
         my $timelimit = $1;         my $first_access=&Apache::lonnet::get_first_access($interval[1],
         my $first_access=&Apache::lonnet::get_first_access($interval[1],  
                                                           $self->{SYMB});                                                            $self->{SYMB});
  if (defined($first_access)) {   if (defined($first_access)) {
             my $interval = $first_access+$timelimit;             my $interval = $first_access+$interval[0];
     $date = (!$due_date || $interval < $due_date) ? $interval       $date = (!$due_date || $interval < $due_date) ? $interval 
                                                           : $due_date;                                                            : $due_date;
  } else {   } else {
Line 5053  sub slot_control { Line 4936  sub slot_control {
     my $available = $self->parmval("available", $part);       my $available = $self->parmval("available", $part); 
     return ($useslots,$availablestudent,$available);      return ($useslots,$availablestudent,$available);
 }  }
 sub deeplink {  
     my ($self,$caller,$action) = @_;  
     my $deeplink = $self->parmval("deeplink");  
     if ($deeplink) {  
         my ($state,$others,$listed,$scope) = split(/,/,$deeplink);  
         if ($action eq 'getlisted') {  
             return $listed;  
         }  
         if ($env{'request.deeplink.login'}) {  
             my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};  
             my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};  
             my $deeplink_symb = &Apache::loncommon::deeplink_login_symb($cnum,$cdom);  
             if ($deeplink_symb) {  
                 my ($loginmap,$mapname);  
                 if ($deeplink_symb =~ /\.(page|sequence)$/) {  
                     $mapname = $self->enclosing_map_src();  
                     $loginmap = &Apache::lonnet::clutter((&Apache::lonnet::decode_symb($deeplink_symb))[2]);  
                     return if ($mapname eq $loginmap);  
                 } else {  
                     return if ($deeplink_symb eq $self->symb());  
                     if (($scope eq 'map') || ($scope eq 'rec')) {  
                         $mapname = $self->enclosing_map_src();  
                         $loginmap = &Apache::lonnet::clutter((&Apache::lonnet::decode_symb($deeplink_symb))[0]);  
                         return if ($mapname eq $loginmap);  
                     }  
                 }  
                 if ($scope eq 'rec') {  
                     my $map_pc = $self->navHash('map_pc_'.$mapname);  
                     my @recurseup = split(/,/,$self->navHash('map_hierarchy_'.$map_pc));  
                     my $login_pc = $self->navHash('map_pc_'.$loginmap);  
                     return if (grep(/^\Q$login_pc\E$/,@recurseup));  
                 }  
             }  
         }  
         unless (($caller eq 'sequence') || ($state eq 'both')) {  
             return $listed;  
         }  
     }  
     return;  
 }  
   
 # Multiple things need this  # Multiple things need this
 sub getReturnHash {  sub getReturnHash {
Line 5498  The problem will be opened later. Line 5341  The problem will be opened later.
   
 Open and not yet due.  Open and not yet due.
   
   
 =item * B<PAST_DUE_ANSWER_LATER>:  =item * B<PAST_DUE_ANSWER_LATER>:
   
 The due date has passed, but the answer date has not yet arrived.  The due date has passed, but the answer date has not yet arrived.
Line 5511  The due date has passed and there is no Line 5353  The due date has passed and there is no
   
 The answer date is here.  The answer date is here.
   
   =item * B<NOTHING_SET>:
   
   No dates have been set for this problem at all.
   
   =item * B<PAST_DUE_ATMPT_ANS>:
   
   The due date has passed, feedback is suppressed, the problem was attempted, and the answer date has not yet arrived.
   
   =item * B<PAST_DUE_ATMPT_NOANS>:
   
   The due date has passed, feedback is suppressed, the problem was attempted, and there is no answer opening date set.
   
   =item * B<PAST_DUE_NO_ATMT_ANS>:
   
   The due date has passed, feedback is suppressed, the problem was not attempted, and the answer date has not yet arrived.
   
   =item * B<PAST_DUE_NO_ATMT_NOANS>:
   
   The due date has passed, feedback is suppressed, the problem was not attempted, and there is no answer opening date set.
   
 =item * B<NETWORK_FAILURE>:  =item * B<NETWORK_FAILURE>:
   
 The information is unknown due to network failure.  The information is unknown due to network failure.
Line 5526  sub PAST_DUE_NO_ANSWER     { return 2; } Line 5388  sub PAST_DUE_NO_ANSWER     { return 2; }
 sub PAST_DUE_ANSWER_LATER  { return 3; }  sub PAST_DUE_ANSWER_LATER  { return 3; }
 sub ANSWER_OPEN            { return 4; }  sub ANSWER_OPEN            { return 4; }
 sub NOTHING_SET            { return 5; }  sub NOTHING_SET            { return 5; }
   sub PAST_DUE_ATMPT_ANS     { return 6; }
   sub PAST_DUE_ATMPT_NOANS   { return 7; }
   sub PAST_DUE_NO_ATMT_ANS   { return 8; }
   sub PAST_DUE_NO_ATMT_NOANS { return 9; }
 sub NETWORK_FAILURE        { return 100; }  sub NETWORK_FAILURE        { return 100; }
   
 # getDateStatus gets the date status for a given problem part.   # getDateStatus gets the date status for a given problem part. 
Line 5715  set. Line 5581  set.
 The problem is past due, not considered correct, and an answer date in  The problem is past due, not considered correct, and an answer date in
 the future is set.  the future is set.
   
   =item * B<PAST_DUE_ATMPT_ANS>:
   
   The problem is past due, feedback is suppressed, the problem was
   attempted and an answer date in the future is set.
   
   =item * B<PAST_DUE_ATMPT_NOANS>:
   
   The problem is past due, feedback is suppressed, the problem was
   attempted and no answer date is set.
   
   =item * B<PAST_DUE_NO_ATMT_ANS>:
   
   The problem is past due, feedback is suppressed, the problem was
   not attempted and an answer date in the future is set.
   
   =item * B<PAST_DUE_NO_ATMT_NOANS>:
   
   The problem is past due, feedback is suppressed, the problem was
   not attempted and no answer date is set.
   
 =item * B<ANSWER_OPEN>:  =item * B<ANSWER_OPEN>:
   
 The problem is past due, not correct, and the answer is now available.  The problem is past due, not correct, and the answer is now available.
Line 5797  sub status { Line 5683  sub status {
     # There are a few whole rows we can dispose of:      # There are a few whole rows we can dispose of:
     if ($completionStatus == CORRECT ||      if ($completionStatus == CORRECT ||
         $completionStatus == CORRECT_BY_OVERRIDE ) {          $completionStatus == CORRECT_BY_OVERRIDE ) {
  if ( $suppressFeedback ) { return ANSWER_SUBMITTED }   if ( $suppressFeedback ) {
               if ($dateStatus == PAST_DUE_ANSWER_LATER ||
                   $dateStatus == PAST_DUE_NO_ANSWER ) {
                   if ($dateStatus == PAST_DUE_ANSWER_LATER) {
                       return PAST_DUE_ATMPT_ANS;
                   } else {
                       return PAST_DUE_ATMPT_NOANS;
                   }
               } else {
                   return ANSWER_SUBMITTED;
               }
           }
  my $awarded=$self->awarded($part);   my $awarded=$self->awarded($part);
  if ($awarded < 1 && $awarded > 0) {   if ($awarded < 1 && $awarded > 0) {
             return PARTIALLY_CORRECT;              return PARTIALLY_CORRECT;
Line 5836  sub status { Line 5733  sub status {
   
     if ($dateStatus == PAST_DUE_ANSWER_LATER ||      if ($dateStatus == PAST_DUE_ANSWER_LATER ||
         $dateStatus == PAST_DUE_NO_ANSWER ) {          $dateStatus == PAST_DUE_NO_ANSWER ) {
         return $suppressFeedback ? ANSWER_SUBMITTED : $dateStatus;           if ($suppressFeedback) {
               if ($completionStatus == NOT_ATTEMPTED) {
                   if ($dateStatus == PAST_DUE_ANSWER_LATER) {
                       return PAST_DUE_NO_ATMT_ANS;
                   } else {
                       return PAST_DUE_NO_ATMT_NOANS;
                   }
               } else {
                   if ($dateStatus == PAST_DUE_ANSWER_LATER) {
                       return PAST_DUE_ATMPT_ANS;
                   } else {
                       return PAST_DUE_ATMPT_NOANS;
                   }
               }
           } else {
               return $dateStatus;
           }
     }      }
   
     if ($dateStatus == ANSWER_OPEN) {      if ($dateStatus == ANSWER_OPEN) {
Line 6046  my %compositeToSimple = Line 5959  my %compositeToSimple =
       EXCUSED()               => CORRECT,        EXCUSED()               => CORRECT,
       PAST_DUE_NO_ANSWER()    => INCORRECT,        PAST_DUE_NO_ANSWER()    => INCORRECT,
       PAST_DUE_ANSWER_LATER() => INCORRECT,        PAST_DUE_ANSWER_LATER() => INCORRECT,
         PAST_DUE_ATMPT_ANS()    => ATTEMPTED,
         PAST_DUE_ATMPT_NOANS()  => ATTEMPTED,
         PAST_DUE_NO_ATMT_ANS()  => CLOSED,
         PAST_DUE_NO_ATMT_NOANS() => CLOSED,
       ANSWER_OPEN()           => INCORRECT,        ANSWER_OPEN()           => INCORRECT,
       OPEN_LATER()            => CLOSED,        OPEN_LATER()            => CLOSED,
       TRIES_LEFT()            => OPEN,        TRIES_LEFT()            => OPEN,
Line 6224  sub getPrevious { Line 6141  sub getPrevious {
 sub browsePriv {  sub browsePriv {
     my $self = shift;      my $self = shift;
     my $noblockcheck = shift;      my $noblockcheck = shift;
     my $deeplinklisted = shift;  
     if (defined($self->{BROWSE_PRIV})) {      if (defined($self->{BROWSE_PRIV})) {
         return $self->{BROWSE_PRIV};          return $self->{BROWSE_PRIV};
     }      }
     my ($nodeeplinkcheck,$nodeeplinkout);  
     if ($deeplinklisted) {  
         my $deeplink = $self->deeplink(undef,'getlisted');  
         if (($deeplink) && ($deeplink ne 'absent')) {  
             $nodeeplinkcheck = 1;  
         }  
         $nodeeplinkout = 1;  
     }  
     $self->{BROWSE_PRIV} = &Apache::lonnet::allowed('bre',$self->src(),      $self->{BROWSE_PRIV} = &Apache::lonnet::allowed('bre',$self->src(),
     $self->{SYMB},undef,      $self->{SYMB},undef,
                                                     undef,$noblockcheck,                                                      undef,$noblockcheck);
                                                     undef,$nodeeplinkcheck,  
                                                     $nodeeplinkout);  
 }  }
   
 =pod  =pod

Removed from v.1.509.2.14.2.7  
changed lines
  Added in v.1.509.2.17


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