: default: constructs one from %env
A reference to a navmap, used only if an iterator is not passed in. If
@@ -1096,7 +794,13 @@ sub render_resource {
if ($resource->is_problem()) {
if ($part eq '0' || $params->{'condensed'}) {
- $icon ='';
+ $icon = '';
} else {
$icon = $params->{'indentString'};
}
@@ -1121,16 +825,16 @@ sub render_resource {
($nowOpen ? &mt('Open Folder') : &mt('Close Folder')).' '.$title."\" border='0' />";
$linkopen = "{'url'} . '?' .
- $params->{'queryString'} . '&filter=';
+ $params->{'queryString'} . '&filter=';
$linkopen .= ($nowOpen xor $it->{CONDITION}) ?
addToFilter($filter, $mapId) :
removeFromFilter($filter, $mapId);
- $linkopen .= "&condition=" . $it->{CONDITION} . '&hereType='
- . $params->{'hereType'} . '&here=' .
+ $linkopen .= "&condition=" . $it->{CONDITION} . '&hereType='
+ . $params->{'hereType'} . '&here=' .
&escape($params->{'here'}) .
- '&jump=' .
+ '&jump=' .
&escape($resource->symb()) .
- "&folderManip=1\">";
+ "&folderManip=1\">";
} else {
# Don't allow users to manipulate folder
@@ -1152,7 +856,7 @@ sub render_resource {
}
# We're done preparing and finally ready to start the rendering
- my $result = "";
+ my $result = " | ";
my $indentLevel = $params->{'indentLevel'};
if ($newBranchText) { $indentLevel--; }
@@ -1216,17 +920,17 @@ sub render_communication_status {
my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc");
if ($resource->hasDiscussion()) {
$discussionHTML = $linkopen .
- '' .
+ '' .
$linkclose;
}
if ($resource->getFeedback()) {
my $feedback = $resource->getFeedback();
- foreach (split(/\,/, $feedback)) {
- if ($_) {
+ foreach my $msgid (split(/\,/, $feedback)) {
+ if ($msgid) {
$feedbackHTML .= ' '
- . ''
+ . '';
}
}
@@ -1235,13 +939,13 @@ sub render_communication_status {
if ($resource->getErrors()) {
my $errors = $resource->getErrors();
my $errorcount = 0;
- foreach (split(/,/, $errors)) {
+ foreach my $msgid (split(/,/, $errors)) {
last if ($errorcount>=10); # Only output 10 bombs maximum
- if ($_) {
+ if ($msgid) {
$errorcount++;
$errorHTML .= ' '
- . ''
+ . '';
}
}
@@ -1251,7 +955,7 @@ sub render_communication_status {
$discussionHTML = $feedbackHTML = $errorHTML = '';
}
- return " | $discussionHTML$feedbackHTML$errorHTML | ";
+ return "$discussionHTML$feedbackHTML$errorHTML | ";
}
sub render_quick_status {
@@ -1276,7 +980,7 @@ sub render_quick_status {
if ($icon) {
my $location=
&Apache::loncommon::lonhttpdurl("/adm/lonIcons/$icon");
- $result .= "$linkopen$linkclose | \n";
+ $result .= "$linkopen$linkclose | \n";
} else {
$result .= " | \n";
}
@@ -1288,12 +992,12 @@ sub render_quick_status {
}
sub render_long_status {
my ($resource, $part, $params) = @_;
- my $result = "\n";
+ my $result = " | \n";
my $firstDisplayed = !$params->{'condensed'} &&
$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) ||
@@ -1303,14 +1007,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
@@ -1345,7 +1052,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 ' | | '; }
@@ -1444,9 +1150,9 @@ sub render {
# marker
my $filterHash = {};
# Figure out what we're not displaying
- foreach (split(/\,/, $env{"form.filter"})) {
- if ($_) {
- $filterHash->{$_} = "1";
+ foreach my $item (split(/\,/, $env{"form.filter"})) {
+ if ($item) {
+ $filterHash->{$item} = "1";
}
}
@@ -1552,7 +1258,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'});
}
}
@@ -1589,7 +1295,6 @@ sub render {
# Print key?
if ($printKey) {
$result .= '';
- my $date=localtime;
$result.='Key: | ';
my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc");
if ($navmap->{LAST_CHECK}) {
@@ -1612,11 +1317,11 @@ sub render {
if ($printCloseAll && !$args->{'resource_no_folder_link'}) {
my ($link,$text);
if ($condition) {
- $link='"navmaps?condition=0&filter=&'.$queryString.
+ $link='"navmaps?condition=0&filter=&'.$queryString.
'&here='.&escape($here).'"';
$text='Close all folders';
} else {
- $link='"navmaps?condition=1&filter=&'.$queryString.
+ $link='"navmaps?condition=1&filter=&'.$queryString.
'&here='.&escape($here).'"';
$text='Open all folders';
}
@@ -2120,6 +1825,7 @@ See iterator documentation below.
use strict;
use GDBM_File;
use Apache::lonnet;
+use LONCAPA;
sub new {
# magic invocation to create a class instance
@@ -2219,10 +1925,10 @@ sub generate_email_discuss_status {
my %lastread = &Apache::lonnet::dump('nohist_'.$cid.'_discuss',
$env{'user.domain'},$env{'user.name'},'lastread');
my %lastreadtime = ();
- foreach (keys %lastread) {
- my $key = $_;
- $key =~ s/_lastread$//;
- $lastreadtime{$key} = $lastread{$_};
+ foreach my $key (keys %lastread) {
+ my $shortkey = $key;
+ $shortkey =~ s/_lastread$//;
+ $lastreadtime{$shortkey} = $lastread{$key};
}
my %feedback=();
@@ -2232,22 +1938,36 @@ sub generate_email_discuss_status {
foreach my $msgid (@keys) {
if ((!$emailstatus{$msgid}) || ($emailstatus{$msgid} eq 'new')) {
- my $plain=
- &LONCAPA::unescape(&LONCAPA::unescape($msgid));
- if ($plain=~/ \[([^\]]+)\]\:/) {
- my $url=$1;
- if ($plain=~/\:Error \[/) {
- $error{$url}.=','.$msgid;
- } else {
- $feedback{$url}.=','.$msgid;
- }
- }
+ my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$fromcid,
+ $symb,$error) = &Apache::lonmsg::unpackmsgid($msgid);
+ &Apache::lonenc::check_decrypt(\$symb);
+ if (($fromcid ne '') && ($fromcid ne $cid)) {
+ next;
+ }
+ if (defined($symb)) {
+ if (defined($error) && $error == 1) {
+ $error{$symb}.=','.$msgid;
+ } else {
+ $feedback{$symb}.=','.$msgid;
+ }
+ } else {
+ my $plain=
+ &LONCAPA::unescape(&LONCAPA::unescape($msgid));
+ if ($plain=~/ \[([^\]]+)\]\:/) {
+ my $url=$1;
+ if ($plain=~/\:Error \[/) {
+ $error{$url}.=','.$msgid;
+ } else {
+ $feedback{$url}.=','.$msgid;
+ }
+ }
+ }
}
}
- #url's of resources that have feedbacks
+ #symbs of resources that have feedbacks (will be urls pre-2.3)
$self->{FEEDBACK} = \%feedback;
- #or errors
+ #or errors (will be urls pre 2.3)
$self->{ERROR_MSG} = \%error;
$self->{DISCUSSION_TIME} = \%discussiontime;
$self->{EMAIL_STATUS} = \%emailstatus;
@@ -2352,26 +2072,25 @@ sub last_post_time {
return $self->{DISCUSSION_TIME}->{$ressymb};
}
-sub unread_discussion {
+sub discussion_info {
my $self = shift;
my $symb = shift;
+ my $filter = shift;
$self->get_discussion_data();
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; }
my $prevread = $self->{LAST_READ}{$ressymb};
- my $unreadcount = 0;
+ my $count = 0;
my $hiddenflag = 0;
my $deletedflag = 0;
- my ($hidden,$deleted);
-
- my %subjects;
+ my ($hidden,$deleted,%info);
for (my $id=$version; $id>0; $id--) {
my $vkeys=$self->{DISCUSSION_DATA}{$id.':keys:'.$discsymb};
@@ -2387,18 +2106,24 @@ sub unread_discussion {
$deletedflag = 1;
}
} else {
- if (($hidden !~/\.$id\./) && ($deleted !~/\.$id\./)
- && $prevread < $self->{DISCUSSION_DATA}{$id.':'.$discsymb.':timestamp'}) {
- $unreadcount++;
- $subjects{$unreadcount}=
- $id.': '.$self->{DISCUSSION_DATA}{$id.':'.$discsymb.':subject'};
- }
+ if (($hidden !~/\.$id\./) && ($deleted !~/\.$id\./)) {
+ if ($filter eq 'unread') {
+ if ($prevread >= $self->{DISCUSSION_DATA}{$id.':'.$discsymb.':timestamp'}) {
+ next;
+ }
+ }
+ $count++;
+ $info{$count}{'subject'} =
+ $self->{DISCUSSION_DATA}{$id.':'.$discsymb.':subject'};
+ $info{$count}{'id'} = $id;
+ $info{$count}{'timestamp'} = $self->{DISCUSSION_DATA}{$id.':'.$discsymb.':timestamp'};
+ }
}
}
if (wantarray) {
- return ($unreadcount,\%subjects);
+ return ($count,%info);
}
- return $unreadcount
+ return $count;
}
sub wrap_symb {
@@ -2429,23 +2154,48 @@ sub unwrap_symb {
sub getFeedback {
my $self = shift;
my $symb = shift;
+ my $source = shift;
$self->generate_email_discuss_status();
if (!defined($self->{FEEDBACK})) { return ""; }
- return $self->{FEEDBACK}->{$symb};
+ my $feedback;
+ if ($self->{FEEDBACK}->{$symb}) {
+ $feedback = $self->{FEEDBACK}->{$symb};
+ if ($self->{FEEDBACK}->{$source}) {
+ $feedback .= ','.$self->{FEEDBACK}->{$source};
+ }
+ } else {
+ if ($self->{FEEDBACK}->{$source}) {
+ $feedback = $self->{FEEDBACK}->{$source};
+ }
+ }
+ return $feedback;
}
# Private method: Get the errors for that resource (by source).
sub getErrors {
my $self = shift;
+ my $symb = shift;
my $src = shift;
$self->generate_email_discuss_status();
if (!defined($self->{ERROR_MSG})) { return ""; }
- return $self->{ERROR_MSG}->{$src};
+
+ my $errors;
+ if ($self->{ERROR_MSG}->{$symb}) {
+ $errors = $self->{ERROR_MSG}->{$symb};
+ if ($self->{ERROR_MSG}->{$src}) {
+ $errors .= ','.$self->{ERROR_MSG}->{$src};
+ }
+ } else {
+ if ($self->{ERROR_MSG}->{$src}) {
+ $errors = $self->{ERROR_MSG}->{$src};
+ }
+ }
+ return $errors;
}
=pod
@@ -2471,7 +2221,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;
@@ -2545,16 +2295,23 @@ 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 (wantarray) {
+ return @{$self->{PARM_CACHE}->{$hashkey}};
+ } else {
+ return $self->{PARM_CACHE}->{$hashkey}->[0];
+ }
}
- 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 {
@@ -2575,7 +2332,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);
@@ -2607,48 +2364,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);
@@ -2658,13 +2416,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
@@ -2672,7 +2430,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)"
@@ -2707,7 +2465,7 @@ all matching resources.
=item * B(map, filterFunc, recursive, showall):
-Convience method for
+Convenience method for
scalar(retrieveResources($map, $filterFunc, $recursive, 1, $showall)) > 0
@@ -2785,6 +2543,10 @@ sub retrieveResources {
my @resources = ();
+ if (&$filterFunc($map)) {
+ push(@resources, $map);
+ }
+
# Run down the iterator and collect the resources.
my $curRes;
@@ -2794,7 +2556,7 @@ sub retrieveResources {
next;
}
- push @resources, $curRes;
+ push(@resources, $curRes);
if ($bailout) {
return @resources;
@@ -2941,7 +2703,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
@@ -3125,6 +2887,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
@@ -3226,7 +2992,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
@@ -3435,9 +3201,9 @@ sub next {
# filter the next possibilities to remove things we've
# already seen.
- foreach (@$nextUnfiltered) {
- if (!defined($self->{ALREADY_SEEN}->{$_->{ID}})) {
- push @$next, $_;
+ foreach my $item (@$nextUnfiltered) {
+ if (!defined($self->{ALREADY_SEEN}->{$item->{ID}})) {
+ push @$next, $item;
}
}
@@ -3562,7 +3328,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
@@ -3638,8 +3404,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:
@@ -3671,6 +3442,10 @@ sub randompick {
my $self = shift;
return $self->parmval('randompick');
}
+sub randomorder {
+ my $self = shift;
+ return ($self->parmval('randomorder') =~ /^yes$/i);
+}
sub link {
my $self=shift;
if ($self->encrypted()) { return &Apache::lonenc::encrypted($self->src); }
@@ -3747,6 +3522,7 @@ sub compTitle {
}
return $title;
}
+
=pod
B
@@ -3833,6 +3609,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) &&
@@ -3939,9 +3724,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
@@ -4038,13 +3823,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 (defined($interval)) {
- 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;
}
@@ -4055,6 +3842,15 @@ sub duedate {
}
sub handgrade {
(my $self, my $part) = @_;
+ my @response_ids = $self->responseIds($part);
+ if (@response_ids) {
+ foreach my $response_id (@response_ids) {
+ if (lc($self->parmval("handgrade",$part.'_'.$response_id))
+ eq 'yes') {
+ return 'yes';
+ }
+ }
+ }
return $self->parmval("handgrade", $part);
}
sub maxtries {
@@ -4153,13 +3949,15 @@ data was not extracted when the nav map
Returns a false value if there hasn't been discussion otherwise returns
unix timestamp of last time a discussion posting (or edit) was made.
-=item * B:
+=item * B:
-returns in scalar context the count of the number of unread discussion
-postings
+optional argument is a filter (currently can be 'unread');
+returns in scalar context the count of the number of discussion postings.
returns in list context both the count of postings and a hash ref
-containing the subjects of all unread postings
+containing information about the postings (subject, id, timestamp) in a hash.
+
+Default is to return counts for all postings. However if called with a second argument set to 'unread', will return information about only unread postings.
=item * B:
@@ -4168,8 +3966,8 @@ for the resource, or the null string if
email data was not extracted when the nav map was constructed. Usually
used like this:
- for (split(/\,/, $res->getFeedback())) {
- my $link = &escape($_);
+ for my $url (split(/\,/, $res->getFeedback())) {
+ my $link = &escape($url);
...
and use the link as appropriate.
@@ -4186,23 +3984,25 @@ sub last_post_time {
return $self->{NAV_MAP}->last_post_time($self->symb());
}
-sub unread_discussion {
- my $self = shift;
- return $self->{NAV_MAP}->unread_discussion($self->symb());
+sub discussion_info {
+ my ($self,$filter) = @_;
+ return $self->{NAV_MAP}->discussion_info($self->symb(),$filter);
}
sub getFeedback {
my $self = shift;
my $source = $self->src();
+ my $symb = $self->symb();
if ($source =~ /^\/res\//) { $source = substr $source, 5; }
- return $self->{NAV_MAP}->getFeedback($source);
+ return $self->{NAV_MAP}->getFeedback($symb,$source);
}
sub getErrors {
my $self = shift;
my $source = $self->src();
+ my $symb = $self->symb();
if ($source =~ /^\/res\//) { $source = substr $source, 5; }
- return $self->{NAV_MAP}->getErrors($source);
+ return $self->{NAV_MAP}->getErrors($symb,$source);
}
=pod
@@ -4363,8 +4163,8 @@ sub extractParts {
$self->{PART_TYPE} = {};
return;
}
- foreach (split(/\,/,$metadata)) {
- if ($_ =~ /^(?:part|Task)_(.*)$/) {
+ foreach my $entry (split(/\,/,$metadata)) {
+ if ($entry =~ /^(?:part|Task)_(.*)$/) {
my $part = $1;
# This floods the logs if it blows up
if (defined($parts{$part})) {
@@ -4389,8 +4189,8 @@ sub extractParts {
# Init the responseIdHash
- foreach (@{$self->{PARTS}}) {
- $responseIdHash{$_} = [];
+ foreach my $part (@{$self->{PARTS}}) {
+ $responseIdHash{$part} = [];
}
# Now, the unfortunate thing about this is that parts, part name, and
@@ -4470,13 +4270,13 @@ the completion information.
Idiomatic usage of these two methods would probably look something
like
- foreach ($resource->parts()) {
- my $dateStatus = $resource->getDateStatus($_);
- my $completionStatus = $resource->getCompletionStatus($_);
+ foreach my $part ($resource->parts()) {
+ my $dateStatus = $resource->getDateStatus($part);
+ my $completionStatus = $resource->getCompletionStatus($part);
or
- my $status = $resource->status($_);
+ my $status = $resource->status($part);
... use it here ...
}
@@ -4767,7 +4567,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.