# The LearningOnline Network with CAPA # Navigate Maps Display Handler # # $Id: lonnavdisplay.pm,v 1.22.4.8 2018/09/10 23:11:26 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # ### package Apache::lonnavdisplay; use strict; use Apache::Constants qw(:common :http REDIRECT); use Apache::lonmenu(); use Apache::loncommon(); use Apache::lonnavmaps(); use Apache::lonhtmlcommon(); use Apache::lonnet; use Apache::lonlocal; use Apache::londocs(); use Apache::lonuserstate; sub handler { my $r = shift; real_handler($r); } sub real_handler { my $r = shift; # Handle header-only request if ($r->header_only) { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK; } # Check for critical messages and redirect if present. my ($redirect,$url) = &Apache::loncommon::critical_redirect(300); if ($redirect) { &Apache::loncommon::content_type($r,'text/html'); $r->header_out(Location => $url); return REDIRECT; } # ------------------------------------------------------------ Get query string &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['sort', 'showOnlyHomework', 'postsymb','register']); # Check if course needs to be re-initialized my $loncaparev = $r->dir_config('lonVersion'); my ($result,@reinit) = &Apache::loncommon::needs_coursereinit($loncaparev); my %prog_state=(); my $closure; if ($result eq 'switch') { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; $r->print(&Apache::loncommon::check_release_result(@reinit)); return OK; } elsif ($result eq 'update') { my $cid = $env{'request.course.id'}; my $cnum = $env{'course.'.$cid.'.num'}; my $cdom = $env{'course.'.$cid.'.domain'}; &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; &startpage($r); my $preamble = '
'. '
'. &mt('Your course session is being updated because of recent changes by course personnel.'). ' '.&mt('Please be patient.').'
'. '
'; $closure = < // ENDCLOSE %prog_state = &Apache::lonhtmlcommon::Create_PrgWin($r,undef,$preamble); &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,&mt('Updating course')); $r->rflush(); my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum",\%prog_state,$r); &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,&mt('Finished')); if ($ferr) { &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); $r->print($closure.&Apache::loncommon::end_page()); my $requrl = $r->uri; $env{'user.error.msg'}="$requrl:bre:0:0:Course not initialized"; $env{'user.reinit'} = 1; return HTTP_NOT_ACCEPTABLE; } } # Create the nav map my $navmap = Apache::lonnavmaps::navmap->new(); if (!defined($navmap)) { if ($result eq 'update') { &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); $r->print($closure.&Apache::loncommon::end_page()); } my $requrl = $r->uri; $env{'user.error.msg'} = "$requrl:bre:0:0:Course not initialized"; $env{'user.reinit'} = 1; return HTTP_NOT_ACCEPTABLE; } if ($result eq 'update') { $r->rflush(); &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); $r->print($closure); $r->rflush(); } else { # Send header, don't cache this page &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; &startpage($r); } &startContentScreen($r,'navmaps'); unless ($result eq 'update') { $r->rflush(); } # Check that it's defined if (!($navmap->courseMapDefined())) { $r->print(&Apache::loncommon::help_open_menu('Navigation Screen','Navigation_Screen',undef,'RAT')); $r->print(''.&mt('Coursemap undefined.'). '' . &Apache::loncommon::end_page()); return OK; } my %toplinkitems=(); my @resources = $navmap->retrieveResources(); my $sequenceCount = 0; my $problemCount = 0; my $notaprobCount = 0; my $sequenceId; my $notools; foreach my $curRes (@resources) { if (ref($curRes)) { if ($curRes->is_sequence()) { $sequenceCount++; $sequenceId = $curRes->map_pc(); } elsif ($curRes->is_problem()) { $problemCount ++; } else { $notaprobCount ++; } } } if (($sequenceCount == 1) && (!$problemCount) && ($notaprobCount <= 1)) { $notools = 1; } # If there's only one map in the top-level and we don't # already have a filter, automatically display it if ($ENV{QUERY_STRING} !~ /filter/) { if ($sequenceCount == 1) { # The automatic iterator creation in the render call # will pick this up. We know the condition because # the defined($env{'form.filter'}) also ensures this # is a fresh call. $env{'form.filter'} = "$sequenceId"; } } # 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; my $now = time(); while ($curRes = $iterator->next()) { if (ref($curRes) && $curRes->is_problem()) { my $status = $curRes->status(); my $thisduedate=$curRes->duedate(); if ($thisduedate > $now && $curRes->completable()) { $foundDoableProblem = 1; if (!defined($minimumduedate) || $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("" .&mt("All homework assignments have been completed.") .""); } } else { my $link = 'navmaps?jumpToFirstHomework'; if ($env{'form.register'}) { $link .= '&register='.$env{'form.register'}; } unless ($notools) { &Apache::lonnavmaps::add_linkitem(\%toplinkitems,'firsthomework', 'location.href="'.$link.'"', "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(); }; my $link = 'navmaps?sort='.$env{'form.sort'}; if ($env{'form.register'}) { $link .= '&register='.$env{'form.register'}; } &Apache::lonnavmaps::add_linkitem(\%toplinkitems,'everything', 'location.href="'.$link.'"', 'Show everything'); $r->print("".&mt("Uncompleted Problems").""); $env{'form.filter'} = ''; $env{'form.condition'} = 1; $resource_no_folder_link = 1; } else { my $link = 'navmaps?sort='.$env{'form.sort'}.'&showOnlyHomework=1'; if ($env{'form.register'}) { $link .= '&register='.$env{'form.register'}; } unless ($notools) { &Apache::lonnavmaps::add_linkitem(\%toplinkitems,'uncompleted', 'location.href="'.$link.'"', 'Show only uncompleted problems'); } } my %selected=($env{'form.sort'} => ' selected="selected"'); my $sort_html; unless ($notools) { $sort_html=( '
'.&mt('Sort by:').'
'); } # 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, 'notools' => $notools}; my $render = &Apache::lonnavmaps::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("

".&mt("This course is empty.")."

"); } } &endContentScreen($r); $r->print(&Apache::loncommon::end_page()); $r->rflush(); return OK; } sub startpage { my ($r) = @_; # ----------------------------------------------------- Force menu registration # Header my $course_type = &Apache::loncommon::course_type(); my $title = $course_type . ' Contents'; my ($start_page,$args); if ($env{'form.register'}) { $args = {'force_register' => $env{'form.register'}}; $start_page = &Apache::loncommon::start_page($title,undef,$args); } else { my $brcrum = [{href => '/adm/navmaps', text => &mt($course_type . ' Contents'), no_mt => 1}, ]; $args = {'bread_crumbs' => $brcrum}; $start_page = &Apache::loncommon::start_page($title,undef,$args); } $r->print($start_page. ''); return; } sub startContentScreen { my ($r,$mode)=@_; $r->print("\n".''."\n"); $r->print('
'); } sub endContentScreen { my ($r)=@_; $r->print('
'); } 1; __END__