header_only) {
- if ($env{'browser.mathml'}) {
- &Apache::loncommon::content_type($r,'text/xml');
- } else {
- &Apache::loncommon::content_type($r,'text/html');
- }
- $r->send_http_header;
- return OK;
- }
-
- # Send header, don't cache this page
- if ($env{'browser.mathml'}) {
- &Apache::loncommon::content_type($r,'text/xml');
- } else {
- &Apache::loncommon::content_type($r,'text/html');
- }
- &Apache::loncommon::no_cache($r);
-
- my %toplinkitems=();
- &add_linkitem(\%toplinkitems,'blank','',"Select Action");
- if ($ENV{QUERY_STRING} eq 'collapseExternal') {
- &Apache::lonnet::put('environment',{'remotenavmap' => 'off'});
- &Apache::lonnet::appenv('environment.remotenavmap' => 'off');
- my $menu=&Apache::lonmenu::reopenmenu();
- my $navstatus=&Apache::lonmenu::get_nav_status();
- if ($menu) {
- $menu=(<');
- $r->print('
- ');
- }
-
- if ($env{'environment.remotenavmap'} ne 'on') {
- $r->print(&launch_win('link','yes',\%toplinkitems));
- }
- if ($env{'environment.remotenavmap'} eq 'on') {
- &add_linkitem(\%toplinkitems,'closenav','collapse()',
- "Close navigation window");
- }
-
-
- # Check to see if the student is jumping to next open, do-able problem
- if ($ENV{QUERY_STRING} =~ /^jumpToFirstHomework/) {
- # Find the next homework problem that they can do.
- my $iterator = $navmap->getIterator(undef, undef, undef, 1);
- my $curRes;
- my $foundDoableProblem = 0;
- my $minimumduedate;
-
- while ($curRes = $iterator->next()) {
- if (ref($curRes) && $curRes->is_problem()) {
- my $status = $curRes->status();
- if ($curRes->completable()) {
- my $thisduedate=$curRes->duedate();
- unless ($foundDoableProblem) {
- $minimumduedate=$thisduedate;
- }
-
- $foundDoableProblem = 1;
-
- if ($thisduedate<=$minimumduedate) {
- # Pop open all previous maps
- my $stack = $iterator->getStack();
- pop @$stack; # last resource in the stack is the problem
- # itself, which we don't need in the map stack
- my @mapPcs = map {$_->map_pc()} @$stack;
- $env{'form.filter'} = join(',', @mapPcs);
-
- # Mark as both "here" and "jump"
- $env{'form.postsymb'} = $curRes->symb();
- $minimumduedate=$thisduedate;
- }
- }
- }
- }
-
- # If we found no problems, print a note to that effect.
- if (!$foundDoableProblem) {
- $r->print("All homework assignments have been completed.
");
- }
- } else {
- &add_linkitem(\%toplinkitems,'firsthomework',
- 'location.href="navmaps?jumpToFirstHomework"',
- "Show my first due problem");
- }
-
- my $suppressEmptySequences = 0;
- my $filterFunc = undef;
- my $resource_no_folder_link = 0;
-
- # Display only due homework.
- my $showOnlyHomework = 0;
- if ($env{'form.showOnlyHomework'} eq "1") {
- $showOnlyHomework = 1;
- $suppressEmptySequences = 1;
- $filterFunc = sub { my $res = shift;
- return $res->completable() || $res->is_map();
- };
- &add_linkitem(\%toplinkitems,'everything',
- 'location.href="navmaps?sort='.$env{'form.sort'}.'"',
- "Show everything");
- $r->print("".&mt("Uncompleted Problems")."
");
- $env{'form.filter'} = '';
- $env{'form.condition'} = 1;
- $resource_no_folder_link = 1;
- } else {
- &add_linkitem(\%toplinkitems,'uncompleted',
- 'location.href="navmaps?sort='.$env{'form.sort'}.
- '&showOnlyHomework=1"',
- "Show only uncompleted problems");
- }
-
- my %selected=($env{'form.sort'} => 'selected=on');
- my $sort_html=("");
- # renderer call
- my $renderArgs = { 'cols' => [0,1,2,3],
- 'sort' => $env{'form.sort'},
- 'url' => '/adm/navmaps',
- 'navmap' => $navmap,
- 'suppressNavmap' => 1,
- 'suppressEmptySequences' => $suppressEmptySequences,
- 'filterFunc' => $filterFunc,
- 'resource_no_folder_link' => $resource_no_folder_link,
- 'sort_html'=> $sort_html,
- 'r' => $r,
- 'caller' => 'navmapsdisplay',
- 'linkitems' => \%toplinkitems};
- my $render = render($renderArgs);
-
- # If no resources were printed, print a reassuring message so the
- # user knows there was no error.
- if ($renderArgs->{'counter'} == 0) {
- if ($showOnlyHomework) {
- $r->print("".&mt("All homework is currently completed").".
");
- } else { # both jumpToFirstHomework and normal use the same: course must be empty
- $r->print("This course is empty.
");
- }
- }
- #my $td=&tv_interval($t0);
- #$r->print("
$td");
-
- $r->print(&Apache::loncommon::end_page());
- $r->rflush();
-
- return OK;
-}
-
# Convenience functions: Returns a string that adds or subtracts
# the second argument from the first hash, appropriate for the
# query string that determines which folders to recurse on
@@ -474,7 +149,7 @@ sub getLinkForResource {
if (defined($res)) {
my $anchor;
if ($res->is_page()) {
- foreach (@$stack) { if (defined($_)) { $anchor = $_; } }
+ foreach my $item (@$stack) { if (defined($item)) { $anchor = $item; } }
$anchor=&escape($anchor->shown_symb());
return ($res->link(),$res->shown_symb(),$anchor);
}
@@ -492,8 +167,8 @@ sub getLinkForResource {
# (when we first recurse on a map, it puts an undefined resource
# on the bottom because $self->{HERE} isn't defined yet, and we
# want the src for the map anyhow)
- foreach (@$stack) {
- if (defined($_)) { $res = $_; }
+ foreach my $item (@$stack) {
+ if (defined($item)) { $res = $item; }
}
return ($res->link(),$res->shown_symb());
@@ -1097,7 +772,13 @@ sub render_resource {
if ($resource->is_problem()) {
if ($part eq '0' || $params->{'condensed'}) {
- $icon ='';
+ $icon = '';
} else {
$icon = $params->{'indentString'};
}
@@ -1122,16 +803,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
@@ -1153,7 +834,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--; }
@@ -1217,17 +898,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 .= ' '
- . ''
+ . '';
}
}
@@ -1236,13 +917,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 .= ' '
- . ''
+ . '';
}
}
@@ -1252,7 +933,7 @@ sub render_communication_status {
$discussionHTML = $feedbackHTML = $errorHTML = '';
}
- return " | $discussionHTML$feedbackHTML$errorHTML | ";
+ return "$discussionHTML$feedbackHTML$errorHTML | ";
}
sub render_quick_status {
@@ -1277,7 +958,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";
}
@@ -1289,7 +970,7 @@ 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";
@@ -1445,9 +1126,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";
}
}
@@ -1475,7 +1156,7 @@ sub render {
$navmap = Apache::lonnavmaps::navmap->new();
if (!defined($navmap)) {
# no londer in course
- return ''.&mt('No course selected').'
+ return ''.&mt('No course selected').'
'.&mt('Select a course').' ';
}
}
@@ -1613,11 +1294,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';
}
@@ -1664,7 +1345,7 @@ END
if ($args->{'caller'} eq 'navmapsdisplay') {
$result .= ''.
- &Apache::loncommon::help_open_menu('','Navigation Screen','Navigation_Screen','',undef,'RAT').' | ';
+ &Apache::loncommon::help_open_menu('Navigation Screen','Navigation_Screen',undef,'RAT').'';
if ($env{'environment.remotenavmap'} ne 'on') {
$result .= ' | ';
} else {
@@ -2220,10 +1901,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=();
@@ -2233,22 +1914,32 @@ 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);
+ 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;
@@ -2353,9 +2044,10 @@ 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();
@@ -2367,12 +2059,10 @@ sub unread_discussion {
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};
@@ -2388,18 +2078,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 {
@@ -2430,23 +2126,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
@@ -3436,9 +3157,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;
}
}
@@ -4041,7 +3762,7 @@ sub duedate {
my $date;
my $interval=$self->parmval("interval", $part);
my $due_date=$self->parmval("duedate", $part);
- if (defined($interval)) {
+ if ($interval =~ /\d+/) {
my $first_access=&Apache::lonnet::get_first_access('map',$self->symb);
if (defined($first_access)) {
$interval = $first_access+$interval;
@@ -4154,13 +3875,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:
@@ -4169,8 +3892,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.
@@ -4187,23 +3910,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
@@ -4364,8 +4089,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})) {
@@ -4390,8 +4115,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
@@ -4471,13 +4196,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 ...
}
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.
|