File:  [LON-CAPA] / loncom / interface / lonnavdisplay.pm
Revision 1.22.4.9.2.1: download - view: text, annotated - select for diffs
Mon May 25 16:12:12 2020 UTC (4 years ago) by raeburn
Branches: version_2_11_2_msu
Diff to branchpoint 1.22.4.9: preferred, colored
- For 2.11.2 (modified)
  Include changes in 1.34

# The LearningOnline Network with CAPA
# Navigate Maps Display Handler
#
# $Id: lonnavdisplay.pm,v 1.22.4.9.2.1 2020/05/25 16:12:12 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,'contents');
    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 = '<div id="LC_update_'.$cid.'" class="LC_info">'.
                       '<br />'.
                       &mt('Your course session is being updated because of recent changes by course personnel.').
                       ' '.&mt('Please be patient.').'<br /></div>'.
                       '<div style="padding:0;clear:both;margin:0;border:0"></div>';
        $closure = <<ENDCLOSE;
<script type="text/javascript">
// <![CDATA[
\$("#LC_update_$cid").hide('slow');
// ]]>
</script>
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('<span class="LC_error">'.&mt('Coursemap undefined.').
		  '</span>' .
                  &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("<span class=\"LC_info\">"
                     .&mt("All homework assignments have been completed.")
                     ."</span>");
        }
    } else {
        my $link = '/adm/navmaps?jumpToFirstHomework';
        if ($env{'form.register'}) {
            $link .= '&amp;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 = '/adm/navmaps?sort='.$env{'form.sort'};
        if ($env{'form.register'}) {
            $link .= '&amp;register='.$env{'form.register'};
        }
	&Apache::lonnavmaps::add_linkitem(\%toplinkitems,'everything',
					  'location.href="'.$link.'"',
					  'Show everything');
        $r->print("<span class=\"LC_info\">".&mt("Uncompleted Problems")."</span>");
        $env{'form.filter'} = '';
        $env{'form.condition'} = 1;
	$resource_no_folder_link = 1;
    } else {
        my $link = '/adm/navmaps?sort='.$env{'form.sort'}.'&amp;showOnlyHomework=1';
        if ($env{'form.register'}) {
            $link .= '&amp;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=(
              '<form name="sortForm" action="">
                 <span class="LC_nobreak">
                    <input type="hidden" name="showOnlyHomework" value="'.$env{'form.showOnlyHomework'}.'" />
                    '.&mt('Sort by:').'
                    <select name="sort" onchange="document.sortForm.submit()">
                       <option value="default"'.$selected{'default'}.'>'.&mt('Default').'</option>
                       <option value="title"'.$selected{'title'}.'>'.&mt('Title').'</option>
                       <option value="duedate"'.$selected{'duedate'}.'>'.&mt('Due Date').'</option>
                       <option value="discussion"'.$selected{'discussion'}.'>'.&mt('Has New Discussion').'</option>
                    </select>
                    <input type="hidden" name="register" value="'.$env{'form.register'}.'" />
                 </span>
               </form>');
    }
    # 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("<p><span class=\"LC_info\">".&mt("All homework is currently completed.")."</span></p>");
        } else { # both jumpToFirstHomework and normal use the same: course must be empty
            $r->print("<p><span class=\"LC_info\">".&mt("This course is empty.")."</span></p>");
        }
    }
    &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.
              '<script type="text/javascript">'."\n".
              '// <![CDATA['."\n".
              'window.focus();'."\n".
              '// ]]>'."\n".
              '</script>');
    return;
}

sub startContentScreen {
    my ($r,$mode)=@_;

    $r->print("\n".'<ul class="LC_TabContentBigger" id="mainnav">'."\n");
    $r->print('<li'.(($mode eq 'navmaps')?' class="active"':'').'><a href="/adm/navmaps"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.&mt('Main Content').'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li>'."\n");
    my $allowed = &Apache::lonnet::allowed('mdc',$env{'request.course.id'});
    my ($suppcount,$errors);
    unless ($allowed) {
        my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
        my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
        ($suppcount,$errors) = &Apache::lonnet::get_numsuppfiles($cnum,$cdom);
    }
    if ($allowed || $suppcount) {
        $r->print('<li '.(($mode eq 'supplemental')?' class="active"':'').'><a href="/adm/supplemental"><b>'.&mt('Supplemental Content').'</b></a></li>');
    }
    $r->print('<li'.(($mode eq 'coursesearch')?' class="active"':'').'><a href="/adm/searchcourse"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.&mt('Content Search').'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li>'."\n");
    $r->print("\n".'</ul>'."\n");
    $r->print('<div class="LC_Box" style="clear:both;margin:0;"><div id="maincoursedoc" style="margin:0 0;padding:0 0;"><div class="LC_ContentBox" id="mainCourseDocuments" style="display: block;">');
}

sub endContentScreen {
   my ($r)=@_;
   $r->print('</div></div></div>');
}

1;
__END__


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
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.