[LON-CAPA-cvs] cvs: loncom / lonmap.pm /interface lonnavmaps.pm doc/loncapafiles loncapafiles.lpml rat lonpage.pm lonuserstate.pm

raeburn raeburn at source.lon-capa.org
Tue Oct 4 16:39:59 EDT 2022


raeburn		Tue Oct  4 20:39:59 2022 EDT

  Modified files:              
    /rat	lonuserstate.pm lonpage.pm 
    /doc/loncapafiles	loncapafiles.lpml 
    /loncom	lonmap.pm 
    /loncom/interface	lonnavmaps.pm 
  Log:
  - Provide more information to privileged users if map could not be loaded
    during course initialization because file was missing.
  
  
-------------- next part --------------
Index: rat/lonuserstate.pm
diff -u rat/lonuserstate.pm:1.168 rat/lonuserstate.pm:1.169
--- rat/lonuserstate.pm:1.168	Sun May 29 12:10:17 2022
+++ rat/lonuserstate.pm	Tue Oct  4 20:39:57 2022
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Construct and maintain state and binary representation of course for user
 #
-# $Id: lonuserstate.pm,v 1.168 2022/05/29 12:10:17 raeburn Exp $
+# $Id: lonuserstate.pm,v 1.169 2022/10/04 20:39:57 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -199,6 +199,10 @@
         $errtext.= '<br />'
                   .&mt('Map not loaded: The file [_1] does not exist.',
                        "<tt>$fn</tt>");
+        $hash{'map_type_'.$lpc}='none';
+        if (&is_advanced($courseid)) {
+            $errtext .= &error_detail($parent_rid,$courseid,$ispage,$uri);
+        }
 	return;
     }
 
@@ -389,6 +393,233 @@
     return $advanced;
 }
 
+sub error_detail {
+    my ($parent_rid,$courseid,$ispage,$uri) = @_;
+    my $errinfo;
+    if ($courseid) {
+        my $courseurl = &Apache::lonnet::courseid_to_courseurl($courseid);
+        if ($parent_rid =~ /^(\d+)\.(\d+)$/) {
+            my ($parent_pc,$parent_id) = ($1,$2);
+            my ($parent_type,$published,$uploaded,$canedit,$role,$switchserver,$audom,$auname,
+                $editfile,$filerole,$fileswitch,$audomfile,$aunamefile);
+            if (($parent_pc eq '0') && ($hash{'map_id_1'} =~ m{^/res/($match_domain)/($match_username)/.+\.(sequence|page)$})) {
+                ($audomfile,$aunamefile) = ($1,$2);
+                ($editfile,$filerole,$fileswitch) = &canedit_published($audomfile,$aunamefile);
+                if ($fileswitch) {
+                    unless ((&Apache::lonnet::will_trust('othcoau',$env{'user.domain'},$audomfile)) &&
+                            (&Apache::lonnet::will_trust('coaurem',$audomfile,$env{'user.domain'}))) {
+                        undef($editfile);
+                    }
+                }
+                $errinfo = &mt('Top level published sequence file is missing.');
+            } else {
+                if ($parent_pc eq '1') {
+                    if ($hash{'map_id_1'} eq "/uploaded$courseurl/default.sequence") {
+                        $uploaded = 1;
+                        if (&Apache::lonnet::allowed('mdc',$courseid)) {
+                            $canedit = 1;
+                        }
+                        $errinfo = &mt('Map is referenced in the top level ([_1]Main Content[_2]) folder.',
+                                       '<span class="LC_cusr_emph">','</span>');
+                    } elsif ($hash{'map_id_1'} =~ m{^/res/($match_domain)/($match_username)/.+\.(sequence|page)$}) {
+                        ($audom,$auname) = ($1,$2);
+                        ($canedit,$role,$switchserver) = &canedit_published($audom,$auname);
+                        $published = 1;
+                        $errinfo = &mt('Map is referenced in the top level published sequence file.');
+                    }
+                } else {
+                    if ($hash{'map_id_'.$parent_pc} =~ m{^\Q/uploaded$courseurl/default_\E\d+\.(sequence|page)$}) {
+                        $uploaded = 1;
+                        if (&Apache::lonnet::allowed('mdc',$courseid)) {
+                            $canedit = 1;
+                        }
+                    } elsif ($hash{'map_id_'.$parent_pc} =~ m{^/res/($match_domain)/($match_username)/.+\.(sequence|page)$}) {
+                        ($audom,$auname) = ($1,$2);
+                        ($canedit,$role,$switchserver) = &canedit_published($audom,$auname);
+                        $published = 1;
+                    }
+                    if (exists($hash{'ids_'.$hash{'map_id_'.$parent_pc}})) {
+                        $parent_type = $hash{'map_type_'.$parent_pc};
+                        if ($published) {
+                            $errinfo = &mt("Map is referenced in the published $parent_type file: [_1].",
+                                           '<span class="LC_cusr_emph">'.$hash{'map_id_'.$parent_pc}.'</span>');
+                        } else {
+                            my $title = $hash{'title_'.$hash{'ids_'.$hash{'map_id_'.$parent_pc}}};
+                            if ($title ne '') {
+                                my $mapdesc;
+                                if ($parent_type eq 'sequence') {
+                                    $mapdesc = 'folder';
+                                } else {
+                                    $mapdesc = 'composite page';
+                                }
+                                $errinfo = &mt("Map is referenced in the $mapdesc named: [_1].",
+                                               '<span class="LC_cusr_emph">'.$title.'</span>');
+                            }
+                            my @containers = split(/,/,$hash{'map_hierarchy_'.$parent_pc});
+                            shift(@containers);
+                            my $folderpath;
+                            foreach my $id (@containers) {
+                                my $name;
+                                if ($id == 1) {
+                                    $name = &mt('Main Content');
+                                } elsif ($hash{'title_'.$hash{'ids_'.$hash{'map_id_'.$id}}} ne '') {
+                                    $name = $hash{'title_'.$hash{'ids_'.$hash{'map_id_'.$id}}};
+                                }
+                                if ($name ne '') {
+                                    $folderpath .= $name.' » ';
+                                }
+                            }
+                            if ($title eq '') {
+                                $folderpath =~ s/\Q » \E$//;
+                            } else {
+                                $folderpath .= $title;
+                            }
+                            if ($folderpath) {
+                                $errinfo .= '<br />'.&mt('Hierarchy is: [_1]',
+                                                    '<span class="LC_cusr_emph">'.$folderpath.'</span>');
+                            }
+                        }
+                    }
+                }
+                if ($uri =~ m{^/res/($match_domain)/($match_username)/.+\.(sequence|page)$}) {
+                    ($audomfile,$aunamefile) = ($1,$2);
+                    ($editfile,$filerole,$fileswitch) = &canedit_published($audomfile,$aunamefile);
+                    if ($fileswitch) {
+                        unless ((&Apache::lonnet::will_trust('othcoau',$env{'user.domain'},$audomfile)) &&
+                                (&Apache::lonnet::will_trust('coaurem',$audomfile,$env{'user.domain'}))) {
+                            undef($editfile);
+                        }
+                    }
+                }
+            }
+            if ($errinfo) {
+                $errinfo = '<br />'.$errinfo.'<br />';
+            }
+            if ($editfile) {
+                if ($errinfo ne '') {
+                    $errinfo .= '<br />';
+                }
+                if ($canedit) {
+                    $errinfo .= &mt('One way to rectify this problem is to create and publish the missing file');
+                } else {
+                    $errinfo .= &mt('To rectify this problem, create and publish the missing file');
+                }
+                if ($fileswitch) {
+                    my $rolename = &Apache::lonnet::plaintext($filerole);
+                    my $rolecode;
+                    if ($filerole eq 'au') {
+                        $rolecode = 'au./'.$audomfile.'/';
+                    } else {
+                        $rolecode = $filerole.'./'.$audomfile.'/'.$aunamefile;
+                    }
+                    $errinfo .= '.<br />'.&mt('You will need to [_1]switch server[_2].',
+                                             '<a href="/adm/switchserver?otherserver='.$switchserver.'&role='.$rolecode.'">','</a>');
+                } else {
+                    my $fileurl = $uri;
+                    $fileurl =~s{^/res/}{/priv/};
+                    $errinfo .= ': <a href="javascript:go('."'$fileurl'".');">'.&mt('Create the missing file').'</a>';
+                }
+            }
+            if ($canedit) {
+                if ($errinfo ne '') {
+                    $errinfo .= '<br />';
+                }
+                if ($published) {
+                    my $rolename = &Apache::lonnet::plaintext($role);
+                    my $rolecode;
+                    if ($role eq 'au') {
+                        $rolecode = 'au./'.$audom.'/';
+                    } else {
+                        $rolecode = $role.'./'.$audom.'/'.$auname;
+                    }
+                    if ($editfile) {
+                        $errinfo .= &mt('Another way is to edit the parent map to remove the reference to the missing file');
+                    } else {
+                        $errinfo .= &mt('To rectify this problem edit the parent map to remove the reference to the missing file');
+                    }
+                    if ($switchserver) {
+                        $errinfo .= '.<br />';
+                        if ((&Apache::lonnet::will_trust('othcoau',$env{'user.domain'},$audom)) &&
+                            (&Apache::lonnet::will_trust('coaurem',$audom,$env{'user.domain'}))) {
+                            $errinfo .= &mt('You will need to [_1]switch server[_2].',
+                                            '<a href="/adm/switchserver?otherserver='.$switchserver.'&role='.$rolecode.'">','</a>');
+                        } else {
+                            $errinfo .= &mt('Session switch required but prohibited.');
+                        }
+                    } else {
+                        my $mapurl = $hash{'map_id_'.$parent_pc};
+                        $mapurl =~s{^/res/}{/priv/};
+                        $errinfo .= ': <a href="javascript:go('."'$mapurl'".');">'.&mt('Edit the map').'</a>';
+                    }
+                } elsif ($uploaded && $courseid) {
+                    my ($dest,$linktext);
+                    my $crstype = &Apache::loncommon::course_type($courseid);
+                    if ($parent_pc eq '1') {
+                        $dest = '/adm/coursedocs?folderpath='.&escape('default&Main%20Content:::::');
+                        $linktext = &mt('Edit Folder');
+                    } elsif ($hash{'ids_'.$hash{'map_id_'.$parent_pc}} =~ /^(\d+)\.(\d+)$/) {
+                        my ($editmap,$editidx) = ($1,$2);
+                        my $symb = &Apache::lonnet::encode_symb($hash{'map_id_'.$editmap},
+                                                                     $editidx,$hash{'map_id_'.$parent_pc});
+                        $dest = '/adm/coursedocs?command=directnav&symb='.&escape($symb);
+                        if ($parent_type eq 'sequence') {
+                            $linktext = &mt('Edit Folder');
+                        } else {
+                            $linktext = &mt('Edit Composite Page');
+                        }
+                    } else {
+                        $dest = '/adm/coursedocs?folderpath='.&escape('default&Main%20Content:::::');
+                        $linktext = &mt("Edit $crstype");
+                    }
+                    if ($editfile) {
+                        $errinfo .= &mt("Another way is to use the $crstype Editor to delete the reference to the missing file");
+                    } else {
+                        $errinfo .= &mt("To rectify this problem use the $crstype Editor to delete the reference to the missing file");
+                    }
+                    $errinfo .= ': <a href="javascript:go('."'$dest'".');">'.$linktext.'</a>';
+                }
+                $errinfo .= '<br />';
+            }
+        }
+    }
+    return $errinfo;
+}
+
+sub canedit_published {
+    my ($audom,$auname) = @_;
+    my ($canedit,$role,$switchserver);
+    my $now = time;
+    if (($auname eq $env{'user.name'}) && ($audom eq $env{'user.domain'})) {
+        if (exists($env{"user.role.au./$audom/"})) {
+            my ($start,$end) = split(/\./,$env{"user.role.au./$audom/"});
+            unless (($end && $end < $now) || ($start && $start > $now)) {
+                $canedit = 1;
+                $role = 'au';
+            }
+        }
+    }
+    unless ($canedit) {
+        foreach my $possrole ('ca','aa') {
+            if (exists($env{"user.role.$possrole./$audom/$auname"})) {
+                my ($end,$start) = split(/\./,$env{"user.role.$possrole./$audom/$auname"});
+                unless (($end && $end < time) || ($start && $start > time)) {
+                    $canedit = 1;
+                    $role = $possrole;
+                    last;
+                }
+            }
+        }
+    }
+    if ($canedit) {
+        my $auhome = &Apache::lonnet::homeserver($auname,$audom);
+        my @ids=&Apache::lonnet::current_machine_ids();
+        if (($auhome ne 'no_host') && (!grep(/^\Q$auhome\E$/, at ids))) {
+            $switchserver = $auhome;
+        }
+    }
+    return ($canedit,$role,$switchserver);
+}
+
 # -------------------------------------------------------------------- Resource
 #
 #  Parses a resource tag to produce the value to push into the
Index: rat/lonpage.pm
diff -u rat/lonpage.pm:1.141 rat/lonpage.pm:1.142
--- rat/lonpage.pm:1.141	Tue Sep 13 12:22:15 2022
+++ rat/lonpage.pm	Tue Oct  4 20:39:57 2022
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Page Handler
 #
-# $Id: lonpage.pm,v 1.141 2022/09/13 12:22:15 raeburn Exp $
+# $Id: lonpage.pm,v 1.142 2022/10/04 20:39:57 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -683,7 +683,7 @@
 # ---------------------------------------------------------------- End SSI cell
                           }
                       }
-                     } 
+                     }
                   }
                   unless ($contents) {
                       &Apache::loncommon::content_type($r,'text/html');
@@ -965,9 +965,30 @@
                   }                  
 # ------------------------------------------------------------- End render page
               } else {
-                  &Apache::loncommon::content_type($r,'text/html');
-                  $r->send_http_header;
-                  &Apache::lonsequence::viewmap($r,$requrl);
+                  if ($hash{'map_type_'.$hash{'map_pc_'.$requrl}} eq 'none') {
+                      &Apache::loncommon::content_type($r,'text/html');
+                      $r->send_http_header;
+                      $r->print(&Apache::loncommon::start_page(undef,undef,
+                                                               {'force_register' => 1,}));
+                      my $crstype = &Apache::loncommon::course_type();
+                      if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) {
+                          $r->print('<span class="LC_warning">'.&mt('Missing composite page file.').'</span><br />'.
+                                    &mt("You may want to use the $crstype Editor to remove this item."));
+                      } else {
+                          if ($crstype eq 'Placement') {
+                              $r->print('<span class="LC_warning">'.&mt('Missing page').'</span>');
+                          } else {
+                              $r->print('<span class="LC_info">'.
+                                        &mt('This resource was unavailable when your '.lc($crstype).' session was loaded').'<br />'.
+                                        &mt("Please use 'Contents' to list items available in the $crstype.").'</span>');
+                          }
+                      }
+                      $r->print(&Apache::loncommon::end_page());
+                  } else {
+                      &Apache::loncommon::content_type($r,'text/html');
+                      $r->send_http_header;
+                      &Apache::lonsequence::viewmap($r,$requrl);
+                  }
               }
 # ------------------------------------------------------------------ Untie hash
               unless (untie(%hash)) {
Index: doc/loncapafiles/loncapafiles.lpml
diff -u doc/loncapafiles/loncapafiles.lpml:1.1033 doc/loncapafiles/loncapafiles.lpml:1.1034
--- doc/loncapafiles/loncapafiles.lpml:1.1033	Thu Sep  8 01:41:16 2022
+++ doc/loncapafiles/loncapafiles.lpml	Tue Oct  4 20:39:58 2022
@@ -2,7 +2,7 @@
  "http://lpml.sourceforge.net/DTD/lpml.dtd">
 <!-- loncapafiles.lpml -->
 
-<!-- $Id: loncapafiles.lpml,v 1.1033 2022/09/08 01:41:16 raeburn Exp $ -->
+<!-- $Id: loncapafiles.lpml,v 1.1034 2022/10/04 20:39:58 raeburn Exp $ -->
 
 <!--
 
@@ -7581,6 +7581,8 @@
 navmap.correct.gif;
 navmap.partial.gif;
 navmap.ellipsis.gif;
+navmap.none.closed.gif;
+navmap.none.open.gif;
 navmap.open.gif;
 navmap.page.open.gif;
 navmap.page.closed.gif;
Index: loncom/lonmap.pm
diff -u loncom/lonmap.pm:1.15 loncom/lonmap.pm:1.16
--- loncom/lonmap.pm:1.15	Thu Dec 11 01:50:27 2014
+++ loncom/lonmap.pm	Tue Oct  4 20:39:58 2022
@@ -2,7 +2,7 @@
 #
 #  Read maps into a 'big hash'.
 #
-# $Id: lonmap.pm,v 1.15 2014/12/11 01:50:27 raeburn Exp $
+# $Id: lonmap.pm,v 1.16 2022/10/04 20:39:58 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1268,6 +1268,7 @@
    
     my $contents = &Apache::lonnet::getfile($filename);
     if($contents eq -1) {
+        $hash->{'map_type_'.$lmap_no} = 'none';
         throw Error::Simple('<br />'.&mt('Map not loaded: The file [_1] does not exist.',
 				'<span class="LC_filename">'.$filename.'</span>'));
     }
Index: loncom/interface/lonnavmaps.pm
diff -u loncom/interface/lonnavmaps.pm:1.561 loncom/interface/lonnavmaps.pm:1.562
--- loncom/interface/lonnavmaps.pm:1.561	Tue Oct  4 14:38:08 2022
+++ loncom/interface/lonnavmaps.pm	Tue Oct  4 20:39:59 2022
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Navigate Maps Handler
 #
-# $Id: lonnavmaps.pm,v 1.561 2022/10/04 14:38:08 raeburn Exp $
+# $Id: lonnavmaps.pm,v 1.562 2022/10/04 20:39:59 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1020,8 +1020,12 @@
         if ($it->{CONDITION}) {
             $nowOpen = !$nowOpen;
         }
-	
-	my $folderType = $resource->is_sequence() ? 'folder' : 'page';
+	my $folderType;
+	if (&advancedUser() && $resource->is_missing_map()) {
+	    $folderType = 'none';
+	} else {
+	    $folderType = $resource->is_sequence() ? 'folder' : 'page';
+	}
         my $title=$resource->title;
 		$title=~s/\"/\&qout;/g;
         if (!$params->{'resource_no_folder_link'}) {
@@ -4805,6 +4809,11 @@
     return $self->navHash("is_map_", 1) && 
     $self->navHash("map_type_" . $self->map_pc()) eq 'sequence';
 }
+sub is_missing_map {
+    my $self=shift;
+    return $self->navHash("is_map_", 1) &&
+    $self->navHash("map_type_" . $self->map_pc()) eq 'none';
+}
 sub is_survey {
     my $self = shift();
     my $part = shift();


More information about the LON-CAPA-cvs mailing list