';
- $result.=&show_linkitems_toolbar($args->{'linkitems'});
- if ($args->{'sort_html'}) {
- $result.='
'.
- '
'.$args->{'sort_html'}.'
';
- }
- $result .= '
';
+ $result .= &show_linkitems_toolbar($args,$condition);
} elsif ($args->{'sort_html'}) {
$result.=$args->{'sort_html'};
}
@@ -1820,6 +1829,8 @@ END
}
}
}
+
+ $result.=&Apache::loncommon::end_data_table();
# Print out the part that jumps to #curloc if it exists
# delay needed because the browser is processing the jump before
@@ -1836,8 +1847,6 @@ if (location.href.indexOf('#curloc')==-1
");
}
- $result.=&Apache::loncommon::end_data_table();
-
if ($r) {
$r->print($result);
$result = "";
@@ -1854,41 +1863,64 @@ sub add_linkitem {
}
sub show_linkitems_toolbar {
- my ($linkitems,$condition)=@_;
- my @linkorder = ('firsthomework','everything','uncompleted',
- 'changefolder','clearbubbles');
- my $result .='
'."\n".
- ''."\n".
- '
';
- foreach my $link (@linkorder) {
- my $link_id = 'LC_content_toolbar_'.$link;
- if (defined($linkitems->{$link})) {
- if ($linkitems->{$link}{'text'} ne '') {
- $linkitems->{$link}{'cmd'}=~s/"/'/g;
- if ($linkitems->{$link}{'cmd'}) {
- if ($link eq 'changefolder') {
- if ($condition) {
- $link_id='LC_content_toolbar_changefolder_toggled';
- } else {
- $link_id='LC_content_toolbar_changefolder';
+ my ($args,$condition) = @_;
+ my $result;
+ if (ref($args) eq 'HASH') {
+ if (ref($args->{'linkitems'}) eq 'HASH') {
+ my $numlinks = scalar(keys(%{$args->{'linkitems'}}));
+ if ($numlinks > 1) {
+ $result = '
'."\n";
return $result;
}
-
1;
@@ -1979,6 +2011,7 @@ sub new {
$self->{USERNAME} = shift || $env{'user.name'};
$self->{DOMAIN} = shift || $env{'user.domain'};
+ $self->{CODE} = shift;
@@ -1995,7 +2028,7 @@ sub new {
# assume there are course hashes for the specific requested user@domamin:
#
- if (($self->{USERNAME} eq $env{'user.name'}) && ($self->{DOMAIN} eq $env{'user.domain'})) {
+ if (($self->{USERNAME} eq $env{'user.name'}) && ($self->{DOMAIN} eq $env{'user.domain'}) && !$self->{CODE}) {
# tie the nav hash
@@ -2018,9 +2051,9 @@ sub new {
$self->{PARM_HASH} = \%parmhash;
$self->{PARM_CACHE} = {};
} else {
- $self->change_user($self->{USERNAME}, $self->{DOMAIN});
+ $self->change_user($self->{USERNAME}, $self->{DOMAIN}, $self->{CODE});
}
-
+
return $self;
}
@@ -2031,12 +2064,14 @@ sub new {
# Parameters:
# user - New user.
# domain- Domain the user belongs to.
+# code - Anonymous CODE in use.
# Implicit inputs:
#
sub change_user {
my $self = shift;
$self->{USERNAME} = shift;
$self->{DOMAIN} = shift;
+ $self->{CODE} = shift;
# If the hashes are already tied make sure to break that bond:
@@ -2052,9 +2087,11 @@ sub change_user {
my ($cdom, $cnum) = split(/\_/, $env{'request.course.id'});
my %big_hash;
- &Apache::lonmap::loadmap($cnum, $cdom, $self->{USERNAME}, $self->{DOMAIN}, \%big_hash);
+ &Apache::lonmap::loadmap($cnum, $cdom, $self->{USERNAME}, $self->{DOMAIN}, $self->{CODE}, \%big_hash);
$self->{NAV_HASH} = \%big_hash;
+
+
# Now clear the parm cache and reconstruct the parm hash fromt he big_hash
# param.xxxx keys.
@@ -2115,6 +2152,8 @@ sub generate_course_user_opt {
return;
}
+
+
sub generate_email_discuss_status {
my $self = shift;
my $symb = shift;
@@ -2528,10 +2567,12 @@ sub parmval {
return $result->[0];
}
+
sub parmval_real {
my $self = shift;
my ($what,$symb,$recurse) = @_;
+
# Make sure the {USER_OPT} and {COURSE_OPT} hashes are populated
$self->generate_course_user_opt();
@@ -2560,18 +2601,23 @@ sub parmval_real {
my $mapparm=$mapname.'___(all).'.$what;
my $usercourseprefix=$cid;
+
+
my $grplevel=$usercourseprefix.'.['.$cgroup.'].'.$what;
my $grplevelr=$usercourseprefix.'.['.$cgroup.'].'.$symbparm;
my $grplevelm=$usercourseprefix.'.['.$cgroup.'].'.$mapparm;
+
my $seclevel= $usercourseprefix.'.['.$csec.'].'.$what;
my $seclevelr=$usercourseprefix.'.['.$csec.'].'.$symbparm;
my $seclevelm=$usercourseprefix.'.['.$csec.'].'.$mapparm;
+
my $courselevel= $usercourseprefix.'.'.$what;
my $courselevelr=$usercourseprefix.'.'.$symbparm;
my $courselevelm=$usercourseprefix.'.'.$mapparm;
+
my $useropt = $self->{USER_OPT};
my $courseopt = $self->{COURSE_OPT};
my $parmhash = $self->{PARM_HASH};
@@ -2638,6 +2684,217 @@ sub parmval_real {
if (defined($pack_def)) { return [$pack_def,'resource']; }
return [''];
}
+#
+# Determines the open/close dates for printing a map that
+# encloses a resource.
+#
+sub map_printdates {
+ my ($self, $res, $part) = @_;
+
+
+
+
+
+ my $opendate = $self->get_mapparam($res->symb(), "$part.printstartdate");
+ my $closedate= $self->get_mapparam($res->symb(), "$part.printenddate");
+
+
+ return ($opendate, $closedate);
+}
+
+sub get_mapparam {
+ my ($self, $symb, $what) = @_;
+
+ # Ensure the course option hash is populated:
+
+ $self->generate_course_user_opt();
+
+ # Get the course id and section if there is one.
+
+ my $cid=$env{'request.course.id'};
+ my $csec=$env{'request.course.sec'};
+ my $cgroup='';
+ my @cgrps=split(/:/,$env{'request.course.groups'});
+ if (@cgrps > 0) {
+ @cgrps = sort(@cgrps);
+ $cgroup = $cgrps[0];
+ }
+ my $uname=$self->{USERNAME};
+ my $udom=$self->{DOMAIN};
+
+ unless ($symb) { return ['']; }
+ my $result='';
+
+
+ # Figure out which map we are in.
+
+ my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb);
+ $mapname = &Apache::lonnet::deversion($mapname);
+
+
+ my $rwhat=$what;
+ $what=~s/^parameter\_//;
+ $what=~s/\_/\./;
+
+ # Build the hash keys for the lookup:
+
+ my $symbparm=$symb.'.'.$what;
+ my $mapparm=$mapname.'___(all).'.$what;
+ my $usercourseprefix=$cid;
+
+
+ my $grplevel = "$usercourseprefix.[$cgroup].$mapparm";
+ my $seclevel = "$usercourseprefix.[$csec].$mapparm";
+ my $courselevel = "$usercourseprefix.$mapparm";
+
+
+ # Get handy references to the hashes we need in $self:
+
+ my $useropt = $self->{USER_OPT};
+ my $courseopt = $self->{COURSE_OPT};
+ my $parmhash = $self->{PARM_HASH};
+
+ # Check per user
+
+
+
+ if ($uname and defined($useropt)) {
+ if (defined($$useropt{$courselevel})) {
+ return $$useropt{$courselevel};
+ }
+ }
+
+ # Check course -- group
+
+
+
+ if ($cgroup ne '' and defined ($courseopt)) {
+ if (defined($$courseopt{$grplevel})) {
+ return $$courseopt{$grplevel};
+ }
+ }
+
+ # Check course -- section
+
+
+
+
+
+ if ($csec and defined($courseopt)) {
+ if (defined($$courseopt{$seclevel})) {
+ return $$courseopt{$seclevel};
+ }
+ }
+ # Check the map parameters themselves:
+
+ my $thisparm = $$parmhash{$symbparm};
+ if (defined($thisparm)) {
+ return $thisparm;
+ }
+
+
+ # Additional course parameters:
+
+ if (defined($courseopt)) {
+ if (defined($$courseopt{$courselevel})) {
+ return $$courseopt{$courselevel};
+ }
+ }
+ return undef; # Unefined if we got here.
+}
+
+sub course_printdates {
+ my ($self, $symb, $part) = @_;
+
+
+ my $opendate = $self->getcourseparam($symb, $part . '.printstartdate');
+ my $closedate = $self->getcourseparam($symb, $part . '.printenddate');
+ return ($opendate, $closedate);
+
+}
+
+sub getcourseparam {
+ my ($self, $symb, $what) = @_;
+
+ $self->generate_course_user_opt(); # If necessary populate the hashes.
+
+ my $uname = $self->{USERNAME};
+ my $udom = $self->{DOMAIN};
+
+ # Course, section, group ids come from the env:
+
+ my $cid = $env{'request.course.id'};
+ my $csec = $env{'request.course.sec'};
+ my $cgroup = ''; # Assume no group
+
+ my @cgroups = split(/:/, $env{'request.course.groups'});
+ if(@cgroups > 0) {
+ @cgroups = sort(@cgroups);
+ $cgroup = $cgroups[0]; # There is a course group.
+ }
+ my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb);
+ $mapname = &Apache::lonnet::deversion($mapname);
+
+ #
+ # Make the various lookup keys:
+ #
+
+ $what=~s/^parameter\_//;
+ $what=~s/\_/\./;
+
+
+ my $symbparm = $symb . '.' . $what;
+ my $mapparm=$mapname.'___(all).'.$what;
+
+ # Local refs to the hashes we're going to look at:
+
+ my $useropt = $self->{USER_OPT};
+ my $courseopt = $self->{COURSE_OPT};
+
+ #
+ # We want the course level stuff from the way
+ # parmval_real operates
+ # TODO: Fator some of this stuff out of
+ # both parmval_real and here
+ #
+ my $courselevel = $cid . '.' . $what;
+ my $grplevel = $cid . '.[' . $cgroup . ']' . $what;
+ my $seclevel = $cid . '.[' . $csec . ']' . $what;
+
+
+ # Try for the user's course level option:
+
+ if ($uname and defined($useropt)) {
+ if (defined($$useropt{$courselevel})) {
+ return $$useropt{$courselevel};
+ }
+ }
+ # Try for the group's course level option:
+
+ if ($uname ne '' and defined($courseopt)) {
+ if (defined($$courseopt{$grplevel})) {
+ return $$courseopt{$grplevel};
+ }
+ }
+
+ # Try for section level parameters:
+
+ if ($csec and defined($courseopt)) {
+ if (defined($$courseopt{$seclevel})) {
+ return $$courseopt{$seclevel};
+ }
+ }
+ # Try for 'additional' course parameterse:
+
+ if (defined($courseopt)) {
+ if (defined($$courseopt{$courselevel})) {
+ return $$courseopt{$courselevel};
+ }
+ }
+ return undef;
+
+}
+
=pod
@@ -3062,12 +3319,14 @@ sub new {
if ($resourceCount == 1 && $resource->is_sequence() && !$self->{FORCE_TOP}) {
my $firstResource = $resource->map_start();
my $finishResource = $resource->map_finish();
- return
- Apache::lonnavmaps::iterator->new($self->{NAV_MAP}, $firstResource,
- $finishResource, $self->{FILTER},
- $self->{ALREADY_SEEN},
- $self->{CONDITION},
- $self->{FORCE_TOP});
+ my $result;
+ $result = Apache::lonnavmaps::iterator->new($self->{NAV_MAP}, $firstResource,
+ $finishResource, $self->{FILTER},
+ $self->{ALREADY_SEEN},
+ $self->{CONDITION},
+ $self->{FORCE_TOP});
+ return $result;
+
}
@@ -3087,7 +3346,6 @@ sub new {
$self->{ALREADY_SEEN}->{$self->{FIRST_RESOURCE}->{ID}} = 1;
bless ($self);
-
return $self;
}
@@ -3102,6 +3360,7 @@ sub next {
# do so.
if ($self->{RETURN_0} && !$self->{HAVE_RETURNED_0}) {
$self->{HAVE_RETURNED_0} = 1;
+ my $nextTopLevel = $self->{NAV_MAP}->getById('0.0');
return $self->{NAV_MAP}->getById('0.0');
}
if ($self->{RETURN_0} && !$self->{HAVE_RETURNED_0_BEGIN_MAP}) {
@@ -3121,7 +3380,6 @@ sub next {
if ($self->{RECURSIVE_DEPTH} == 0) {
$self->{RECURSIVE_ITERATOR_FLAG} = 0;
}
-
return $next;
}
@@ -3197,6 +3455,8 @@ sub next {
# So we need to look at all the resources we can get to from here,
# categorize them if we haven't seen them, remember if we have a new
my $nextUnfiltered = $here->getNext();
+
+
my $maxDepthAdded = -1;
for (@$nextUnfiltered) {
@@ -3230,7 +3490,6 @@ sub next {
$self->{RECURSIVE_ITERATOR_FLAG} = 1;
my $firstResource = $self->{HERE}->map_start();
my $finishResource = $self->{HERE}->map_finish();
-
$self->{RECURSIVE_ITERATOR} =
Apache::lonnavmaps::iterator->new($self->{NAV_MAP}, $firstResource,
$finishResource, $self->{FILTER},
@@ -3568,6 +3827,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.
@@ -4035,11 +4296,13 @@ their code.)
=over 4
+
=item * B
returns true if the current date is such that the
specified resource part is printable.
+
=item * B
Returns true if all parts in the resource are printable making the
@@ -4098,23 +4361,41 @@ Get the weight for the problem.
=cut
+
+
+
sub printable {
my ($self, $part) = @_;
- # Get the print open/close dates for the resource.
+ &Apache::lonnet::logthis($self->symb());
- my $start = $self->parmval("prinstartdate", $part);
- my $end = $self->parmval("printenddate", $part);
# The following cases apply:
- # - No dates set: Printable.
+ # - If a start date is not set, it is replaced by the open date.
+ # - Ditto for start/open replaced by content open.
+ # - If neither start nor printdates are set the part is printable.
# - Start date set but no end date: Printable if now >= start date.
# - End date set but no start date: Printable if now <= end date.
# - both defined: printable if start <= now <= end
#
+
+ # Get the print open/close dates for the resource.
+
+ my $start = $self->parmval("printstartdate", $part);
+ my $end = $self->parmval("printenddate", $part);
+
+ if (!$start) {
+ $start = $self->parmval("opendate", $part);
+ }
+ if (!$start) {
+ $start = $self->parmval("contentopen", $part);
+ }
+
+
my $now = time();
+
my $startok = 1;
my $endok = 1;
@@ -4135,7 +4416,7 @@ sub resprintable {
my $partsref = $self->parts();
my @parts = @$partsref;
- if ((!defined(@parts)) || (scalar(@parts) == 0)) {
+ if (!@parts) {
return $self->printable(0);
} else {
foreach my $part (@parts) {
@@ -4206,6 +4487,9 @@ sub checkedin {
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);
@@ -4222,6 +4506,7 @@ sub duedate {
} else {
$date = $due_date;
}
+ $self->{DUEDATE_CACHE}->{$part} = $date;
return $date;
}
sub handgrade {
@@ -5073,12 +5358,13 @@ sub status {
}
# Otherwise, it's untried and open
- return OPEN;
+ return OPEN;
}
sub check_for_slot {
my $self = shift;
my $part = shift;
+ my $symb = $self->symb();
my ($use_slots,$available,$availablestudent) = $self->slot_control($part);
if (($use_slots ne '') && ($use_slots !~ /^\s*no\s*$/i)) {
my @slots = (split(/:/,$availablestudent),split(/:/,$available));
@@ -5086,50 +5372,45 @@ sub check_for_slot {
my $cdom=$env{'course.'.$cid.'.domain'};
my $cnum=$env{'course.'.$cid.'.num'};
my $now = time;
+ my $num_usable_slots = 0;
if (@slots > 0) {
my %slots=&Apache::lonnet::get('slots',[@slots],$cdom,$cnum);
if (&Apache::lonnet::error(%slots)) {
return (UNKNOWN);
}
- my @sorted_slots = &Apache::loncommon::sorted_slots(\@slots,\%slots);
+ my @sorted_slots = &Apache::loncommon::sorted_slots(\@slots,\%slots,'starttime');
my ($checkedin,$checkedinslot);
foreach my $slot_name (@sorted_slots) {
- next if (!defined($slots{$slot_name}) ||
- !ref($slots{$slot_name}));
+ next if (!defined($slots{$slot_name}) || !ref($slots{$slot_name}));
my $end = $slots{$slot_name}->{'endtime'};
my $start = $slots{$slot_name}->{'starttime'};
my $ip = $slots{$slot_name}->{'ip'};
if ($self->simpleStatus() == OPEN) {
- my $startreserve = $slots{$slot_name}->{'startreserve'};
- my @proctors;
- if ($slots{$slot_name}->{'proctor'} ne '') {
- @proctors = split(',',$slots{$slot_name}->{'proctor'});
- }
if ($end > $now) {
- ($checkedin,$checkedinslot) = $self->checkedin();
- if ($startreserve < $now) {
- if ($start > $now) {
- return (RESERVED_LATER,$start,$slot_name);
- } else {
- if ($ip ne '') {
- if (!&Apache::loncommon::check_ip_acc($ip)) {
- return (RESERVED_LOCATION,$ip,$slot_name);
- }
- }
- if (@proctors > 0) {
- unless ((grep(/^\Q$checkedin\E/,@proctors)) &&
- ($checkedinslot eq $slot_name)) {
- return (NEEDS_CHECKIN,undef,$slot_name);
- }
+ if ($start > $now) {
+ return (RESERVED_LATER,$start,$slot_name);
+ } else {
+ if ($ip ne '') {
+ if (!&Apache::loncommon::check_ip_acc($ip)) {
+ return (RESERVED_LOCATION,$ip,$slot_name);
}
- return (RESERVED,$end,$slot_name);
}
- } else {
- if ($start > $now) {
- return (RESERVABLE,$startreserve,$slot_name);
+ my @proctors;
+ if ($slots{$slot_name}->{'proctor'} ne '') {
+ @proctors = split(',',$slots{$slot_name}->{'proctor'});
+ }
+ if (@proctors > 0) {
+ ($checkedin,$checkedinslot) = $self->checkedin();
+ unless ((grep(/^\Q$checkedin\E/,@proctors)) &&
+ ($checkedinslot eq $slot_name)) {
+ return (NEEDS_CHECKIN,undef,$slot_name);
+ }
}
+ return (RESERVED,$end,$slot_name);
}
}
+ } elsif ($end > $now) {
+ $num_usable_slots ++;
}
}
my ($is_correct,$got_grade);
@@ -5150,32 +5431,33 @@ sub check_for_slot {
return (CORRECT);
}
}
- return(NOT_IN_A_SLOT);
- } else {
- if (!$future_slots_checked) {
- $future_slots = &get_future_slots($cdom,$cnum,$now);
- $future_slots_checked = 1;
- }
- if ($future_slots) {
+ if ($num_usable_slots) {
return(NOT_IN_A_SLOT);
}
- return(NOTRESERVABLE);
}
- }
- return;
-}
-
-sub get_future_slots {
- my ($cdom,$cnum,$now) = @_;
- my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);
- my $future_slots = 0;
- foreach my $slot (keys(%slots)) {
- if (($slots{$slot}->{'starttime'} > $now) &&
- ($slots{$slot}->{'endtime'} > $now)) {
- $future_slots ++;
+ my $reservable = &Apache::lonnet::get_reservable_slots($cnum,$cdom,$env{'user.name'},
+ $env{'user.domain'});
+ if (ref($reservable) eq 'HASH') {
+ if ((ref($reservable->{'now_order'}) eq 'ARRAY') && (ref($reservable->{'now'}) eq 'HASH')) {
+ foreach my $slot (reverse (@{$reservable->{'now_order'}})) {
+ if (($reservable->{'now'}{$slot}{'symb'} eq '') ||
+ ($reservable->{'now'}{$slot}{'symb'} eq $symb)) {
+ return(RESERVABLE,$reservable->{'now'}{$slot}{'endreserve'});
+ }
+ }
+ }
+ if ((ref($reservable->{'future_order'}) eq 'ARRAY') && (ref($reservable->{'future'}) eq 'HASH')) {
+ foreach my $slot (@{$reservable->{'future_order'}}) {
+ if (($reservable->{'future'}{$slot}{'symb'} eq '') ||
+ ($reservable->{'future'}{$slot}{'symb'} eq $symb)) {
+ return(RESERVABLE_LATER,$reservable->{'future'}{$slot}{'startreserve'});
+ }
+ }
+ }
}
+ return(NOTRESERVABLE);
}
- return $future_slots;
+ return;
}
sub CLOSED { return 23; }