--- loncom/interface/lonnavmaps.pm 2010/02/10 16:45:31 1.423.2.3 +++ loncom/interface/lonnavmaps.pm 2011/03/14 15:48:00 1.458 @@ -1,7 +1,8 @@ # The LearningOnline Network with CAPA # Navigate Maps Handler # -# $Id: lonnavmaps.pm,v 1.423.2.3 2010/02/10 16:45:31 raeburn Exp $ +# $Id: lonnavmaps.pm,v 1.458 2011/03/14 15:48:00 bisitz Exp $ + # # Copyright Michigan State University Board of Trustees # @@ -477,6 +478,7 @@ use Apache::loncommon(); use Apache::lonenc(); use Apache::lonlocal; use Apache::lonnet; + use POSIX qw (floor strftime); use Time::HiRes qw( gettimeofday tv_interval ); use LONCAPA; @@ -491,7 +493,7 @@ sub NOTHING { return 3; } my $resObj = "Apache::lonnavmaps::resource"; -# Keep these mappings in sync with lonquickgrades, which uses the colors +# Keep these mappings in sync with lonquickgrades, which usesthe colors # instead of the icons. my %statusIconMap = ( @@ -504,10 +506,13 @@ my %statusIconMap = $resObj->ERROR => '' ); -my %iconAltTags = - ( 'navmap.correct.gif' => 'Correct', - 'navmap.wrong.gif' => 'Incorrect', - 'navmap.open.gif' => 'Open' ); +my %iconAltTags = #texthash does not work here + ( 'navmap.correct.gif' => 'Correct', + 'navmap.wrong.gif' => 'Incorrect', + 'navmap.open.gif' => 'Open', + 'navmap.partial.gif' => 'Partially Correct', + 'navmap.ellipsis.gif' => 'Attempted', + ); # Defines a status->color mapping, null string means don't color my %colormap = @@ -523,6 +528,7 @@ my %colormap = $resObj->OPEN => '', $resObj->NOTHING_SET => '', $resObj->ATTEMPTED => '', + $resObj->CREDIT_ATTEMPTED => '', $resObj->ANSWER_SUBMITTED => '', $resObj->PARTIALLY_CORRECT => '#006600' ); @@ -533,35 +539,6 @@ my $hurryUpColor = "#FF0000"; my $future_slots_checked = 0; my $future_slots = 0; -sub close { - if ($env{'environment.remotenavmap'} ne 'on') { return ''; } - return(< -window.status='Accessing Nav Control'; -menu=window.open("/adm/rat/empty.html","loncapanav", - "height=600,width=400,scrollbars=1"); -window.status='Closing Nav Control'; -menu.close(); -window.status='Done.'; - -ENDCLOSE -} - -sub update { - if ($env{'environment.remotenavmap'} ne 'on') { return ''; } - if (!$env{'request.course.id'}) { return ''; } - if ($ENV{'REQUEST_URI'}=~m|^/adm/navmaps|) { return ''; } - return(< - -ENDUPDATE -} - - sub addToFilter { my $hashIn = shift; my $addition = shift; @@ -597,7 +574,7 @@ sub getLinkForResource { my ($map,$id,$src)=&Apache::lonnet::decode_symb($res->symb()); if ($map=~/\.page$/) { my $url=&Apache::lonnet::clutter($map); - $anchor=&escape($res->shown_symb()); + $anchor=&escape($res->shown_symb()); return ($url,$res->shown_symb(),$anchor); } } @@ -632,10 +609,10 @@ sub getDescription { return &mt("Having technical difficulties; please check status later"); } if ($status == $res->NOTHING_SET) { - return &mt("Not currently assigned."); + return &Apache::lonhtmlcommon::direct_parm_link(&mt("Not currently assigned.",$res->symb(),'opendate'),$part); } if ($status == $res->OPEN_LATER) { - return &mt("Open ") .timeToHumanString($open,'start'); + return &mt("Open ") .&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($open,'start'),$res->symb(),'opendate',$part); } if ($res->simpleStatus($part) == $res->OPEN) { unless (&Apache::lonnet::allowed('mgr',$env{'request.course.id'})) { @@ -669,33 +646,42 @@ sub getDescription { if ($status == $res->OPEN) { if ($due) { if ($res->is_practice()) { - return &mt("Closes ")." " .timeToHumanString($due,'start'); + return &mt("Closes ")." " .&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'start'),$res->symb(),'duedate',$part); } else { - return &mt("Due")." " .timeToHumanString($due,'end'); + return &mt("Due")." " .&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'end'),$res->symb(),'duedate',$part); } } else { - return &mt("Open, no due date"); + return &Apache::lonhtmlcommon::direct_parm_link(&mt("Open, no due date"),$res->symb(),'duedate',$part); } } if ($status == $res->PAST_DUE_ANSWER_LATER) { - return &mt("Answer open")." " .timeToHumanString($answer,'start'); + return &mt("Answer open")." " .&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($answer,'start'),$res->symb(),'answerdate',$part); } if ($status == $res->PAST_DUE_NO_ANSWER) { if ($res->is_practice()) { - return &mt("Closed")." " . timeToHumanString($due,'start'); + return &mt("Closed")." " . &Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'start'),$res->symb(),'answerdate,duedate',$part); } else { - return &mt("Was due")." " . timeToHumanString($due,'end'); + return &mt("Was due")." " .&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'end'),$res->symb(),'answerdate,duedate',$part); } } if (($status == $res->ANSWER_OPEN || $status == $res->PARTIALLY_CORRECT) && $res->handgrade($part) ne 'yes') { - return &mt("Answer available"); + return &Apache::lonhtmlcommon::direct_parm_link(&mt("Answer available"),$res->symb(),'answerdate,duedate',$part); } if ($status == $res->EXCUSED) { return &mt("Excused by instructor"); } if ($status == $res->ATTEMPTED) { - return &mt("Answer submitted, not yet graded"); + if ($res->is_anonsurvey($part) || $res->is_survey($part)) { + return &mt("Survey submission recorded"); + } else { + return &mt("Answer submitted, not yet graded"); + } + } + if ($status == $res->CREDIT_ATTEMPTED) { + if ($res->is_anonsurvey($part) || $res->is_survey($part)) { + return &mt("Credit for survey submission"); + } } if ($status == $res->TRIES_LEFT) { my $tries = $res->tries($part); @@ -708,10 +694,10 @@ sub getDescription { } } if ($due) { - return &mt("Due")." " . timeToHumanString($due,'end') . + return &mt("Due")." " . &Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'end'),$res->symb(),'duedate',$part) . " $triesString"; } else { - return &mt("No due date")." $triesString"; + return &Apache::lonhtmlcommon::direct_parm_link(&mt("No due date"),$res->symb(),'duedate',$part)." $triesString"; } } if ($status == $res->ANSWER_SUBMITTED) { @@ -892,35 +878,32 @@ sub render_resource { my $location=&Apache::loncommon::lonhttpdurl("/adm/lonIcons"); # If this is a new branch, label it so if ($params->{'isNewBranch'}) { - $newBranchText = ''.
-                         &mt('Branch').''; + $newBranchText = ".mt('Branch')."; } # links to open and close the folder - - my $linkopen = ""; - - + my $whitespace = $location.'/whitespace_21.gif'; + my $linkopen = "".""; my $linkclose = ""; # Default icon: unknown page - my $icon = ""; + my $icon = ""; if ($resource->is_problem()) { if ($part eq '0' || $params->{'condensed'}) { - $icon = ''.&mt('Task');
 	    } else {
 		$icon .= 'problem.gif'; + $icon .='" />'; } else { $icon = $params->{'indentString'}; } } else { - $icon = "  "; + $icon = ""; } # Display the correct map icon to open or shut map @@ -930,15 +913,15 @@ sub render_resource { if ($it->{CONDITION}) { $nowOpen = !$nowOpen; } - + my $folderType = $resource->is_sequence() ? 'folder' : 'page'; my $title=$resource->title; - $title=~s/\"/\"/g; + $title=~s/\"/\&qout;/g; if (!$params->{'resource_no_folder_link'}) { $icon = "navmap.$folderType." . ($nowOpen ? 'closed' : 'open') . '.gif'; - $icon = "\""."; - + $icon = "" + ."\"""; $linkopen = "{'url'} . '?' . $params->{'queryString'} . '&filter='; $linkopen .= ($nowOpen xor $it->{CONDITION}) ? @@ -953,10 +936,8 @@ sub render_resource { } else { # Don't allow users to manipulate folder - $icon = "navmap.$folderType." . ($nowOpen ? 'closed' : 'open') . - '.nomanip.gif'; - $icon = "\""."; + $icon = "navmap.$folderType." . ($nowOpen ? 'closed' : 'open') . '.gif'; + $icon = ""."\"".($nowOpen"; $linkopen = ""; $linkclose = ""; @@ -964,18 +945,19 @@ sub render_resource { } if ($resource->randomout()) { - $nonLinkedText .= ' ('.&mt('hidden').') '; + $nonLinkedText .= ' ('.&mt('hidden').') '; } if (!$resource->condval()) { - $nonLinkedText .= ' ('.&mt('conditionally hidden').') '; + $nonLinkedText .= ' ('.&mt('conditionally hidden').') '; } if (($resource->is_practice()) && ($resource->is_raw_problem())) { $nonLinkedText .=' '.&mt('not graded').''; } - - # We're done preparing and finally ready to start the rendering - my $result = ""; + # We're done preparing and finally ready to start the rendering + my $result = ''; + my $newfolderType = $resource->is_sequence() ? 'folder' : 'page'; + my $indentLevel = $params->{'indentLevel'}; if ($newBranchText) { $indentLevel--; } @@ -985,7 +967,6 @@ sub render_resource { } # Decide what to display - $result .= "$newBranchText$linkopen$icon$linkclose"; my $curMarkerBegin = ''; @@ -994,9 +975,9 @@ sub render_resource { # Is this the current resource? if (!$params->{'displayedHereMarker'} && $resource->symb() eq $params->{'here'} ) { - $curMarkerBegin = '>'; - $curMarkerEnd = '<'; - $params->{'displayedHereMarker'} = 1; + $curMarkerBegin = ''; + $curMarkerEnd = ''; + $params->{'displayedHereMarker'} = 1; } if ($resource->is_problem() && $part ne '0' && @@ -1011,14 +992,10 @@ sub render_resource { $nonLinkedText .= ' ('.&mt('[_1] parts', $resource->countParts()).')'; } - my $target; - if ($env{'environment.remotenavmap'} eq 'on') { - $target=' target="loncapaclient" '; - } if (!$params->{'resource_nolink'} && !$resource->is_sequence() && !$resource->is_empty_sequence) { - $result .= " $curMarkerBegin$title$partLabel$curMarkerEnd $nonLinkedText"; + $result .= "$curMarkerBegin$title$partLabel$curMarkerEnd$nonLinkedText"; } else { - $result .= " $curMarkerBegin$title$partLabel$curMarkerEnd $nonLinkedText"; + $result .= "$curMarkerBegin$linkopen$title$partLabel$curMarkerEnd$nonLinkedText"; } return $result; @@ -1029,16 +1006,12 @@ sub render_communication_status { my $discussionHTML = ""; my $feedbackHTML = ""; my $errorHTML = ""; my $link = $params->{"resourceLink"}; - my $target; - if ($env{'environment.remotenavmap'} eq 'on') { - $target=' target="loncapaclient" '; - } - my $linkopen = ""; + my $linkopen = ""; my $linkclose = ""; my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc"); if ($resource->hasDiscussion()) { $discussionHTML = $linkopen . - ''.&mt('New Discussion').'' . + ''.&mt('New Discussion').'' . $linkclose; } @@ -1046,10 +1019,9 @@ sub render_communication_status { my $feedback = $resource->getFeedback(); foreach my $msgid (split(/\,/, $feedback)) { if ($msgid) { - $feedbackHTML .= ' ' - . ''.&mt('New E-mail').''; + . ''.&mt('New E-mail').''; } } } @@ -1061,10 +1033,9 @@ sub render_communication_status { last if ($errorcount>=10); # Only output 10 bombs maximum if ($msgid) { $errorcount++; - $errorHTML .= ' ' - . ''.&mt('New Error').''; + . ''.&mt('New Error').''; } } } @@ -1072,8 +1043,7 @@ sub render_communication_status { if ($params->{'multipart'} && $part != '0') { $discussionHTML = $feedbackHTML = $errorHTML = ''; } - - return "$discussionHTML$feedbackHTML$errorHTML "; + return "$discussionHTML$feedbackHTML$errorHTML "; } sub render_quick_status { @@ -1083,34 +1053,30 @@ sub render_quick_status { $params->{'multipart'} && $part eq "0"; my $link = $params->{"resourceLink"}; - my $target; - if ($env{'environment.remotenavmap'} eq 'on') { - $target=' target="loncapaclient" '; - } - my $linkopen = ""; + my $linkopen = ""; my $linkclose = ""; - + + $result .= ''; if ($resource->is_problem() && !$firstDisplayed) { - my $icon = $statusIconMap{$resource->simpleStatus($part)}; my $alt = $iconAltTags{$icon}; if ($icon) { my $location= &Apache::loncommon::lonhttpdurl("/adm/lonIcons/$icon"); - $result .= "$linkopen$alt$linkclose\n"; + $result .= $linkopen.''.&mt($alt).''.$linkclose; } else { - $result .= " \n"; + $result .= " "; } } else { # not problem, no icon - $result .= " \n"; + $result .= " "; } - + $result .= "\n"; return $result; } sub render_long_status { my ($resource, $part, $params) = @_; - my $result = "\n"; + my $result = ''; my $firstDisplayed = !$params->{'condensed'} && $params->{'multipart'} && $part eq "0"; @@ -1124,9 +1090,10 @@ sub render_long_status { } } - if ($resource->kind() eq "res" && + if (($resource->kind() eq "res" && ($resource->is_problem() || $resource->is_practice()) && - !$firstDisplayed) { + !$firstDisplayed) && + $resource->is_raw_problem()) { if ($color) {$result .= ""; } $result .= getDescription($resource, $part); if ($color) {$result .= ""; } @@ -1414,7 +1381,7 @@ sub render { my $printKey = $args->{'printKey'}; my $printCloseAll = $args->{'printCloseAll'}; if (!defined($printCloseAll)) { $printCloseAll = 1; } - + # Print key? if ($printKey) { $result .= ''; @@ -1440,19 +1407,22 @@ sub render { if ($printCloseAll && !$args->{'resource_no_folder_link'}) { my ($link,$text); if ($condition) { - $link='"navmaps?condition=0&filter=&'.$queryString. - '&here='.&escape($here).'"'; + $link='navmaps?condition=0&filter=&'.$queryString. + '&here='.&escape($here); $text='Close all folders'; } else { - $link='"navmaps?condition=1&filter=&'.$queryString. - '&here='.&escape($here).'"'; + $link='navmaps?condition=1&filter=&'.$queryString. + '&here='.&escape($here); $text='Open all folders'; } + if ($env{'form.register'}) { + $link .= '&register='.$env{'form.register'}; + } if ($args->{'caller'} eq 'navmapsdisplay') { &add_linkitem($args->{'linkitems'},'changefolder', - 'location.href='.$link,$text); + "location.href='$link'",$text); } else { - $result.=''.&mt($text).''; + $result.= ''.&mt($text).''; } $result .= "\n"; } @@ -1468,6 +1438,9 @@ sub render { END + if ($env{'form.register'}) { + $result .= ''; + } if ($args->{'sort'} eq 'discussion') { my $totdisc = 0; my $haveDisc = ''; @@ -1492,51 +1465,45 @@ END if ($args->{'caller'} eq 'navmapsdisplay') { $result .= '
'; - if ($env{'environment.remotenavmap'} ne 'on') { $result .= ''; - } else { - $result .= ''; - } - $result.=&show_linkitems($args->{'linkitems'}); + $result.=''; + $result.=&show_linkitems_toolbar($args->{'linkitems'}); if ($args->{'sort_html'}) { - if ($env{'environment.remotenavmap'} ne 'on') { - $result.=''. - ''; - } else { - $result.=''; - } - } + $result.=''. + ''; + } $result .= '
'. &Apache::loncommon::help_open_menu('Navigation Screen','Navigation_Screen',undef,'RAT').' 
'.&mt('Tools:').'   '.$args->{'sort_html'}.'

'. - $args->{'sort_html'}.'
   '.$args->{'sort_html'}.'
'; } elsif ($args->{'sort_html'}) { $result.=$args->{'sort_html'}; } - $result .= "
\n"; + #$result .= "
\n"; if ($r) { $r->print($result); $r->rflush(); $result = ""; } # End parameter setting - + + $result .= "
\n"; + # Data - $result .= '' ."\n"; + $result.=&Apache::loncommon::start_data_table("LC_tableOfContent"); + my $res = "Apache::lonnavmaps::resource"; my %condenseStatuses = ( $res->NETWORK_FAILURE => 1, $res->NOTHING_SET => 1, $res->CORRECT => 1 ); - my @backgroundColors = ("#FFFFFF", "#F6F6F6"); # Shared variables $args->{'counter'} = 0; # counts the rows $args->{'indentLevel'} = 0; $args->{'isNewBranch'} = 0; - $args->{'condensed'} = 0; - my $location= - &Apache::loncommon::lonhttpdurl("/adm/lonIcons/whitespace1.gif"); - $args->{'indentString'} = setDefault($args->{'indentString'}, "  "); + $args->{'condensed'} = 0; + + my $location = &Apache::loncommon::lonhttpdurl("/adm/lonIcons/whitespace_21.gif"); + $args->{'indentString'} = setDefault($args->{'indentString'}, ""); $args->{'displayedHereMarker'} = 0; # If we're suppressing empty sequences, look for them here. Use DFS for speed, @@ -1755,16 +1722,15 @@ END if (defined($anchor)) { $anchor='#'.$anchor; } my $srcHasQuestion = $src =~ /\?/; $args->{"resourceLink"} = $src. - ($srcHasQuestion?'&':'?') . + ($srcHasQuestion?'&':'?') . 'symb=' . &escape($symb).$anchor; } # Now, we've decided what parts to show. Loop through them and # show them. foreach my $part (@parts) { $rownum ++; - my $backgroundColor = $backgroundColors[$rownum % scalar(@backgroundColors)]; - $result .= " \n"; + $result .= &Apache::loncommon::start_data_table_row(); # Set up some data about the parts that the cols might want my $filter = $it->{FILTER}; @@ -1790,7 +1756,7 @@ END } $result .= $colHTML . "\n"; } - $result .= " \n"; + $result .= &Apache::loncommon::end_data_table_row(); $args->{'isNewBranch'} = 0; } @@ -1818,16 +1784,15 @@ END # it's quite likely this might fix other browsers, too, and # certainly won't hurt anything. if ($displayedJumpMarker) { - $result .= " -"; +"); } - $result .= "
"; - + $result.=&Apache::loncommon::end_data_table(); + if ($r) { $r->print($result); $result = ""; @@ -1843,40 +1808,42 @@ sub add_linkitem { $$linkitems{$name}{'text'}=&mt($text); } -sub show_linkitems { - my ($linkitems)=@_; - my @linkorder = ("blank","launchnav","closenav","firsthomework", - "everything","uncompleted","changefolder","clearbubbles"); - - my $result .= (< - -
-   -
'."\n"; - + $result .= ''. + ''."\n"; return $result; } + 1; @@ -1964,6 +1931,9 @@ sub new { my $class = ref($proto) || $proto; my $self = {}; + $self->{USERNAME} = shift || $env{'user.name'}; + $self->{DOMAIN} = shift || $env{'user.domain'}; + # Resource cache stores navmap resources as we reference them. We generate # them on-demand so we don't pay for creating resources unless we use them. $self->{RESOURCE_CACHE} = {}; @@ -2002,8 +1972,9 @@ sub generate_course_user_opt { my $self = shift; if ($self->{COURSE_USER_OPT_GENERATED}) { return; } - my $uname=$env{'user.name'}; - my $udom=$env{'user.domain'}; + my $uname=$self->{USERNAME}; + my $udom=$self->{DOMAIN}; + my $cid=$env{'request.course.id'}; my $cdom=$env{'course.'.$cid.'.domain'}; my $cnum=$env{'course.'.$cid.'.num'}; @@ -2046,7 +2017,7 @@ sub generate_email_discuss_status { my $cdom=$env{'course.'.$cid.'.domain'}; my $cnum=$env{'course.'.$cid.'.num'}; - my %emailstatus = &Apache::lonnet::dump('email_status'); + my %emailstatus = &Apache::lonnet::dump('email_status',$self->{DOMAIN},$self->{USERNAME}); my $logoutTime = $emailstatus{'logout'}; my $courseLeaveTime = $emailstatus{'logout_'.$env{'request.course.id'}}; $self->{LAST_CHECK} = (($courseLeaveTime > $logoutTime) ? @@ -2054,7 +2025,7 @@ sub generate_email_discuss_status { my %discussiontime = &Apache::lonnet::dump('discussiontimes', $cdom, $cnum); my %lastread = &Apache::lonnet::dump('nohist_'.$cid.'_discuss', - $env{'user.domain'},$env{'user.name'},'lastread'); + $self->{DOMAIN},$self->{USERNAME},'lastread'); my %lastreadtime = (); foreach my $key (keys %lastread) { my $shortkey = $key; @@ -2064,8 +2035,8 @@ sub generate_email_discuss_status { my %feedback=(); my %error=(); - my @keys = &Apache::lonnet::getkeys('nohist_email',$env{'user.domain'}, - $env{'user.name'}); + my @keys = &Apache::lonnet::getkeys('nohist_email',$self->{DOMAIN}, + $self->{USERNAME}); foreach my $msgid (@keys) { if ((!$emailstatus{$msgid}) || ($emailstatus{$msgid} eq 'new')) { @@ -2113,8 +2084,8 @@ sub get_user_data { # Retrieve performance data on problems my %student_data = Apache::lonnet::currentdump($env{'request.course.id'}, - $env{'user.domain'}, - $env{'user.name'}); + $self->{DOMAIN}, + $self->{USERNAME}); $self->{STUDENT_DATA} = \%student_data; $self->{RETRIEVED_USER_DATA} = 1; @@ -2343,7 +2314,7 @@ resource object. Based on the symb of the resource, get a resource object for that resource. This is one of the proper ways to get a resource object. -=item * B(map_pc): +=item * B(map_pc): Based on the map_pc of the resource, get a resource object for the given map. This is one of the proper ways to get a resource object. @@ -2465,8 +2436,8 @@ sub parmval_real { @cgrps = sort(@cgrps); $cgroup = $cgrps[0]; } - my $uname=$env{'user.name'}; - my $udom=$env{'user.domain'}; + my $uname=$self->{USERNAME}; + my $udom=$self->{DOMAIN}; unless ($symb) { return ['']; } my $result=''; @@ -2613,7 +2584,7 @@ in the filter function. Retrieves version infomation for a url. Returns the version (a number, or the string "mostrecent") for resources which have version information in the big hash. - + =cut @@ -2868,6 +2839,9 @@ sub new { weaken($self->{NAV_MAP} = shift); return undef unless ($self->{NAV_MAP}); + $self->{USERNAME} = $self->{NAV_MAP}->{USERNAME}; + $self->{DOMAIN} = $self->{NAV_MAP}->{DOMAIN}; + # Handle the parameters $self->{FIRST_RESOURCE} = shift || $self->{NAV_MAP}->firstResource(); $self->{FINISH_RESOURCE} = shift || $self->{NAV_MAP}->finishResource(); @@ -3241,6 +3215,9 @@ sub new { weaken($self->{NAV_MAP} = shift); return undef unless ($self->{NAV_MAP}); + $self->{USERNAME} = $self->{NAV_MAP}->{USERNAME}; + $self->{DOMAIN} = $self->{NAV_MAP}->{DOMAIN}; + $self->{FIRST_RESOURCE} = shift || $self->{NAV_MAP}->firstResource(); $self->{FINISH_RESOURCE} = shift || $self->{NAV_MAP}->finishResource(); @@ -3477,6 +3454,9 @@ sub new { weaken($self->{NAV_MAP} = shift); $self->{ID} = shift; + $self->{USERNAME} = $self->{NAV_MAP}->{USERNAME}; + $self->{DOMAIN} = $self->{NAV_MAP}->{DOMAIN}; + # Store this new resource in the parent nav map's cache. $self->{NAV_MAP}->{RESOURCE_CACHE}->{$self->{ID}} = $self; $self->{RESOURCE_ERROR} = 0; @@ -3499,7 +3479,7 @@ sub navHash { my $param = shift; my $id = shift; my $arg = $param . ($id?$self->{ID}:""); - if (defined($arg)) { + if (ref($self) && ref($self->{NAV_MAP}) && defined($arg)) { return $self->{NAV_MAP}->navhash($arg); } return; @@ -3745,6 +3725,35 @@ sub is_problem { } return 0; } +# +# The has below is the set of status that are considered 'incomplete' +# +my %incomplete_hash = +( + TRIES_LEFT() => 1, + OPEN() => 1, + ATTEMPTED() => 1 + + ); +# +# Return tru if a problem is incomplete... for now incomplete means that +# any part of the problem is incomplete. +# Note that if the resources is not a problem, 0 is returned. +# +sub is_incomplete { + my $self = shift; + if ($self->is_problem()) { + &Apache::lonnet::logthis('is problem'); + foreach my $part (@{$self->parts()}) { + &Apache::lonnet::logthis("$part status ".$self->status($part)); + if (exists($incomplete_hash{$self->status($part)})) { + return 1; + } + } + } + return 0; + +} sub is_raw_problem { my $self=shift; my $src = $self->src(); @@ -3774,13 +3783,13 @@ sub map_contains_problem { sub is_sequence { my $self=shift; return $self->navHash("is_map_", 1) && - $self->navHash("map_type_" . $self->map_pc()) eq 'sequence'; + $self->navHash("map_type_" . $self->map_pc()) eq 'sequence'; } sub is_survey { my $self = shift(); my $part = shift(); my $type = $self->parmval('type',$part); - if ($type eq 'survey') { + if (($type eq 'survey') || ($type eq 'surveycred')) { return 1; } if ($self->src() =~ /\.(survey)$/) { @@ -3788,6 +3797,15 @@ sub is_survey { } return 0; } +sub is_anonsurvey { + my $self = shift(); + my $part = shift(); + my $type = $self->parmval('type',$part); + if (($type eq 'anonsurvey') || ($type eq 'anonsurveycred')) { + return 1; + } + return 0; +} sub is_task { my $self=shift; my $src = $self->src(); @@ -3841,6 +3859,12 @@ resource of the map. Returns a string with the type of the map in it. +=item *B: + +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 +map first, then descending to deeper levels, with the enclosing map last. + =back =cut @@ -3871,6 +3895,11 @@ sub map_type { my $pc = $self->map_pc(); return $self->navHash("map_type_$pc", 0); } +sub map_hierarchy { + my $self = shift; + my $pc = $self->map_pc(); + return $self->navHash("map_hierarchy_$pc", 0); +} ##### # Property queries @@ -4085,8 +4114,8 @@ sub weight { my $self = shift; my $part = shift; if (!defined($part)) { $part = '0'; } my $weight = &Apache::lonnet::EXT('resource.'.$part.'.weight', - $self->symb(), $env{'user.domain'}, - $env{'user.name'}, + $self->symb(), $self->{DOMAIN}, + $self->{USERNAME}, $env{'request.course.sec'}); return $weight; } @@ -4105,7 +4134,7 @@ sub slot_control { if (!defined($part)) { $part = '0'; } my $useslots = $self->parmval("useslots", $part); my $availablestudent = $self->parmval("availablestudent", $part); - my $available = $self->parmval("available", $part); + my $available = $self->parmval("available", $part); return ($useslots,$availablestudent,$available); } @@ -4114,7 +4143,7 @@ sub getReturnHash { my $self = shift; if (!defined($self->{RETURN_HASH})) { - my %tmpHash = &Apache::lonnet::restore($self->symb()); + my %tmpHash = &Apache::lonnet::restore($self->symb(),undef,$self->{DOMAIN},$self->{USERNAME}); $self->{RETURN_HASH} = \%tmpHash; } } @@ -4540,7 +4569,7 @@ sub OPEN { return 1; } sub PAST_DUE_NO_ANSWER { return 2; } sub PAST_DUE_ANSWER_LATER { return 3; } sub ANSWER_OPEN { return 4; } -sub NOTHING_SET { return 5; } +sub NOTHING_SET { return 5; } sub NETWORK_FAILURE { return 100; } # getDateStatus gets the date status for a given problem part. @@ -4626,6 +4655,10 @@ Information not available due to network Attempted, and not yet graded. +=item * B: + +Attempted, and credit received for attempt (survey and anonymous survey only). + =back =cut @@ -4637,6 +4670,7 @@ sub CORRECT { return 13; } sub CORRECT_BY_OVERRIDE { return 14; } sub EXCUSED { return 15; } sub ATTEMPTED { return 16; } +sub CREDIT_ATTEMPTED { return 17; } sub getCompletionStatus { my $self = shift; @@ -4655,6 +4689,13 @@ sub getCompletionStatus { if ($status eq 'incorrect_by_override') {return $self->INCORRECT_BY_OVERRIDE; } if ($status eq 'excused') {return $self->EXCUSED; } if ($status eq 'ungraded_attempted') {return $self->ATTEMPTED; } + if ($status eq 'credit_attempted') { + if ($self->is_anonsurvey($part) || $self->is_survey($part)) { + return $self->CREDIT_ATTEMPTED; + } else { + return $self->ATTEMPTED; + } + } return $self->NOT_ATTEMPTED; } @@ -4744,6 +4785,10 @@ The item is open and not yet tried. The problem has been attempted. +=item * B: + +The problem has been attempted, and credit given for the attempt (survey and anonymous survey only). + =item * B: An answer has been submitted, but the student should not see it. @@ -4752,9 +4797,9 @@ An answer has been submitted, but the st =cut -sub TRIES_LEFT { return 20; } -sub ANSWER_SUBMITTED { return 21; } -sub PARTIALLY_CORRECT{ return 22; } +sub TRIES_LEFT { return 20; } +sub ANSWER_SUBMITTED { return 21; } +sub PARTIALLY_CORRECT { return 22; } sub RESERVED_LATER { return 30; } sub RESERVED { return 31; } @@ -4817,6 +4862,10 @@ sub status { return ATTEMPTED; } + if ($completionStatus == CREDIT_ATTEMPTED) { + return CREDIT_ATTEMPTED; + } + # If it's EXCUSED, then return that no matter what if ($completionStatus == EXCUSED) { return EXCUSED; @@ -4897,11 +4946,11 @@ sub check_for_slot { if (!&Apache::loncommon::check_ip_acc($ip)) { return (RESERVED_LOCATION,$ip,$slot_name); } - } + } if (@proctors > 0) { unless ((grep(/^\Q$checkedin\E/,@proctors)) && ($checkedinslot eq $slot_name)) { - return (NEEDS_CHECKIN,undef,$slot_name); + return (NEEDS_CHECKIN,undef,$slot_name); } } return (RESERVED,$end,$slot_name); @@ -4917,19 +4966,19 @@ sub check_for_slot { my ($is_correct,$got_grade); if ($self->is_task()) { my $taskstatus = $self->taskstatus(); - $is_correct = (($taskstatus eq 'pass') || + $is_correct = (($taskstatus eq 'pass') || ($self->solved() =~ /^correct_/)); - $got_grade = ($self->solved() =~ /^(?:pass|fail)$/); + $got_grade = ($taskstatus =~ /^(?:pass|fail)$/); } else { $got_grade = 1; - $is_correct = ($self->solved() =~ /^correct_/); + $is_correct = ($self->solved() =~ /^correct_/); } ($checkedin,$checkedinslot) = $self->checkedin(); if ($checkedin) { if (!$got_grade) { return (WAITING_FOR_GRADE); } elsif ($is_correct) { - return (CORRECT); + return (CORRECT); } } return(NOT_IN_A_SLOT); @@ -5009,6 +5058,7 @@ my %compositeToSimple = INCORRECT() => INCORRECT, OPEN() => OPEN, ATTEMPTED() => ATTEMPTED, + CREDIT_ATTEMPTED() => CORRECT, ANSWER_SUBMITTED() => ATTEMPTED ); @@ -5083,6 +5133,7 @@ sub completable { # and it is not "attempted" (manually graded problem), it is # not "complete" if ($self->getCompletionStatus($part) == ATTEMPTED() || + $self->getCompletionStatus($part) == CREDIT_ATTEMPTED() || $status == ANSWER_SUBMITTED() ) { # did this part already, as well as we can next;