--- loncom/interface/lonnavmaps.pm 2012/04/04 15:00:17 1.482 +++ loncom/interface/lonnavmaps.pm 2012/12/01 13:14:56 1.490 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Navigate Maps Handler # -# $Id: lonnavmaps.pm,v 1.482 2012/04/04 15:00:17 raeburn Exp $ +# $Id: lonnavmaps.pm,v 1.490 2012/12/01 13:14:56 raeburn Exp $ # # Copyright Michigan State University Board of Trustees @@ -225,7 +225,7 @@ automatically. =over 4 -=item * B +=item * B: default: constructs one from %env A reference to a fresh ::iterator to use from the navmaps. The rendering will reflect the options passed to the iterator, so you can @@ -484,10 +484,11 @@ use POSIX qw (floor strftime); use Time::HiRes qw( gettimeofday tv_interval ); use LONCAPA; use DateTime(); +use HTML::Entities; # For debugging -# use Data::Dumper; +use Data::Dumper; # symbolic constants @@ -691,7 +692,7 @@ sub getDescription { my $maxtries = $res->maxtries($part); my $triesString = ""; if ($tries && $maxtries) { - $triesString = '('.&mt('[_1] of [quant,_2,try,tries] used',$tries,$maxtries).')'; + $triesString = '('.&mt('[_1] of [quant,_2,try,tries] used',$tries,$maxtries).')'; if ($maxtries > 1 && $maxtries - $tries == 1) { $triesString = "$triesString"; } @@ -995,7 +996,7 @@ sub render_resource { $nonLinkedText .= ' ('.&mt('conditionally hidden').') '; } if (($resource->is_practice()) && ($resource->is_raw_problem())) { - $nonLinkedText .=' '.&mt('not graded').''; + $nonLinkedText .=' '.&mt('not graded').''; } # We're done preparing and finally ready to start the rendering @@ -1039,7 +1040,7 @@ sub render_resource { } if (!$params->{'resource_nolink'} && !$resource->is_sequence() && !$resource->is_empty_sequence) { - $result .= "$curMarkerBegin$title$partLabel$curMarkerEnd$nonLinkedText"; + $result .= "$curMarkerBegin$title$partLabel$curMarkerEnd$editmapLink$nonLinkedText"; } else { $result .= "$curMarkerBegin$linkopen$title$partLabel$curMarkerEnd$editmapLink$nonLinkedText"; } @@ -1128,21 +1129,23 @@ sub render_long_status { $params->{'multipart'} && $part eq "0"; my $color; + my $info = ''; if ($resource->is_problem() || $resource->is_practice()) { $color = $colormap{$resource->status}; if (dueInLessThan24Hours($resource, $part) || lastTry($resource, $part)) { $color = $hurryUpColor; + $info = ' title="'.&mt('Due in less than 24 hours!').'"'; } } if ($resource->kind() eq "res" && $resource->is_raw_problem() && !$firstDisplayed) { - if ($color) {$result .= ""; } + if ($color) {$result .= ''; } $result .= getDescription($resource, $part); - if ($color) {$result .= ""; } + if ($color) {$result .= ""; } } if ($resource->is_map() && &advancedUser() && $resource->randompick()) { $result .= &mt('(randomly select [_1])', $resource->randompick()); @@ -1224,11 +1227,11 @@ sub render_parts_summary_status { } $return.= $td . $totalParts . ' parts: '; foreach my $status (@statuses) { - if ($overallstatus{$status}) { - $return.="" . $overallstatus{$status} . ' ' - . $statusStrings{$status} . ""; - } + if ($overallstatus{$status}) { + $return.='' . $overallstatus{$status} . ' ' + . $statusStrings{$status} . ''; + } } $return.= $endtd; return $return; @@ -1398,7 +1401,6 @@ sub render { } } - # (re-)Locate the jump point, if any # Note this does not take filtering or hidden into account... need # to be fixed? @@ -1482,9 +1484,10 @@ sub render { 'document.clearbubbles.submit()', 'Mark all posts read'); my $time=time; + my $querystr = &HTML::Entities::encode($ENV{'QUERY_STRING'},'<>&"'); $result .= (< - + END if ($env{'form.register'}) { @@ -1655,7 +1658,6 @@ END $curRes = shift(@resources); } else { $curRes = $it->next($closeAllPages); - } if (!$curRes) { last; } @@ -1827,6 +1829,8 @@ END } } } + + $result.=&Apache::loncommon::end_data_table(); # Print out the part that jumps to #curloc if it exists # delay needed because the browser is processing the jump before @@ -1843,8 +1847,6 @@ if (location.href.indexOf('#curloc')==-1 "); } - $result.=&Apache::loncommon::end_data_table(); - if ($r) { $r->print($result); $result = ""; @@ -1875,7 +1877,6 @@ sub show_linkitems_toolbar { ''.&mt('Tools:').''; } $result .= ''."\n". - ''."\n". '
    '; my @linkorder = ('firsthomework','everything','uncompleted', 'changefolder','clearbubbles','edittoplevel'); @@ -1903,7 +1904,7 @@ sub show_linkitems_toolbar { } } $result .= '
'. - '
'; + ''; if (($numlinks==1) && (exists($args->{'linkitems'}{'edittoplevel'}))) { $result .= ''. &mt('Content Editor').''; @@ -2026,7 +2027,7 @@ sub new { # assume there are course hashes for the specific requested user@domamin: # - 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'})) { # tie the nav hash @@ -2052,8 +2053,6 @@ sub new { $self->change_user($self->{USERNAME}, $self->{DOMAIN}); } - my $d = Data::Dumper->new([$self]); - return $self; } @@ -2105,7 +2104,6 @@ sub change_user { } $self->{PARM_HASH} = \%parm_hash; - @@ -2151,6 +2149,8 @@ sub generate_course_user_opt { return; } + + sub generate_email_discuss_status { my $self = shift; my $symb = shift; @@ -2564,10 +2564,12 @@ sub parmval { return $result->[0]; } + sub parmval_real { my $self = shift; my ($what,$symb,$recurse) = @_; + # Make sure the {USER_OPT} and {COURSE_OPT} hashes are populated $self->generate_course_user_opt(); @@ -2596,18 +2598,23 @@ sub parmval_real { my $mapparm=$mapname.'___(all).'.$what; my $usercourseprefix=$cid; + + my $grplevel=$usercourseprefix.'.['.$cgroup.'].'.$what; my $grplevelr=$usercourseprefix.'.['.$cgroup.'].'.$symbparm; my $grplevelm=$usercourseprefix.'.['.$cgroup.'].'.$mapparm; + my $seclevel= $usercourseprefix.'.['.$csec.'].'.$what; my $seclevelr=$usercourseprefix.'.['.$csec.'].'.$symbparm; my $seclevelm=$usercourseprefix.'.['.$csec.'].'.$mapparm; + my $courselevel= $usercourseprefix.'.'.$what; my $courselevelr=$usercourseprefix.'.'.$symbparm; my $courselevelm=$usercourseprefix.'.'.$mapparm; + my $useropt = $self->{USER_OPT}; my $courseopt = $self->{COURSE_OPT}; my $parmhash = $self->{PARM_HASH}; @@ -2674,6 +2681,217 @@ sub parmval_real { if (defined($pack_def)) { return [$pack_def,'resource']; } 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 @@ -3099,7 +3317,6 @@ sub new { my $firstResource = $resource->map_start(); my $finishResource = $resource->map_finish(); my $result; - my $rdump = Data::Dumper->new([$result]); $result = Apache::lonnavmaps::iterator->new($self->{NAV_MAP}, $firstResource, $finishResource, $self->{FILTER}, $self->{ALREADY_SEEN}, @@ -3126,8 +3343,6 @@ sub new { $self->{ALREADY_SEEN}->{$self->{FIRST_RESOURCE}->{ID}} = 1; bless ($self); - my $selfDump = Data::Dumper->new([$self]); - return $self; } @@ -3143,7 +3358,6 @@ sub next { if ($self->{RETURN_0} && !$self->{HAVE_RETURNED_0}) { $self->{HAVE_RETURNED_0} = 1; my $nextTopLevel = $self->{NAV_MAP}->getById('0.0'); - return $self->{NAV_MAP}->getById('0.0'); } if ($self->{RETURN_0} && !$self->{HAVE_RETURNED_0_BEGIN_MAP}) { @@ -3169,7 +3383,6 @@ sub next { if (defined($self->{FORCE_NEXT})) { my $tmp = $self->{FORCE_NEXT}; $self->{FORCE_NEXT} = undef; - return $tmp; } @@ -3291,8 +3504,6 @@ sub next { return $self->next($closeAllPages); } - my $hereResource = $self->{HERE}; - return $self->{HERE}; } @@ -3459,7 +3670,6 @@ sub next { my $nextUnfiltered; if ($self->{DIRECTION} == FORWARD()) { $nextUnfiltered = $self->{HERE}->getNext(); - } else { $nextUnfiltered = $self->{HERE}->getPrevious(); } @@ -4083,11 +4293,13 @@ their code.) =over 4 + =item * B returns true if the current date is such that the specified resource part is printable. + =item * B Returns true if all parts in the resource are printable making the @@ -4146,23 +4358,41 @@ Get the weight for the problem. =cut + + + sub printable { my ($self, $part) = @_; - # Get the print open/close dates for the resource. + &Apache::lonnet::logthis($self->symb()); - my $start = $self->parmval("printstartdate", $part); - my $end = $self->parmval("printenddate", $part); # 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. # - End date set but no start date: Printable if now <= end date. # - 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 $startok = 1; my $endok = 1; @@ -4183,7 +4413,7 @@ sub resprintable { my $partsref = $self->parts(); my @parts = @$partsref; - if ((!defined(@parts)) || (scalar(@parts) == 0)) { + if (!@parts) { return $self->printable(0); } else { foreach my $part (@parts) {