Diff for /loncom/interface/loncommon.pm between versions 1.1378 and 1.1462

version 1.1378, 2022/05/24 16:23:03 version 1.1462, 2025/02/21 20:55:17
Line 61  use POSIX qw(strftime mktime); Line 61  use POSIX qw(strftime mktime);
 use Apache::lonmenu();  use Apache::lonmenu();
 use Apache::lonenc();  use Apache::lonenc();
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet();  use Apache::lonnavmaps();
 use HTML::Entities;  use HTML::Entities;
 use Apache::lonhtmlcommon();  use Apache::lonhtmlcommon();
 use Apache::loncoursedata();  use Apache::loncoursedata();
Line 71  use Apache::lonuserutils(); Line 71  use Apache::lonuserutils();
 use Apache::lonuserstate();  use Apache::lonuserstate();
 use Apache::courseclassifier();  use Apache::courseclassifier();
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
   use LONCAPA::ltiutils;
 use LONCAPA::LWPReq;  use LONCAPA::LWPReq;
   use LONCAPA::map();
 use HTTP::Request;  use HTTP::Request;
 use DateTime::TimeZone;  use DateTime::TimeZone;
 use DateTime::Locale;  use DateTime::Locale;
Line 435  sub studentbrowser_javascript { Line 437  sub studentbrowser_javascript {
 <script type="text/javascript" language="Javascript">  <script type="text/javascript" language="Javascript">
 // <![CDATA[  // <![CDATA[
     var stdeditbrowser;      var stdeditbrowser;
     function openstdbrowser(formname,uname,udom,clicker,roleflag,ignorefilter,courseadv) {      function openstdbrowser(formname,uname,udom,clicker,roleflag,ignorefilter,courseadv,uident) {
         var url = '/adm/pickstudent?';          var url = '/adm/pickstudent?';
         var filter;          var filter;
  if (!ignorefilter) {   if (!ignorefilter) {
Line 456  sub studentbrowser_javascript { Line 458  sub studentbrowser_javascript {
             }              }
         }          }
         if ((courseadv == 'only') || (courseadv == 'none')) { url+="&courseadv="+courseadv; }          if ((courseadv == 'only') || (courseadv == 'none')) { url+="&courseadv="+courseadv; }
           if (uident !== '') { url+="&identelement="+uident; } 
         var title = 'Student_Browser';          var title = 'Student_Browser';
         var options = 'scrollbars=1,resizable=1,menubar=0';          var options = 'scrollbars=1,resizable=1,menubar=0';
         options += ',width=700,height=600';          options += ',width=700,height=600';
Line 487  ENDRESBRW Line 490  ENDRESBRW
 }  }
   
 sub selectstudent_link {  sub selectstudent_link {
    my ($form,$unameele,$udomele,$courseadv,$clickerid)=@_;     my ($form,$unameele,$udomele,$courseadv,$clickerid,$identelem)=@_;
    my $callargs = "'".&Apache::lonhtmlcommon::entity_encode($form)."','".     my $callargs = "'".&Apache::lonhtmlcommon::entity_encode($form)."','".
                       &Apache::lonhtmlcommon::entity_encode($unameele)."','".                        &Apache::lonhtmlcommon::entity_encode($unameele)."','".
                       &Apache::lonhtmlcommon::entity_encode($udomele)."'";                        &Apache::lonhtmlcommon::entity_encode($udomele)."'";
Line 504  sub selectstudent_link { Line 507  sub selectstudent_link {
            $callargs .= ",'','','$courseadv'";             $callargs .= ",'','','$courseadv'";
        } elsif ($courseadv eq 'condition') {         } elsif ($courseadv eq 'condition') {
            $callargs .= ",'','','$courseadv'";             $callargs .= ",'','','$courseadv'";
          } elsif ($identelem ne '') {
              $callargs .= ",'','',''";
          }
          if ($identelem ne '') {
              $callargs .= ",'".&Apache::lonhtmlcommon::entity_encode($identelem)."'";
        }         }
        return '<span class="LC_nobreak">'.         return '<span class="LC_nobreak">'.
               '<a href="javascript:openstdbrowser('.$callargs.');">'.                '<a href="javascript:openstdbrowser('.$callargs.');">'.
Line 957  ENDSCRT Line 965  ENDSCRT
 }  }
   
 sub select_timezone {  sub select_timezone {
    my ($name,$selected,$onchange,$includeempty,$disabled)=@_;     my ($name,$selected,$onchange,$includeempty,$id,$disabled)=@_;
    my $output='<select name="'.$name.'" '.$onchange.$disabled.'>'."\n";     my $output='<select name="'.$name.'" '.$id.$onchange.$disabled.'>'."\n";
    if ($includeempty) {     if ($includeempty) {
        $output .= '<option value=""';         $output .= '<option value=""';
        if (($selected eq '') || ($selected eq 'local')) {         if (($selected eq '') || ($selected eq 'local')) {
Line 1166  sub linked_select_forms { Line 1174  sub linked_select_forms {
         $menuorder,          $menuorder,
         $onchangefirst,          $onchangefirst,
         $onchangesecond,          $onchangesecond,
         $suffix          $suffix,
           $haslabel
         ) = @_;          ) = @_;
     my $second = "document.$formname.$secondselectname";      my $second = "document.$formname.$secondselectname";
     my $first = "document.$formname.$firstselectname";      my $first = "document.$formname.$firstselectname";
Line 1232  END Line 1241  END
         $result.=">".&mt($hashref->{$value}->{'text'})."</option>\n";          $result.=">".&mt($hashref->{$value}->{'text'})."</option>\n";
     }      }
     $result .= "</select>\n";      $result .= "</select>\n";
     my %select2 = %{$hashref->{$firstdefault}->{'select2'}};      if ($haslabel) {
     $result .= $middletext;          $result .= '</label>';
       }
       my %select2;
       if (ref($hashref->{$firstdefault}) eq 'HASH') {
           if (ref($hashref->{$firstdefault}->{'select2'}) eq 'HASH') {
               %select2 = %{$hashref->{$firstdefault}->{'select2'}};
           }
       }
       if ($middletext ne '') {
           $result .= '<label>'.$middletext;
       }
     $result .= "<select size=\"1\" name=\"$secondselectname\"";      $result .= "<select size=\"1\" name=\"$secondselectname\"";
     if ($onchangesecond) {      if ($onchangesecond) {
         $result .= ' onchange="'.$onchangesecond.'"';          $result .= ' onchange="'.$onchangesecond.'"';
Line 1251  END Line 1270  END
         $result.=">".&mt($select2{$value})."</option>\n";          $result.=">".&mt($select2{$value})."</option>\n";
     }      }
     $result .= "</select>\n";      $result .= "</select>\n";
       if ($middletext ne '') {
           $result .= '</label>';
       }
     #    return $debug;      #    return $debug;
     return $result;      return $result;
 }   #  end of sub linked_select_forms {  }   #  end of sub linked_select_forms {
   
 =pod  =pod
   
 =item * &help_open_topic($topic,$text,$stayOnPage,$width,$height,$imgid)  =item * &help_open_topic($topic,$text,$stayOnPage,$width,$height,$imgid,$links_target)
   
 Returns a string corresponding to an HTML link to the given help  Returns a string corresponding to an HTML link to the given help
 $topic, where $topic corresponds to the name of a .tex file in  $topic, where $topic corresponds to the name of a .tex file in
Line 1281  $imgid is the id of the img tag used for Line 1303  $imgid is the id of the img tag used for
 used in a javascript call to switch the image src.  See   used in a javascript call to switch the image src.  See 
 lonhtmlcommon::htmlareaselectactive() for an example.  lonhtmlcommon::htmlareaselectactive() for an example.
   
   $links_target will optionally be set to a target (_top, _parent or _self).
   
 =cut  =cut
   
 sub help_open_topic {  sub help_open_topic {
     my ($topic, $text, $stayOnPage, $width, $height, $imgid) = @_;      my ($topic, $text, $stayOnPage, $width, $height, $imgid, $links_target) = @_;
     $text = "" if (not defined $text);      $text = "" if (not defined $text);
     $stayOnPage = 0 if (not defined $stayOnPage);      $stayOnPage = 0 if (not defined $stayOnPage);
     $width = 500 if (not defined $width);      $width = 500 if (not defined $width);
Line 1307  sub help_open_topic { Line 1331  sub help_open_topic {
   
     # Add the text      # Add the text
     my $target = ' target="_top"';      my $target = ' target="_top"';
     if (($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) {      if ($links_target) {
           $target = ' target="'.$links_target.'"';
       } elsif ((($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) ||
                (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'} eq '_self'))) {
         $target = '';          $target = '';
     }      }
     if (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'})) {      if ($text ne "") {
         $target = ' target="'.$env{'request.deeplink.target'}.'"';  
     }  
     if ($text ne "") {  
  $template.='<span class="LC_help_open_topic">'   $template.='<span class="LC_help_open_topic">'
                   .'<a'.$target.' href="'.$link.'">'                    .'<a'.$target.' href="'.$link.'">'
                   .$text.'</a>';                    .$text.'</a>';
Line 1357  sub helpLatexCheatsheet { Line 1381  sub helpLatexCheatsheet {
         $out .= '<span>'          $out .= '<span>'
                .&help_open_topic('Authoring_Output_Tags',&mt('Output Tags'),$stayOnPage,undef,600)                 .&help_open_topic('Authoring_Output_Tags',&mt('Output Tags'),$stayOnPage,undef,600)
                .'</span> <span>'                 .'</span> <span>'
                .&help_open_topic('Authoring_Multilingual_Problems',&mt('How to create problems in different languages'),$stayOnPage,undef,600)                 .&help_open_topic('Authoring_Multilingual_Problems',&mt('Languages'),$stayOnPage,undef,600)
        .'</span>';         .'</span>';
     }      }
     $out .= '</span>'; # End cheatsheet      $out .= '</span>'; # End cheatsheet
Line 1398  ENDOUTPUT Line 1422  ENDOUTPUT
   
 # now just updates the help link and generates a blue icon  # now just updates the help link and generates a blue icon
 sub help_open_menu {  sub help_open_menu {
     my ($topic,$component_help,$faq,$bug,$stayOnPage,$width,$height,$text)       my ($topic,$component_help,$faq,$bug,$stayOnPage,$width,$height,$text,$links_target) 
  = @_;       = @_;    
     $stayOnPage = 1;      $stayOnPage = 1;
     my $output;      my $output;
     if ($component_help) {      if ($component_help) {
  if (!$text) {   if (!$text) {
     $output=&help_open_topic($component_help,undef,$stayOnPage,      $output=&help_open_topic($component_help,undef,$stayOnPage,
        $width,$height);         $width,$height,'',$links_target);
  } else {   } else {
     my $help_text;      my $help_text;
     $help_text=&unescape($topic);      $help_text=&unescape($topic);
     $output='<table><tr><td>'.      $output='<table><tr><td>'.
  &help_open_topic($component_help,$help_text,$stayOnPage,   &help_open_topic($component_help,$help_text,$stayOnPage,
  $width,$height).'</td></tr></table>';   $width,$height,'',$links_target).'</td></tr></table>';
  }   }
     }      }
     my $banner_link = &update_help_link($topic,$component_help,$faq,$bug,$stayOnPage);      my $banner_link = &update_help_link($topic,$component_help,$faq,$bug,$stayOnPage);
Line 1436  $banner_link Line 1460  $banner_link
 <a href="$link" title="$title" $linkattr>$text</a>  <a href="$link" title="$title" $linkattr>$text</a>
 END  END
     } else {      } else {
         return '&nbsp;'.$text.'&nbsp;';          return '&nbsp;<h1 class="LC_helpmenu">'.$text.'</h1>&nbsp;';
     }      }
 }  }
   
Line 1448  sub help_menu_js { Line 1472  sub help_menu_js {
     my $helptopic=&general_help();      my $helptopic=&general_help();
     my $details_link = $httphost.'/adm/help/'.$helptopic.'.hlp';      my $details_link = $httphost.'/adm/help/'.$helptopic.'.hlp';
     my $nothing=&Apache::lonhtmlcommon::javascript_nothing();      my $nothing=&Apache::lonhtmlcommon::javascript_nothing();
       my $bannertitle = &mt('Help Menu');
       &js_escape(\$bannertitle);
       my $bodytitle = &mt('Documentation');
       &js_escape(\$bodytitle);
     my $start_page =      my $start_page =
         &Apache::loncommon::start_page('Help Menu', undef,          &Apache::loncommon::start_page('Help Menu', undef,
        {'frameset'    => 1,         {'frameset'    => 1,
Line 1459  sub help_menu_js { Line 1487  sub help_menu_js {
     my $end_page =      my $end_page =
         &Apache::loncommon::end_page({'frameset' => 1,          &Apache::loncommon::end_page({'frameset' => 1,
       'js_ready' => 1,});        'js_ready' => 1,});
   
     my $template .= <<"ENDTEMPLATE";      my $template .= <<"ENDTEMPLATE";
 <script type="text/javascript">  <script type="text/javascript">
 // <![CDATA[  // <![CDATA[
Line 1484  function helpMenu(target) { Line 1511  function helpMenu(target) {
     return;      return;
 }  }
 function writeHelp(caller) {  function writeHelp(caller) {
     caller.document.writeln('$start_page\\n<frame name="bannerframe" src="'+banner_link+'" marginwidth="0" marginheight="0" frameborder="0">\\n');      caller.document.writeln('$start_page\\n<frame name="bannerframe" title="$bannertitle" src="'+banner_link+'" marginwidth="0" marginheight="0" frameborder="0">\\n');
     caller.document.writeln('<frame name="bodyframe" src="$details_link" marginwidth="0" marginheight="0" frameborder="0">\\n$end_page');      caller.document.writeln('<frame name="bodyframe" title="$bodytitle" src="$details_link" marginwidth="0" marginheight="0" frameborder="0">\\n$end_page');
     caller.document.close();      caller.document.close();
     caller.focus();      caller.focus();
 }  }
Line 1519  sub help_open_bug { Line 1546  sub help_open_bug {
  $link = $url;   $link = $url;
     }      }
   
     my $target = ' target="_top"';      my $target = '_top';
     if (($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) {      if ((($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) ||
         $target = '';          (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'} eq '_self'))) {
     }          $target = '_blank';
     if (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'})) {  
         $target = ' target="'.$env{'request.deeplink.target'}.'"';  
     }      }
   
     # Add the text      # Add the text
     if ($text ne "")      if ($text ne "")
     {      {
  $template .=    $template .= 
   "<table bgcolor='#AA3333' cellspacing='1' cellpadding='1' border='0'><tr>".    "<table bgcolor='#AA3333' cellspacing='1' cellpadding='1' border='0'><tr>".
   "<td bgcolor='#FF5555'><a".$target." href=\"$link\"><span style=\"color:#FFFFFF;font-size:10pt;\">$text</span></a>";    "<td bgcolor='#FF5555'><a target=\"$target\" href=\"$link\"><span style=\"color:#FFFFFF;font-size:10pt;\">$text</span></a>";
     }      }
   
     # Add the graphic      # Add the graphic
     my $title = &mt('Report a Bug');      my $title = &mt('Report a Bug');
     my $bugicon=&lonhttpdurl("/adm/lonMisc/smallBug.gif");      my $bugicon=&lonhttpdurl("/adm/lonMisc/smallBug.gif");
     $template .= <<"ENDTEMPLATE";      $template .= <<"ENDTEMPLATE";
  <a$target href="$link" title="$title"><img src="$bugicon" border="0" alt="(Bug: $topic)" /></a>   <a target="$target" href="$link" title="$title"><img src="$bugicon" border="0" alt="(Bug: $topic)" /></a>
 ENDTEMPLATE  ENDTEMPLATE
     if ($text ne '') { $template.='</td></tr></table>' };      if ($text ne '') { $template.='</td></tr></table>' };
     return $template;      return $template;
Line 1750  the id of the element to resize, second Line 1776  the id of the element to resize, second
 surrounds everything that comes after the textarea, this routine needs  surrounds everything that comes after the textarea, this routine needs
 to be attached to the <body> for the onload and onresize events.  to be attached to the <body> for the onload and onresize events.
   
 =back  
   
 =cut  =cut
   
 sub resize_textarea_js {  sub resize_textarea_js {
Line 1814  sub colorfuleditor_js { Line 1838  sub colorfuleditor_js {
             save => 'Save page to make this permanent',              save => 'Save page to make this permanent',
         );          );
         &js_escape(\%js_lt);          &js_escape(\%js_lt);
           my $showfile_js = &show_crsfiles_js();
         $browse_or_search = <<"END";          $browse_or_search = <<"END";
   
       $showfile_js
   
     function toggleChooser(form,element,titleid,only,search) {      function toggleChooser(form,element,titleid,only,search) {
         var disp = 'none';          var disp = 'none';
         if (document.getElementById('chooser_'+element)) {          if (document.getElementById('chooser_'+element)) {
Line 1830  sub colorfuleditor_js { Line 1857  sub colorfuleditor_js {
                 toggleResImport(form,element);                  toggleResImport(form,element);
             }              }
             document.getElementById('chooser_'+element).style.display = disp;              document.getElementById('chooser_'+element).style.display = disp;
               var dirsel = '';
               var filesel = '';
               if (document.getElementById('chooser_'+element+'_crsres')) {
                   var currcrsres = document.getElementById('chooser_'+element+'_crsres').style.display;
                   if (currcrsres == 'none') {
                       dirsel = 'coursepath_'+element;
                       var filesel = 'coursefile_'+element;
                       var include;
                       if (document.getElementById('crsres_include_'+element)) {
                           include = document.getElementById('crsres_include_'+element).value;
                       }
                       populateCrsSelects(form,dirsel,filesel,1,include,1,0,1,1,0);
                   }
               }
               if (document.getElementById('chooser_'+element+'_upload')) {
                   var currcrsupload = document.getElementById('chooser_'+element+'_upload').style.display;
                   if (currcrsupload == 'none') {
                       dirsel = 'crsauthorpath_'+element;
                       filesel = '';
                       populateCrsSelects(form,dirsel,filesel,0,'',1,0,1,0,1);
                   }
               }
         }          }
     }      }
   
     function toggleCrsFile(form,element,numdirs) {      function toggleCrsFile(form,element) {
         if (document.getElementById('chooser_'+element+'_crsres')) {          if (document.getElementById('chooser_'+element+'_crsres')) {
             var curr = document.getElementById('chooser_'+element+'_crsres').style.display;              var curr = document.getElementById('chooser_'+element+'_crsres').style.display;
             if (curr == 'none') {              if (curr == 'none') {
                 if (numdirs) {                  if (document.getElementById('coursepath_'+element)) {
                       var numdirs;
                       if (document.getElementById('coursepath_'+element).length) {
                           numdirs = document.getElementById('coursepath_'+element).length;
                       }
                       if ((document.getElementById('hascrsres_'+element)) &&
                           (document.getElementById('nocrsres_'+element))) {
                           if (numdirs) {
                               document.getElementById('hascrsres_'+element).style.display='inline-block';
                               document.getElementById('nocrsres_'+element).style.display='none';
                           } else {
                               document.getElementById('hascrsres_'+element).style.display='none';
                               document.getElementById('nocrsres_'+element).style.display='inline-block';
                           }
                       }
                     form.elements['coursepath_'+element].selectedIndex = 0;                      form.elements['coursepath_'+element].selectedIndex = 0;
                     if (numdirs > 1) {                      if (numdirs > 1) {
                         window['select1'+element+'_changed']();                          var selelem = form.elements['coursefile_'+element];
                           var i, len = selelem.options.length -1;
                           if (len >=0) {
                               for (i = len; i >= 0; i--) {
                                   selelem.remove(i);
                               }
                               selelem.options[0] = new Option('','');
                           }
                     }                      }
                 }                  }
             }               }
             document.getElementById('chooser_'+element+'_crsres').style.display = 'block';              document.getElementById('chooser_'+element+'_crsres').style.display = 'block';
               
         }          }
         if (document.getElementById('chooser_'+element+'_upload')) {          if (document.getElementById('chooser_'+element+'_upload')) {
             document.getElementById('chooser_'+element+'_upload').style.display = 'none';              document.getElementById('chooser_'+element+'_upload').style.display = 'none';
Line 1856  sub colorfuleditor_js { Line 1925  sub colorfuleditor_js {
         return;          return;
     }      }
   
     function toggleCrsUpload(form,element,numcrsdirs) {      function toggleCrsUpload(form,element) {
         if (document.getElementById('chooser_'+element+'_crsres')) {          if (document.getElementById('chooser_'+element+'_crsres')) {
             document.getElementById('chooser_'+element+'_crsres').style.display = 'none';              document.getElementById('chooser_'+element+'_crsres').style.display = 'none';
         }          }
         if (document.getElementById('chooser_'+element+'_upload')) {          if (document.getElementById('chooser_'+element+'_upload')) {
             var curr = document.getElementById('chooser_'+element+'_upload').style.display;              var curr = document.getElementById('chooser_'+element+'_upload').style.display;
             if (curr == 'none') {              if (curr == 'none') {
                 if (numcrsdirs) {                  form.elements['newsubdir_'+element][0].checked = true;
                    form.elements['crsauthorpath_'+element].selectedIndex = 0;                  toggleNewsubdir(form,element);
                    form.elements['newsubdir_'+element][0].checked = true;                  document.getElementById('chooser_'+element+'_upload').style.display = 'block';
                    toggleNewsubdir(form,element);                  if (document.getElementById('uploadcrsres_'+element)) {
                       document.getElementById('uploadcrsres_'+element).value = '';
                 }                  }
             }              }
             document.getElementById('chooser_'+element+'_upload').style.display = 'block';  
         }          }
         return;          return;
     }      }
Line 1913  sub colorfuleditor_js { Line 1982  sub colorfuleditor_js {
         var filename = form.elements['coursefile_'+element];          var filename = form.elements['coursefile_'+element];
         var path = directory.options[directory.selectedIndex].value;          var path = directory.options[directory.selectedIndex].value;
         var file = filename.options[filename.selectedIndex].value;          var file = filename.options[filename.selectedIndex].value;
         form.elements[element].value = '$respath';          if (file != '') {
         if (path == '/') {              form.elements[element].value = '$respath';
             form.elements[element].value += file;              if (path == '/') {
         } else {                  form.elements[element].value += file;
             form.elements[element].value += path+'/'+file;              } else {
         }                  form.elements[element].value += path+'/'+file;
         unClean();              }
         if (document.getElementById('previewimg_'+element)) {              unClean();
             document.getElementById('previewimg_'+element).src = form.elements[element].value;              if (document.getElementById('previewimg_'+element)) {
             var newsrc = document.getElementById('previewimg_'+element).src;                   document.getElementById('previewimg_'+element).src = form.elements[element].value;
         }                  var newsrc = document.getElementById('previewimg_'+element).src; 
         if (document.getElementById('showimg_'+element)) {              }
             document.getElementById('showimg_'+element).innerHTML = '($js_lt{save})';              if (document.getElementById('showimg_'+element)) {
                   document.getElementById('showimg_'+element).innerHTML = '($js_lt{save})';
               }
         }          }
         toggleChooser(form,element);          toggleChooser(form,element);
         return;          return;
Line 2214  sub crsauthor_url { Line 2285  sub crsauthor_url {
 }  }
   
 sub import_crsauthor_form {  sub import_crsauthor_form {
     my ($form,$firstselectname,$secondselectname,$onchangefirst,$only,$suffix,$disabled) = @_;      my ($firstselectname,$secondselectname,$onchangefirst,$only,$suffix,$disabled) = @_;
     return (0) unless ($env{'request.course.id'});      return (0) unless ($env{'request.course.id'});
     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};      my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};      my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
     my $crshome = $env{'course.'.$env{'request.course.id'}.'.home'};      my $crshome = $env{'course.'.$env{'request.course.id'}.'.home'};
     return (0) unless (($cnum ne '') && ($cdom ne ''));      return (0) unless (($cnum ne '') && ($cdom ne ''));
     my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};  
     my @ids=&Apache::lonnet::current_machine_ids();      my @ids=&Apache::lonnet::current_machine_ids();
     my ($output,$is_home,$relpath,%subdirs,%files,%selimport_menus);      my ($output,$is_home,$toppath,%subdirs,%files,%selimport_menus,$include,$exclude);
       
     if (grep(/^\Q$crshome\E$/,@ids)) {      if (grep(/^\Q$crshome\E$/,@ids)) {
         $is_home = 1;          $is_home = 1;
     }      }
     $relpath = "/priv/$cdom/$cnum";      $toppath = "/priv/$cdom/$cnum";
     &Apache::lonnet::recursedirs($is_home,'priv',$londocroot,$relpath,'',\%subdirs,\%files);      my $nonemptydir = 1;
       my $js_only;
       if ($only) {
           map { $include->{$_} = 1; } split(/\s*,\s*/,$only);
           $js_only = join(',',map { &js_escape($_); } sort(keys(%{$include})));
       }
       $exclude = &Apache::lonnet::priv_exclude();
       &Apache::lonnet::recursedirs($is_home,1,$include,$exclude,1,0,$toppath,'',\%subdirs,\%files);
       my $numdirs = scalar(keys(%files));
     my %lt = &Apache::lonlocal::texthash (      my %lt = &Apache::lonlocal::texthash (
         fnam => 'Filename',          fnam => 'Filename',
         dire => 'Directory',          dire => 'Directory',
           se   => 'Select',
     );      );
     my $numdirs = scalar(keys(%files));      $output = '<label>'.$lt{'dire'}.':&nbsp;'.
     my (%possexts,$singledir,@singledirfiles);                '<select id="'.$firstselectname.'" name="'.$firstselectname.'" '.
     if ($only) {                'onchange="populateCrsSelects(this.form,'."'$firstselectname','$secondselectname',1,'$js_only',0,1,0,0,0".');">'.
         map { $possexts{$_} = 1; } split(/\s*,\s*/,$only);                '<option value="" selected="selected">'.$lt{'se'}.'</option>';
     }      if ($files{'/'}) {
     my (%nonemptydirs,$possdirs);          $output .= '<option value="/">/</option>'."\n";
     if ($numdirs > 1) {      }
         my @order;      foreach my $key (sort { lc($a) cmp lc($b) } (keys(%files))) {
         foreach my $key (sort { lc($a) cmp lc($b) } (keys(%files))) {          next if ($key eq '/');
             if (ref($files{$key}) eq 'HASH') {          $output .= '<option value="'.$key.'">'.$key.'</option>'."\n";
                 my $shown = $key;      }
                 if ($key eq '') {      $output .= '</select></label><br /><label>'."\n".
                     $shown = '/';                 $lt{'fnam'}.':&nbsp;<select id="'.$secondselectname.'" name="'.$secondselectname.'">'."\n".
                 }                 '<option value="" selected="selected"></option>'."\n".
                 my @ordered = ();                 '</select></label>'."\n".
                 foreach my $file (sort { lc($a) cmp lc($b) } (keys(%{$files{$key}}))) {                 '<input type="hidden" id="crsres_include_'.$suffix.'" value="'.$only.'" />';
                     next if ($file =~ /\.rights$/);      return ($numdirs,$output);
                     if ($only) {  }
                         my ($ext) = ($file =~ /\.([^.]+)$/);  
                         unless ($possexts{lc($ext)}) {  sub show_crsfiles_js {
                             next;      my $excluderef = &Apache::lonnet::priv_exclude();
                         }      my $se = &js_escape(&mt('Select'));
       my $exclude;
       if (ref($excluderef) eq 'HASH') {
           $exclude = join(',', map { &js_escape($_); } sort(keys(%{$excluderef})));
       }
       my $js = <<"END";
   
   
       function populateCrsSelects (form,dirsel,filesel,exc,include,setdir,setfile,recurse,nonemptydir,addtopdir) {
           var relpath = '';
           if ((setfile) && (dirsel != null) && (dirsel != 'undefined') && (dirsel != '')) {
               var currdir = form.elements[dirsel].options[form.elements[dirsel].selectedIndex].value;
               if (currdir == '') {
                   if ((filesel != null) && (filesel != 'undefined') && (filesel != '')) {
                       selelem = form.elements[filesel];
                       var j, numfiles = selelem.options.length -1;
                       if (numfiles >=0) {
                           for (j = numfiles; j >= 0; j--) {
                               selelem.remove(j);
                           }
                       }
                       if (selelem.options.length == 0) {
                           selelem.options[selelem.options.length] = new Option('','');
                           selelem.selectedIndex = 0;
                     }                      }
                     $selimport_menus{$key}->{'select2'}->{$file} = $file;  
                     push(@ordered,$file);  
                 }  
                 if (@ordered) {  
                     push(@order,$key);  
                     $nonemptydirs{$key} = 1;  
                     $selimport_menus{$key}->{'text'} = $shown;  
                     $selimport_menus{$key}->{'default'} = '';  
                     $selimport_menus{$key}->{'select2'}->{''} = '';  
                     $selimport_menus{$key}->{'order'} = \@ordered;  
                 }                  }
                   return;
               } else {
                   relpath = encodeURIComponent(form.elements[dirsel].options[form.elements[dirsel].selectedIndex].value);
             }              }
         }          }
         $possdirs = scalar(keys(%nonemptydirs));          var http = new XMLHttpRequest();
         if ($possdirs > 1) {          var url = "/adm/courseauthor";
             my @order = sort { lc($a) cmp lc($b) } (keys(%nonemptydirs));          var crsrole = "$env{'request.role'}";
             $output = $lt{'dire'}.          var exclude = '';
                       &linked_select_forms($form,'<br />'.          if (exc) {
                                            $lt{'fnam'},'',              exclude = '$exclude';
                                            $firstselectname,$secondselectname,          }
                                            \%selimport_menus,\@order,          var params = "role=course&files=1&rec="+recurse+"&nonempty="+nonemptydir+"&exc="+exclude+"&inc="+include+"&addtop="+addtopdir+"&path="+relpath;
                                            $onchangefirst,'',$suffix).'<br />';          http.open("POST", url, true);
         } elsif ($possdirs == 1) {          http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
             $singledir = (keys(%nonemptydirs))[0];          http.onreadystatechange = function() {
             if (ref($selimport_menus{$singledir}->{'order'}) eq 'ARRAY') {              if (http.readyState == 4 && http.status == 200) {
                 @singledirfiles = @{$selimport_menus{$singledir}->{'order'}};                  var data = JSON.parse(http.responseText);
             }                  var selelem;
             delete($selimport_menus{$singledir});                  if ((setdir) && (dirsel != null) && (dirsel != 'undefined') && (dirsel != '')) {
         }                      if (Array.isArray(data.dirs)) {
     } elsif ($numdirs == 1) {                          selelem = form.elements[dirsel];
         $singledir = (keys(%files))[0];                          var i, numdirs = selelem.options.length -1;
         foreach my $file (sort { lc($a) cmp lc($b) } (keys(%{$files{$singledir}}))) {                          if (numdirs >=0) {
             if ($only) {                              for (i = numdirs; i >= 0; i--) {
                 my ($ext) = ($file =~ /\.([^.]+)$/);                                  selelem.remove(i);
                 unless ($possexts{lc($ext)}) {                              }
                     next;                          }
                           var len = data.dirs.length;
                           if (len) {
                               selelem.options[selelem.options.length] = new Option('$se','');
                               var j;
                               for (j = 0; j < len; j++) {
                                   selelem.options[selelem.options.length] = new Option(data.dirs[j],data.dirs[j]);
                               }
                               selelem.selectedIndex = 0;
                           }
                           if (!setfile) {
                               if ((filesel != null) && (filesel != 'undefined') && (filesel != '')) {
                                   selelem = form.elements[filesel];
                                   var j, numfiles = selelem.options.length -1;
                                   if (numfiles >=0) {
                                       for (j = numfiles; j >= 0; j--) {
                                           selelem.remove(j);
                                       }
                                   }
                                   if (selelem.options.length == 0) {
                                       selelem.options[selelem.options.length] = new Option('','');
                                       selelem.selectedIndex = 0;
                                   }
                               }
                           }
                       }
                   }
                   if ((setfile) && (filesel != null) && (filesel != 'undefined') && (filesel != '')) {
                       selelem = form.elements[filesel];
                       var i, numfiles = selelem.options.length -1;
                       if (numfiles >=0) {
                           for (i = numfiles; i >= 0; i--) {
                               selelem.remove(i);
                           }
                       }
                       var x;
                       for (x in data.files) {
                           if (Array.isArray(data.files[x])) {
                               if (data.files[x].length > 1) {
                                   selelem.options[selelem.options.length] = new Option('$se','');
                               }
                               var len = data.files[x].length;
                               if (len) {
                                   var k;
                                   for (k = 0; k < len; k++) {
                                       selelem.options[selelem.options.length] = new Option(data.files[x][k],data.files[x][k]);
                                   }
                                   selelem.selectedIndex = 0;
                               }
                           }
                       }
                       if (selelem.options.length == 0) {
                           selelem.options[selelem.options.length] = new Option('','');
                           selelem.selectedIndex = 0;
                       }
                 }                  }
             } else {  
                 next if ($file =~ /\.rights$/);  
             }              }
             push(@singledirfiles,$file);  
         }  
         if (@singledirfiles) {  
             $possdirs = 1;  
         }          }
           http.send(params);
     }      }
     if (($possdirs == 1) && (@singledirfiles)) {  END
         my $showdir = $singledir;  }
         if ($singledir eq '') {  
             $showdir = '/';  sub crsauthor_rights {
       my ($rightsfile,$path,$docroot,$cnum,$cdom) = @_;
       my $sourcerights = "$path/$rightsfile";
       my $now = time;
       if (!-e $sourcerights) {
           my $cid = $cdom.'_'.$cnum;
           if (!-e "$docroot/priv/$cdom") {
               mkdir("$docroot/priv/$cdom",0755);
           }
           if (!-e "$docroot/priv/$cdom/$cnum") {
               mkdir("$docroot/priv/$cdom/$cnum",0755);
           }
           if (open(my $fh,">$sourcerights")) {
               print $fh <<END;
   <accessrule effect="deny" realm="" type="course" role="" />
   <accessrule effect="allow" realm="$cid" type="course" role="" />
   END
               close($fh);
         }          }
         $output = $lt{'dire'}.      }
                   '<select name="'.$firstselectname.'">'.      if (!-e "$sourcerights.meta") {
                   '<option value="'.$singledir.'">'.$showdir.'</option>'."\n".          if (open(my $fh,">$sourcerights.meta")) {
                   '</select><br />'.              my $author=$env{'environment.firstname'}.' '.
                   $lt{'fnam'}.'<select name="'.$secondselectname.'">'."\n".                         $env{'environment.middlename'}.' '.
                   '<option value="" selected="selected">'.$lt{'se'}.'</option>'."\n";                         $env{'environment.lastname'}.' '.
         foreach my $file (@singledirfiles) {                         $env{'environment.generation'};
             $output .= '<option value="'.$file.'">'.$file.'</option>'."\n";              $author =~ s/\s+$//;
               print $fh <<"END";
   
   <abstract></abstract>
   <author>$author</author>
   <authorspace>$cnum:$cdom</authorspace>
   <copyright>private</copyright>
   <creationdate>$now</creationdate>
   <customdistributionfile></customdistributionfile>
   <dependencies></dependencies>
   <domain>$cdom</domain>
   <highestgradelevel>0</highestgradelevel>
   <keywords></keywords>
   <language>notset</language>
   <lastrevisiondate>$now</lastrevisiondate>
   <lowestgradelevel>0</lowestgradelevel>
   <mime>rights</mime>
   <modifyinguser>$env{'user.name'}:$env{'user.domain'}</modifyinguser>
   <notes></notes>
   <obsolete></obsolete>
   <obsoletereplacement></obsoletereplacement>
   <owner>$cnum:$cdom</owner>
   <rule>deny:::course,allow:$cid::course</rule>
   <sourceavail></sourceavail>
   <standards></standards>
   <subject></subject>
   <title>Course Authoring Rights</title>
   END
               close($fh);
         }          }
         $output .= '</select><br />'."\n";  
     }      }
     return ($possdirs,$output);      return;
   }
   
   =pod
   
   =item * &iframe_wrapper_headjs()
   
   emits javascript containing two global vars to facilitate handling of resizing
   by code in iframe_wrapper_resizejs() used when an iframe is present in a page
   with standard LON-CAPA menus.
   
   =cut
   
   #
   # Where iframe is in use, if window.onload() executes before the custom resize function
   # has been defined (jQuery), two global javascript vars (LCnotready and LCresizedef)
   # are used to ensure document.ready() triggers a call to resize, so the iframe contents
   # do not obscure the Functions menu.
   #
   
   sub iframe_wrapper_headjs {
       return <<"ENDJS";
   <script type="text/javascript">
   // <![CDATA[
   var LCnotready = 0;
   var LCresizedef = 0;
   // ]]>
   </script>
   
   ENDJS
   
   }
   
   =pod
   
   =item * &iframe_wrapper_resizejs()
   
   emits javascript used to handle resizing for a page containing
   an iframe, to ensure that the iframe does not obscure any
   standard LON-CAPA menu items.
   
   =back
   
   =cut
   
   #
   # jQuery to use when iframe is in use and a page resize occurs.
   # This script will ensure that the iframe does not obscure any
   # standard LON-CAPA inline menus (primary, secondary, and/or
   # breadcrumbs and Functions menus. Expects javascript from
   # &iframe_wrapper_headjs() to be in head portion of the web page,
   # e.g., by inclusion in second arg passed to &start_page().
   #
   
   sub iframe_wrapper_resizejs {
       my $offset = 5;
       &get_unprocessed_cgi($ENV{'QUERY_STRING'},['inhibitmenu']);
       if (($env{'form.inhibitmenu'} eq 'yes') || ($env{'form.only_body'})) {
           $offset = 0;
       }
       return &Apache::lonhtmlcommon::scripttag(<<SCRIPT);
       \$(document).ready( function() {
           \$(window).unbind('resize').resize(function(){
               var header = null;
               var offset = $offset;
               var height = 0;
               var hdrtop = 0;
               if (\$('div.LC_menus_content:first').length) {
                   if (\$('div.LC_menus_content:first').hasClass ("shown")) {
                       header = \$('div.LC_menus_content:first');
                       offset = 12;
                   }
               } else if (\$('div.LC_head_subbox:first').length) {
                   header = \$('div.LC_head_subbox:first');
                   offset = 9;
               } else {
                   if (\$('#LC_breadcrumbs').length) {
                       header = \$('#LC_breadcrumbs');
                   }
               }
               if (header != null && header.length) {
                   height = header.height();
                   hdrtop = header.position().top;
               }
               var pos = height + hdrtop + offset;
               \$('.LC_iframecontainer').css('top', pos);
           });
           LCresizedef = 1;
           if (LCnotready == 1) {
               LCnotready = 0;
               \$(window).trigger('resize');
           }
       });
       window.onload = function(){
            if (LCresizedef) {
                LCnotready = 0;
                \$(window).trigger('resize');
            } else {
                LCnotready = 1;
            }
       };
   SCRIPT
   
 }  }
   
 =pod  =pod
Line 2670  sub display_filter { Line 2960  sub display_filter {
     my $onchange = "javascript:toggleHistoryOptions(this,'containingphrase','$context',      my $onchange = "javascript:toggleHistoryOptions(this,'containingphrase','$context',
                                                     '$secondid','$thirdid')";                                                      '$secondid','$thirdid')";
     return '<span class="LC_nobreak"><label>'.&mt('Records: [_1]',      return '<span class="LC_nobreak"><label>'.&mt('Records: [_1]',
        &Apache::lonmeta::selectbox('show',$env{'form.show'},undef,         &Apache::lonmeta::selectbox('show',$env{'form.show'},'',undef,
    (&mt('all'),10,20,50,100,1000,10000))).     (&mt('all'),10,20,50,100,1000,10000))).
    '</label></span> <span class="LC_nobreak">'.     '</label></span> <span class="LC_nobreak">'.
            &mt('Filter: [_1]',             &mt('Filter: [_1]',
Line 2788  sub select_level_form { Line 3078  sub select_level_form {
   
 =pod  =pod
   
 =item * &select_dom_form($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms,$excdoms,$disabled)  =item * &select_dom_form($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms,$excdoms,$disabled,$id)
   
 Returns a string containing a <select name='$name' size='1'> form to   Returns a string containing a <select name='$name' size='1'> form to 
 allow a user to select the domain to preform an operation in.    allow a user to select the domain to preform an operation in.  
Line 2807  The optional $excdoms is a reference to Line 3097  The optional $excdoms is a reference to
   
 The optional $disabled argument, if true, adds the disabled attribute to the select tag.  The optional $disabled argument, if true, adds the disabled attribute to the select tag.
   
   The option $id argument is the value (if any) to set as the (unique) id attribute for the select tag.
   
 =cut  =cut
   
 #-------------------------------------------  #-------------------------------------------
 sub select_dom_form {  sub select_dom_form {
     my ($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms,$excdoms,$disabled) = @_;      my ($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms,$excdoms,$disabled,$id) = @_;
     if ($onchange) {      if ($onchange) {
         $onchange = ' onchange="'.$onchange.'"';          $onchange = ' onchange="'.$onchange.'"';
     }      }
     if ($disabled) {      if ($disabled) {
         $disabled = ' disabled="disabled"';          $disabled = ' disabled="disabled"';
     }      }
       if ($id ne '') {
           $id = ' id="'.$id.'"';
       }
     my (@domains,%exclude);      my (@domains,%exclude);
     if (ref($incdoms) eq 'ARRAY') {      if (ref($incdoms) eq 'ARRAY') {
         @domains = sort {lc($a) cmp lc($b)} (@{$incdoms});          @domains = sort {lc($a) cmp lc($b)} (@{$incdoms});
Line 2828  sub select_dom_form { Line 3123  sub select_dom_form {
     if (ref($excdoms) eq 'ARRAY') {      if (ref($excdoms) eq 'ARRAY') {
         map { $exclude{$_} = 1; } @{$excdoms};           map { $exclude{$_} = 1; } @{$excdoms}; 
     }      }
     my $selectdomain = "<select name=\"$name\" size=\"1\"$onchange$disabled>\n";      my $selectdomain = "<select name=\"$name\" size=\"1\"$onchange$disabled$id>\n";
     foreach my $dom (@domains) {      foreach my $dom (@domains) {
         next if ($exclude{$dom});          next if ($exclude{$dom});
         $selectdomain.="<option value=\"$dom\" ".          $selectdomain.="<option value=\"$dom\" ".
Line 3672  sub passwd_validation_js { Line 3967  sub passwd_validation_js {
         } else {          } else {
             $alertmsg = &mt('A secret did not satisfy requirement(s):').'\n\n';              $alertmsg = &mt('A secret did not satisfy requirement(s):').'\n\n';
         }          }
       } elsif ($context eq 'ltitools') {
           my %domconfig = &Apache::lonnet::get_dom('configuration',['toolsec'],$domain);
           if (ref($domconfig{'toolsec'}) eq 'HASH') {
               if (ref($domconfig{'toolsec'}{'rules'}) eq 'HASH') {
                   %passwdconf = %{$domconfig{'toolsec'}{'rules'}};
               }
           }
           if ($id eq 'add') {
               $alertmsg = &mt('Secret for added external tool did not satisfy requirement(s):').'\n\n';
           } elsif ($id =~ /^\d+$/) {
               my $pos = $id+1;
               $alertmsg = &mt('Secret for external tool [_1] did not satisfy requirement(s):','#'.$pos).'\n\n';
           } else {
               $alertmsg = &mt('A secret did not satisfy requirement(s):').'\n\n';
           }
     } else {      } else {
         %passwdconf = &Apache::lonnet::get_passwdconf($domain);          %passwdconf = &Apache::lonnet::get_passwdconf($domain);
         $alertmsg = &mt('Initial password did not satisfy requirement(s):').'\n\n';          $alertmsg = &mt('Initial password did not satisfy requirement(s):').'\n\n';
Line 4283  sub syllabuswrapper { Line 4593  sub syllabuswrapper {
   
 # -----------------------------------------------------------------------------  # -----------------------------------------------------------------------------
   
   sub aboutme_on {
       my ($uname,$udom)=@_;
       unless ($uname) { $uname=$env{'user.name'}; }
       unless ($udom)  { $udom=$env{'user.domain'}; }
       return if ($udom eq 'public' && $uname eq 'public');
       my $hashkey=$uname.':'.$udom;
       my ($aboutme,$cached)=&Apache::lonnet::is_cached_new('aboutme',$hashkey);
       if ($cached) {
           return $aboutme;
       }
       $aboutme = &Apache::lonnet::usertools_access($uname,$udom,'aboutme');
       &Apache::lonnet::do_cache_new('aboutme',$hashkey,$aboutme,3600);
       return $aboutme;
   }
   
   sub devalidate_aboutme_cache {
       my ($uname,$udom)=@_;
       if (!$udom)  { $udom =$env{'user.domain'}; }
       if (!$uname) { $uname=$env{'user.name'};   }
       return if ($udom eq 'public' && $uname eq 'public');
       my $id=$uname.':'.$udom;
       &Apache::lonnet::devalidate_cache_new('aboutme',$id);
   }
   
 sub track_student_link {  sub track_student_link {
     my ($linktext,$sname,$sdom,$target,$start,$only_body) = @_;      my ($linktext,$sname,$sdom,$target,$start,$only_body) = @_;
     my $link ="/adm/trackstudent?";      my $link ="/adm/trackstudent?";
Line 5011  sub get_student_view { Line 5345  sub get_student_view {
   $userview=~s/\<\/html\>//gi;    $userview=~s/\<\/html\>//gi;
   $userview=~s/\<head\>//gi;    $userview=~s/\<head\>//gi;
   $userview=~s/\<\/head\>//gi;    $userview=~s/\<\/head\>//gi;
     $userview=~s/\Q<div class="LC_landmark" role="main"\E/<div class="LC_landmark"/; 
   $userview=~s/action\s*\=/would_be_action\=/gi;    $userview=~s/action\s*\=/would_be_action\=/gi;
   $userview=&relative_to_absolute($feedurl,$userview);    $userview=&relative_to_absolute($feedurl,$userview);
   if (wantarray) {    if (wantarray) {
Line 5374  sub blockcheck { Line 5709  sub blockcheck {
             }              }
             unless ($has_evb) {              unless ($has_evb) {
                 if (($activity eq 'printout') || ($activity eq 'grades') || ($activity eq 'search') ||                  if (($activity eq 'printout') || ($activity eq 'grades') || ($activity eq 'search') ||
                     ($activity eq 'boards') || ($activity eq 'groups') || ($activity eq 'chat')) {                      ($activity eq 'index') || ($activity eq 'boards') || ($activity eq 'groups') || 
                       ($activity eq 'chat')) {
                     if ($udom eq $cdom) {                      if ($udom eq $cdom) {
                         $check_ipaccess = 1;                          $check_ipaccess = 1;
                     }                      }
Line 5465  sub blockcheck { Line 5801  sub blockcheck {
   
     if (($activity eq 'boards' || $activity eq 'chat' ||      if (($activity eq 'boards' || $activity eq 'chat' ||
          $activity eq 'groups' || $activity eq 'printout' ||           $activity eq 'groups' || $activity eq 'printout' ||
          $activity eq 'search' || $activity eq 'reinit' ||           $activity eq 'search' || $activity eq 'index' ||
          $activity eq 'alert') &&           $activity eq 'reinit' || $activity eq 'alert') &&
         ($env{'request.course.id'})) {          ($env{'request.course.id'})) {
         foreach my $key (keys(%live_courses)) {          foreach my $key (keys(%live_courses)) {
             if ($key ne $env{'request.course.id'}) {              if ($key ne $env{'request.course.id'}) {
Line 5801  END_MYBLOCK Line 6137  END_MYBLOCK
         $text = &mt('Gradebook Blocked');          $text = &mt('Gradebook Blocked');
     } elsif ($activity eq 'search') {      } elsif ($activity eq 'search') {
         $text = &mt('Search Blocked');          $text = &mt('Search Blocked');
       } elsif ($activity eq 'index') {
           $text = &mt('Content Index Blocked');
     } elsif ($activity eq 'alert') {      } elsif ($activity eq 'alert') {
         $text = &mt('Checking Critical Messages Blocked');          $text = &mt('Checking Critical Messages Blocked');
     } elsif ($activity eq 'reinit') {      } elsif ($activity eq 'reinit') {
Line 5997  sub get_domainconf { Line 6335  sub get_domainconf {
                                 foreach my $host (keys(%{$domconfig{'login'}{$key}})) {                                  foreach my $host (keys(%{$domconfig{'login'}{$key}})) {
                                     if (ref($domconfig{'login'}{$key}{$host}) eq 'HASH') {                                      if (ref($domconfig{'login'}{$key}{$host}) eq 'HASH') {
                                         $designhash{$udom.'.login.'.$key.'_'.$host} = 1;                                          $designhash{$udom.'.login.'.$key.'_'.$host} = 1;
                                         foreach my $item ('text','img','alt','url','title','notsso') {                                          foreach my $item ('text','img','alt','url','title','window','notsso') {
                                             $designhash{$udom.'.login.'.$key.'_'.$item.'_'.$host} = $domconfig{'login'}{$key}{$host}{$item};                                              $designhash{$udom.'.login.'.$key.'_'.$item.'_'.$host} = $domconfig{'login'}{$key}{$host}{$item};
                                         }                                          }
                                     }                                      }
Line 6230  sub head_subbox { Line 6568  sub head_subbox {
 Input: (optional) filename from which breadcrumb trail is built.  Input: (optional) filename from which breadcrumb trail is built.
        In most cases no input as needed, as $env{'request.filename'}         In most cases no input as needed, as $env{'request.filename'}
        is appropriate for use in building the breadcrumb trail.         is appropriate for use in building the breadcrumb trail.
          frameset flag
          If page header is being requested for use in a frameset, then
          the second (option) argument -- frameset will be true, and
          the target attribute set for links should be target="_parent".
          If $title is supplied as the third arg, that will be used to 
          the left of the breadcrumbs tail for the current path.
   
 Returns: HTML div with CSTR path and recent box  Returns: HTML div with CSTR path and recent box
          To be included on Authoring Space pages           To be included on Authoring Space pages
Line 6237  Returns: HTML div with CSTR path and rec Line 6581  Returns: HTML div with CSTR path and rec
 =cut  =cut
   
 sub CSTR_pageheader {  sub CSTR_pageheader {
     my ($trailfile) = @_;      my ($trailfile,$frameset,$title) = @_;
     if ($trailfile eq '') {      if ($trailfile eq '') {
         $trailfile = $env{'request.filename'};          $trailfile = $env{'request.filename'};
     }      }
Line 6260  sub CSTR_pageheader { Line 6604  sub CSTR_pageheader {
         $lastitem = $thisdisfn;          $lastitem = $thisdisfn;
     }      }
   
     my ($crsauthor,$title);      my $crsauthor;
     if (($env{'request.course.id'}) &&      if (($env{'request.course.id'}) &&
         ($env{'course.'.$env{'request.course.id'}.'.num'} eq $uname) &&          ($env{'course.'.$env{'request.course.id'}.'.num'} eq $uname) &&
         ($env{'course.'.$env{'request.course.id'}.'.domain'} eq $udom)) {          ($env{'course.'.$env{'request.course.id'}.'.domain'} eq $udom)) {
         $crsauthor = 1;          $crsauthor = 1;
         $title = &mt('Course Authoring Space');          if ($title eq '') {
     } else {              $title = &mt('Course Authoring Space');
           }
       } elsif ($title eq '') {
         $title = &mt('Authoring Space');          $title = &mt('Authoring Space');
     }      }
   
     my ($target,$crumbtarget) = (' target="_top"','_top'); #FIXME lonpubdir: target="_parent"      my ($target,$crumbtarget) = (' target="_top"','_top');
     if (($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) {      if ($frameset) {
           $target = ' target="_parent"';
           $crumbtarget = '_parent';
       } elsif (($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) {
         $target = '';          $target = '';
         $crumbtarget = '';          $crumbtarget = '';
     }      } elsif (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'})) {
     if (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'})) {  
         $target = ' target="'.$env{'request.deeplink.target'}.'"';          $target = ' target="'.$env{'request.deeplink.target'}.'"';
         $crumbtarget = $env{'request.deeplink.target'};          $crumbtarget = $env{'request.deeplink.target'};
     }      }
Line 6295  sub CSTR_pageheader { Line 6643  sub CSTR_pageheader {
     }      }
   
     if ($crsauthor) {      if ($crsauthor) {
         $output .= '</form>'.&Apache::lonmenu::constspaceform();          $output .= '</form>'.&Apache::lonmenu::constspaceform($frameset);
     } else {      } else {
         $output .=          $output .=
              '<br />'               '<br />'
             #FIXME lonpubdir: &Apache::lonhtmlcommon::crumbs($uname.$thisdisfn.'/',$crumbtarget,'/priv','','+1',1)."</b></tt><br />"              #FIXME lonpubdir: &Apache::lonhtmlcommon::crumbs($uname.$thisdisfn.'/',$crumbtarget,'/priv','','+1',1)."</b></tt><br />"
             .&Apache::lonhtmlcommon::select_recent('construct','recent','this.form.action=this.form.recent.value;this.form.submit()')              .&Apache::lonhtmlcommon::select_recent('construct','recent','this.form.action=this.form.recent.value;this.form.submit()')
             .'</form>'              .'</form>'
             .&Apache::lonmenu::constspaceform();              .&Apache::lonmenu::constspaceform($frameset);
     }      }
     $output .= '</div>';      $output .= '</div>';
   
     return $output;      return $output;
 }  }
   
   ##############################################
   =pod
   
   =item * &nocodemirror()
   
   Input: None
   
   Returns: 1 if CodeMirror is deactivated based on
            user's preference, or domain default,
            if user indicated use of default.
   
   =cut
   
   sub nocodemirror {
       my $nocodem = $env{'environment.nocodemirror'};
       unless ($nocodem) {
           my %domdefs = &Apache::lonnet::get_domain_defaults($env{'user.domain'});
           if ($domdefs{'nocodemirror'}) {
               $nocodem = 'yes';
           }
       }
       if ($nocodem eq 'yes') {
           return 1;
       }
       return;
   }
   
   ##############################################
   =pod
   
   =item * &permitted_editors()
   
   Input: $uri (optional)
   
   Returns: %editors hash in which keys are editors
            permitted in current Authoring Space,
            or in current course for web pages
            created in a course.
   
            Value for each key is 1. Possible keys
            are: edit, xml, and daxe.
   
            For a regular Authoring Space, if no specific
            set of editors has been set for the Author
            who owns the Authoring Space, then the
            domain default will be used.  If no domain
            default has been set, then the keys will be
            edit and xml.
   
            For a course author, or for web pages created
            in a course, if no specific set of editors has
            been set for the course, then the domain
            course default will be used. If no domain
            course default has been set, then the keys
            will be edit and xml.
   
   =cut
   
   sub permitted_editors {
       my ($uri) = @_;
       my ($is_author,$is_coauthor,$is_course,$auname,$audom,%editors);
       if ($env{'request.role'} =~ m{^au\./}) {
           $is_author = 1;
       } elsif ($env{'request.role'} =~ m{^(?:ca|aa)\./($match_domain)/($match_username)}) {
           ($audom,$auname) = ($1,$2);
           if (($audom ne '') && ($auname ne '')) {
               if (($env{'user.domain'} eq $audom) &&
                   ($env{'user.name'} eq $auname)) {
                   $is_author = 1;
               } else {
                   $is_coauthor = 1;
               }
           }
       } elsif ($env{'request.course.id'}) {
           my ($cdom,$cnum);
           $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
           $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
           if (($env{'request.editurl'} =~ m{^/priv/\Q$cdom/$cnum\E/}) ||
               ($env{'request.editurl'} =~ m{^/uploaded/\Q$cdom/$cnum\E/(docs|supplemental)/}) ||
               ($uri =~ m{^/uploaded/\Q$cdom/$cnum\E/(docs|supplemental)/})) {
               $is_course = 1;
           } elsif ($env{'request.editurl'} =~ m{^/priv/($match_domain)/($match_username)/}) {
               ($audom,$auname) = ($1,$2);
           } elsif ($env{'request.uri'} =~ m{^/priv/($match_domain)/($match_username)/}) {
               ($audom,$auname) = ($1,$2);
           } elsif (($uri eq '/daxesave') &&
                    (($env{'form.path'} =~ m{^/daxeopen/priv/\Q$cdom/$cnum\E/}) ||
                     ($env{'form.path'} =~ m{^/daxeopen/uploaded/\Q$cdom/$cnum\E/(docs|supplemental)/}))) {
               $is_course = 1;
           } elsif (($uri eq '/daxesave') &&
                    ($env{'form.path'} =~ m{^/daxeopen/priv/($match_domain)/($match_username)/})) {
               ($audom,$auname) = ($1,$2);
           }
           unless ($is_course) {
               if (($audom ne '') && ($auname ne '')) {
                   if (($env{'user.domain'} eq $audom) &&
                       ($env{'user.name'} eq $auname)) {
                       $is_author = 1;
                   } else {
                       $is_coauthor = 1;
                   }
               }
           }
       }
       if ($is_author) {
           if (exists($env{'environment.editors'})) {
               map { $editors{$_} = 1; } split(/,/,$env{'environment.editors'});
           } else {
               %editors = ( edit => 1,
                            xml => 1,
                          );
           }
       } elsif ($is_coauthor) {
           if (exists($env{"environment.internal.editors./$audom/$auname"})) {
               map { $editors{$_} = 1; } split(/,/,$env{"environment.internal.editors./$audom/$auname"});
           } else {
               %editors = ( edit => 1,
                            xml => 1,
                          );
           }
       } elsif ($is_course) {
           if (exists($env{'course.'.$env{'request.course.id'}.'.internal.crseditors'})) {
               map { $editors{$_} = 1; } split(/,/,$env{'course.'.$env{'request.course.id'}.'.internal.crseditors'});
           } else {
               my %domdefaults = &Apache::lonnet::get_domain_defaults($env{'course.'.$env{'request.course.id'}.'.domain'});
               if (exists($domdefaults{'crseditors'})) {
                   map { $editors{$_} = 1; } split(/,/,$domdefaults{'crseditors'});
               } else {
                   %editors = ( edit => 1,
                                xml => 1,
                              );
               }
           }
       } else {
           %editors = ( edit => 1,
                        xml => 1,
                      );
       }
       return %editors;
   }
   
 ###############################################  ###############################################
 ###############################################  ###############################################
   
Line 6370  Inputs: Line 6859  Inputs:
             context, this will contain a reference to hash of items              context, this will contain a reference to hash of items
             to be included in the page header and/or inline menu.              to be included in the page header and/or inline menu.
   
   =item * $menucoll, optional argument, if specific menu collection is in
               effect, either set as the default for the course, or set for
               the deeplink paramater for $env{'request.deeplink.login'}
               then $menucoll will be the number of that collection. 
   
   =item * $menuref, optional argument, reference to a hash, containing the
               menu options included for the menu in effect, based on the
               configuration for the numbered menu collection in use.  
   
   =item * $showncrumbsref, reference to a scalar. Calls to lonmenu::innerregister
               within &bodytag() can result in calls to lonhtmlcommon::breadcrumbs(),
               if so, $showncrumbsref is set there to 1, and will propagate back
               via &bodytag() to &start_page(), to prevent lonhtmlcommon::breadcrumbs()
               being called a second time.
   
 =back  =back
   
 Returns: A uniform header for LON-CAPA web pages.    Returns: A uniform header for LON-CAPA web pages.  
Line 6382  other decorations will be returned. Line 6886  other decorations will be returned.
 sub bodytag {  sub bodytag {
     my ($title,$function,$addentries,$bodyonly,$domain,$forcereg,      my ($title,$function,$addentries,$bodyonly,$domain,$forcereg,
         $no_nav_bar,$bgcolor,$args,$advtoolsref,$ltiscope,$ltiuri,          $no_nav_bar,$bgcolor,$args,$advtoolsref,$ltiscope,$ltiuri,
         $ltimenu,$menucoll,$menuref)=@_;          $ltimenu,$menucoll,$menuref,$showncrumbsref)=@_;
   
     my $public;      my $public;
     if ((($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public'))      if ((($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public'))
Line 6394  sub bodytag { Line 6898  sub bodytag {
     my $hostname = $args->{'hostname'};      my $hostname = $args->{'hostname'};
   
     $function = &get_users_function() if (!$function);      $function = &get_users_function() if (!$function);
     my $img =    &designparm($function.'.img',$domain);  
     my $font =   &designparm($function.'.font',$domain);      my $font =   &designparm($function.'.font',$domain);
     my $pgbg   = $bgcolor || &designparm($function.'.pgbg',$domain);      my $pgbg   = $bgcolor || &designparm($function.'.pgbg',$domain);
   
Line 6448  sub bodytag { Line 6951  sub bodytag {
         $role = &Apache::lonnet::plaintext($role);          $role = &Apache::lonnet::plaintext($role);
     }      }
   
     if (!$realm) { $realm='&nbsp;'; }  
   
     my $extra_body_attr = &make_attr_string($forcereg,\%design);      my $extra_body_attr = &make_attr_string($forcereg,\%design);
   
 # construct main body tag  # construct main body tag
Line 6473  sub bodytag { Line 6974  sub bodytag {
                 undef($role);                  undef($role);
             }              }
             unless ($ltimenu->{'coursetitle'}) {              unless ($ltimenu->{'coursetitle'}) {
                 $realm='&nbsp;';  
                 $showcrstitle = 0;                  $showcrstitle = 0;
             }              }
         }          }
Line 6483  sub bodytag { Line 6983  sub bodytag {
                 undef($role);                  undef($role);
             }              }
             unless ($menuref->{'crs'}) {              unless ($menuref->{'crs'}) {
                 $realm='&nbsp;';  
                 $showcrstitle = 0;                  $showcrstitle = 0;
             }              }
         }          }
Line 6517  sub bodytag { Line 7016  sub bodytag {
         #        $titleinfo = &CSTR_pageheader(); #FIXME: Will be removed once all scripts have their own calls          #        $titleinfo = &CSTR_pageheader(); #FIXME: Will be removed once all scripts have their own calls
         #    }          #    }
   
         $bodytag .= Apache::lonhtmlcommon::scripttag(          my $need_endlcint;
             Apache::lonmenu::utilityfunctions($httphost), 'start');          unless ($args->{'switchserver'}) {
               $bodytag .= Apache::lonhtmlcommon::scripttag(
                   Apache::lonmenu::utilityfunctions($httphost), 'start');
               $need_endlcint = 1;
           }
   
           my $collapsible;
           if ($args->{'collapsible_header'} ne '') {
               $collapsible = 1;
               my ($menustate,$tiptext,$divclass);
               if ($args->{'start_collapsed'}) {
                   $menustate = 'collapsed';
                   $tiptext = 'display';
                   $divclass = 'hidden';
               } else {
                   $menustate = 'expanded';
                   $tiptext = 'hide';
                   $divclass = 'shown';
               }
               my $alttext = &mt('menu state: '.$menustate);
               my $tooltip = &mt($tiptext.' standard menus');
               $bodytag .= <<"END";
   <div id="LC_expandingContainer" style="display:inline;" role="navigation">
   <div id="LC_collapsible" class="LC_collapse_trigger" style="position: absolute;top: -5px;left: 0px; z-index:101; display:inline;">
   <a href="#" style="text-decoration:none;"><img class="LC_collapsible_indicator" alt="$alttext" title="$tooltip" src="/res/adm/pages/$menustate.png" style="border:0;margin:0;padding:0;max-width:100%;height:auto" /></a></div>
   <div class="LC_menus_content $divclass">
   END
           }
         unless ($args->{'no_primary_menu'}) {          unless ($args->{'no_primary_menu'}) {
             my ($left,$right) = Apache::lonmenu::primary_menu($crstype,$ltimenu,$menucoll,$menuref,              my ($left,$right) = Apache::lonmenu::primary_menu($crstype,$ltimenu,$menucoll,$menuref,
                                                               $args->{'links_disabled'});                                                                $args->{'links_disabled'},
                                                                 $args->{'links_target'},
                                                                 $collapsible);
               my $labeltext = &HTML::Entities::encode(&mt('Primary links'));
             if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) {              if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) {
                 if ($dc_info) {                  if ($dc_info) {
                     $dc_info = qq|<span class="LC_cusr_subheading">$dc_info</span>|;                      $dc_info = qq|<span class="LC_cusr_subheading">$dc_info</span>|;
                 }                  }
                 $bodytag .= qq|<div id="LC_nav_bar">$left $role<br />                  $bodytag .= qq|<div id="LC_nav_bar" role="navigation" aria-label="$labeltext">$left $role</div>|;
                                <em>$realm</em> $dc_info</div>|;                  unless (($realm eq '') && ($dc_info eq '')) {
                       $bodytag .= qq|<div id="LC_realm" role="complementary"><em>$realm</em> $dc_info</div>|;
                   }
                   if ($need_endlcint) {
                       $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end');
                   }
                 return $bodytag;                  return $bodytag;
             }              }
   
               $bodytag .= '<div class="LC_landmark" style="margin: 3px 0 0 0;" role="navigation" aria-label="'.$labeltext.'">';
             unless ($env{'request.symb'} =~ m/\.page___\d+___/) {              unless ($env{'request.symb'} =~ m/\.page___\d+___/) {
                 $bodytag .= qq|<div id="LC_nav_bar">$left $role</div>|;                  $bodytag .= qq|<div id="LC_nav_bar">$left $role</div>|;
             }              }
   
             $bodytag .= $right;              $bodytag .= $right.'</div>';
   
             if ($dc_info) {              if ($dc_info) {
                 $dc_info = &dc_courseid_toggle($dc_info);                  $dc_info = &dc_courseid_toggle($dc_info);
             }              }
             $bodytag .= qq|<div id="LC_realm">$realm $dc_info</div>|;              unless (($realm eq '') && ($dc_info eq '')) {
                   $bodytag .= qq|<div id="LC_realm" role="complementary">$realm $dc_info</div>|;
               }
               $bodytag .= qq|<div style="clear: both; margin: 5px 0 0 0;"></div>|;
         }          }
   
         #if directed to not display the secondary menu, don't.            #if directed to not display the secondary menu, don't.  
         if ($args->{'no_secondary_menu'}) {          if ($args->{'no_secondary_menu'}) {
               if ($need_endlcint) {
                   $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end');
               }
             return $bodytag;              return $bodytag;
         }          }
         #don't show menus for public users          #don't show menus for public users
         if (!$public){          if (!$public){
             unless ($args->{'no_inline_menu'}) {              unless ($args->{'no_inline_menu'}) {
                 $bodytag .= Apache::lonmenu::secondary_menu($httphost,$ltiscope,$ltimenu,                  $bodytag .= '<div class="LC_landmark" role="navigation" aria-label="Secondary Links">'.
                               Apache::lonmenu::secondary_menu($httphost,$ltiscope,$ltimenu,
                                                             $args->{'no_primary_menu'},                                                              $args->{'no_primary_menu'},
                                                             $menucoll,$menuref,                                                              $menucoll,$menuref,
                                                             $args->{'links_disabled'});                                                              $args->{'links_disabled'},
                                                               $args->{'links_target'}).
                               '</div>';
             }              }
             $bodytag .= Apache::lonmenu::serverform();              $bodytag .= Apache::lonmenu::serverform();
             $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end');              if ($need_endlcint) {
                   $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end');
               }
             if ($env{'request.state'} eq 'construct') {              if ($env{'request.state'} eq 'construct') {
                 $bodytag .= &Apache::lonmenu::innerregister($forcereg,                  $bodytag .= &Apache::lonmenu::innerregister($forcereg,
                                 $args->{'bread_crumbs'},'','',$hostname,$ltiscope,$ltiuri);                                  $args->{'bread_crumbs'},'','',$hostname,
                                   $ltiscope,$ltiuri,$showncrumbsref);
             } elsif ($forcereg) {              } elsif ($forcereg) {
                 $bodytag .= &Apache::lonmenu::innerregister($forcereg,undef,                  $bodytag .= &Apache::lonmenu::innerregister($forcereg,undef,
                                                             $args->{'group'},                                  $args->{'group'},$args->{'hide_buttons'},
                                                             $args->{'hide_buttons'},                                  $hostname,$ltiscope,$ltiuri,$showncrumbsref);
                                                             $hostname,$ltiscope,$ltiuri);  
             } else {              } else {
                 $bodytag .=                   $bodytag .=
                     &Apache::lonmenu::prepare_functions($env{'request.noversionuri'},                      &Apache::lonmenu::prepare_functions($env{'request.noversionuri'},
                                                         $forcereg,$args->{'group'},                                                          $forcereg,$args->{'group'},
                                                         $args->{'bread_crumbs'},                                                          $args->{'bread_crumbs'},
                                                         $advtoolsref,'',$hostname);                                                          $advtoolsref,'',$hostname);
             }              }
         }else{          } else {
             # this is to seperate menu from content when there's no secondary              # this is to separate menu from content when there's no secondary
             # menu. Especially needed for public accessible ressources.              # menu. Especially needed for publicly accessible resources.
             $bodytag .= '<hr style="clear:both" />';              $bodytag .= '<hr style="clear:both" role="complementary" />';
             $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end');               if ($need_endlcint) {
                   $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end');
               }
           }
           if ($args->{'collapsible_header'} ne '') {
               $bodytag .= $args->{'collapsible_header'}.
                           '<div id="LC_collapsible_separator"></div>'.
                           '</div></div>';
         }          }
   
         return $bodytag;          return $bodytag;
 }  }
   
Line 6650  sub endbodytag { Line 7200  sub endbodytag {
     }      }
     if ( exists( $env{'internal.head.redirect'} ) ) {      if ( exists( $env{'internal.head.redirect'} ) ) {
         if (!(ref($args) eq 'HASH' && $args->{'noredirectlink'})) {          if (!(ref($args) eq 'HASH' && $args->{'noredirectlink'})) {
               my ($endbodyjs,$idattr);
               if ($env{'internal.head.to_opener'}) {
                   my $linkid = 'LC_continue_link';
                   $idattr = ' id="'.$linkid.'"';
                   my $redirect_for_js = &js_escape($env{'internal.head.redirect'});
                   $endbodyjs=<<ENDJS;
   <script type="text/javascript">
   // <![CDATA[
   function ebFunction(evt) {
       evt.preventDefault();
       var dest = '$redirect_for_js';
       if (window.opener != null && !window.opener.closed) {
           window.opener.location.href=dest;
           window.close();
       } else {
           window.location.href=dest;
       }
       return false;
   }
   
   \$(document).ready(function () {
     if (document.getElementById('$linkid')) {
       var clickelem = document.getElementById('$linkid');
       clickelem.addEventListener('click',ebFunction,false);
     }
   });
   // ]]>
   </script>
   ENDJS
               }
     $endbodytag=      $endbodytag=
         "<br /><a href=\"$env{'internal.head.redirect'}\">".          "$endbodyjs<br /><a href=\"$env{'internal.head.redirect'}\"$idattr>".
         &mt('Continue').'</a>'.          &mt('Continue').'</a>'.
         $endbodytag;          $endbodytag;
         }          }
     }      }
       if ((ref($args) eq 'HASH') && ($args->{'dashjs'})) {
           $endbodytag = &Apache::lonhtmlcommon::dash_to_minus_js().$endbodytag;
       }
     return $endbodytag;      return $endbodytag;
 }  }
   
Line 6676  Inputs: (all optional) Line 7259  Inputs: (all optional)
 sub standard_css {  sub standard_css {
     my ($function,$domain,$bgcolor) = @_;      my ($function,$domain,$bgcolor) = @_;
     $function  = &get_users_function() if (!$function);      $function  = &get_users_function() if (!$function);
     my $img    = &designparm($function.'.img',   $domain);  
     my $tabbg  = &designparm($function.'.tabbg', $domain);      my $tabbg  = &designparm($function.'.tabbg', $domain);
     my $font   = &designparm($function.'.font',  $domain);      my $font   = &designparm($function.'.font',  $domain);
     my $fontmenu = &designparm($function.'.fontmenu', $domain);      my $fontmenu = &designparm($function.'.fontmenu', $domain);
Line 6729  body { Line 7311  body {
   line-height:130%;    line-height:130%;
   font-size:0.83em;    font-size:0.83em;
   color:$font;    color:$font;
     background-color: $pgbg_or_bgcolor;
 }  }
   
 a:focus,  a:focus,
Line 6740  form, .inline { Line 7323  form, .inline {
   display: inline;    display: inline;
 }  }
   
   .LC_landmark {
     margin: 0;
     padding: 0;
     border: none;
   }
   
   .LC_visually_hidden:not(:focus):not(:active) {
       clip-path: inset(50%);
       height: 1px;
       overflow: hidden;
       position: absolute;
       white-space: nowrap;
       width: 1px;
       display: inline;
   }
   
   .LC_heading_2 {
     font-size: 1.17em;
   }
   
   .LC_heading_3 {
     font-size: 1.0em;
   }
   
   .LC_menus_content.shown{
     display: block;
   }
   
   .LC_menus_content.hidden {
     display: none;
   }
   
 .LC_right {  .LC_right {
   text-align:right;    text-align:right;
 }  }
   
   .LC_center {
     text-align:center;
   }
   
 .LC_middle {  .LC_middle {
   vertical-align:middle;    vertical-align:middle;
 }  }
Line 6760  form, .inline { Line 7379  form, .inline {
   width:400px;    width:400px;
 }  }
   
   #LC_collapsible_separator {
       border: 1px solid black;
       width: 99.9%;
       height: 0px;
   }
   
 .LC_iframecontainer {  .LC_iframecontainer {
     width: 98%;      width: 98%;
     margin: 0;      margin: 0;
Line 7380  table.LC_parm_overview_restrictions th { Line 8005  table.LC_parm_overview_restrictions th {
   border-color: $pgbg;    border-color: $pgbg;
 }  }
   
 table#LC_helpmenu {  h1.LC_helpmenu {
   border: none;    display: inline;
   height: 55px;    font-size: 100%;
   border-spacing: 0;    font-weight: normal;
     line-height: 1em;
     margin: 0;
     padding: 0;
     border: 0;
 }  }
   
 table#LC_helpmenu fieldset legend {  .LC_helpdesk_headbox {
   font-size: larger;    border: 2px groove threedface;
     padding: 1em;
 }  }
   
 table#LC_helpmenu_links {  h1.LC_helpdesk_legend {
   width: 100%;    float: left;
   border: 1px solid black;    margin: -1.7em 0 0;
     padding: 0 .5em;
   background: $pgbg;    background: $pgbg;
     font-size: 1em;
     font-weight: bold;
   }
   
   h1.LC_helpdesk_title {
     display: inline;
     font-size: 1em;
     line-height: 2.5em;
     margin: 0;
   padding: 0;    padding: 0;
   border-spacing: 1px;    vertical-align: bottom;
 }  }
   
 table#LC_helpmenu_links tr td {  .LC_helpdesk_links {
   padding: 1px;    border: 1px solid black;
     padding: 3px;
   background: $tabbg;    background: $tabbg;
   text-align: center;    text-align: center;
   font-weight: bold;    font-weight: bold;
     display: inline;
     margin-right: -6px;
   }
   
   .LC_helpdesk_img,
   .LC_helpdesk_text {
     padding: 0;
     margin: 0;
     border: 0;
     display: inline;
 }  }
   
 table#LC_helpmenu_links a:link,  .LC_helpdesk_img a:link,
 table#LC_helpmenu_links a:visited,  .LC_helpdesk_img a:visited,
 table#LC_helpmenu_links a:active {  .LC_helpdesk_img a:active,
   .LC_helpdesk_text a:link,
   .LC_helpdesk_text a:visited,
   .LC_helpdesk_text a:active {
   text-decoration: none;    text-decoration: none;
   color: $font;    color: $font;
 }  }
   
 table#LC_helpmenu_links a:hover {  div.LC_helpdesk_text a:hover {
   text-decoration: underline;    text-decoration: underline;
   color: $vlink;    color: $vlink;
 }  }
Line 7439  table.LC_pick_box { Line 8093  table.LC_pick_box {
   border-spacing: 1px;    border-spacing: 1px;
 }  }
   
 table.LC_pick_box td.LC_pick_box_title {  table.LC_pick_box th.LC_pick_box_title {
   background: $sidebg;    background: $sidebg;
   font-weight: bold;    font-weight: bold;
   text-align: left;    text-align: left;
Line 7642  table.LC_prior_tries td { Line 8296  table.LC_prior_tries td {
   padding: 6px;    padding: 6px;
 }  }
   
   .LC_prob_status {
     margin-top: 5px;
     padding-top: 0;
     padding-left: 0;
     padding-bottom: 0;
     padding-right: 5px;
   }
   
   .LC_mail_actions {
     float: left;
     padding: 0;
     margin: 6px;
   }
   
   .LC_vertical_line {
     width: 1px;
     background-color: black;
     height: 4em;
     float: left;
     margin: 0;
     padding: 0;
   }
   
 span.LC_prior_numerical,  span.LC_prior_numerical,
 span.LC_prior_string,  span.LC_prior_string,
 span.LC_prior_custom,  span.LC_prior_custom,
Line 7795  div.LC_grade_show_user div.LC_Box { Line 8472  div.LC_grade_show_user div.LC_Box {
   margin-right: 50px;    margin-right: 50px;
 }  }
   
   div.LC_grade_show_user div.LC_Box table tr th {
     font-weight: normal;
   }
   
 div.LC_grade_submissions,  div.LC_grade_submissions,
 div.LC_grade_message_center,  div.LC_grade_message_center,
 div.LC_grade_info_links {  div.LC_grade_info_links {
Line 7825  table.LC_scantron_action tr th { Line 8506  table.LC_scantron_action tr th {
   font-style:normal;    font-style:normal;
 }  }
   
   div.LC_edit_problem_daxe_header {
     padding: 3px;
     background: $tabbg;
     z-index: 100;
   }
   
 .LC_edit_problem_header,  .LC_edit_problem_header,
 div.LC_edit_problem_footer {  div.LC_edit_problem_footer {
   font-weight: normal;    font-weight: normal;
Line 7890  img.stift { Line 8577  img.stift {
   vertical-align: middle;    vertical-align: middle;
 }  }
   
 table td.LC_mainmenu_col_fieldset {  div.LC_mainmenu {
   vertical-align: top;    margin: 3px 2px 2px 1px;
     float: left;
 }  }
   
 div.LC_createcourse {  div.LC_createcourse {
Line 7972  fieldset { Line 8660  fieldset {
   /* overflow: hidden; */    /* overflow: hidden; */
 }  }
   
   fieldset#LC_selectuser {
     margin: -1px 0 0 0;
     padding: 0;
     border: 0;
   }
   
 article.geogebraweb div {  article.geogebraweb div {
     margin: 0;      margin: 0;
 }  }
Line 8515  a#LC_content_toolbar_edittoplevel { Line 9209  a#LC_content_toolbar_edittoplevel {
   background-image:url(/res/adm/pages/edittoplevel.gif);    background-image:url(/res/adm/pages/edittoplevel.gif);
 }  }
   
   a#LC_content_toolbar_printout {
     background-image:url(/res/adm/pages/printout.gif);
   }
   
 ul#LC_toolbar li a:hover {  ul#LC_toolbar li a:hover {
   background-position: bottom center;    background-position: bottom center;
 }  }
Line 8523  ul#LC_toolbar { Line 9221  ul#LC_toolbar {
   padding: 0;    padding: 0;
   margin: 2px;    margin: 2px;
   list-style:none;    list-style:none;
   position:relative;    display:inline;
   background-color:white;    background-color:white;
   overflow: auto;    overflow: auto;
 }  }
Line 8551  a.LC_toolbarItem { Line 9249  a.LC_toolbarItem {
   background-color:transparent;    background-color:transparent;
 }  }
   
   .LC_navtools {
     display: inline-block;
     padding: 0;
     margin: 2px;
     vertical-align: middle;
   }
   
 ul.LC_funclist {  ul.LC_funclist {
     margin: 0;      margin: 0;
     padding: 0.5em 1em 0.5em 0;      padding: 0.5em 1em 0.5em 0;
Line 8655  pre.LC_wordwrap { Line 9360  pre.LC_wordwrap {
 /*  /*
   styles used for response display    styles used for response display
 */  */
 div.LC_radiofoil, div.LC_rankfoil {  div.LC_radiofoil, div.LC_rankfoil, div.LC_optionfoil, div.LC_matchfoil {
   margin: .5em 0em .5em 0em;    margin: .5em 0em .5em 0em;
 }  }
 table.LC_itemgroup {  table.LC_itemgroup {
   margin-top: 1em;    margin-top: 1em;
 }  }
   
   table.LC_itemgroup tr th {
     font-weight: normal;
   }
   
   fieldset.LC_webbubbles {
     margin: 2px 0 0 0;
     padding: 0;
     border: 0;
   }
   
   ul.LC_webbubbles {
     list-style: none;
     padding: 0;
     margin: 0;
     text-align: left;
     float: left;
   }
   
   ul.LC_webbubbles li {
     line-height: 1.8em;
     border: 1px solid black;
     padding: 0 2px 0 5px;
     margin: 0 0 0 -1px;
     float: left;
   }
   
 /*  /*
   styles used by TTH when "Default set of options to pass to tth/m    styles used by TTH when "Default set of options to pass to tth/m
   when converting TeX" in course settings has been set    when converting TeX" in course settings has been set
Line 8817  Inputs: $title - optional title for the Line 9548  Inputs: $title - optional title for the
                                    3- whether the side effect should occur                                     3- whether the side effect should occur
                            (side effect of setting                              (side effect of setting 
                                $env{'internal.head.redirect'} to the url                                  $env{'internal.head.redirect'} to the url 
                                redirected too)                                 redirected to)
                                      4- whether the redirect target should be
                                         the opener of the current (pop-up)
                                         window (side effect of setting
                                         $env{'internal.head.to_opener'} to
                                         1, if true.
                                      5- whether encrypt check should be skipped
             domain         -> force to color decorate a page for a specific              domain         -> force to color decorate a page for a specific
                                domain                                 domain
             function       -> force usage of a specific rolish color scheme              function       -> force usage of a specific rolish color scheme
Line 8851  sub headtag { Line 9588  sub headtag {
         $inhibitprint = &print_suppression();          $inhibitprint = &print_suppression();
     }      }
   
     if (!$args->{'frameset'}) {      if (!$args->{'frameset'} && !$args->{'switchserver'}) {
  $result .= &Apache::lonhtmlcommon::htmlareaheaders();   $result .= &Apache::lonhtmlcommon::htmlareaheaders();
     }      }
     if ($args->{'force_register'} && $env{'request.noversionuri'} !~ m{^/res/adm/pages/}) {      if ($args->{'force_register'} && $env{'request.noversionuri'} !~ m{^/res/adm/pages/}) {
Line 8859  sub headtag { Line 9596  sub headtag {
     }      }
     if (!$args->{'no_nav_bar'}       if (!$args->{'no_nav_bar'} 
  && !$args->{'only_body'}   && !$args->{'only_body'}
  && !$args->{'frameset'}) {   && !$args->{'frameset'}
    && !$args->{'switchserver'}) {
  $result .= &help_menu_js($httphost);   $result .= &help_menu_js($httphost);
         $result.=&modal_window();          $result.=&modal_window();
         $result.=&togglebox_script();          $result.=&togglebox_script();
Line 8880  sub headtag { Line 9618  sub headtag {
         }          }
     }      }
     if (ref($args->{'redirect'})) {      if (ref($args->{'redirect'})) {
  my ($time,$url,$inhibit_continue) = @{$args->{'redirect'}};   my ($time,$url,$inhibit_continue,$to_opener,$skip_enc_check) = @{$args->{'redirect'}};
  $url = &Apache::lonenc::check_encrypt($url);          if (!$skip_enc_check) {
               $url = &Apache::lonenc::check_encrypt($url);
           }
  if (!$inhibit_continue) {   if (!$inhibit_continue) {
     $env{'internal.head.redirect'} = $url;      $env{'internal.head.redirect'} = $url;
  }   }
  $result.=<<ADDMETA   $result.=<<"ADDMETA";
 <meta http-equiv="pragma" content="no-cache" />  <meta http-equiv="pragma" content="no-cache" />
   ADDMETA
           if ($to_opener) {
               $env{'internal.head.to_opener'} = 1;
               my $dest = &js_escape($url);
               my $timeout = int($time * 1000);
               $result .=<<"ENDJS";
   <script type="text/javascript">
   // <![CDATA[
   function LC_To_Opener() {
       var dest = '$dest';
       if (dest != '') {
           if (window.opener != null && !window.opener.closed) {
               window.opener.location.href=dest;
               window.close();
           } else {
               window.location.href=dest;
           }
       }
   }
   \$(document).ready(function () {
       setTimeout('LC_To_Opener()',$timeout);
   });
   // ]]>
   </script>
   ENDJS
           } else {
               $result.=<<"ADDMETA";
 <meta http-equiv="Refresh" content="$time; url=$url" />  <meta http-equiv="Refresh" content="$time; url=$url" />
 ADDMETA  ADDMETA
           }
     } else {      } else {
         unless (($args->{'frameset'}) || ($args->{'js_ready'}) || ($args->{'only_body'}) || ($args->{'no_nav_bar'})) {          unless (($args->{'frameset'}) || ($args->{'js_ready'}) || ($args->{'only_body'}) || ($args->{'no_nav_bar'})) {
             my $requrl = $env{'request.uri'};              my $requrl = $env{'request.uri'};
Line 9025  OFFLOAD Line 9793  OFFLOAD
  $title = 'The LearningOnline Network with CAPA';   $title = 'The LearningOnline Network with CAPA';
     }      }
     if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); }      if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); }
     $result .= '<title> LON-CAPA '.$title.'</title>'      if ($title =~ /^LON-CAPA\s+/) {
  .'<link rel="stylesheet" type="text/css" href="'.$url.'"';          $result .= '<title> '.$title.'</title>';
       } else {
           $result .= '<title> LON-CAPA '.$title.'</title>';
       }
       $result .= "\n".'<link rel="stylesheet" type="text/css" href="'.$url.'"';
     if (!$args->{'frameset'}) {      if (!$args->{'frameset'}) {
         $result .= ' /';          $result .= ' /';
     }      }
Line 9041  OFFLOAD Line 9813  OFFLOAD
     }      }
     if ($clientmobile) {      if ($clientmobile) {
         $result .= '          $result .= '
 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">  <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta name="apple-mobile-web-app-capable" content="yes" />';  <meta name="apple-mobile-web-app-capable" content="yes" />';
     }      }
     $result .= '<meta name="google" content="notranslate" />'."\n";      $result .= '<meta name="google" content="notranslate"';
       if (!$args->{'frameset'}) {
           $result .= ' /';
       }
       $result .= '>'."\n";
     return $result.'</head>';      return $result.'</head>';
 }  }
   
Line 9175  sub xml_begin { Line 9951  sub xml_begin {
     .'xmlns="http://www.w3.org/1999/xhtml">';      .'xmlns="http://www.w3.org/1999/xhtml">';
     } elsif ($is_frameset) {      } elsif ($is_frameset) {
         $output='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'."\n".          $output='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'."\n".
                 '<html>'."\n";                  '<html lang="en">'."\n";
     } else {      } else {
  $output='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'."\n".   $output='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'."\n".
                 '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'."\n";                  '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'."\n";
Line 9225  $args - additional optional args support Line 10001  $args - additional optional args support
              no_auto_mt_title -> prevent &mt()ing the title arg               no_auto_mt_title -> prevent &mt()ing the title arg
              bread_crumbs ->             Array containing breadcrumbs               bread_crumbs ->             Array containing breadcrumbs
              bread_crumbs_component ->  if exists show it as headline else show only the breadcrumbs               bread_crumbs_component ->  if exists show it as headline else show only the breadcrumbs
                bread_crumbs_style -> breadcrumbs are contained within <div id="LC_breadcrumbs">,
                                      and &standard_css() contains CSS for #LC_breadcrumbs, if you want
                                      to override those values, or add to them, specify the value to
                                      include in the style attribute to include in the div tag by using
                                      bread_crumbs_style (e.g., overflow: visible)
              bread_crumbs_nomenu -> if true will pass false as the value of $menulink               bread_crumbs_nomenu -> if true will pass false as the value of $menulink
                                     to lonhtmlcommon::breadcrumbs                                      to lonhtmlcommon::breadcrumbs
              group          -> includes the current group, if page is for a                group          -> includes the current group, if page is for a 
Line 9236  $args - additional optional args support Line 10017  $args - additional optional args support
              links_disabled -> Links in primary and secondary menus are disabled               links_disabled -> Links in primary and secondary menus are disabled
                                (Can enable them once page has loaded - see lonroles.pm                                 (Can enable them once page has loaded - see lonroles.pm
                                for an example).                                 for an example).
                links_target   -> Target for links, e.g., _parent (optional).
   
 =back  =back
   
Line 9324  sub start_page { Line 10106  sub start_page {
         }          }
     }      }
   
       my $showncrumbs;
     if (! exists($args->{'skip_phases'}{'body'}) ) {      if (! exists($args->{'skip_phases'}{'body'}) ) {
  if ($args->{'frameset'}) {   if ($args->{'frameset'}) {
     my $attr_string = &make_attr_string($args->{'force_register'},      my $attr_string = &make_attr_string($args->{'force_register'},
Line 9336  sub start_page { Line 10119  sub start_page {
                          $args->{'only_body'},      $args->{'domain'},                           $args->{'only_body'},      $args->{'domain'},
                          $args->{'force_register'}, $args->{'no_nav_bar'},                           $args->{'force_register'}, $args->{'no_nav_bar'},
                          $args->{'bgcolor'},        $args,                           $args->{'bgcolor'},        $args,
                          \@advtools,$ltiscope,$ltiuri,\%ltimenu,$menucoll,\%menu);                           \@advtools,$ltiscope,$ltiuri,\%ltimenu,$menucoll,
                            \%menu,\$showncrumbs);
         }          }
     }      }
   
Line 9358  sub start_page { Line 10142  sub start_page {
   
     #Breadcrumbs      #Breadcrumbs
     if (exists($args->{'bread_crumbs'}) or exists($args->{'bread_crumbs_component'})) {      if (exists($args->{'bread_crumbs'}) or exists($args->{'bread_crumbs_component'})) {
           unless ($showncrumbs) {
  &Apache::lonhtmlcommon::clear_breadcrumbs();   &Apache::lonhtmlcommon::clear_breadcrumbs();
  #if any br links exists, add them to the breadcrumbs   #if any br links exists, add them to the breadcrumbs
  if (exists($args->{'bread_crumbs'}) and ref($args->{'bread_crumbs'}) eq 'ARRAY') {            if (exists($args->{'bread_crumbs'}) and ref($args->{'bread_crumbs'}) eq 'ARRAY') {         
Line 9380  sub start_page { Line 10165  sub start_page {
                 } else {                  } else {
                     undef($menulink);                      undef($menulink);
                 }                  }
                   my $linkprotout;
                   if ($env{'request.deeplink.login'}) {
                       my $linkprotout = &Apache::lonmenu::linkprot_exit();
                       if ($linkprotout) {
                           &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$linkprotout);
                       }
                   }
  #if bread_crumbs_component exists show it as headline else show only the breadcrumbs   #if bread_crumbs_component exists show it as headline else show only the breadcrumbs
  if(exists($args->{'bread_crumbs_component'})){   if(exists($args->{'bread_crumbs_component'})){
  $result .= &Apache::lonhtmlcommon::breadcrumbs($args->{'bread_crumbs_component'},'',$menulink);   $result .= &Apache::lonhtmlcommon::breadcrumbs($args->{'bread_crumbs_component'},
                                                                          '',$menulink,'',
                                                                          $args->{'bread_crumbs_style'});
                 } else {                  } else {
  $result .= &Apache::lonhtmlcommon::breadcrumbs('','',$menulink);   $result .= &Apache::lonhtmlcommon::breadcrumbs('','',$menulink,'',
                                                                          $args->{'bread_crumbs_style'});
  }   }
           }
     }      }
     return $result;      return $result;
 }  }
Line 9519  sub symb_from_tinyurl { Line 10315  sub symb_from_tinyurl {
     }      }
 }  }
   
   sub usable_exttools {
       my %tooltypes;
       if ($env{'request.course.id'}) {
           if ($env{'course.'.$env{'request.course.id'}.'.internal.exttool'}) {
              if ($env{'course.'.$env{'request.course.id'}.'.internal.exttool'} eq 'both') {
                  %tooltypes = (
                                crs => 1,
                                dom => 1,
                               );
              } elsif ($env{'course.'.$env{'request.course.id'}.'.internal.exttool'} eq 'crs') {
                  $tooltypes{'crs'} = 1;
              } elsif ($env{'course.'.$env{'request.course.id'}.'.internal.exttool'} eq 'dom') {
                  $tooltypes{'dom'} = 1;
              }
           } else {
               my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
               my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
               my $crstype = lc($env{'course.'.$env{'request.course.id'}.'.type'});
               if ($crstype eq '') {
                   $crstype = 'course';
               }
               if ($crstype eq 'course') {
                   if ($env{'course.'.$env{'request.course.id'}.'internal.coursecode'}) {
                       $crstype = 'official';
                   } elsif ($env{'course.'.$env{'request.course.id'}.'.internal.textbook'}) {
                       $crstype = 'textbook';
                   } elsif ($env{'course.'.$env{'request.course.id'}.'.internal.lti'}) {
                       $crstype = 'lti';
                   } else {
                       $crstype = 'unofficial';
                   }
               }
               my %domdefaults = &Apache::lonnet::get_domain_defaults($cdom);
               if ($domdefaults{$crstype.'domexttool'}) {
                   $tooltypes{'dom'} = 1;
               }
               if ($domdefaults{$crstype.'exttool'}) {
                   $tooltypes{'crs'} = 1;
               }
           }
       }
       return %tooltypes;
   }
   
 sub wishlist_window {  sub wishlist_window {
     return(<<'ENDWISHLIST');      return(<<'ENDWISHLIST');
 <script type="text/javascript">  <script type="text/javascript">
Line 10024  sub simple_error_page { Line 10864  sub simple_error_page {
     }      }
   
     my $page =      my $page =
  &Apache::loncommon::start_page($title,'',\%displayargs).   &Apache::loncommon::start_page($title,'',\%displayargs)."\n".
           '<div class="LC_landmark" style="clear:both" role="main">'.
  '<p class="LC_error">'.$msg.'</p>'.   '<p class="LC_error">'.$msg.'</p>'.
           '</div>'.
  &Apache::loncommon::end_page();   &Apache::loncommon::end_page();
     if (ref($r)) {      if (ref($r)) {
  $r->print($page);   $r->print($page);
Line 10207  Scalar: 1 if 'Course' to be used, 0 othe Line 11049  Scalar: 1 if 'Course' to be used, 0 othe
   
 ###############################################  ###############################################
 sub show_course {  sub show_course {
       my ($udom,$uname) = @_;
       if (($udom ne '') && ($uname ne '')) {
           if (($udom ne $env{'user.domain'}) || ($uname ne $env{'user.name'})) {
               if (&Apache::lonnet::is_advanced_user($udom,$uname)) {
                   return 0;
               } else {
                   return 1;
               }
           }
       }
     my $course = !$env{'user.adv'};      my $course = !$env{'user.adv'};
     if (!$env{'user.adv'}) {      if (!$env{'user.adv'}) {
         foreach my $env (keys(%env)) {          foreach my $env (keys(%env)) {
Line 14181  sub process_extracted_files { Line 15033  sub process_extracted_files {
                             my $url = '/uploaded/'.$docudom.'/'.$docuname.'/'.                              my $url = '/uploaded/'.$docudom.'/'.$docuname.'/'.
                                       $docstype.'/'.$mapinner{$outer}.'/'.$newidx.'/'.                                        $docstype.'/'.$mapinner{$outer}.'/'.$newidx.'/'.
                                       $title;                                        $title;
                             if (($outer !~ /\D/) && ($mapinner{$outer} !~ /\D/) && ($newidx !~ /\D/)) {                              if (($outer !~ /\D/) &&
                                   (($mapinner{$outer} eq 'default') || ($mapinner{$outer} !~ /\D/)) &&
                                   ($newidx !~ /\D/)) {
                                 if (!-e "$prefix$dir/$docstype/$mapinner{$outer}") {                                  if (!-e "$prefix$dir/$docstype/$mapinner{$outer}") {
                                     mkdir("$prefix$dir/$docstype/$mapinner{$outer}",0755);                                      mkdir("$prefix$dir/$docstype/$mapinner{$outer}",0755);
                                 }                                  }
Line 16236  sub assign_category_rows { Line 17090  sub assign_category_rows {
   
   
 sub commit_customrole {  sub commit_customrole {
     my ($udom,$uname,$url,$three,$four,$five,$start,$end,$context) = @_;      my ($udom,$uname,$url,$three,$four,$five,$start,$end,$context,$othdomby,$requester) = @_;
       my $result = &Apache::lonnet::assigncustomrole(
                        $udom,$uname,$url,$three,$four,$five,$end,$start,undef,undef,
                        $context,$othdomby,$requester);
     my $output = &mt('Assigning custom role').' "'.$five.'" by '.$four.':'.$three.' in '.$url.      my $output = &mt('Assigning custom role').' "'.$five.'" by '.$four.':'.$three.' in '.$url.
                          ($start?', '.&mt('starting').' '.localtime($start):'').                           ($start?', '.&mt('starting').' '.localtime($start):'').
                          ($end?', ending '.localtime($end):'').': <b>'.                           ($end?', ending '.localtime($end):'').': <b>'.$result.'</b><br />';
               &Apache::lonnet::assigncustomrole(      if (wantarray) {
                  $udom,$uname,$url,$three,$four,$five,$end,$start,undef,undef,$context).          return ($output,$result);
                  '</b><br />';      } else {
     return $output;          return $output;
       }
 }  }
   
 sub commit_standardrole {  sub commit_standardrole {
     my ($udom,$uname,$url,$three,$start,$end,$one,$two,$sec,$context,$credits) = @_;      my ($udom,$uname,$url,$three,$start,$end,$one,$two,$sec,$context,$credits,
     my ($output,$logmsg,$linefeed);          $othdomby,$requester) = @_;
       my ($output,$logmsg,$linefeed,$result);
     if ($context eq 'auto') {      if ($context eq 'auto') {
         $linefeed = "\n";          $linefeed = "\n";
     } else {      } else {
         $linefeed = "<br />\n";          $linefeed = "<br />\n";
     }        }  
     if ($three eq 'st') {      if ($three eq 'st') {
         my $result = &commit_studentrole(\$logmsg,$udom,$uname,$url,$three,$start,$end,          $result = &commit_studentrole(\$logmsg,$udom,$uname,$url,$three,$start,$end,
                                          $one,$two,$sec,$context,$credits);                                        $one,$two,$sec,$context,$credits,$othdomby,
                                         $requester);
         if (($result =~ /^error/) || ($result eq 'not_in_class') ||           if (($result =~ /^error/) || ($result eq 'not_in_class') || 
             ($result eq 'unknown_course') || ($result eq 'refused')) {              ($result eq 'unknown_course') || ($result eq 'refused')) {
             $output = $logmsg.' '.&mt('Error: ').$result."\n";               $output = $logmsg.' '.&mt('Error: ').$result."\n"; 
Line 16276  sub commit_standardrole { Line 17136  sub commit_standardrole {
         $output = &mt('Assigning').' '.$three.' in '.$url.          $output = &mt('Assigning').' '.$three.' in '.$url.
                ($start?', '.&mt('starting').' '.localtime($start):'').                 ($start?', '.&mt('starting').' '.localtime($start):'').
                ($end?', '.&mt('ending').' '.localtime($end):'').': ';                 ($end?', '.&mt('ending').' '.localtime($end):'').': ';
         my $result = &Apache::lonnet::assignrole($udom,$uname,$url,$three,$end,$start,'','',$context);          $result = &Apache::lonnet::assignrole($udom,$uname,$url,$three,$end,$start,
                                                 '','',$context,$othdomby,$requester);
         if ($context eq 'auto') {          if ($context eq 'auto') {
             $output .= $result.$linefeed;              $output .= $result.$linefeed;
         } else {          } else {
             $output .= '<b>'.$result.'</b>'.$linefeed;              $output .= '<b>'.$result.'</b>'.$linefeed;
         }          }
     }      }
     return $output;      if (wantarray) {
           return ($output,$result);
       } else {
           return $output;
       }
 }  }
   
 sub commit_studentrole {  sub commit_studentrole {
     my ($logmsg,$udom,$uname,$url,$three,$start,$end,$one,$two,$sec,$context,      my ($logmsg,$udom,$uname,$url,$three,$start,$end,$one,$two,$sec,$context,
         $credits) = @_;          $credits,$othdomby,$requester) = @_;
     my ($result,$linefeed,$oldsecurl,$newsecurl);      my ($result,$linefeed,$oldsecurl,$newsecurl);
     if ($context eq 'auto') {      if ($context eq 'auto') {
         $linefeed = "\n";          $linefeed = "\n";
Line 16312  sub commit_studentrole { Line 17177  sub commit_studentrole {
                 }                  }
                 $oldsecurl = $uurl;                  $oldsecurl = $uurl;
                 $expire_role_result =                   $expire_role_result = 
                     &Apache::lonnet::assignrole($udom,$uname,$uurl,'st',$now,'','',$context);                      &Apache::lonnet::assignrole($udom,$uname,$uurl,'st',$now,
                 if ($env{'request.course.sec'} ne '') {                                                   '','','',$context,$othdomby,$requester);
                   if ($env{'request.course.sec'} ne '') {
                     if ($expire_role_result eq 'refused') {                      if ($expire_role_result eq 'refused') {
                         my @roles = ('st');                          my @roles = ('st');
                         my @statuses = ('previous');                          my @statuses = ('previous');
Line 16339  sub commit_studentrole { Line 17205  sub commit_studentrole {
                 &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,                  &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,
                                                            undef,undef,undef,$sec,                                                             undef,undef,undef,$sec,
                                                            $end,$start,'','',$cid,                                                             $end,$start,'','',$cid,
                                                            '',$context,$credits);                                                             '',$context,$credits,'',
                                                              $othdomby,$requester);
             if ($modify_section_result =~ /^ok/) {              if ($modify_section_result =~ /^ok/) {
                 if ($secchange == 1) {                  if ($secchange == 1) {
                     if ($sec eq '') {                      if ($sec eq '') {
Line 16732  sub construct_course { Line 17599  sub construct_course {
         $cenv{'internal.defaultcredits'} = $args->{'defaultcredits'};          $cenv{'internal.defaultcredits'} = $args->{'defaultcredits'};
     }      }
     my @badclasses = (); # Used to accumulate sections/crosslistings that did not pass classlist access check for course owner.      my @badclasses = (); # Used to accumulate sections/crosslistings that did not pass classlist access check for course owner.
       my @oklcsecs = (); # Used to accumulate LON-CAPA sections for validated institutional sections.
     if ($args->{'crssections'}) {      if ($args->{'crssections'}) {
         $cenv{'internal.sectionnums'} = '';          $cenv{'internal.sectionnums'} = '';
         if ($args->{'crssections'} =~ m/,/) {          if ($args->{'crssections'} =~ m/,/) {
Line 16745  sub construct_course { Line 17613  sub construct_course {
                 my $class = $args->{'crscode'}.$sec;                  my $class = $args->{'crscode'}.$sec;
                 my $addcheck = &Apache::lonnet::auto_new_course($$crsunum,$$crsudom,$class,$cenv{'internal.courseowner'});                  my $addcheck = &Apache::lonnet::auto_new_course($$crsunum,$$crsudom,$class,$cenv{'internal.courseowner'});
                 $cenv{'internal.sectionnums'} .= $item.',';                  $cenv{'internal.sectionnums'} .= $item.',';
                 unless ($addcheck eq 'ok') {                  if ($addcheck eq 'ok') {
                       unless (grep(/^\Q$gp\E$/,@oklcsecs)) {
                           push(@oklcsecs,$gp);
                       }
                   } else {
                     push(@badclasses,$class);                      push(@badclasses,$class);
                 }                  }
             }              }
Line 16773  sub construct_course { Line 17645  sub construct_course {
                 my ($xl,$gp) = split/:/,$item;                  my ($xl,$gp) = split/:/,$item;
                 my $addcheck =  &Apache::lonnet::auto_new_course($$crsunum,$$crsudom,$xl,$cenv{'internal.courseowner'});                  my $addcheck =  &Apache::lonnet::auto_new_course($$crsunum,$$crsudom,$xl,$cenv{'internal.courseowner'});
                 $cenv{'internal.crosslistings'} .= $item.',';                  $cenv{'internal.crosslistings'} .= $item.',';
                 unless ($addcheck eq 'ok') {                  if ($addcheck eq 'ok') {
                       unless (grep(/^\Q$gp\E$/,@oklcsecs)) {
                           push(@oklcsecs,$gp);
                       }
                   } else {
                     push(@badclasses,$xl);                      push(@badclasses,$xl);
                 }                  }
             }              }
Line 16836  sub construct_course { Line 17712  sub construct_course {
     if ($args->{'no_end_date'}) {      if ($args->{'no_end_date'}) {
         $args->{'endaccess'} = 0;          $args->{'endaccess'} = 0;
     }      }
   #  If an official course with institutional sections is created by cloning 
   #  an existing course, section-specific hiding of course totals in student's
   #  view of grades as copied from cloned course, will be checked for valid 
   #  sections.
       if (($can_clone && $cloneid) &&
           ($cenv{'internal.coursecode'} ne '') &&
           ($cenv{'grading'} eq 'standard') &&
           ($cenv{'hidetotals'} ne '') &&
           ($cenv{'hidetotals'} ne 'all')) {
           my @hidesecs;
           my $deletehidetotals;
           if (@oklcsecs) {
               foreach my $sec (split(/,/,$cenv{'hidetotals'})) {
                   if (grep(/^\Q$sec$/,@oklcsecs)) {
                       push(@hidesecs,$sec);
                   }
               }
               if (@hidesecs) {
                   $cenv{'hidetotals'} = join(',',@hidesecs);
               } else {
                   $deletehidetotals = 1;
               }
           } else {
               $deletehidetotals = 1;
           }
           if ($deletehidetotals) {
               delete($cenv{'hidetotals'});
               &Apache::lonnet::del('environment',['hidetotals'],$$crsudom,$$crsunum);
           }
       }
     $cenv{'internal.autostart'}=$args->{'enrollstart'};      $cenv{'internal.autostart'}=$args->{'enrollstart'};
     $cenv{'internal.autoend'}=$args->{'enrollend'};      $cenv{'internal.autoend'}=$args->{'enrollend'};
     $cenv{'default_enrollment_start_date'}=$args->{'startaccess'};      $cenv{'default_enrollment_start_date'}=$args->{'startaccess'};
Line 16954  sub construct_course { Line 17860  sub construct_course {
 #  #
     unless (($args->{'nonstandard'}) || ($args->{'firstres'} eq 'blank')      unless (($args->{'nonstandard'}) || ($args->{'firstres'} eq 'blank')
     || ($cloneid)) {      || ($cloneid)) {
  use LONCAPA::map;  
  $outcome .= &mt('Setting first resource').': ';   $outcome .= &mt('Setting first resource').': ';
   
  my $map = '/uploaded/'.$$crsudom.'/'.$$crsunum.'/default.sequence';   my $map = '/uploaded/'.$$crsudom.'/'.$$crsunum.'/default.sequence';
Line 17197  sub init_user_environment { Line 18102  sub init_user_environment {
   
     my $public=($username eq 'public' && $domain eq 'public');      my $public=($username eq 'public' && $domain eq 'public');
   
     my ($filename,$cookie,$userroles,$firstaccenv,$timerintenv);      my ($filename,$cookie,$userroles,$firstaccenv,$timerintenv,
           $coauthorenv);
     my $now=time;      my $now=time;
   
     if ($public) {      if ($public) {
Line 17263  sub init_user_environment { Line 18169  sub init_user_environment {
           
 # Initialize roles  # Initialize roles
   
  ($userroles,$firstaccenv,$timerintenv) =    ($userroles,$firstaccenv,$timerintenv,$coauthorenv) = 
             &Apache::lonnet::rolesinit($domain,$username,$authhost);              &Apache::lonnet::rolesinit($domain,$username,$authhost);
     }      }
 # ------------------------------------ Check browser type and MathML capability  # ------------------------------------ Check browser type and MathML capability
Line 17341  sub init_user_environment { Line 18247  sub init_user_environment {
             my %is_adv = ( is_adv => $env{'user.adv'} );              my %is_adv = ( is_adv => $env{'user.adv'} );
             my %domdef = &Apache::lonnet::get_domain_defaults($domain);              my %domdef = &Apache::lonnet::get_domain_defaults($domain);
   
             foreach my $tool ('aboutme','blog','webdav','portfolio') {              foreach my $tool ('aboutme','blog','webdav','portfolio','portaccess','timezone') {
                 $userenv{'availabletools.'.$tool} =                   $userenv{'availabletools.'.$tool} =
                     &Apache::lonnet::usertools_access($username,$domain,$tool,'reload',                      &Apache::lonnet::usertools_access($username,$domain,$tool,'reload',
                                                       undef,\%userenv,\%domdef,\%is_adv);                                                        undef,\%userenv,\%domdef,\%is_adv);
             }              }
Line 17354  sub init_user_environment { Line 18260  sub init_user_environment {
                                                       \%userenv,\%domdef,\%is_adv);                                                        \%userenv,\%domdef,\%is_adv);
             }              }
   
               if ((ref($userroles) eq 'HASH') && ($userroles->{'user.author'}) &&
                   (exists($userroles->{"user.role.au./$domain/"}))) {
                   if ($userenv{'authoreditors'}) {
                       $userenv{'editors'} = $userenv{'authoreditors'};
                   } elsif ($domdef{'editors'} ne '') {
                       $userenv{'editors'} = $domdef{'editors'};
                   } else {
                       $userenv{'editors'} = 'edit,xml';
                   }
                   if ($userenv{'authorarchive'}) {
                       $userenv{'canarchive'} = 1;
                   } elsif (($userenv{'authorarchive'} eq '') &&
                            ($domdef{'archive'})) {
                       $userenv{'canarchive'} = 1;
                   }
               }
   
             $userenv{'canrequest.author'} =              $userenv{'canrequest.author'} =
                 &Apache::lonnet::usertools_access($username,$domain,'requestauthor',                  &Apache::lonnet::usertools_access($username,$domain,'requestauthor',
                                                   'reload','requestauthor',                                                    'reload','requestauthor',
Line 17410  sub init_user_environment { Line 18333  sub init_user_environment {
             if (ref($timerintenv) eq 'HASH') {              if (ref($timerintenv) eq 'HASH') {
                 &_add_to_env(\%disk_env,$timerintenv);                  &_add_to_env(\%disk_env,$timerintenv);
             }              }
               if (ref($coauthorenv) eq 'HASH') {
                   if (keys(%{$coauthorenv})) {
                       &_add_to_env(\%disk_env,$coauthorenv);
                   }
               }
     if (ref($args->{'extra_env'})) {      if (ref($args->{'extra_env'})) {
  &_add_to_env(\%disk_env,$args->{'extra_env'});   &_add_to_env(\%disk_env,$args->{'extra_env'});
     }      }
Line 18214  sub needs_coursereinit { Line 19142  sub needs_coursereinit {
         if ($blocked) {          if ($blocked) {
             return ();              return ();
         }          }
         my $lastchange = &Apache::lonnet::get_coursechange($cdom,$cnum);          my $update;
         if ($lastchange > $env{'request.course.tied'}) {          my $lastmainchange = &Apache::lonnet::get_coursechange($cdom,$cnum);
             my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired');          my $lastsuppchange = &Apache::lonnet::get_suppchange($cdom,$cnum);
             if ($curr_reqd_hash{'internal.releaserequired'} ne '') {          if ($lastmainchange > $env{'request.course.tied'}) {
                 my $required = $env{'course.'.$cdom.'_'.$cnum.'.internal.releaserequired'};              my ($needswitch,$switchwarning,$switchserver) = &switch_for_update($loncaparev,$cdom,$cnum);
                 if ($curr_reqd_hash{'internal.releaserequired'} ne $required) {              if ($needswitch) {
                     &Apache::lonnet::appenv({'course.'.$cdom.'_'.$cnum.'.internal.releaserequired' =>                  return ('switch',$switchwarning,$switchserver);
                                              $curr_reqd_hash{'internal.releaserequired'}});              }
                     my ($switchserver,$switchwarning) =              $update = 'main';
                         &check_release_required($loncaparev,$cdom.'_'.$cnum,$env{'request.role'},          }
                                                 $curr_reqd_hash{'internal.releaserequired'});          if ($lastsuppchange > $env{'request.course.suppupdated'}) {
                     if ($switchwarning ne '' || $switchserver ne '') {              if ($update) {
                         return ('switch',$switchwarning,$switchserver);                  $update = 'both';
                     }              } else {
                   my ($needswitch,$switchwarning,$switchserver) = &switch_for_update($loncaparev,$cdom,$cnum);
                   if ($needswitch) {
                       return ('switch',$switchwarning,$switchserver);
                   } else {
                       $update = 'supp';
                 }                  }
             }              }
             return ('update');          }
           return ($update);
       }
       return ();
   }
   
   sub switch_for_update {
       my ($loncaparev,$cdom,$cnum) = @_;
       my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired');
       if ($curr_reqd_hash{'internal.releaserequired'} ne '') {
           my $required = $env{'course.'.$cdom.'_'.$cnum.'.internal.releaserequired'};
           if ($curr_reqd_hash{'internal.releaserequired'} ne $required) {
               &Apache::lonnet::appenv({'course.'.$cdom.'_'.$cnum.'.internal.releaserequired' =>
                                       $curr_reqd_hash{'internal.releaserequired'}});
               my ($switchserver,$switchwarning) =
                   &check_release_required($loncaparev,$cdom.'_'.$cnum,$env{'request.role'},
                                           $curr_reqd_hash{'internal.releaserequired'});
               if ($switchwarning ne '' || $switchserver ne '') {
                   return ('switch',$switchwarning,$switchserver);
               }
         }          }
     }      }
     return ();      return ();
 }  }
   
 sub update_content_constraints {  sub update_content_constraints {
     my ($cdom,$cnum,$chome,$cid,$keeporder) = @_;      my ($cdom,$cnum,$chome,$cid) = @_;
     my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired');      my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired');
     my ($reqdmajor,$reqdminor) = split(/\./,$curr_reqd_hash{'internal.releaserequired'});      my ($reqdmajor,$reqdminor) = split(/\./,$curr_reqd_hash{'internal.releaserequired'});
     my (%checkresponsetypes,%checkcrsrestypes);      my (%checkresponsetypes,%checkcrsrestypes);
Line 18285  sub update_content_constraints { Line 19237  sub update_content_constraints {
         }          }
         undef($navmap);          undef($navmap);
     }      }
     my (@resources,@order,@resparms,@zombies);      if (&Apache::lonnet::count_supptools($cnum,$cdom,1)) {
     if ($keeporder) {  
         use LONCAPA::map;  
         @resources = @LONCAPA::map::resources;  
         @order = @LONCAPA::map::order;  
         @resparms = @LONCAPA::map::resparms;  
         @zombies = @LONCAPA::map::zombies;  
     }  
     my $suppmap = 'supplemental.sequence';  
     my ($suppcount,$supptools,$errors) = (0,0,0);  
     ($suppcount,$supptools,$errors) = &recurse_supplemental($cnum,$cdom,$suppmap,  
                                                             $suppcount,$supptools,$errors);  
     if ($keeporder) {  
         @LONCAPA::map::resources = @resources;  
         @LONCAPA::map::order = @order;  
         @LONCAPA::map::resparms = @resparms;  
         @LONCAPA::map::zombies = @zombies;  
     }  
     if ($supptools) {  
         my ($major,$minor) = split(/\./,$checkcrsrestypes{'exttool'});          my ($major,$minor) = split(/\./,$checkcrsrestypes{'exttool'});
         if (($major > $reqdmajor) || ($major == $reqdmajor && $minor > $reqdminor)) {          if (($major > $reqdmajor) || ($major == $reqdmajor && $minor > $reqdminor)) {
             ($reqdmajor,$reqdminor) = ($major,$minor);              ($reqdmajor,$reqdminor) = ($major,$minor);
Line 18329  sub allmaps_incourse { Line 19263  sub allmaps_incourse {
     if ($lastchange > $env{'request.course.tied'}) {      if ($lastchange > $env{'request.course.tied'}) {
         my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum");          my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum");
         unless ($ferr) {          unless ($ferr) {
             &update_content_constraints($cdom,$cnum,$chome,$cid,1);              &update_content_constraints($cdom,$cnum,$chome,$cid);
         }          }
     }      }
     my $navmap = Apache::lonnavmaps::navmap->new();      my $navmap = Apache::lonnavmaps::navmap->new();
Line 18355  sub parse_supplemental_title { Line 19289  sub parse_supplemental_title {
         my $name =  &plainname($uname,$udom);          my $name =  &plainname($uname,$udom);
         $name = &HTML::Entities::encode($name,'"<>&\'');          $name = &HTML::Entities::encode($name,'"<>&\'');
         $renametitle = &HTML::Entities::encode($renametitle,'"<>&\'');          $renametitle = &HTML::Entities::encode($renametitle,'"<>&\'');
         $title='<i>'.&Apache::lonlocal::locallocaltime($time).'</i> '.          $title='<i>'.&Apache::lonlocal::locallocaltime($time).'</i> '.$name;
             $name.': <br />'.$foldertitle;          if ($foldertitle ne '') {
               $title .= ': <br />'.$foldertitle;
           }
     }      }
     if (wantarray) {      if (wantarray) {
         return ($title,$foldertitle,$renametitle);          return ($title,$foldertitle,$renametitle);
Line 18364  sub parse_supplemental_title { Line 19300  sub parse_supplemental_title {
     return $title;      return $title;
 }  }
   
   sub get_supplemental {
       my ($cnum,$cdom,$ignorecache,$possdel)=@_;
       my $hashid=$cnum.':'.$cdom;
       my ($supplemental,$cached,$set_httprefs);
       unless ($ignorecache) {
           ($supplemental,$cached) = &Apache::lonnet::is_cached_new('supplemental',$hashid);
       }
       unless (defined($cached)) {
           my $chome=&Apache::lonnet::homeserver($cnum,$cdom);
           unless ($chome eq 'no_host') {
               my @order = @LONCAPA::map::order;
               my @resources = @LONCAPA::map::resources;
               my @resparms = @LONCAPA::map::resparms;
               my @zombies = @LONCAPA::map::zombies;
               my ($errors,%ids,%hidden);
               $errors =
                   &recurse_supplemental($cnum,$cdom,'supplemental.sequence',
                                         $errors,$possdel,\%ids,\%hidden);
               @LONCAPA::map::order = @order;
               @LONCAPA::map::resources = @resources;
               @LONCAPA::map::resparms = @resparms;
               @LONCAPA::map::zombies = @zombies;
               $set_httprefs = 1;
               if ($env{'request.course.id'} eq $cdom.'_'.$cnum) {
                   &Apache::lonnet::appenv({'request.course.suppupdated' => time});
               }
               $supplemental = {
                                  ids => \%ids,
                                  hidden => \%hidden,
                               };
               &Apache::lonnet::do_cache_new('supplemental',$hashid,$supplemental,600);
           }
       }
       return ($supplemental,$set_httprefs);
   }
   
 sub recurse_supplemental {  sub recurse_supplemental {
     my ($cnum,$cdom,$suppmap,$numfiles,$numexttools,$errors) = @_;      my ($cnum,$cdom,$suppmap,$errors,$possdel,$suppids,$hiddensupp,$hidden) = @_;
     if ($suppmap) {      if (($suppmap) && (ref($suppids) eq 'HASH') && (ref($hiddensupp) eq 'HASH')) {
           my $mapnum;
           if ($suppmap eq 'supplemental.sequence') {
               $mapnum = 0;
           } else {
               ($mapnum) = ($suppmap =~ /^supplemental_(\d+)\.sequence$/);
           }
         my ($errtext,$fatal) = &LONCAPA::map::mapread('/uploaded/'.$cdom.'/'.$cnum.'/'.$suppmap);          my ($errtext,$fatal) = &LONCAPA::map::mapread('/uploaded/'.$cdom.'/'.$cnum.'/'.$suppmap);
         if ($fatal) {          if ($fatal) {
             $errors ++;              $errors ++;
         } else {          } else {
             if ($#LONCAPA::map::resources > 0) {              my @order = @LONCAPA::map::order;
                 foreach my $res (@LONCAPA::map::resources) {              if (@order > 0) {
                     my ($title,$src,$ext,$type,$status)=split(/\:/,$res);                  my @resources = @LONCAPA::map::resources;
                   my @resparms = @LONCAPA::map::resparms;
                   foreach my $idx (@order) {
                       my ($title,$src,$ext,$type,$status)=split(/\:/,$resources[$idx]);
                     if (($src ne '') && ($status eq 'res')) {                      if (($src ne '') && ($status eq 'res')) {
                           my $id = $mapnum.':'.$idx;
                           push(@{$suppids->{$src}},$id);
                           if (($hidden) || (&get_supp_parameter($resparms[$idx],'parameter_hiddenresource') =~ /^yes/i)) {
                               $hiddensupp->{$id} = 1;
                           }
                         if ($src =~ m{^\Q/uploaded/$cdom/$cnum/\E(supplemental_\d+\.sequence)$}) {                          if ($src =~ m{^\Q/uploaded/$cdom/$cnum/\E(supplemental_\d+\.sequence)$}) {
                             ($numfiles,$numexttools,$errors) = &recurse_supplemental($cnum,$cdom,$1,                              $errors = &recurse_supplemental($cnum,$cdom,$1,$errors,$possdel,$suppids,
                                                                    $numfiles,$numexttools,$errors);                                                              $hiddensupp,$hiddensupp->{$id});
                         } else {                          } else {
                             if ($src =~ m{^/adm/$cdom/$cnum/\d+/ext\.tool$}) {                              my $allowed;
                                 $numexttools ++;                              if (($env{'request.role.adv'}) || (!$hiddensupp->{$id})) {
                                   $allowed = 1;
                               } elsif ($possdel) {
                                   foreach my $item (@{$suppids->{$src}}) {
                                       next if ($item eq $id);
                                       unless ($hiddensupp->{$item}) {
                                          $allowed = 1;
                                          last;
                                       }
                                   }
                                   if ((!$allowed) && (exists($env{'httpref.'.$src}))) {
                                       &Apache::lonnet::delenv('httpref.'.$src);
                                   }
                               }
                               if ($allowed && (!exists($env{'httpref.'.$src}))) {
                                   &Apache::lonnet::allowuploaded('/adm/coursedoc',$src);
                             }                              }
                             $numfiles ++;  
                         }                          }
                     }                      }
                 }                  }
             }              }
         }          }
     }      }
     return ($numfiles,$numexttools,$errors);      return $errors;
   }
   
   sub set_supp_httprefs {
       my ($cnum,$cdom,$supplemental,$possdel) = @_;
       if (ref($supplemental) eq 'HASH') {
           if ((ref($supplemental->{'ids'}) eq 'HASH') && (ref($supplemental->{'hidden'}) eq 'HASH')) {
               foreach my $src (keys(%{$supplemental->{'ids'}})) {
                   next if ($src =~ /\.sequence$/);
                   if (ref($supplemental->{'ids'}->{$src}) eq 'ARRAY') {
                       my $allowed;
                       if ($env{'request.role.adv'}) {
                           $allowed = 1;
                       } else {
                           foreach my $id (@{$supplemental->{'ids'}->{$src}}) {
                               unless ($supplemental->{'hidden'}->{$id}) {
                                   $allowed = 1;
                                   last;
                               }
                           }
                       }
                       if (exists($env{'httpref.'.$src})) {
                           if ($possdel) {
                               unless ($allowed) {
                                   &Apache::lonnet::delenv('httpref.'.$src);
                               }
                           }
                       } elsif ($allowed) {
                           &Apache::lonnet::allowuploaded('/adm/coursedoc',$src);
                       }
                   }
               }
               if ($env{'request.course.id'} eq $cdom.'_'.$cnum) {
                   &Apache::lonnet::appenv({'request.course.suppupdated' => time});
               }
           }
       }
   }
   
   sub get_supp_parameter {
       my ($resparm,$name)=@_;
       return if ($resparm eq '');
       my $value=undef;
       my $ptype=undef;
       foreach (split('&&&',$resparm)) {
           my ($thistype,$thisname,$thisvalue)=split('___',$_);
           if ($thisname eq $name) {
               $value=$thisvalue;
               $ptype=$thistype;
           }
       }
       return $value;
 }  }
   
 sub symb_to_docspath {  sub symb_to_docspath {
Line 18462  sub symb_to_docspath { Line 19513  sub symb_to_docspath {
     return $path;      return $path;
 }  }
   
   sub validate_folderpath {
       my ($supplementalflag,$allowed,$coursenum,$coursedom) = @_;
       if ($env{'form.folderpath'} ne '') {
           my @items = split(/\&/,$env{'form.folderpath'});
           my ($badpath,$changed,$got_supp,$supppath,%supphidden,%suppids);
           for (my $i=0; $i<@items; $i++) {
               my $odd = $i%2;
               if (($odd) && (!$supplementalflag) && ($items[$i] !~ /^[^:]*:(|\d+):(|1):(|1):(|1):(|1)$/)) {
                   $badpath = 1;
               } elsif ($odd && $supplementalflag) {
                   my $idx = $i-1;
                   if ($items[$i] =~ /^([^:]*)::(|1):::$/) {
                       my $esc_name = $1;
                       if ((!$allowed) || ($items[$idx] eq 'supplemental')) {
                           $supppath .= '&'.$esc_name;
                           $changed = 1;
                       } else {
                           $supppath .= '&'.$items[$i];
                       }
                   } elsif (($allowed) && ($items[$idx] ne 'supplemental')) {
                       $changed = 1;
                       my $is_hidden;
                       unless ($got_supp) {
                           my ($supplemental) = &get_supplemental($coursenum,$coursedom);
                           if (ref($supplemental) eq 'HASH') {
                               if (ref($supplemental->{'hidden'}) eq 'HASH') {
                                   %supphidden = %{$supplemental->{'hidden'}};
                               }
                               if (ref($supplemental->{'ids'}) eq 'HASH') {
                                   %suppids = %{$supplemental->{'ids'}};
                               }
                           }
                           $got_supp = 1;
                       }
                       if (ref($suppids{"/uploaded/$coursedom/$coursenum/$items[$idx].sequence"}) eq 'ARRAY') {
                           my $mapid = $suppids{"/uploaded/$coursedom/$coursenum/$items[$idx].sequence"}->[0];
                           if ($supphidden{$mapid}) {
                               $is_hidden = 1;
                           }
                       }
                       $supppath .= '&'.$items[$i].'::'.$is_hidden.':::';
                   } else {
                       $supppath .= '&'.$items[$i];
                   }
               } elsif ((!$odd) && ($items[$i] !~ /^(default|supplemental)(|_\d+)$/)) {
                   $badpath = 1;
               } elsif ($supplementalflag) {
                   $supppath .= '&'.$items[$i];
               }
               last if ($badpath);
           }
           if ($badpath) {
               delete($env{'form.folderpath'});
           } elsif ($changed && $supplementalflag) {
               $supppath =~ s/^\&//;
               $env{'form.folderpath'} = $supppath;
           }
       }
       return;
   }
   
 sub captcha_display {  sub captcha_display {
     my ($context,$lonhost,$defdom) = @_;      my ($context,$lonhost,$defdom) = @_;
     my ($output,$error);      my ($output,$error);
Line 18583  sub create_captcha { Line 19695  sub create_captcha {
         if (-e $Apache::lonnet::perlvar{'lonCaptchaDir'}.'/'.$md5sum.'.png') {          if (-e $Apache::lonnet::perlvar{'lonCaptchaDir'}.'/'.$md5sum.'.png') {
             $output = '<input type="hidden" name="crypt" value="'.$md5sum.'" />'."\n".              $output = '<input type="hidden" name="crypt" value="'.$md5sum.'" />'."\n".
                       '<span class="LC_nobreak">'.                        '<span class="LC_nobreak">'.
                       &mt('Type in the letters/numbers shown below').'&nbsp;'.                        '<label>'.&mt('Type in the letters/numbers shown below').'&nbsp;'.
                       '<input type="text" size="5" name="code" value="" autocomplete="off" />'.                        '<input type="text" size="5" name="code" value="" autocomplete="new-password" />'.
                       '</span><br />'.                        '</label></span><br />'.
                       '<img src="'.$captcha_params{'www_output_dir'}.'/'.$md5sum.'.png" alt="captcha" />';                        '<img src="'.$captcha_params{'www_output_dir'}.'/'.$md5sum.'.png" alt="captcha" />';
             last;              last;
         }          }

Removed from v.1.1378  
changed lines
  Added in v.1.1462


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>