version 1.161, 2003/03/20 17:19:29
|
version 1.167, 2003/03/25 22:35:58
|
Line 42
|
Line 42
|
# Jeremy Bowers ... lots of days |
# Jeremy Bowers ... lots of days |
|
|
package Apache::lonnavmaps; |
package Apache::lonnavmaps; |
|
use vars qw($test @refsToUntie %navmaphash %parmhash); |
|
|
use strict; |
use strict; |
use Apache::Constants qw(:common :http); |
use Apache::Constants qw(:common :http); |
Line 49 use Apache::loncommon();
|
Line 50 use Apache::loncommon();
|
use Apache::lonmenu(); |
use Apache::lonmenu(); |
use POSIX qw (floor strftime); |
use POSIX qw (floor strftime); |
|
|
my %navmaphash; |
|
my %parmhash; |
|
|
|
# symbolic constants |
# symbolic constants |
sub SYMB { return 1; } |
sub SYMB { return 1; } |
sub URL { return 2; } |
sub URL { return 2; } |
Line 98 my %colormap =
|
Line 96 my %colormap =
|
# And a special case in the nav map; what to do when the assignment |
# And a special case in the nav map; what to do when the assignment |
# is not yet done and due in less then 24 hours |
# is not yet done and due in less then 24 hours |
my $hurryUpColor = "#FF0000"; |
my $hurryUpColor = "#FF0000"; |
|
$test = 'abc'; |
sub cleanup { |
sub cleanup { |
|
&Apache::lonnet::logthis("Cleanup called."); |
|
&Apache::lonnet::logthis("refs size".scalar(@refsToUntie)); |
|
&Apache::lonnet::logthis("test is ".$test); |
|
$test = '467'; |
if (tied(%navmaphash)){ |
if (tied(%navmaphash)){ |
&Apache::lonnet::logthis('Cleanup navmaps: navmaphash'); |
&Apache::lonnet::logthis('Cleanup navmaps: navmaphash'); |
unless (untie(%navmaphash)) { |
unless (untie(%navmaphash)) { |
Line 112 sub cleanup {
|
Line 114 sub cleanup {
|
&Apache::lonnet::logthis('Failed cleanup navmaps: parmhash'); |
&Apache::lonnet::logthis('Failed cleanup navmaps: parmhash'); |
} |
} |
} |
} |
|
# Apparently, if you take a reference to a tied hash, both the |
|
# original hash and the tied hash must be untied. Bleh. |
|
for my $ref (@refsToUntie) { |
|
&Apache::lonnet::logthis('Cleanup navmaps: reference'); |
|
unless (untie(%$ref)) { |
|
&Apache::lonnet::logthis('Failed cleanup navmaps: reference'); |
|
} |
|
} |
|
@refsToUntie = (); |
} |
} |
|
|
sub handler { |
sub handler { |
Line 143 sub real_handler {
|
Line 154 sub real_handler {
|
$r->send_http_header; |
$r->send_http_header; |
|
|
# Create the nav map |
# Create the nav map |
my $navmap = Apache::lonnavmaps::navmap->new( |
my $navmap = Apache::lonnavmaps::navmap->new($r, |
$ENV{"request.course.fn"}.".db", |
$ENV{"request.course.fn"}.".db", |
$ENV{"request.course.fn"}."_parms.db", 1, 1); |
$ENV{"request.course.fn"}."_parms.db", 1, 1); |
|
|
Line 220 sub real_handler {
|
Line 231 sub real_handler {
|
'suppressNavmap' => 1, |
'suppressNavmap' => 1, |
'r' => $r}); |
'r' => $r}); |
|
|
$navmap->untieHashes(); |
#$navmap->untieHashes(); |
|
|
|
if (tied(%navmaphash)) { |
|
$r->print("Dang it."); |
|
} else { |
|
$r->print("It's out."); |
|
} |
|
|
|
if (tied(%parmhash)) { |
|
$r->print("Dang it."); |
|
} else { |
|
$r->print("It's out."); |
|
} |
|
|
$r->print("</body></html>"); |
$r->print("</body></html>"); |
$r->rflush(); |
$r->rflush(); |
Line 544 Most of these parameters are only useful
|
Line 567 Most of these parameters are only useful
|
|
|
=item * B<navmap>: A reference to a navmap, used only if an iterator is not passed in. If this is necessary to make an iterator but it is not passed in, a new one will be constructed based on ENV info. This is useful to do basic error checking before passing it off to render. |
=item * B<navmap>: A reference to a navmap, used only if an iterator is not passed in. If this is necessary to make an iterator but it is not passed in, a new one will be constructed based on ENV info. This is useful to do basic error checking before passing it off to render. |
|
|
|
=item * B<r>: The standard Apache response object. This must be passed to the renderer or the course hash will be locked. |
|
|
=item * B<cols>: An array reference |
=item * B<cols>: An array reference |
|
|
=item * B<showParts>: A flag. If yes (default), a line for the resource itself, and a line for each part will be displayed. If not, only one line for each resource will be displayed. |
=item * B<showParts>: A flag. If yes (default), a line for the resource itself, and a line for each part will be displayed. If not, only one line for each resource will be displayed. |
Line 562 Most of these parameters are only useful
|
Line 587 Most of these parameters are only useful
|
|
|
=item * B<currentJumpIndex>: Describes the currently-open row number to cause the browser to jump to, because the user just opened that folder. By default, pulled from the Jump information in the ENV{'form.*'}. |
=item * B<currentJumpIndex>: Describes the currently-open row number to cause the browser to jump to, because the user just opened that folder. By default, pulled from the Jump information in the ENV{'form.*'}. |
|
|
=item * B<r>: The standard Apache response object. If you pass this to the render, it will use it to flush the table every 20 rows and handle the rendering itself. |
|
|
|
=item * B<printKey>: If true, print the key that appears on the top of the standard navmaps. Default is false. |
=item * B<printKey>: If true, print the key that appears on the top of the standard navmaps. Default is false. |
|
|
=item * B<printCloseAll>: If true, print the "Close all folders" or "open all folders" links. Default is true. |
=item * B<printCloseAll>: If true, print the "Close all folders" or "open all folders" links. Default is true. |
Line 700 sub render_resource {
|
Line 723 sub render_resource {
|
$title = ""; |
$title = ""; |
} |
} |
|
|
if ($params->{'multipart'} && $params->{'condensed'}) { |
if ($params->{'condensed'} && $resource->countParts() > 1) { |
$nonLinkedText .= ' (' . $resource->countParts() . ' parts)'; |
$nonLinkedText .= ' (' . $resource->countParts() . ' parts)'; |
} |
} |
|
|
Line 865 sub render {
|
Line 888 sub render {
|
if (!$ENV{'form.folderManip'} && !defined($args->{'iterator'})) { |
if (!$ENV{'form.folderManip'} && !defined($args->{'iterator'})) { |
# Step 1: Check to see if we have a navmap |
# Step 1: Check to see if we have a navmap |
if (!defined($navmap)) { |
if (!defined($navmap)) { |
$navmap = Apache::lonnavmaps::navmap->new( |
$navmap = Apache::lonnavmaps::navmap->new($r, |
$ENV{"request.course.fn"}.".db", |
$ENV{"request.course.fn"}.".db", |
$ENV{"request.course.fn"}."_parms.db", 1, 1); |
$ENV{"request.course.fn"}."_parms.db", 1, 1); |
$mustCloseNavMap = 1; |
$mustCloseNavMap = 1; |
Line 931 sub render {
|
Line 954 sub render {
|
|
|
# Step 1: Check to see if we have a navmap |
# Step 1: Check to see if we have a navmap |
if (!defined($navmap)) { |
if (!defined($navmap)) { |
$navmap = Apache::lonnavmaps::navmap->new( |
$navmap = Apache::lonnavmaps::navmap->new($r, |
$ENV{"request.course.fn"}.".db", |
$ENV{"request.course.fn"}.".db", |
$ENV{"request.course.fn"}."_parms.db", 1, 1); |
$ENV{"request.course.fn"}."_parms.db", 1, 1); |
$mustCloseNavMap = 1; |
$mustCloseNavMap = 1; |
Line 1107 sub render {
|
Line 1130 sub render {
|
|
|
if ($condenseParts) { # do the condensation |
if ($condenseParts) { # do the condensation |
if (!$curRes->opendate("0")) { |
if (!$curRes->opendate("0")) { |
@parts = ("0"); |
@parts = (); |
$args->{'condensed'} = 1; |
$args->{'condensed'} = 1; |
} |
} |
if (!$args->{'condensed'}) { |
if (!$args->{'condensed'}) { |
Line 1226 sub render {
|
Line 1249 sub render {
|
$r->rflush(); |
$r->rflush(); |
} |
} |
|
|
if ($mustCloseNavMap) { $navmap->untieHashes(); } |
#if ($mustCloseNavMap) { $navmap->untieHashes(); } |
|
|
return $result; |
return $result; |
} |
} |
Line 1251 You must obtain resource objects through
|
Line 1274 You must obtain resource objects through
|
|
|
=over 4 |
=over 4 |
|
|
=item * B<new>(navHashFile, parmHashFile, genCourseAndUserOptions, genMailDiscussStatus): Binds a new navmap object to the compiled nav map hash and parm hash given as filenames. genCourseAndUserOptions is a flag saying whether the course options and user options hash should be generated. This is for when you are using the parameters of the resources that require them; see documentation in resource object documentation. genMailDiscussStatus causes the nav map to retreive information about the email and discussion status of resources. Returns the navmap object if this is successful, or B<undef> if not. You must check for undef; errors will occur when you try to use the other methods otherwise. |
=item * B<new>(responseObject, navHashFile, parmHashFile, genCourseAndUserOptions, genMailDiscussStatus): Binds a new navmap object to the compiled nav map hash and parm hash given as filenames. responseObject is the Apache response object (typically $r). genCourseAndUserOptions is a flag saying whether the course options and user options hash should be generated. This is for when you are using the parameters of the resources that require them; see documentation in resource object documentation. genMailDiscussStatus causes the nav map to retreive information about the email and discussion status of resources. Returns the navmap object if this is successful, or B<undef> if not. You must check for undef; errors will occur when you try to use the other methods otherwise. |
|
|
=item * B<getIterator>(first, finish, filter, condition): See iterator documentation below. |
=item * B<getIterator>(first, finish, filter, condition): See iterator documentation below. |
|
|
Line 1266 sub new {
|
Line 1289 sub new {
|
my $class = ref($proto) || $proto; |
my $class = ref($proto) || $proto; |
my $self = {}; |
my $self = {}; |
|
|
|
$self->{RESPONSE} = shift; |
$self->{NAV_HASH_FILE} = shift; |
$self->{NAV_HASH_FILE} = shift; |
$self->{PARM_HASH_FILE} = shift; |
$self->{PARM_HASH_FILE} = shift; |
$self->{GENERATE_COURSE_USER_OPT} = shift; |
$self->{GENERATE_COURSE_USER_OPT} = shift; |
Line 1281 sub new {
|
Line 1305 sub new {
|
|
|
# tie the nav hash |
# tie the nav hash |
|
|
if (!(tie(%navmaphash, 'GDBM_File', $self->{NAV_HASH_FILE}, |
if (!(tie(%Apache::lonnavmaps::navmaphash, 'GDBM_File', $self->{NAV_HASH_FILE}, |
&GDBM_READER(), 0640))) { |
&GDBM_READER(), 0640))) { |
return undef; |
return undef; |
} |
} |
|
|
if (!(tie(%parmhash, 'GDBM_File', $self->{PARM_HASH_FILE}, |
if (!(tie(%Apache::lonnavmaps::parmhash, 'GDBM_File', $self->{PARM_HASH_FILE}, |
&GDBM_READER(), 0640))) |
&GDBM_READER(), 0640))) |
{ |
{ |
untie $self->{PARM_HASH}; |
untie $self->{PARM_HASH}; |
return undef; |
return undef; |
} |
} |
|
|
$self->{HASH_TIED} = 1; |
$self->{NAV_HASH} = \%Apache::lonnavmaps::navmaphash; |
$self->{NAV_HASH} = \%navmaphash; |
$self->{PARM_HASH} = \%Apache::lonnavmaps::parmhash; |
$self->{PARM_HASH} = \%parmhash; |
push @Apache::lonnavmaps::refsToUntie, $self->{NAV_HASH}; |
|
push @Apache::lonnavmaps::refsToUntie, $self->{PARM_HASH}; |
|
&Apache::lonnet::logthis("refstountie ".scalar(@Apache::lonnavmaps::refsToUntie)); |
|
&Apache::lonnet::logthis("navmaps test".$Apache::lonnavmaps::test); |
|
$Apache::lonnavmaps::test = '123'; |
|
&Apache::lonnet::logthis("navmaps test".$Apache::lonnavmaps::test); |
$self->{INITED} = 0; |
$self->{INITED} = 0; |
|
|
|
$self->{RESPONSE}->register_cleanup(\&Apache::lonnavmaps::cleanup); |
|
Apache::lonnet::logthis("Pushed cleanup."); |
|
|
bless($self); |
bless($self); |
|
|
return $self; |
return $self; |
Line 1440 sub getIterator {
|
Line 1472 sub getIterator {
|
|
|
# unties the hash when done |
# unties the hash when done |
sub untieHashes { |
sub untieHashes { |
my $self = shift; |
# my $self = shift; |
untie %{$self->{NAV_HASH}} if ($self->{HASH_TIED}); |
# untie $self->{NAV_HASH}; |
untie %{$self->{PARM_HASH}} if ($self->{HASH_TIED}); |
# untie $self->{PARM_HASH}; |
$self->{HASH_TIED} = 0; |
# &Apache::lonnavmaps::cleanup(); |
} |
} |
|
|
# when the object is destroyed, be sure to untie all the hashes we tied. |
# when the object is destroyed, be sure to untie all the hashes we tied. |
sub DESTROY { |
#sub DESTROY { |
my $self = shift; |
# my $self = shift; |
$self->untieHashes(); |
# $self->untieHashes(); |
} |
#} |
|
|
# Private method: Does the given resource (as a symb string) have |
# Private method: Does the given resource (as a symb string) have |
# current discussion? Returns 0 if chat/mail data not extracted. |
# current discussion? Returns 0 if chat/mail data not extracted. |
Line 1757 getIterator behaves as follows:
|
Line 1789 getIterator behaves as follows:
|
|
|
=over 4 |
=over 4 |
|
|
=item * B<getIterator>(firstResource, finishResource, filterHash, condition, forceTop): All parameters are optional. firstResource is a resource reference corresponding to where the iterator should start. It defaults to navmap->firstResource() for the corresponding nav map. finishResource corresponds to where you want the iterator to end, defaulting to navmap->finishResource(). filterHash is a hash used as a set containing strings representing the resource IDs, defaulting to empty. Condition is a 1 or 0 that sets what to do with the filter hash: If a 0, then only resource that exist IN the filterHash will be recursed on. If it is a 1, only resources NOT in the filterHash will be recursed on. Defaults to 0. forceTop is a boolean value. If it is false (default), the iterator will only return the first level of map that is not just a single, 'redirecting' map. If true, the iterator will return all information, starting with the top-level map, regardless of content. |
=item * B<getIterator>(firstResource, finishResource, filterHash, condition, forceTop, returnTopMap): All parameters are optional. firstResource is a resource reference corresponding to where the iterator should start. It defaults to navmap->firstResource() for the corresponding nav map. finishResource corresponds to where you want the iterator to end, defaulting to navmap->finishResource(). filterHash is a hash used as a set containing strings representing the resource IDs, defaulting to empty. Condition is a 1 or 0 that sets what to do with the filter hash: If a 0, then only resource that exist IN the filterHash will be recursed on. If it is a 1, only resources NOT in the filterHash will be recursed on. Defaults to 0. forceTop is a boolean value. If it is false (default), the iterator will only return the first level of map that is not just a single, 'redirecting' map. If true, the iterator will return all information, starting with the top-level map, regardless of content. returnTopMap, if true (default false), will cause the iterator to return the top-level map object (resource 0.0) before anything else. |
|
|
Thus, by default, only top-level resources will be shown. Change the condition to a 1 without changing the hash, and all resources will be shown. Changing the condition to 1 and including some values in the hash will allow you to selectively suppress parts of the navmap, while leaving it on 0 and adding things to the hash will allow you to selectively add parts of the nav map. See the handler code for examples. |
Thus, by default, only top-level resources will be shown. Change the condition to a 1 without changing the hash, and all resources will be shown. Changing the condition to 1 and including some values in the hash will allow you to selectively suppress parts of the navmap, while leaving it on 0 and adding things to the hash will allow you to selectively add parts of the nav map. See the handler code for examples. |
|
|
Line 1832 sub new {
|
Line 1864 sub new {
|
# Do we want to automatically follow "redirection" maps? |
# Do we want to automatically follow "redirection" maps? |
$self->{FORCE_TOP} = shift; |
$self->{FORCE_TOP} = shift; |
|
|
|
# Do we want to return the top-level map object (resource 0.0)? |
|
$self->{RETURN_0} = shift; |
|
# have we done that yet? |
|
$self->{HAVE_RETURNED_0} = 0; |
|
|
# Now, we need to pre-process the map, by walking forward and backward |
# Now, we need to pre-process the map, by walking forward and backward |
# over the parts of the map we're going to look at. |
# over the parts of the map we're going to look at. |
|
|
Line 1945 sub new {
|
Line 1982 sub new {
|
sub next { |
sub next { |
my $self = shift; |
my $self = shift; |
|
|
|
# If we want to return the top-level map object, and haven't yet, |
|
# do so. |
|
if ($self->{RETURN_0} && !$self->{HAVE_RETURNED_0}) { |
|
$self->{HAVE_RETURNED_0} = 1; |
|
return $self->{NAV_MAP}->getById('0.0'); |
|
} |
|
|
if ($self->{RECURSIVE_ITERATOR_FLAG}) { |
if ($self->{RECURSIVE_ITERATOR_FLAG}) { |
# grab the next from the recursive iterator |
# grab the next from the recursive iterator |
my $next = $self->{RECURSIVE_ITERATOR}->next(); |
my $next = $self->{RECURSIVE_ITERATOR}->next(); |
Line 2686 sub countParts {
|
Line 2730 sub countParts {
|
my $self = shift; |
my $self = shift; |
|
|
my $parts = $self->parts(); |
my $parts = $self->parts(); |
|
my $delta = 0; |
|
for my $part (@$parts) { |
|
if ($part eq '0') { $delta--; } |
|
} |
|
|
if ($self->{RESOURCE_ERROR}) { |
if ($self->{RESOURCE_ERROR}) { |
return 0; |
return 0; |
} |
} |
|
|
if (scalar(@{$parts}) < 2) { return 1;} |
return scalar(@{$parts}) + $delta; |
|
|
return scalar(@{$parts}) - 1; |
|
} |
} |
|
|
# Private function: Extracts the parts information and saves it |
# Private function: Extracts the parts information and saves it |