'."\n";
return $result;
}
@@ -2380,7 +2356,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.
@@ -3518,6 +3494,8 @@ sub new {
$self->{NAV_MAP}->{RESOURCE_CACHE}->{$self->{ID}} = $self;
$self->{RESOURCE_ERROR} = 0;
+ $self->{DUEDATE_CACHE} = undef;
+
# A hash that can be used by two-pass algorithms to store data
# about this resource in. Not used by the resource object
# directly.
@@ -3535,7 +3513,11 @@ sub navHash {
my $self = shift;
my $param = shift;
my $id = shift;
- return $self->{NAV_MAP}->navhash($param . ($id?$self->{ID}:""));
+ my $arg = $param . ($id?$self->{ID}:"");
+ if (defined($arg)) {
+ return $self->{NAV_MAP}->navhash($arg);
+ }
+ return;
}
=pod
@@ -3778,6 +3760,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();
@@ -3813,7 +3824,7 @@ 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)$/) {
@@ -3821,6 +3832,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();
@@ -3874,6 +3894,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
@@ -3904,6 +3930,12 @@ 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
@@ -4041,6 +4073,9 @@ sub checkedin {
# this should work exactly like the copy in lonhomework.pm
sub duedate {
(my $self, my $part) = @_;
+ if (defined ($self->{DUEDATE_CACHE}->{$part})) {
+ return $self->{DUEDATE_CACHE}->{$part};
+ }
my $date;
my @interval=$self->parmval("interval", $part);
my $due_date=$self->parmval("duedate", $part);
@@ -4057,6 +4092,7 @@ sub duedate {
} else {
$date = $due_date;
}
+ $self->{DUEDATE_CACHE}->{$part} = $date;
return $date;
}
sub handgrade {
@@ -4659,6 +4695,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
@@ -4670,6 +4710,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;
@@ -4688,6 +4729,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;
}
@@ -4777,6 +4825,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.
@@ -4850,6 +4902,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;
@@ -4952,7 +5008,7 @@ sub check_for_slot {
my $taskstatus = $self->taskstatus();
$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_/);
@@ -5042,6 +5098,7 @@ my %compositeToSimple =
INCORRECT() => INCORRECT,
OPEN() => OPEN,
ATTEMPTED() => ATTEMPTED,
+ CREDIT_ATTEMPTED() => CORRECT,
ANSWER_SUBMITTED() => ATTEMPTED
);
@@ -5115,8 +5172,9 @@ sub completable {
# "If any of the parts are open, or have tries left (implies open),
# and it is not "attempted" (manually graded problem), it is
# not "complete"
- if ($self->getCompletionStatus($part) == ATTEMPTED() ||
- $status == ANSWER_SUBMITTED() ) {
+ if ($self->getCompletionStatus($part) == ATTEMPTED() ||
+ $self->getCompletionStatus($part) == CREDIT_ATTEMPTED() ||
+ $status == ANSWER_SUBMITTED() ) {
# did this part already, as well as we can
next;
}