: default: constructs one from %env
A reference to a navmap, used only if an iterator is not passed in. If
@@ -832,7 +854,10 @@ sub render_resource {
if (!$resource->condval()) {
$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 = "";
@@ -975,7 +1000,7 @@ sub render_long_status {
$params->{'multipart'} && $part eq "0";
my $color;
- if ($resource->is_problem()) {
+ if ($resource->is_problem() || $resource->is_practice()) {
$color = $colormap{$resource->status};
if (dueInLessThan24Hours($resource, $part) ||
@@ -985,14 +1010,17 @@ sub render_long_status {
}
if ($resource->kind() eq "res" &&
- $resource->is_problem() &&
+ ($resource->is_problem() || $resource->is_practice()) &&
!$firstDisplayed) {
if ($color) {$result .= ""; }
$result .= getDescription($resource, $part);
if ($color) {$result .= ""; }
}
- if ($resource->is_map() && advancedUser() && $resource->randompick()) {
- $result .= '(randomly select ' . $resource->randompick() .')';
+ if ($resource->is_map() && &advancedUser() && $resource->randompick()) {
+ $result .= &mt('(randomly select [_1])', $resource->randompick());
+ }
+ if ($resource->is_map() && &advancedUser() && $resource->randomorder()) {
+ $result .= &mt('(randomly ordered)');
}
# Debugging code
@@ -1027,7 +1055,6 @@ my %statusStrings =
);
my @statuses = ($resObj->CORRECT, $resObj->ATTEMPTED, $resObj->INCORRECT, $resObj->OPEN, $resObj->CLOSED, $resObj->ERROR);
-use Data::Dumper;
sub render_parts_summary_status {
my ($resource, $part, $params) = @_;
if (!$resource->is_problem() && !$resource->contains_problem) { return ' | | '; }
@@ -1234,7 +1261,7 @@ sub render {
$args->{'iterator'} = $it = $navmap->getIterator($firstResource, $finishResource, $filterHash, $condition);
} else {
- $args->{'iterator'} = $it = $navmap->getIterator(undef, undef, $filterHash, $condition);
+ $args->{'iterator'} = $it = $navmap->getIterator(undef, undef, $filterHash, $condition,undef,$args->{'include_top_level_map'});
}
}
@@ -1271,7 +1298,6 @@ sub render {
# Print key?
if ($printKey) {
$result .= '';
- my $date=localtime;
$result.='Key: | ';
my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc");
if ($navmap->{LAST_CHECK}) {
@@ -1715,7 +1741,7 @@ ENDBLOCK
$result.='}
'."\n";
+ '."\n";
return $result;
}
@@ -1802,6 +1828,7 @@ See iterator documentation below.
use strict;
use GDBM_File;
use Apache::lonnet;
+use LONCAPA;
sub new {
# magic invocation to create a class instance
@@ -2057,7 +2084,7 @@ sub discussion_info {
my $ressymb = $self->wrap_symb($symb);
# keys used to store bulletinboard postings use 'unwrapped' symb.
- my $discsymb = $self->unwrap_symb($ressymb);
+ my $discsymb = &escape($self->unwrap_symb($ressymb));
my $version = $self->{DISCUSSION_DATA}{'version:'.$discsymb};
if (!$version) { return; }
@@ -2197,7 +2224,7 @@ the given map. This is one of the proper
# The strategy here is to cache the resource objects, and only construct them
# as we use them. The real point is to prevent reading any more from the tied
-# hash then we have to, which should hopefully alleviate speed problems.
+# hash than we have to, which should hopefully alleviate speed problems.
sub getById {
my $self = shift;
@@ -2271,16 +2298,28 @@ sub finishResource {
# the actual lookup; parmval caches the results.
sub parmval {
my $self = shift;
- my ($what,$symb)=@_;
+ my ($what,$symb,$recurse)=@_;
my $hashkey = $what."|||".$symb;
if (defined($self->{PARM_CACHE}->{$hashkey})) {
- return $self->{PARM_CACHE}->{$hashkey};
+ if (ref($self->{PARM_CACHE}->{$hashkey}) eq 'ARRAY') {
+ if (defined($self->{PARM_CACHE}->{$hashkey}->[0])) {
+ if (wantarray) {
+ return @{$self->{PARM_CACHE}->{$hashkey}};
+ } else {
+ return $self->{PARM_CACHE}->{$hashkey}->[0];
+ }
+ }
+ } else {
+ return $self->{PARM_CACHE}->{$hashkey};
+ }
}
-
- my $result = $self->parmval_real($what, $symb);
+ my $result = $self->parmval_real($what, $symb, $recurse);
$self->{PARM_CACHE}->{$hashkey} = $result;
- return $result;
+ if (wantarray) {
+ return @{$result};
+ }
+ return $result->[0];
}
sub parmval_real {
@@ -2301,7 +2340,7 @@ sub parmval_real {
my $uname=$env{'user.name'};
my $udom=$env{'user.domain'};
- unless ($symb) { return ''; }
+ unless ($symb) { return ['']; }
my $result='';
my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb);
@@ -2333,48 +2372,49 @@ sub parmval_real {
# ---------------------------------------------------------- first, check user
if ($uname and defined($useropt)) {
- if (defined($$useropt{$courselevelr})) { return $$useropt{$courselevelr}; }
- if (defined($$useropt{$courselevelm})) { return $$useropt{$courselevelm}; }
- if (defined($$useropt{$courselevel})) { return $$useropt{$courselevel}; }
+ if (defined($$useropt{$courselevelr})) { return [$$useropt{$courselevelr},'resource']; }
+ if (defined($$useropt{$courselevelm})) { return [$$useropt{$courselevelm},'map']; }
+ if (defined($$useropt{$courselevel})) { return [$$useropt{$courselevel},'course']; }
}
# ------------------------------------------------------- second, check course
if ($cgroup ne '' and defined($courseopt)) {
- if (defined($$courseopt{$grplevelr})) { return $$courseopt{$grplevelr}; }
- if (defined($$courseopt{$grplevelm})) { return $$courseopt{$grplevelm}; }
- if (defined($$courseopt{$grplevel})) { return $$courseopt{$grplevel}; }
+ if (defined($$courseopt{$grplevelr})) { return [$$courseopt{$grplevelr},'resource']; }
+ if (defined($$courseopt{$grplevelm})) { return [$$courseopt{$grplevelm},'map']; }
+ if (defined($$courseopt{$grplevel})) { return [$$courseopt{$grplevel},'course']; }
}
if ($csec and defined($courseopt)) {
- if (defined($$courseopt{$seclevelr})) { return $$courseopt{$seclevelr}; }
- if (defined($$courseopt{$seclevelm})) { return $$courseopt{$seclevelm}; }
- if (defined($$courseopt{$seclevel})) { return $$courseopt{$seclevel}; }
+ if (defined($$courseopt{$seclevelr})) { return [$$courseopt{$seclevelr},'resource']; }
+ if (defined($$courseopt{$seclevelm})) { return [$$courseopt{$seclevelm},'map']; }
+ if (defined($$courseopt{$seclevel})) { return [$$courseopt{$seclevel},'course']; }
}
if (defined($courseopt)) {
- if (defined($$courseopt{$courselevelr})) { return $$courseopt{$courselevelr}; }
+ if (defined($$courseopt{$courselevelr})) { return [$$courseopt{$courselevelr},'resource']; }
}
# ----------------------------------------------------- third, check map parms
my $thisparm=$$parmhash{$symbparm};
- if (defined($thisparm)) { return $thisparm; }
+ if (defined($thisparm)) { return [$thisparm,'map']; }
# ----------------------------------------------------- fourth , check default
my $meta_rwhat=$rwhat;
$meta_rwhat=~s/\./_/g;
my $default=&Apache::lonnet::metadata($fn,$meta_rwhat);
- if (defined($default)) { return $default}
+ if (defined($default)) { return [$default,'resource']}
$default=&Apache::lonnet::metadata($fn,'parameter_'.$meta_rwhat);
- if (defined($default)) { return $default}
-
+ if (defined($default)) { return [$default,'resource']}
# --------------------------------------------------- fifth, check more course
if (defined($courseopt)) {
- if (defined($$courseopt{$courselevelm})) { return $$courseopt{$courselevelm}; }
- if (defined($$courseopt{$courselevel})) { return $$courseopt{$courselevel}; }
+ if (defined($$courseopt{$courselevelm})) { return [$$courseopt{$courselevelm},'map']; }
+ if (defined($$courseopt{$courselevel})) {
+ my $ret = [$$courseopt{$courselevel},'course'];
+ return $ret;
+ }
}
-
# --------------------------------------------------- sixth , cascade up parts
my ($space,@qualifier)=split(/\./,$rwhat);
@@ -2384,13 +2424,13 @@ sub parmval_real {
my $id=pop(@parts);
my $part=join('_',@parts);
if ($part eq '') { $part='0'; }
- my $partgeneral=$self->parmval($part.".$qualifier",$symb,1);
- if (defined($partgeneral)) { return $partgeneral; }
+ my @partgeneral=$self->parmval($part.".$qualifier",$symb,1);
+ if (defined($partgeneral[0])) { return \@partgeneral; }
}
- if ($recurse) { return undef; }
- my $pack_def=&Apache::lonnet::packages_tab_default($fn,'resource.'.$what);
- if (defined($pack_def)) { return $pack_def; }
- return '';
+ if ($recurse) { return []; }
+ my $pack_def=&Apache::lonnet::packages_tab_default($fn,'resource.'.$rwhat);
+ if (defined($pack_def)) { return [$pack_def,'resource']; }
+ return [''];
}
=pod
@@ -2398,7 +2438,7 @@ sub parmval_real {
=item * B(url,multiple):
Retrieves a resource object by URL of the resource, unless the optional
-multiple parameter is included in wahich caes an array of resource
+multiple parameter is included in which case an array of resource
objects is returned. If passed a resource object, it will simply return
it, so it is safe to use this method in code like
"$res = $navmap->getResourceByUrl($res)"
@@ -2433,7 +2473,7 @@ all matching resources.
=item * B(map, filterFunc, recursive, showall):
-Convience method for
+Convenience method for
scalar(retrieveResources($map, $filterFunc, $recursive, 1, $showall)) > 0
@@ -2511,6 +2551,10 @@ sub retrieveResources {
my @resources = ();
+ if (&$filterFunc($map)) {
+ push(@resources, $map);
+ }
+
# Run down the iterator and collect the resources.
my $curRes;
@@ -2520,7 +2564,7 @@ sub retrieveResources {
next;
}
- push @resources, $curRes;
+ push(@resources, $curRes);
if ($bailout) {
return @resources;
@@ -2667,7 +2711,7 @@ be the tokens described above.
Also note there is some old code floating around that trys to track
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 then
+code. It is difficult to get right and harder to understand than
this. They should be migrated to this new style.
=cut
@@ -2851,6 +2895,10 @@ sub next {
$self->{HAVE_RETURNED_0} = 1;
return $self->{NAV_MAP}->getById('0.0');
}
+ if ($self->{RETURN_0} && !$self->{HAVE_RETURNED_0_BEGIN_MAP}) {
+ $self->{HAVE_RETURNED_0_BEGIN_MAP} = 1;
+ return $self->BEGIN_MAP();
+ }
if ($self->{RECURSIVE_ITERATOR_FLAG}) {
# grab the next from the recursive iterator
@@ -2952,7 +3000,7 @@ sub next {
}
# Is this the end of a branch? If so, all of the resources examined above
- # led to lower levels then the one we are currently at, so we push a END_BRANCH
+ # led to lower levels than the one we are currently at, so we push a END_BRANCH
# marker onto the stack so we don't forget.
# Example: For the usual A(BC)(DE)F case, when the iterator goes down the
# BC branch and gets to C, it will see F as the only next resource, but it's
@@ -3288,7 +3336,7 @@ X X
All resources also have Bs, which uniquely identify a resource
in a course. Many internal LON-CAPA functions expect a symb. A symb
carries along with it the URL of the resource, and the map it appears
-in. Symbs are much larger then resource IDs.
+in. Symbs are much larger than resource IDs.
=cut
@@ -3364,8 +3412,13 @@ false.
=item * B:
-Returns true for a map if the randompick feature is being used on the
-map. (?)
+Returns the number of randomly picked items for a map if the randompick
+feature is being used on the map.
+
+=item * B:
+
+Returns true for a map if the randomorder feature is being used on the
+map.
=item * B:
@@ -3395,7 +3448,13 @@ sub kind { my $self=shift; return $self-
sub randomout { my $self=shift; return $self->navHash("randomout_", 1); }
sub randompick {
my $self = shift;
- return $self->parmval('randompick');
+ my $randompick = $self->parmval('randompick');
+ return $randompick;
+}
+sub randomorder {
+ my $self = shift;
+ my $randomorder = $self->parmval('randomorder');
+ return ($randomorder =~ /^yes$/i);
}
sub link {
my $self=shift;
@@ -3473,6 +3532,7 @@ sub compTitle {
}
return $title;
}
+
=pod
B
@@ -3515,7 +3575,8 @@ sub retrieveResources {
sub is_exam {
my ($self,$part) = @_;
- if ($self->parmval('type',$part) eq 'exam') {
+ my $type = $self->parmval('type',$part);
+ if ($type eq 'exam') {
return 1;
}
if ($self->src() =~ /\.(exam)$/) {
@@ -3538,7 +3599,8 @@ sub is_page {
sub is_practice {
my $self=shift;
my ($part) = @_;
- if ($self->parmval('type',$part) eq 'practice') {
+ my $type = $self->parmval('type',$part);
+ if ($type eq 'practice') {
return 1;
}
return 0;
@@ -3551,6 +3613,15 @@ sub is_problem {
}
return 0;
}
+sub is_raw_problem {
+ my $self=shift;
+ my $src = $self->src();
+ if ($src =~ /\.(problem|exam|quiz|assess|survey|form|library|task)$/) {
+ return 1;
+ }
+ return 0;
+}
+
sub contains_problem {
my $self=shift;
if ($self->is_page()) {
@@ -3559,6 +3630,15 @@ sub contains_problem {
}
return 0;
}
+sub map_contains_problem {
+ my $self=shift;
+ if ($self->is_map()) {
+ my $has_problem=
+ $self->hasResource($self,sub { $_[0]->is_problem() },1);
+ return $has_problem;
+ }
+ return 0;
+}
sub is_sequence {
my $self=shift;
return $self->navHash("is_map_", 1) &&
@@ -3567,7 +3647,8 @@ sub is_sequence {
sub is_survey {
my $self = shift();
my $part = shift();
- if ($self->parmval('type',$part) eq 'survey') {
+ my $type = $self->parmval('type',$part);
+ if ($type eq 'survey') {
return 1;
}
if ($self->src() =~ /\.(survey)$/) {
@@ -3665,9 +3746,9 @@ sub map_type {
# These functions will be responsible for returning the CORRECT
# VALUE for the parameter, no matter what. So while they may look
-# like direct calls to parmval, they can be more then that.
+# like direct calls to parmval, they can be more than that.
# So, for instance, the duedate function should use the "duedatetype"
-# information, rather then the resource object user.
+# information, rather than the resource object user.
=pod
@@ -3743,16 +3824,19 @@ Get the weight for the problem.
sub acc {
(my $self, my $part) = @_;
- return $self->parmval("acc", $part);
+ my $acc = $self->parmval("acc", $part);
+ return $acc;
}
sub answerdate {
(my $self, my $part) = @_;
# Handle intervals
- if ($self->parmval("answerdate.type", $part) eq 'date_interval') {
- return $self->duedate($part) +
- $self->parmval("answerdate", $part);
+ my $answerdatetype = $self->parmval("answerdate.type", $part);
+ my $answerdate = $self->parmval("answerdate", $part);
+ my $duedate = $self->parmval("duedate", $part);
+ if ($answerdatetype eq 'date_interval') {
+ $answerdate = $duedate + $answerdate;
}
- return $self->parmval("answerdate", $part);
+ return $answerdate;
}
sub awarded {
my $self = shift; my $part = shift;
@@ -3764,13 +3848,15 @@ sub awarded {
sub duedate {
(my $self, my $part) = @_;
my $date;
- my $interval=$self->parmval("interval", $part);
+ my @interval=$self->parmval("interval", $part);
my $due_date=$self->parmval("duedate", $part);
- if ($interval =~ /\d+/) {
- my $first_access=&Apache::lonnet::get_first_access('map',$self->symb);
+ if ($interval[0] =~ /\d+/) {
+ my $first_access=&Apache::lonnet::get_first_access($interval[1],
+ $self->symb);
if (defined($first_access)) {
- $interval = $first_access+$interval;
- $date = ($interval < $due_date)? $interval : $due_date;
+ my $interval = $first_access+$interval[0];
+ $date = (!$due_date || $interval < $due_date) ? $interval
+ : $due_date;
} else {
$date = $due_date;
}
@@ -3781,33 +3867,49 @@ sub duedate {
}
sub handgrade {
(my $self, my $part) = @_;
- return $self->parmval("handgrade", $part);
+ my @response_ids = $self->responseIds($part);
+ if (@response_ids) {
+ foreach my $response_id (@response_ids) {
+ my $handgrade = $self->parmval("handgrade",$part.'_'.$response_id);
+ if (lc($handgrade) eq 'yes') {
+ return 'yes';
+ }
+ }
+ }
+ my $handgrade = $self->parmval("handgrade", $part);
+ return $handgrade;
}
sub maxtries {
(my $self, my $part) = @_;
- return $self->parmval("maxtries", $part);
+ my $maxtries = $self->parmval("maxtries", $part);
+ return $maxtries;
}
sub opendate {
(my $self, my $part) = @_;
- if ($self->parmval("opendate.type", $part) eq 'date_interval') {
- return $self->duedate($part) -
- $self->parmval("opendate", $part);
+ my $opendatetype = $self->parmval("opendate.type", $part);
+ my $opendate = $self->parmval("opendate", $part);
+ if ($opendatetype eq 'date_interval') {
+ my $duedate = $self->duedate($part);
+ $opendate = $duedate - $opendate;
}
- return $self->parmval("opendate");
+ return $opendate;
}
sub problemstatus {
(my $self, my $part) = @_;
- return lc $self->parmval("problemstatus", $part);
+ my $problemstatus = $self->parmval("problemstatus", $part);
+ return lc($problemstatus);
}
sub sig {
(my $self, my $part) = @_;
- return $self->parmval("sig", $part);
+ my $sig = $self->parmval("sig", $part);
+ return $sig;
}
sub tol {
(my $self, my $part) = @_;
- return $self->parmval("tol", $part);
+ my $tol = $self->parmval("tol", $part);
+ return $tol;
}
-sub tries {
+sub tries {
my $self = shift;
my $tries = $self->queryRestoreHash('tries', shift);
if (!defined($tries)) { return '0';}
@@ -3815,15 +3917,17 @@ sub tries {
}
sub type {
(my $self, my $part) = @_;
- return $self->parmval("type", $part);
+ my $type = $self->parmval("type", $part);
+ return $type;
}
sub weight {
my $self = shift; my $part = shift;
if (!defined($part)) { $part = '0'; }
- return &Apache::lonnet::EXT('resource.'.$part.'.weight',
- $self->symb(), $env{'user.domain'},
- $env{'user.name'},
- $env{'request.course.sec'});
+ my $weight = &Apache::lonnet::EXT('resource.'.$part.'.weight',
+ $self->symb(), $env{'user.domain'},
+ $env{'user.name'},
+ $env{'request.course.sec'});
+ return $weight;
}
sub part_display {
my $self= shift(); my $partID = shift();
@@ -4497,7 +4601,11 @@ sub status {
#if ($self->{RESOURCE_ERROR}) { return NETWORK_FAILURE; }
if ($completionStatus == NETWORK_FAILURE) { return NETWORK_FAILURE; }
- my $suppressFeedback = $self->problemstatus($part) eq 'no';
+ my $suppressFeedback = 0;
+ if (($self->problemstatus($part) eq 'no') ||
+ ($self->problemstatus($part) eq 'no_feedback_ever')) {
+ $suppressFeedback = 1;
+ }
# If there's an answer date and we're past it, don't
# suppress the feedback; student should know
if ($self->duedate($part) && $self->duedate($part) < time() &&
500 Internal Server Error
Internal Server Error
The server encountered an internal error or
misconfiguration and was unable to complete
your request.
Please contact the server administrator at
root@localhost to inform them of the time this error occurred,
and the actions you performed just before this error.
More information about this error may be available
in the server error log.