Diff for /loncom/interface/loncommon.pm between versions 1.1075.2.50 and 1.1085

version 1.1075.2.50, 2013/09/01 02:34:28 version 1.1085, 2012/07/06 22:46:06
Line 67  use Apache::lonhtmlcommon(); Line 67  use Apache::lonhtmlcommon();
 use Apache::loncoursedata();  use Apache::loncoursedata();
 use Apache::lontexconvert();  use Apache::lontexconvert();
 use Apache::lonclonecourse();  use Apache::lonclonecourse();
 use Apache::lonuserutils();  
 use Apache::lonuserstate();  
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
 use DateTime::TimeZone;  use DateTime::TimeZone;
 use DateTime::Locale::Catalog;  use DateTime::Locale::Catalog;
 use Authen::Captcha;  
 use Captcha::reCAPTCHA;  
   
 # ---------------------------------------------- Designs  # ---------------------------------------------- Designs
 use vars qw(%defaultdesign);  use vars qw(%defaultdesign);
Line 528  ENDAUTHORBRW Line 524  ENDAUTHORBRW
 }  }
   
 sub coursebrowser_javascript {  sub coursebrowser_javascript {
     my ($domainfilter,$sec_element,$formname,$role_element,$crstype,      my ($domainfilter,$sec_element,$formname,$role_element,$crstype) = @_;
         $credits_element) = @_;  
     my $wintitle = 'Course_Browser';      my $wintitle = 'Course_Browser';
     if ($crstype eq 'Community') {      if ($crstype eq 'Community') {
         $wintitle = 'Community_Browser';          $wintitle = 'Community_Browser';
Line 592  sub coursebrowser_javascript { Line 587  sub coursebrowser_javascript {
     }      }
 $id_functions  $id_functions
 ENDSTDBRW  ENDSTDBRW
     if (($sec_element ne '') || ($role_element ne '') || ($credits_element ne '')) {      if (($sec_element ne '') || ($role_element ne '')) {
         $output .= &setsec_javascript($sec_element,$formname,$role_element,          $output .= &setsec_javascript($sec_element,$formname,$role_element);
                                       $credits_element);  
     }      }
     $output .= '      $output .= '
 // ]]>  // ]]>
Line 751  ENDUSERBRW Line 745  ENDUSERBRW
 }  }
   
 sub setsec_javascript {  sub setsec_javascript {
     my ($sec_element,$formname,$role_element,$credits_element) = @_;      my ($sec_element,$formname,$role_element) = @_;
     my (@courserolenames,@communityrolenames,$rolestr,$courserolestr,      my (@courserolenames,@communityrolenames,$rolestr,$courserolestr,
         $communityrolestr);          $communityrolestr);
     if ($role_element ne '') {      if ($role_element ne '') {
Line 846  function setRole(crstype) { Line 840  function setRole(crstype) {
 }  }
 |;  |;
     }      }
     if ($credits_element) {  
         $setsections .= qq|  
 function setCredits(defaultcredits) {  
     document.$formname.$credits_element.value = defaultcredits;  
     return;  
 }  
 |;  
     }  
     return $setsections;      return $setsections;
 }  }
   
Line 899  sub check_uncheck_jscript { Line 885  sub check_uncheck_jscript {
 function checkAll(field) {  function checkAll(field) {
     if (field.length > 0) {      if (field.length > 0) {
         for (i = 0; i < field.length; i++) {          for (i = 0; i < field.length; i++) {
             if (!field[i].disabled) {              field[i].checked = true ;
                 field[i].checked = true;  
             }  
         }          }
     } else {      } else {
         if (!field.disabled) {          field.checked = true
             field.checked = true;  
         }  
     }      }
 }  }
     
Line 1008  sub select_language { Line 990  sub select_language {
             $langchoices{$code} = &plainlanguagedescription($id);              $langchoices{$code} = &plainlanguagedescription($id);
         }          }
     }      }
     %langchoices = &Apache::lonlocal::texthash(%langchoices);  
     return &select_form($selected,$name,\%langchoices);      return &select_form($selected,$name,\%langchoices);
 }  }
   
Line 1040  linked_select_forms takes the following Line 1021  linked_select_forms takes the following
   
 =item * $menuorder, the order of values in the first menu  =item * $menuorder, the order of values in the first menu
   
 =item * $onchangefirst, additional javascript call to execute for an onchange  
         event for the first <select> tag  
   
 =item * $onchangesecond, additional javascript call to execute for an onchange  
         event for the second <select> tag  
   
 =back   =back 
   
 Below is an example of such a hash.  Only the 'text', 'default', and   Below is an example of such a hash.  Only the 'text', 'default', and 
Line 1099  sub linked_select_forms { Line 1074  sub linked_select_forms {
         $secondselectname,           $secondselectname, 
         $hashref,          $hashref,
         $menuorder,          $menuorder,
         $onchangefirst,  
         $onchangesecond  
         ) = @_;          ) = @_;
     my $second = "document.$formname.$secondselectname";      my $second = "document.$formname.$secondselectname";
     my $first = "document.$formname.$firstselectname";      my $first = "document.$formname.$firstselectname";
Line 1157  function select1_changed() { Line 1130  function select1_changed() {
 </script>  </script>
 END  END
     # output the initial values for the selection lists      # output the initial values for the selection lists
     $result .= "<select size=\"1\" name=\"$firstselectname\" onchange=\"select1_changed();$onchangefirst\">\n";      $result .= "<select size=\"1\" name=\"$firstselectname\" onchange=\"select1_changed()\">\n";
     my @order = sort(keys(%{$hashref}));      my @order = sort(keys(%{$hashref}));
     if (ref($menuorder) eq 'ARRAY') {      if (ref($menuorder) eq 'ARRAY') {
         @order = @{$menuorder};          @order = @{$menuorder};
Line 1170  END Line 1143  END
     $result .= "</select>\n";      $result .= "</select>\n";
     my %select2 = %{$hashref->{$firstdefault}->{'select2'}};      my %select2 = %{$hashref->{$firstdefault}->{'select2'}};
     $result .= $middletext;      $result .= $middletext;
     $result .= "<select size=\"1\" name=\"$secondselectname\"";      $result .= "<select size=\"1\" name=\"$secondselectname\">\n";
     if ($onchangesecond) {  
         $result .= ' onchange="'.$onchangesecond.'"';  
     }  
     $result .= ">\n";  
     my $seconddefault = $hashref->{$firstdefault}->{'default'};      my $seconddefault = $hashref->{$firstdefault}->{'default'};
           
     my @secondorder = sort(keys(%select2));      my @secondorder = sort(keys(%select2));
Line 1234  sub help_open_topic { Line 1203  sub help_open_topic {
     $topic=~s/\W/\_/g;      $topic=~s/\W/\_/g;
   
     if (!$stayOnPage) {      if (!$stayOnPage) {
         if ($env{'browser.mobile'}) {   $link = "javascript:openMyModal('/adm/help/${filename}.hlp',$width,$height,'yes');";
     $link = "javascript:openMyModal('/adm/help/${filename}.hlp',$width,$height,'yes');";  
         } else {  
             $link = "javascript:void(open('/adm/help/${filename}.hlp', 'Help_for_$topic', 'menubar=0,toolbar=1,scrollbars=1,width=$width,height=$height,resizable=yes'))";  
         }  
     } elsif ($stayOnPage eq 'popup') {      } elsif ($stayOnPage eq 'popup') {
         $link = "javascript:void(open('/adm/help/${filename}.hlp', 'Help_for_$topic', 'menubar=0,toolbar=1,scrollbars=1,width=$width,height=$height,resizable=yes'))";          $link = "javascript:void(open('/adm/help/${filename}.hlp', 'Help_for_$topic', 'menubar=0,toolbar=1,scrollbars=1,width=$width,height=$height,resizable=yes'))";
     } else {      } else {
Line 2165  sub select_level_form { Line 2130  sub select_level_form {
   
 =pod  =pod
   
 =item * &select_dom_form($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms,$excdoms)  =item * &select_dom_form($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms)
   
 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 2178  If the $showdomdesc flag is set, the dom Line 2143  If the $showdomdesc flag is set, the dom
   
 The optional $onchange argument specifies what should occur if the domain selector is changed, e.g., 'this.form.submit()' if the form is to be automatically submitted.  The optional $onchange argument specifies what should occur if the domain selector is changed, e.g., 'this.form.submit()' if the form is to be automatically submitted.
   
 The optional $incdoms is a reference to an array of domains which will be the only available options.  The optional $incdoms is a reference to an array of domains which will be the only available options. 
   
 The optional $excdoms is a reference to an array of domains which will be excluded from the available options.   
   
 =cut  =cut
   
 #-------------------------------------------  #-------------------------------------------
 sub select_dom_form {  sub select_dom_form {
     my ($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms,$excdoms) = @_;      my ($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms) = @_;
     if ($onchange) {      if ($onchange) {
         $onchange = ' onchange="'.$onchange.'"';          $onchange = ' onchange="'.$onchange.'"';
     }      }
     my (@domains,%exclude);      my @domains;
     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});
     } else {      } else {
         @domains = sort {lc($a) cmp lc($b)} (&Apache::lonnet::all_domains());          @domains = sort {lc($a) cmp lc($b)} (&Apache::lonnet::all_domains());
     }      }
     if ($includeempty) { @domains=('',@domains); }      if ($includeempty) { @domains=('',@domains); }
     if (ref($excdoms) eq 'ARRAY') {  
         map { $exclude{$_} = 1; } @{$excdoms};  
     }  
     my $selectdomain = "<select name=\"$name\" size=\"1\"$onchange>\n";      my $selectdomain = "<select name=\"$name\" size=\"1\"$onchange>\n";
     foreach my $dom (@domains) {      foreach my $dom (@domains) {
         next if ($exclude{$dom});  
         $selectdomain.="<option value=\"$dom\" ".          $selectdomain.="<option value=\"$dom\" ".
             ($dom eq $defdom ? 'selected="selected" ' : '').'>'.$dom;              ($dom eq $defdom ? 'selected="selected" ' : '').'>'.$dom;
         if ($showdomdesc) {          if ($showdomdesc) {
Line 2323  Outputs: Line 2282  Outputs:
   
 =item * $clientos  =item * $clientos
   
 =item * $clientmobile  
   
 =item * $clientinfo  
   
 =back  =back
   
 =back   =back 
Line 2345  sub decode_user_agent { Line 2300  sub decode_user_agent {
     my $clientversion='0';      my $clientversion='0';
     my $clientmathml='';      my $clientmathml='';
     my $clientunicode='0';      my $clientunicode='0';
     my $clientmobile=0;  
     for (my $i=0;$i<=$#browsertype;$i++) {      for (my $i=0;$i<=$#browsertype;$i++) {
         my ($bname,$match,$notmatch,$vreg,$minv,$univ)=split(/\:/,$browsertype[$i]);          my ($bname,$match,$notmatch,$vreg,$minv,$univ)=split(/\:/,$browsertype[$i]);
  if (($httpbrowser=~/$match/i)  && ($httpbrowser!~/$notmatch/i)) {   if (($httpbrowser=~/$match/i)  && ($httpbrowser!~/$notmatch/i)) {
Line 2357  sub decode_user_agent { Line 2311  sub decode_user_agent {
  }   }
     }      }
     my $clientos='unknown';      my $clientos='unknown';
     my $clientinfo;  
     if (($httpbrowser=~/linux/i) ||      if (($httpbrowser=~/linux/i) ||
         ($httpbrowser=~/unix/i) ||          ($httpbrowser=~/unix/i) ||
         ($httpbrowser=~/ux/i) ||          ($httpbrowser=~/ux/i) ||
Line 2369  sub decode_user_agent { Line 2322  sub decode_user_agent {
         ($httpbrowser=~/powerpc/i)) { $clientos='mac'; }          ($httpbrowser=~/powerpc/i)) { $clientos='mac'; }
     if ($httpbrowser=~/win/i) { $clientos='win'; }      if ($httpbrowser=~/win/i) { $clientos='win'; }
     if ($httpbrowser=~/embed/i) { $clientos='pda'; }      if ($httpbrowser=~/embed/i) { $clientos='pda'; }
     if ($httpbrowser=~/(Android|iPod|iPad|iPhone|webOS|Blackberry|Windows Phone|Opera m(?:ob|in)|Fennec)/i) {  
         $clientmobile=lc($1);  
     }  
     if ($httpbrowser=~ m{Firefox/(\d+\.\d+)}) {  
         $clientinfo = 'firefox-'.$1;  
     } elsif ($httpbrowser=~ m{chromeframe/(\d+\.\d+)\.}) {  
         $clientinfo = 'chromeframe-'.$1;  
     }  
     return ($httpbrowser,$clientbrowser,$clientversion,$clientmathml,      return ($httpbrowser,$clientbrowser,$clientversion,$clientmathml,
             $clientunicode,$clientos,$clientmobile,$clientinfo);              $clientunicode,$clientos,);
 }  }
   
 ###############################################################  ###############################################################
Line 2530  END Line 2475  END
     return $result;      return $result;
 }  }
   
 sub authform_authorwarning {  sub authform_authorwarning{
     my $result='';      my $result='';
     $result='<i>'.      $result='<i>'.
         &mt('As a general rule, only authors or co-authors should be '.          &mt('As a general rule, only authors or co-authors should be '.
Line 2539  sub authform_authorwarning { Line 2484  sub authform_authorwarning {
     return $result;      return $result;
 }  }
   
 sub authform_nochange {  sub authform_nochange{  
     my %in = (      my %in = (
               formname => 'document.cu',                formname => 'document.cu',
               kerb_def_dom => 'MSU.EDU',                kerb_def_dom => 'MSU.EDU',
               @_,                @_,
           );            );
     my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'});       my ($authnum,%can_assign) =  &get_assignable_auth($in{'domain'}); 
     my $result;      my $result;
     if (!$authnum) {      if (keys(%can_assign) == 0) {
         $result = &mt('Under your current role you are not permitted to change login settings for this user');          $result = &mt('Under you current role you are not permitted to change login settings for this user');  
     } else {      } else {
         $result = '<label>'.&mt('[_1] Do not change login data',          $result = '<label>'.&mt('[_1] Do not change login data',
                   '<input type="radio" name="login" value="nochange" '.                    '<input type="radio" name="login" value="nochange" '.
Line 2568  sub authform_kerberos { Line 2513  sub authform_kerberos {
               );                );
     my ($check4,$check5,$krbcheck,$krbarg,$krbver,$result,$authtype,      my ($check4,$check5,$krbcheck,$krbarg,$krbver,$result,$authtype,
         $autharg,$jscall);          $autharg,$jscall);
     my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'});      my ($authnum,%can_assign) =  &get_assignable_auth($in{'domain'});
     if ($in{'kerb_def_auth'} eq 'krb5') {      if ($in{'kerb_def_auth'} eq 'krb5') {
        $check5 = ' checked="checked"';         $check5 = ' checked="checked"';
     } else {      } else {
Line 2618  sub authform_kerberos { Line 2563  sub authform_kerberos {
         if (defined($in{'mode'})) {          if (defined($in{'mode'})) {
             if ($in{'mode'} eq 'modifycourse') {              if ($in{'mode'} eq 'modifycourse') {
                 if ($authnum == 1) {                  if ($authnum == 1) {
                     $authtype = '<input type="radio" name="login" value="krb" />';                      $authtype = '<input type="hidden" name="login" value="krb" />';
                 }                  }
             }              }
         }          }
Line 2630  sub authform_kerberos { Line 2575  sub authform_kerberos {
                     $krbcheck.' />';                      $krbcheck.' />';
     }      }
     if (($can_assign{'krb4'} && $can_assign{'krb5'}) ||      if (($can_assign{'krb4'} && $can_assign{'krb5'}) ||
         ($can_assign{'krb4'} && !$can_assign{'krb5'} &&          ($can_assign{'krb4'} && !$can_assign{'krb5'} && 
          $in{'curr_authtype'} eq 'krb5') ||           $in{'curr_authtype'} eq 'krb5') ||
         (!$can_assign{'krb4'} && $can_assign{'krb5'} &&          (!$can_assign{'krb4'} && $can_assign{'krb5'} && 
          $in{'curr_authtype'} eq 'krb4')) {           $in{'curr_authtype'} eq 'krb4')) {
         $result .= &mt          $result .= &mt
         ('[_1] Kerberos authenticated with domain [_2] '.          ('[_1] Kerberos authenticated with domain [_2] '.
Line 2668  sub authform_kerberos { Line 2613  sub authform_kerberos {
     return $result;      return $result;
 }  }
   
 sub authform_internal {  sub authform_internal{  
     my %in = (      my %in = (
                 formname => 'document.cu',                  formname => 'document.cu',
                 kerb_def_dom => 'MSU.EDU',                  kerb_def_dom => 'MSU.EDU',
                 @_,                  @_,
                 );                  );
     my ($intcheck,$intarg,$result,$authtype,$autharg,$jscall);      my ($intcheck,$intarg,$result,$authtype,$autharg,$jscall);
     my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'});      my ($authnum,%can_assign) =  &get_assignable_auth($in{'domain'});
     if (defined($in{'curr_authtype'})) {      if (defined($in{'curr_authtype'})) {
         if ($in{'curr_authtype'} eq 'int') {          if ($in{'curr_authtype'} eq 'int') {
             if ($can_assign{'int'}) {              if ($can_assign{'int'}) {
Line 2704  sub authform_internal { Line 2649  sub authform_internal {
         if (defined($in{'mode'})) {          if (defined($in{'mode'})) {
             if ($in{'mode'} eq 'modifycourse') {              if ($in{'mode'} eq 'modifycourse') {
                 if ($authnum == 1) {                  if ($authnum == 1) {
                     $authtype = '<input type="radio" name="login" value="int" />';                      $authtype = '<input type="hidden" name="login" value="int" />';
                 }                  }
             }              }
         }          }
Line 2723  sub authform_internal { Line 2668  sub authform_internal {
     return $result;      return $result;
 }  }
   
 sub authform_local {  sub authform_local{  
     my %in = (      my %in = (
               formname => 'document.cu',                formname => 'document.cu',
               kerb_def_dom => 'MSU.EDU',                kerb_def_dom => 'MSU.EDU',
               @_,                @_,
               );                );
     my ($loccheck,$locarg,$result,$authtype,$autharg,$jscall);      my ($loccheck,$locarg,$result,$authtype,$autharg,$jscall);
     my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'});      my ($authnum,%can_assign) =  &get_assignable_auth($in{'domain'});
     if (defined($in{'curr_authtype'})) {      if (defined($in{'curr_authtype'})) {
         if ($in{'curr_authtype'} eq 'loc') {          if ($in{'curr_authtype'} eq 'loc') {
             if ($can_assign{'loc'}) {              if ($can_assign{'loc'}) {
Line 2759  sub authform_local { Line 2704  sub authform_local {
         if (defined($in{'mode'})) {          if (defined($in{'mode'})) {
             if ($in{'mode'} eq 'modifycourse') {              if ($in{'mode'} eq 'modifycourse') {
                 if ($authnum == 1) {                  if ($authnum == 1) {
                     $authtype = '<input type="radio" name="login" value="loc" />';                      $authtype = '<input type="hidden" name="login" value="loc" />';
                 }                  }
             }              }
         }          }
Line 2777  sub authform_local { Line 2722  sub authform_local {
     return $result;      return $result;
 }  }
   
 sub authform_filesystem {  sub authform_filesystem{  
     my %in = (      my %in = (
               formname => 'document.cu',                formname => 'document.cu',
               kerb_def_dom => 'MSU.EDU',                kerb_def_dom => 'MSU.EDU',
               @_,                @_,
               );                );
     my ($fsyscheck,$result,$authtype,$autharg,$jscall);      my ($fsyscheck,$result,$authtype,$autharg,$jscall);
     my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'});      my ($authnum,%can_assign) =  &get_assignable_auth($in{'domain'});
     if (defined($in{'curr_authtype'})) {      if (defined($in{'curr_authtype'})) {
         if ($in{'curr_authtype'} eq 'fsys') {          if ($in{'curr_authtype'} eq 'fsys') {
             if ($can_assign{'fsys'}) {              if ($can_assign{'fsys'}) {
Line 2810  sub authform_filesystem { Line 2755  sub authform_filesystem {
         if (defined($in{'mode'})) {          if (defined($in{'mode'})) {
             if ($in{'mode'} eq 'modifycourse') {              if ($in{'mode'} eq 'modifycourse') {
                 if ($authnum == 1) {                  if ($authnum == 1) {
                     $authtype = '<input type="radio" name="login" value="fsys" />';                      $authtype = '<input type="hidden" name="login" value="fsys" />';
                 }                  }
             }              }
         }          }
Line 3238  sub screenname { Line 3183  sub screenname {
 # ------------------------------------------------------------- Confirm Wrapper  # ------------------------------------------------------------- Confirm Wrapper
 =pod  =pod
   
 =item * &confirmwrapper($message)  =item confirmwrapper
   
 Wrap messages about completion of operation in box  Wrap messages about completion of operation in box
   
Line 3281  sub aboutmewrapper { Line 3226  sub aboutmewrapper {
     if (!defined($username)  && !defined($domain)) {      if (!defined($username)  && !defined($domain)) {
         return;          return;
     }      }
     return '<a href="/adm/'.$domain.'/'.$username.'/aboutme"'.      return '<a href="/adm/'.$domain.'/'.$username.'/aboutme?forcestudent=1"'.
  ($target?' target="'.$target.'"':'').($class?' class="'.$class.'"':'').' title="'.&mt("View this user's personal information page").'">'.$link.'</a>';   ($target?' target="'.$target.'"':'').($class?' class="'.$class.'"':'').' title="'.&mt("View this user's personal information page").'">'.$link.'</a>';
 }  }
   
Line 4856  sub designparm { Line 4801  sub designparm {
   
 Inputs: $url (usually will be undef).  Inputs: $url (usually will be undef).
   
 Returns: Path to Authoring Space containing the resource or   Returns: Path to Construction Space containing the resource or 
          directory being viewed (or for which action is being taken).            directory being viewed (or for which action is being taken). 
          If $url is provided, and begins /priv/<domain>/<uname>           If $url is provided, and begins /priv/<domain>/<uname>
          the path will be that portion of the $context argument.           the path will be that portion of the $context argument.
Line 4919  Input: (optional) filename from which br Line 4864  Input: (optional) filename from which br
        is appropriate for use in building the breadcrumb trail.         is appropriate for use in building the breadcrumb trail.
   
 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 Construction Space pages
   
 =cut  =cut
   
Line 4934  sub CSTR_pageheader { Line 4879  sub CSTR_pageheader {
   
     my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};      my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
     my ($udom,$uname,$thisdisfn)=      my ($udom,$uname,$thisdisfn)=
         ($trailfile =~ m{^\Q$londocroot\E/priv/([^/]+)/([^/]+)(?:|/(.*))$});          ($trailfile =~ m{^\Q$londocroot\E/priv/([^/]+)/([^/]+)/(.*)$});
     my $formaction = "/priv/$udom/$uname/$thisdisfn";      my $formaction = "/priv/$udom/$uname/$thisdisfn";
     $formaction =~ s{/+}{/}g;      $formaction =~ s{/+}{/}g;
   
Line 4950  sub CSTR_pageheader { Line 4895  sub CSTR_pageheader {
     my $output =      my $output =
          '<div>'           '<div>'
         .&Apache::loncommon::help_open_menu('','',3,'Authoring') #FIXME: Broken? Where is it?          .&Apache::loncommon::help_open_menu('','',3,'Authoring') #FIXME: Broken? Where is it?
         .'<b>'.&mt('Authoring Space:').'</b> '          .'<b>'.&mt('Construction Space:').'</b> '
         .'<form name="dirs" method="post" action="'.$formaction          .'<form name="dirs" method="post" action="'.$formaction
         .'" target="_top">' #FIXME lonpubdir: target="_parent"          .'" target="_top">' #FIXME lonpubdir: target="_parent"
         .&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,'_top','/priv/'.$udom,undef,undef);          .&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,'_top','/priv/'.$udom,undef,undef);
Line 5009  Inputs: Line 4954  Inputs:
   
 =item * $bgcolor, used to override the bgcolor on a webpage to a specific value  =item * $bgcolor, used to override the bgcolor on a webpage to a specific value
   
 =item * $no_inline_link, if true and in remote mode, don't show the  
          'Switch To Inline Menu' link  
   
 =item * $args, optional argument valid values are  =item * $args, optional argument valid values are
             no_auto_mt_title -> prevents &mt()ing the title arg              no_auto_mt_title -> prevents &mt()ing the title arg
             inherit_jsmath -> when creating popup window in a page,              inherit_jsmath -> when creating popup window in a page,
                               should it have jsmath forced on by the                                should it have jsmath forced on by the
                               current page                                current page
   
 =item * $advtoolsref, optional argument, ref to an array containing  
             inlineremote items to be added in "Functions" menu below  
             breadcrumbs.  
   
 =back  =back
   
 Returns: A uniform header for LON-CAPA web pages.    Returns: A uniform header for LON-CAPA web pages.  
Line 5033  other decorations will be returned. Line 4971  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,$no_inline_link,$args,$advtoolsref)=@_;          $no_nav_bar,$bgcolor,$args)=@_;
   
     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 5082  sub bodytag { Line 5020  sub bodytag {
     my $bodytag = "<body $extra_body_attr>".      my $bodytag = "<body $extra_body_attr>".
  &Apache::lontexconvert::init_math_support($args->{'inherit_jsmath'});   &Apache::lontexconvert::init_math_support($args->{'inherit_jsmath'});
   
     &get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['inhibitmenu']);      if ($bodyonly) {
   
     if (($bodyonly) || ($no_nav_bar) || ($env{'form.inhibitmenu'} eq 'yes')) {  
         return $bodytag;          return $bodytag;
     }      } 
   
       my $name = &plainname($env{'user.name'},$env{'user.domain'});
     if ($public) {      if ($public) {
  undef($role);   undef($role);
       } else {
    $name = &aboutmewrapper($name,$env{'user.name'},$env{'user.domain'},
                                   undef,'LC_menubuttons_link');
     }      }
           
     my $titleinfo = '<h1>'.$title.'</h1>';      my $titleinfo = '<h1>'.$title.'</h1>';
Line 5105  sub bodytag { Line 5045  sub bodytag {
     }      }
   
     $role = '<span class="LC_nobreak">('.$role.')</span>' if $role;      $role = '<span class="LC_nobreak">('.$role.')</span>' if $role;
       &get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['inhibitmenu']);
   
     if ($env{'request.state'} eq 'construct') { $forcereg=1; }          if ($no_nav_bar || $env{'form.inhibitmenu'} eq 'yes') { 
               return $bodytag; 
           } 
   
     my $funclist;          if ($env{'request.state'} eq 'construct') { $forcereg=1; }
     if (($env{'environment.remote'} eq 'on') && ($env{'request.state'} ne 'construct')) {  
         $bodytag .= Apache::lonhtmlcommon::scripttag(Apache::lonmenu::utilityfunctions(), 'start')."\n".  
                     Apache::lonmenu::serverform();  
         my $forbodytag;  
         &Apache::lonmenu::prepare_functions($env{'request.noversionuri'},  
                                             $forcereg,$args->{'group'},  
                                             $args->{'bread_crumbs'},  
                                             $advtoolsref,'',\$forbodytag);  
         unless (ref($args->{'bread_crumbs'}) eq 'ARRAY') {  
             $funclist = $forbodytag;  
         }  
     } else {  
   
         #    if ($env{'request.state'} eq 'construct') {          #    if ($env{'request.state'} eq 'construct') {
         #        $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(  
             Apache::lonmenu::utilityfunctions(), 'start');  
   
         my ($left,$right) = Apache::lonmenu::primary_menu();  
   
         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">$name $role<br />
                            <em>$realm</em> $dc_info</div>|;                  <em>$realm</em> $dc_info</div>|;
             return $bodytag;              return $bodytag;
         }          }
   
         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">$name $role</div>|;
         }          }
   
         $bodytag .= $right;          $bodytag .= Apache::lonhtmlcommon::scripttag(
               Apache::lonmenu::utilityfunctions(), 'start');
   
           $bodytag .= Apache::lonmenu::primary_menu();
   
         if ($dc_info) {          if ($dc_info) {
             $dc_info = &dc_courseid_toggle($dc_info);              $dc_info = &dc_courseid_toggle($dc_info);
Line 5162  sub bodytag { Line 5091  sub bodytag {
                 $bodytag .= &Apache::lonmenu::innerregister($forcereg,                  $bodytag .= &Apache::lonmenu::innerregister($forcereg,
                                 $args->{'bread_crumbs'});                                  $args->{'bread_crumbs'});
             } elsif ($forcereg) {               } elsif ($forcereg) { 
                 $bodytag .= &Apache::lonmenu::innerregister($forcereg,undef,                  $bodytag .= &Apache::lonmenu::innerregister($forcereg);
                                                             $args->{'group'});  
             } else {  
                 my $forbodytag;  
                 &Apache::lonmenu::prepare_functions($env{'request.noversionuri'},  
                                                     $forcereg,$args->{'group'},  
                                                     $args->{'bread_crumbs'},  
                                                     $advtoolsref,'',\$forbodytag);  
                 unless (ref($args->{'bread_crumbs'}) eq 'ARRAY') {  
                     $bodytag .= $forbodytag;  
                 }  
             }              }
         }else{          }else{
             # this is to seperate menu from content when there's no secondary              # this is to seperate menu from content when there's no secondary
Line 5182  sub bodytag { Line 5101  sub bodytag {
         }          }
   
         return $bodytag;          return $bodytag;
     }  
   
 #  
 # Top frame rendering, Remote is up  
 #  
   
     my $imgsrc = $img;  
     if ($img =~ /^\/adm/) {  
         $imgsrc = &lonhttpdurl($img);  
     }  
     my $upperleft='<img src="'.$imgsrc.'" alt="'.$function.'" />';  
   
     # Explicit link to get inline menu  
     my $menu= ($no_inline_link?''  
                :'<a href="/adm/remote?action=collapse" target="_top">'.&mt('Switch to Inline Menu Mode').'</a>');  
   
     if ($dc_info) {  
         $dc_info = qq|<span class="LC_cusr_subheading">($dc_info)</span>|;  
     }  
   
     my $name = &plainname($env{'user.name'},$env{'user.domain'});  
     unless ($public) {  
         $name = &aboutmewrapper($name,$env{'user.name'},$env{'user.domain'},  
                                 undef,'LC_menubuttons_link');  
     }  
   
     unless ($env{'form.inhibitmenu'}) {  
         $bodytag .= qq|<div id="LC_nav_bar">$name $role</div>  
                        <ol class="LC_primary_menu LC_floatright LC_right">  
                        <li>$menu</li>  
                        </ol><div id="LC_realm"> $realm $dc_info</div>|;  
     }  
     if ($env{'request.state'} eq 'construct') {  
         if (!$public){  
             if ($env{'request.state'} eq 'construct') {  
                 $funclist = &Apache::lonhtmlcommon::scripttag(  
                                 &Apache::lonmenu::utilityfunctions(), 'start').  
                             &Apache::lonhtmlcommon::scripttag('','end').  
                             &Apache::lonmenu::innerregister($forcereg,  
                                                             $args->{'bread_crumbs'});  
             }  
         }  
     }  
     return $bodytag."\n".$funclist;  
 }  }
   
 sub dc_courseid_toggle {  sub dc_courseid_toggle {
Line 5257  sub make_attr_string { Line 5132  sub make_attr_string {
  delete($attr_ref->{$key});   delete($attr_ref->{$key});
     }      }
  }   }
         if ($env{'environment.remote'} eq 'on') {   $attr_ref->{'onload'}  = $on_load;
             $attr_ref->{'onload'}  =   $attr_ref->{'onunload'}= $on_unload;
                 &Apache::lonmenu::loadevents().  $on_load;  
             $attr_ref->{'onunload'}=  
                 &Apache::lonmenu::unloadevents().$on_unload;  
         } else {    
     $attr_ref->{'onload'}  = $on_load;  
     $attr_ref->{'onunload'}= $on_unload;  
         }  
     }      }
   
     my $attr_string;      my $attr_string;
Line 5400  form, .inline { Line 5268  form, .inline {
   vertical-align:middle;    vertical-align:middle;
 }  }
   
 .LC_floatleft {  
   float: left;  
 }  
   
 .LC_floatright {  
   float: right;  
 }  
   
 .LC_400Box {  .LC_400Box {
   width:400px;    width:400px;
 }  }
Line 5446  form, .inline { Line 5306  form, .inline {
   
 .LC_error {  .LC_error {
   color: red;    color: red;
     font-size: larger;
 }  }
   
 .LC_warning {  .LC_warning,
   color: darkorange;  
 }  
   
 .LC_diff_removed {  .LC_diff_removed {
   color: red;    color: red;
 }  }
Line 5614  td.LC_table_cell_checkbox { Line 5472  td.LC_table_cell_checkbox {
   text-align: left;    text-align: left;
 }  }
   
 .LC_head_subbox, .LC_actionbox {  .LC_head_subbox {
   clear:both;    clear:both;
   background: #F8F8F8; /* $sidebg; */    background: #F8F8F8; /* $sidebg; */
   border: 1px solid $sidebg;    border: 1px solid $sidebg;
   margin: 0 0 10px 0;    margin: 0 0 10px 0;      
   padding: 3px;    padding: 3px;
   text-align: left;    text-align: left;
 }  }
Line 5751  table.LC_nested tr.LC_empty_row td { Line 5609  table.LC_nested tr.LC_empty_row td {
   padding: 8px;    padding: 8px;
 }  }
   
 table.LC_data_table tr.LC_empty_row td,  table.LC_data_table tr.LC_empty_row td {
 table.LC_data_table tr.LC_footer_row td {  
   background-color: $sidebg;    background-color: $sidebg;
 }  }
   
Line 6314  div.LC_docs_entry_move { Line 6171  div.LC_docs_entry_move {
   
 table.LC_data_table tr > td.LC_docs_entry_commands,  table.LC_data_table tr > td.LC_docs_entry_commands,
 table.LC_data_table tr > td.LC_docs_entry_parameter {  table.LC_data_table tr > td.LC_docs_entry_parameter {
     background: #DDDDDD;
   font-size: x-small;    font-size: x-small;
 }  }
   
Line 6478  div.LC_edit_problem_saves { Line 6336  div.LC_edit_problem_saves {
   padding-bottom: 5px;    padding-bottom: 5px;
 }  }
   
 .LC_edit_opt {  
   padding-left: 1em;  
   white-space: nowrap;  
 }  
   
 img.stift {  img.stift {
   border-width: 0;    border-width: 0;
   vertical-align: middle;    vertical-align: middle;
Line 6497  div.LC_createcourse { Line 6350  div.LC_createcourse {
 }  }
   
 .LC_dccid {  .LC_dccid {
   float: right;  
   margin: 0.2em 0 0 0;    margin: 0.2em 0 0 0;
   padding: 0;    padding: 0;
   font-size: 90%;    font-size: 90%;
Line 6595  fieldset > legend { Line 6447  fieldset > legend {
 }  }
   
 ol.LC_primary_menu {  ol.LC_primary_menu {
     float: right;
   margin: 0;    margin: 0;
   padding: 0;    padding: 0;
   background-color: $pgbg_or_bgcolor;    background-color: $pgbg_or_bgcolor;
Line 6691  ol.LC_docs_parameters li.LC_docs_paramet Line 6544  ol.LC_docs_parameters li.LC_docs_paramet
 }  }
   
 ul#LC_secondary_menu {  ul#LC_secondary_menu {
   clear: right;    clear: both;
   color: $fontmenu;    color: $fontmenu;
   background: $tabbg;    background: $tabbg;
   list-style: none;    list-style: none;
Line 6699  ul#LC_secondary_menu { Line 6552  ul#LC_secondary_menu {
   margin: 0;    margin: 0;
   width: 100%;    width: 100%;
   text-align: left;    text-align: left;
   float: left;  
 }  }
   
 ul#LC_secondary_menu li {  ul#LC_secondary_menu li {
   font-weight: bold;    font-weight: bold;
   line-height: 1.8em;    line-height: 1.8em;
   border-right: 1px solid black;  
   vertical-align: middle;  
   float: left;  
 }  
   
 ul#LC_secondary_menu li.LC_hoverable:hover, ul#LC_secondary_menu li.hover {  
   background-color: $data_table_light;  
 }  
   
 ul#LC_secondary_menu li a {  
   padding: 0 0.8em;    padding: 0 0.8em;
 }  
   
 ul#LC_secondary_menu li ul {  
   display: none;  
 }  
   
 ul#LC_secondary_menu li:hover ul, ul#LC_secondary_menu li.hover ul {  
   display: block;  
   position: absolute;  
   margin: 0;  
   padding: 0;  
   list-style:none;  
   float: none;  
   background-color: $data_table_light;  
   z-index: 2;  
   margin-left: -1px;  
 }  
   
 ul#LC_secondary_menu li ul li {  
   font-size: 90%;  
   vertical-align: top;  
   border-left: 1px solid black;  
   border-right: 1px solid black;    border-right: 1px solid black;
   background-color: $data_table_light;    display: inline;
   list-style:none;    vertical-align: middle;
   float: none;  
 }  
   
 ul#LC_secondary_menu li ul li:hover, ul#LC_secondary_menu li ul li.hover {  
   background-color: $data_table_dark;  
 }  }
   
 ul.LC_TabContent {  ul.LC_TabContent {
Line 7192  ul.LC_funclist li { Line 7007  ul.LC_funclist li {
  cursor:pointer;   cursor:pointer;
 }  }
   
 /*  
   styles used by TTH when "Default set of options to pass to tth/m  
   when converting TeX" in course settings has been set  
   
   option passed: -t  
   
 */  
   
 td div.comp { margin-top: -0.6ex; margin-bottom: -1ex;}  
 td div.comb { margin-top: -0.6ex; margin-bottom: -.6ex;}  
 td div.hrcomp { line-height: 0.9; margin-top: -0.8ex; margin-bottom: -1ex;}  
 td div.norm {line-height:normal;}  
   
 /*  
   option passed -y3  
 */  
   
 span.roman {font-family: serif; font-style: normal; font-weight: normal;}  
 span.overacc2 {position: relative;  left: .8em; top: -1.2ex;}  
 span.overacc1 {position: relative;  left: .6em; top: -1.2ex;}  
   
 END  END
 }  }
   
Line 7266  sub headtag { Line 7060  sub headtag {
     if (!$args->{'frameset'}) {      if (!$args->{'frameset'}) {
  $result .= &Apache::lonhtmlcommon::htmlareaheaders();   $result .= &Apache::lonhtmlcommon::htmlareaheaders();
     }      }
     if ($args->{'force_register'}) {      if ($args->{'force_register'} && $env{'request.noversionuri'} !~ m{^/res/adm/pages/}) {
         $result .= &Apache::lonmenu::registerurl(1);          $result .= Apache::lonxml::display_title();
     }      }
     if (!$args->{'no_nav_bar'}       if (!$args->{'no_nav_bar'} 
  && !$args->{'only_body'}   && !$args->{'only_body'}
Line 7310  ADDMETA Line 7104  ADDMETA
  .'<link rel="stylesheet" type="text/css" href="'.$url.'" />'   .'<link rel="stylesheet" type="text/css" href="'.$url.'" />'
         .$inhibitprint          .$inhibitprint
  .$head_extra;   .$head_extra;
     if ($env{'browser.mobile'}) {  
         $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="apple-mobile-web-app-capable" content="yes" />';  
     }  
     return $result.'</head>';      return $result.'</head>';
 }  }
   
Line 7481  $args - additional optional args support Line 7270  $args - additional optional args support
              skip_phases    -> hash ref of                skip_phases    -> hash ref of 
                                     head -> skip the <html><head> generation                                      head -> skip the <html><head> generation
                                     body -> skip all <body> generation                                      body -> skip all <body> generation
              no_inline_link -> if true and in remote mode, don't show the  
                                     'Switch To Inline Menu' link  
              no_auto_mt_title -> prevent &mt()ing the title arg               no_auto_mt_title -> prevent &mt()ing the title arg
              inherit_jsmath -> when creating popup window in a page,               inherit_jsmath -> when creating popup window in a page,
                                     should it have jsmath forced on by the                                      should it have jsmath forced on by the
                                     current page                                      current page
              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
              group          -> includes the current group, if page is for a  
                                specific group  
   
 =back  =back
   
Line 7503  sub start_page { Line 7288  sub start_page {
     #&Apache::lonnet::logthis("start_page ".join(':',caller(0)));      #&Apache::lonnet::logthis("start_page ".join(':',caller(0)));
   
     $env{'internal.start_page'}++;      $env{'internal.start_page'}++;
     my ($result,@advtools);      my $result;
   
     if (! exists($args->{'skip_phases'}{'head'}) ) {      if (! exists($args->{'skip_phases'}{'head'}) ) {
         $result .= &xml_begin() . &headtag($title, $head_extra, $args);          $result .= &xml_begin() . &headtag($title, $head_extra, $args);
Line 7520  sub start_page { Line 7305  sub start_page {
                          $args->{'function'},       $args->{'add_entries'},                           $args->{'function'},       $args->{'add_entries'},
                          $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->{'no_inline_link'},                           $args->{'bgcolor'},        $args);
                          $args,                     \@advtools);  
         }          }
     }      }
   
Line 7550  sub start_page { Line 7334  sub start_page {
  &Apache::lonhtmlcommon::add_breadcrumb($crumb);   &Apache::lonhtmlcommon::add_breadcrumb($crumb);
  }   }
  }   }
                 # if @advtools array contains items add then to the breadcrumbs  
                 if (@advtools > 0) {  
                     &Apache::lonmenu::advtools_crumbs(@advtools);  
                 }  
   
  #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'})){
Line 7561  sub start_page { Line 7341  sub start_page {
  }else{   }else{
  $result .= &Apache::lonhtmlcommon::breadcrumbs();   $result .= &Apache::lonhtmlcommon::breadcrumbs();
  }   }
     } elsif (($env{'environment.remote'} eq 'on') &&  
              ($env{'form.inhibitmenu'} ne 'yes') &&  
              ($env{'request.noversionuri'} =~ m{^/res/}) &&  
              ($env{'request.noversionuri'} !~ m{^/res/adm/pages/})) {  
         $result .= '<div style="padding:0;margin:0;clear:both"><hr /></div>';  
     }      }
     return $result;      return $result;
 }  }
Line 7655  var modalWindow = { Line 7430  var modalWindow = {
  $(".LCmodal-overlay").click(function(){modalWindow.close();});   $(".LCmodal-overlay").click(function(){modalWindow.close();});
  }   }
 };  };
  var openMyModal = function(source,width,height,scrolling,transparency,style)   var openMyModal = function(source,width,height,scrolling)
  {   {
  modalWindow.windowId = "myModal";   modalWindow.windowId = "myModal";
  modalWindow.width = width;   modalWindow.width = width;
  modalWindow.height = height;   modalWindow.height = height;
  modalWindow.content = "<iframe width='"+width+"' height='"+height+"' frameborder='0' scrolling='"+scrolling+"' allowtransparency='"+transparency+"' src='" + source + "' style='"+style+"'>&lt/iframe>";   modalWindow.content = "<iframe width='"+width+"' height='"+height+"' frameborder='0' scrolling='"+scrolling+"' allowtransparency='true' src='" + source + "'>&lt/iframe>";
  modalWindow.open();   modalWindow.open();
  };   };
 // END LON-CAPA Internal -->  // END LON-CAPA Internal -->
Line 7670  ENDMODAL Line 7445  ENDMODAL
 }  }
   
 sub modal_link {  sub modal_link {
     my ($link,$linktext,$width,$height,$target,$scrolling,$title,$transparency,$style)=@_;      my ($link,$linktext,$width,$height,$target,$scrolling,$title)=@_;
     unless ($width) { $width=480; }      unless ($width) { $width=480; }
     unless ($height) { $height=400; }      unless ($height) { $height=400; }
     unless ($scrolling) { $scrolling='yes'; }      unless ($scrolling) { $scrolling='yes'; }
     unless ($transparency) { $transparency='true'; }  
   
     my $target_attr;      my $target_attr;
     if (defined($target)) {      if (defined($target)) {
         $target_attr = 'target="'.$target.'"';          $target_attr = 'target="'.$target.'"';
     }      }
     return <<"ENDLINK";      return <<"ENDLINK";
 <a href="$link" $target_attr title="$title" onclick="javascript:openMyModal('$link',$width,$height,'$scrolling','$transparency','$style'); return false;">  <a href="$link" $target_attr title="$title" onclick="javascript:openMyModal('$link',$width,$height,'$scrolling'); return false;">
            $linktext</a>             $linktext</a>
 ENDLINK  ENDLINK
 }  }
Line 7709  sub modal_adhoc_inner { Line 7482  sub modal_adhoc_inner {
     my $innerwidth=$width-20;      my $innerwidth=$width-20;
     $content=&js_ready(      $content=&js_ready(
                &start_page('Dialog',undef,{'only_body'=>1,'bgcolor'=>'#FFFFFF'}).                 &start_page('Dialog',undef,{'only_body'=>1,'bgcolor'=>'#FFFFFF'}).
                  &start_scrollbox($width.'px',$innerwidth.'px',$height.'px','myModal','#FFFFFF',undef,1).                   &start_scrollbox($width.'px',$innerwidth.'px',$height.'px').
                  $content.                      $content.
                  &end_scrollbox().                   &end_scrollbox().
                  &end_page()                 &end_page()
              );               );
     return &modal_adhoc_script($funcname,$width,$height,$content);      return &modal_adhoc_script($funcname,$width,$height,$content);
 }  }
Line 7831  sub LCprogressbar { Line 7604  sub LCprogressbar {
     $LCcurrentid=$$.'_'.$LCidcnt;      $LCcurrentid=$$.'_'.$LCidcnt;
     my $starting=&mt('Starting');      my $starting=&mt('Starting');
     my $content=(<<ENDPROGBAR);      my $content=(<<ENDPROGBAR);
   <p>
   <div id="progressbar$LCcurrentid">    <div id="progressbar$LCcurrentid">
     <span class="pblabel">$starting</span>      <span class="pblabel">$starting</span>
   </div>    </div>
   </p>
 ENDPROGBAR  ENDPROGBAR
     &r_print($r,$content.&LCprogressbar_script($LCcurrentid));      &r_print($r,$content.&LCprogressbar_script($LCcurrentid));
 }  }
Line 7929  sub validate_page { Line 7704  sub validate_page {
   
   
 sub start_scrollbox {  sub start_scrollbox {
     my ($outerwidth,$width,$height,$id,$bgcolor,$cursor,$needjsready)=@_;      my ($outerwidth,$width,$height,$id,$bgcolor)=@_;
     unless ($outerwidth) { $outerwidth='520px'; }      unless ($outerwidth) { $outerwidth='520px'; }
     unless ($width) { $width='500px'; }      unless ($width) { $width='500px'; }
     unless ($height) { $height='200px'; }      unless ($height) { $height='200px'; }
     my ($table_id,$div_id,$tdcol);      my ($table_id,$div_id,$tdcol);
     if ($id ne '') {      if ($id ne '') {
         $table_id = ' id="table_'.$id.'"';          $table_id = " id='table_$id'";
         $div_id = ' id="div_'.$id.'"';          $div_id = " id='div_$id'";
     }      }
     if ($bgcolor ne '') {      if ($bgcolor ne '') {
         $tdcol = "background-color: $bgcolor;";          $tdcol = "background-color: $bgcolor;";
     }      }
     my $nicescroll_js;  
     if ($env{'browser.mobile'}) {  
         $nicescroll_js = &nicescroll_javascript('div_'.$id,$cursor,$needjsready);  
     }  
     return <<"END";      return <<"END";
 $nicescroll_js  <table style="width: $outerwidth; border: 1px solid none;"$table_id><tr><td style="width: $width;$tdcol"><div style="overflow:auto; width:$width; height: $height;"$div_id>
   
 <table style="width: $outerwidth; border: 1px solid none;"$table_id><tr><td style="width: $width;$tdcol">  
 <div style="overflow:auto; width:$width; height: $height;"$div_id>  
 END  END
 }  }
   
Line 7957  sub end_scrollbox { Line 7725  sub end_scrollbox {
     return '</div></td></tr></table>';      return '</div></td></tr></table>';
 }  }
   
 sub nicescroll_javascript {  
     my ($id,$cursor,$needjsready,$framecheck,$location) = @_;  
     my %options;  
     if (ref($cursor) eq 'HASH') {  
         %options = %{$cursor};  
     }  
     unless ($options{'railalign'} =~ /^left|right$/) {  
         $options{'railalign'} = 'left';  
     }  
     unless ($options{'cursorcolor'} =~ /^\#\w+$/) {  
         my $function  = &get_users_function();  
         $options{'cursorcolor'} = &designparm($function.'.sidebg',$env{'request.role.domain'});  
         unless ($options{'cursorcolor'} =~ /^\#\w+$/) {  
             $options{'cursorcolor'} = '#00F';  
         }  
     }  
     if ($options{'cursoropacity'} =~ /^[\d.]+$/) {  
         unless ($options{'cursoropacity'} >= 0.0 && $options{'cursoropacity'} <=1.0) {  
             $options{'cursoropacity'}='1.0';  
         }  
     } else {  
         $options{'cursoropacity'}='1.0';  
     }  
     if ($options{'cursorfixedheight'} eq 'none') {  
         delete($options{'cursorfixedheight'});  
     } else {  
         unless ($options{'cursorfixedheight'} =~ /^\d+$/) { $options{'cursorfixedheight'}='50'; }  
     }  
     unless ($options{'railoffset'} =~ /^{[\w\:\d\-,]+}$/) {  
         delete($options{'railoffset'});  
     }  
     my @niceoptions;  
     while (my($key,$value) = each(%options)) {  
         if ($value =~ /^\{.+\}$/) {  
             push(@niceoptions,$key.':'.$value);  
         } else {  
             push(@niceoptions,$key.':"'.$value.'"');  
         }  
     }  
     my $nicescroll_js = '  
 $(document).ready(  
       function() {  
           $("#'.$id.'").niceScroll({'.join(',',@niceoptions).'});  
       }  
 );  
 ';  
     if ($framecheck) {  
         $nicescroll_js .= '  
 function expand_div(caller) {  
     if (top === self) {  
         document.getElementById("'.$id.'").style.width = "auto";  
         document.getElementById("'.$id.'").style.height = "auto";  
     } else {  
         try {  
             if (parent.frames) {  
                 if (parent.frames.length > 1) {  
                     var framesrc = parent.frames[1].location.href;  
                     var currsrc = framesrc.replace(/\#.*$/,"");  
                     if ((caller == "search") || (currsrc == "'.$location.'")) {  
                         document.getElementById("'.$id.'").style.width = "auto";  
                         document.getElementById("'.$id.'").style.height = "auto";  
                     }  
                 }  
             }  
         } catch (e) {  
             return;  
         }  
     }  
     return;  
 }  
 ';  
     }  
     if ($needjsready) {  
         $nicescroll_js = '  
 <script type="text/javascript">'."\n".$nicescroll_js."\n</script>\n";  
     } else {  
         $nicescroll_js = &Apache::lonhtmlcommon::scripttag($nicescroll_js);  
     }  
     return $nicescroll_js;  
 }  
   
 sub simple_error_page {  sub simple_error_page {
     my ($r,$title,$msg,$args) = @_;      my ($r,$title,$msg) = @_;
     if (ref($args) eq 'HASH') {  
         if (!$args->{'no_auto_mt_msg'}) { $msg = &mt($msg); }  
     } else {  
         $msg = &mt($msg);  
     }  
   
     my $page =      my $page =
  &Apache::loncommon::start_page($title).   &Apache::loncommon::start_page($title).
  '<p class="LC_error">'.$msg.'</p>'.   &mt($msg).
  &Apache::loncommon::end_page();   &Apache::loncommon::end_page();
     if (ref($r)) {      if (ref($r)) {
  $r->print($page);   $r->print($page);
Line 8341  sub get_sections { Line 8022  sub get_sections {
     my %sectioncount;      my %sectioncount;
     my $now = time;      my $now = time;
   
     my $check_students = 1;      if (!defined($possible_roles) || (grep(/^st$/,@$possible_roles))) {
     my $only_students = 0;  
     if (ref($possible_roles) eq 'ARRAY') {  
         if (grep(/^st$/,@{$possible_roles})) {  
             if (@{$possible_roles} == 1) {  
                 $only_students = 1;  
             }  
         } else {  
             $check_students = 0;  
         }  
     }  
   
     if ($check_students) {  
  my ($classlist) = &Apache::loncoursedata::get_classlist($cdom,$cnum);   my ($classlist) = &Apache::loncoursedata::get_classlist($cdom,$cnum);
  my $sec_index = &Apache::loncoursedata::CL_SECTION();   my $sec_index = &Apache::loncoursedata::CL_SECTION();
  my $status_index = &Apache::loncoursedata::CL_STATUS();   my $status_index = &Apache::loncoursedata::CL_STATUS();
Line 8380  sub get_sections { Line 8049  sub get_sections {
     }      }
  }   }
     }      }
     if ($only_students) {  
         return %sectioncount;  
     }  
     my %courseroles = &Apache::lonnet::dump('nohist_userroles',$cdom,$cnum);      my %courseroles = &Apache::lonnet::dump('nohist_userroles',$cdom,$cnum);
     foreach my $user (sort(keys(%courseroles))) {      foreach my $user (sort(keys(%courseroles))) {
  if ($user !~ /^(\w{2})/) { next; }   if ($user !~ /^(\w{2})/) { next; }
Line 8530  sub get_course_users { Line 8196  sub get_course_users {
                               active   => 'Active',                                active   => 'Active',
                               future   => 'Future',                                future   => 'Future',
                             );                              );
         my (%nothide,@possdoms);          my %nothide;
         if ($hidepriv) {          if ($hidepriv) {
             my %coursehash=&Apache::lonnet::coursedescription($cdom.'_'.$cnum);              my %coursehash=&Apache::lonnet::coursedescription($cdom.'_'.$cnum);
             foreach my $user (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) {              foreach my $user (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) {
Line 8540  sub get_course_users { Line 8206  sub get_course_users {
                     $nothide{$user} = 1;                      $nothide{$user} = 1;
                 }                  }
             }              }
             my @possdoms = ($cdom);  
             if ($coursehash{'checkforpriv'}) {  
                 push(@possdoms,split(/,/,$coursehash{'checkforpriv'}));  
             }  
         }          }
         foreach my $person (sort(keys(%coursepersonnel))) {          foreach my $person (sort(keys(%coursepersonnel))) {
             my $match = 0;              my $match = 0;
Line 8579  sub get_course_users { Line 8241  sub get_course_users {
                 }                  }
                 if ($uname ne '' && $udom ne '') {                  if ($uname ne '' && $udom ne '') {
                     if ($hidepriv) {                      if ($hidepriv) {
                         if ((&Apache::lonnet::privileged($uname,$udom,\@possdoms)) &&                          if ((&Apache::lonnet::privileged($uname,$udom)) &&
                             (!$nothide{$uname.':'.$udom})) {                              (!$nothide{$uname.':'.$udom})) {
                             next;                              next;
                         }                          }
Line 8667  sub get_user_info { Line 8329  sub get_user_info {
   
 =item * &get_user_quota()  =item * &get_user_quota()
   
 Retrieves quota assigned for storage of user files.  Retrieves quota assigned for storage of portfolio files for a user  
 Default is to report quota for portfolio files.  
   
 Incoming parameters:  Incoming parameters:
 1. user's username  1. user's username
 2. user's domain  2. user's domain
 3. quota name - portfolio, author, or course  
    (if no quota name provided, defaults to portfolio).  
 4. crstype - official, unofficial or community, if quota name is  
    course  
   
 Returns:  Returns:
 1. Disk quota (in Mb) assigned to student.  1. Disk quota (in Mb) assigned to student.
Line 8690  Returns: Line 8347  Returns:
   
 If a value has been stored in the user's environment,   If a value has been stored in the user's environment, 
 it will return that, otherwise it returns the maximal default  it will return that, otherwise it returns the maximal default
 defined for the user's institutional status(es) in the domain.  defined for the user's instituional status(es) in the domain.
   
 =cut  =cut
   
Line 8698  defined for the user's institutional sta Line 8355  defined for the user's institutional sta
   
   
 sub get_user_quota {  sub get_user_quota {
     my ($uname,$udom,$quotaname,$crstype) = @_;      my ($uname,$udom) = @_;
     my ($quota,$quotatype,$settingstatus,$defquota);      my ($quota,$quotatype,$settingstatus,$defquota);
     if (!defined($udom)) {      if (!defined($udom)) {
         $udom = $env{'user.domain'};          $udom = $env{'user.domain'};
Line 8713  sub get_user_quota { Line 8370  sub get_user_quota {
         $defquota = 0;           $defquota = 0; 
     } else {      } else {
         my $inststatus;          my $inststatus;
         if ($quotaname eq 'course') {          if ($udom eq $env{'user.domain'} && $uname eq $env{'user.name'}) {
             if (($env{'course.'.$udom.'_'.$uname.'.num'} eq $uname) &&              $quota = $env{'environment.portfolioquota'};
                 ($env{'course.'.$udom.'_'.$uname.'.domain'} eq $udom)) {              $inststatus = $env{'environment.inststatus'};
                 $quota = $env{'course.'.$udom.'_'.$uname.'.internal.uploadquota'};          } else {
             } else {              my %userenv = 
                 my %cenv = &Apache::lonnet::coursedescription("$udom/$uname");                  &Apache::lonnet::get('environment',['portfolioquota',
                 $quota = $cenv{'internal.uploadquota'};                                       'inststatus'],$udom,$uname);
             }              my ($tmp) = keys(%userenv);
               if ($tmp !~ /^(con_lost|error|no_such_host)/i) {
                   $quota = $userenv{'portfolioquota'};
                   $inststatus = $userenv{'inststatus'};
               } else {
                   undef(%userenv);
               }
           }
           ($defquota,$settingstatus) = &default_quota($udom,$inststatus);
           if ($quota eq '') {
               $quota = $defquota;
               $quotatype = 'default';
         } else {          } else {
             if ($udom eq $env{'user.domain'} && $uname eq $env{'user.name'}) {              $quotatype = 'custom';
                 if ($quotaname eq 'author') {  
                     $quota = $env{'environment.authorquota'};  
                 } else {  
                     $quota = $env{'environment.portfolioquota'};  
                 }  
                 $inststatus = $env{'environment.inststatus'};  
             } else {  
                 my %userenv =   
                     &Apache::lonnet::get('environment',['portfolioquota',  
                                          'authorquota','inststatus'],$udom,$uname);  
                 my ($tmp) = keys(%userenv);  
                 if ($tmp !~ /^(con_lost|error|no_such_host)/i) {  
                     if ($quotaname eq 'author') {  
                         $quota = $userenv{'authorquota'};  
                     } else {  
                         $quota = $userenv{'portfolioquota'};  
                     }  
                     $inststatus = $userenv{'inststatus'};  
                 } else {  
                     undef(%userenv);  
                 }  
             }  
         }  
         if ($quota eq '' || wantarray) {  
             if ($quotaname eq 'course') {  
                 my %domdefs = &Apache::lonnet::get_domain_defaults($udom);  
                 if (($crstype eq 'official') || ($crstype eq 'unofficial') || ($crstype eq 'community')) {  
                     $defquota = $domdefs{$crstype.'quota'};  
                 }  
                 if ($defquota eq '') {  
                     $defquota = 500;  
                 }  
             } else {  
                 ($defquota,$settingstatus) = &default_quota($udom,$inststatus,$quotaname);  
             }  
             if ($quota eq '') {  
                 $quota = $defquota;  
                 $quotatype = 'default';  
             } else {  
                 $quotatype = 'custom';  
             }  
         }          }
     }      }
     if (wantarray) {      if (wantarray) {
Line 8783  Retrieves default quota assigned for sto Line 8410  Retrieves default quota assigned for sto
 given an (optional) user's institutional status.  given an (optional) user's institutional status.
   
 Incoming parameters:  Incoming parameters:
   
 1. domain  1. domain
 2. (Optional) institutional status(es).  This is a : separated list of   2. (Optional) institutional status(es).  This is a : separated list of 
    status types (e.g., faculty, staff, student etc.)     status types (e.g., faculty, staff, student etc.)
    which apply to the user for whom the default is being retrieved.     which apply to the user for whom the default is being retrieved.
    If the institutional status string in undefined, the domain     If the institutional status string in undefined, the domain
    default quota will be returned.     default quota will be returned. 
 3.  quota name - portfolio, author, or course  
    (if no quota name provided, defaults to portfolio).  
   
 Returns:  Returns:
   
 1. Default disk quota (in Mb) for user portfolios in the domain.  1. Default disk quota (in Mb) for user portfolios in the domain.
 2. (Optional) institutional type which determined the value of the  2. (Optional) institutional type which determined the value of the
    default quota.     default quota.
Line 8808  If the user's status includes multiple t Line 8431  If the user's status includes multiple t
 the largest default quota which applies to the user determines the  the largest default quota which applies to the user determines the
 default quota returned.  default quota returned.
   
   =back
   
 =cut  =cut
   
 ###############################################  ###############################################
   
   
 sub default_quota {  sub default_quota {
     my ($udom,$inststatus,$quotaname) = @_;      my ($udom,$inststatus) = @_;
     my ($defquota,$settingstatus);      my ($defquota,$settingstatus);
     my %quotahash = &Apache::lonnet::get_dom('configuration',      my %quotahash = &Apache::lonnet::get_dom('configuration',
                                             ['quotas'],$udom);                                              ['quotas'],$udom);
     my $key = 'defaultquota';  
     if ($quotaname eq 'author') {  
         $key = 'authorquota';  
     }  
     if (ref($quotahash{'quotas'}) eq 'HASH') {      if (ref($quotahash{'quotas'}) eq 'HASH') {
         if ($inststatus ne '') {          if ($inststatus ne '') {
             my @statuses = map { &unescape($_); } split(/:/,$inststatus);              my @statuses = map { &unescape($_); } split(/:/,$inststatus);
             foreach my $item (@statuses) {              foreach my $item (@statuses) {
                 if (ref($quotahash{'quotas'}{$key}) eq 'HASH') {                  if (ref($quotahash{'quotas'}{'defaultquota'}) eq 'HASH') {
                     if ($quotahash{'quotas'}{$key}{$item} ne '') {                      if ($quotahash{'quotas'}{'defaultquota'}{$item} ne '') {
                         if ($defquota eq '') {                          if ($defquota eq '') {
                             $defquota = $quotahash{'quotas'}{$key}{$item};                              $defquota = $quotahash{'quotas'}{'defaultquota'}{$item};
                             $settingstatus = $item;                              $settingstatus = $item;
                         } elsif ($quotahash{'quotas'}{$key}{$item} > $defquota) {                          } elsif ($quotahash{'quotas'}{'defaultquota'}{$item} > $defquota) {
                             $defquota = $quotahash{'quotas'}{$key}{$item};                              $defquota = $quotahash{'quotas'}{'defaultquota'}{$item};
                             $settingstatus = $item;                              $settingstatus = $item;
                         }                          }
                     }                      }
                 } elsif ($key eq 'defaultquota') {                  } else {
                     if ($quotahash{'quotas'}{$item} ne '') {                      if ($quotahash{'quotas'}{$item} ne '') {
                         if ($defquota eq '') {                          if ($defquota eq '') {
                             $defquota = $quotahash{'quotas'}{$item};                              $defquota = $quotahash{'quotas'}{$item};
Line 8850  sub default_quota { Line 8471  sub default_quota {
             }              }
         }          }
         if ($defquota eq '') {          if ($defquota eq '') {
             if (ref($quotahash{'quotas'}{$key}) eq 'HASH') {              if (ref($quotahash{'quotas'}{'defaultquota'}) eq 'HASH') {
                 $defquota = $quotahash{'quotas'}{$key}{'default'};                  $defquota = $quotahash{'quotas'}{'defaultquota'}{'default'};
             } elsif ($key eq 'defaultquota') {              } else {
                 $defquota = $quotahash{'quotas'}{'default'};                  $defquota = $quotahash{'quotas'}{'default'};
             }              }
             $settingstatus = 'default';              $settingstatus = 'default';
             if ($defquota eq '') {  
                 if ($quotaname eq 'author') {  
                     $defquota = 500;  
                 }  
             }  
         }          }
     } else {      } else {
         $settingstatus = 'default';          $settingstatus = 'default';
         if ($quotaname eq 'author') {          $defquota = 20;
             $defquota = 500;  
         } else {  
             $defquota = 20;  
         }  
     }      }
     if (wantarray) {      if (wantarray) {
         return ($defquota,$settingstatus);          return ($defquota,$settingstatus);
Line 8877  sub default_quota { Line 8489  sub default_quota {
     }      }
 }  }
   
 ###############################################  
   
 =pod  
   
 =item * &excess_filesize_warning()  
   
 Returns warning message if upload of file to authoring space, or copying  
 of existing file within authoring space will cause quota for the authoring  
 space to be exceeded.  
   
 Same, if upload of a file directly to a course/community via Course Editor  
 will cause quota for uploaded content for the course to be exceeded.  
   
 Inputs: 6  
 1. username or coursenum  
 2. domain  
 3. context ('author' or 'course')  
 4. filename of file for which action is being requested  
 5. filesize (kB) of file  
 6. action being taken: copy or upload.  
   
 Returns: 1 scalar: HTML to display containing warning if quota would be exceeded,  
          otherwise return null.  
   
 =back  
   
 =cut  
   
 sub excess_filesize_warning {  
     my ($uname,$udom,$context,$filename,$filesize,$action) = @_;  
     my $current_disk_usage = 0;  
     my $disk_quota = &get_user_quota($uname,$udom,$context); #expressed in MB  
     if ($context eq 'author') {  
         my $authorspace = $Apache::lonnet::perlvar{'lonDocRoot'}."/priv/$udom/$uname";  
         $current_disk_usage = &Apache::lonnet::diskusage($udom,$uname,$authorspace);  
     } else {  
         foreach my $subdir ('docs','supplemental') {  
             $current_disk_usage += &Apache::lonnet::diskusage($udom,$uname,"userfiles/$subdir",1);  
         }  
     }  
     $disk_quota = int($disk_quota * 1000);  
     if (($current_disk_usage + $filesize) > $disk_quota) {  
         return '<p><span class="LC_warning">'.  
                 &mt("Unable to $action [_1]. (size = [_2] kilobytes). Disk quota will be exceeded.",  
                     '<span class="LC_filename">'.$filename.'</span>',$filesize).'</span>'.  
                '<br />'.&mt('Disk quota is [_1] kilobytes. Your current disk usage is [_2] kilobytes.',  
                             $disk_quota,$current_disk_usage).  
                '</p>';  
     }  
     return;  
 }  
   
 ###############################################  
   
   
 sub get_secgrprole_info {  sub get_secgrprole_info {
     my ($cdom,$cnum,$needroles,$type)  = @_;      my ($cdom,$cnum,$needroles,$type)  = @_;
     my %sections_count = &get_sections($cdom,$cnum);      my %sections_count = &get_sections($cdom,$cnum);
Line 9289  sub user_rule_formats { Line 8846  sub user_rule_formats {
     my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($domain,$check);      my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($domain,$check);
     if ((ref($rules) eq 'HASH') && (ref($ruleorder) eq 'ARRAY')) {      if ((ref($rules) eq 'HASH') && (ref($ruleorder) eq 'ARRAY')) {
         if (@{$ruleorder} > 0) {          if (@{$ruleorder} > 0) {
             $output = '<br />'.              $output = '<br />'.&mt("$text{$check} with the following format(s) may <span class=\"LC_cusr_emph\">only</span> be used for verified users at [_1]:",$domdesc).' <ul>';
                       &mt($text{$check}.' with the following format(s) may [_1]only[_2] be used for verified users at [_3]:',  
                           '<span class="LC_cusr_emph">','</span>',$domdesc).  
                       ' <ul>';  
             foreach my $rule (@{$ruleorder}) {              foreach my $rule (@{$ruleorder}) {
                 if (ref($curr_rules) eq 'ARRAY') {                  if (ref($curr_rules) eq 'ARRAY') {
                     if (grep(/^\Q$rule\E$/,@{$curr_rules})) {                      if (grep(/^\Q$rule\E$/,@{$curr_rules})) {
Line 9775  sub ask_for_embedded_content { Line 9329  sub ask_for_embedded_content {
     my $heading = &mt('Upload embedded files');      my $heading = &mt('Upload embedded files');
     my $buttontext = &mt('Upload');      my $buttontext = &mt('Upload');
   
     my ($navmap,$cdom,$cnum);      my $navmap;
     if ($env{'request.course.id'}) {      if ($env{'request.course.id'}) {
         if ($actionurl eq '/adm/dependencies') {          $navmap = Apache::lonnavmaps::navmap->new();
             $navmap = Apache::lonnavmaps::navmap->new();  
         }  
         $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};  
         $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};  
     }      }
     if (($actionurl eq '/adm/portfolio') ||      if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {
         ($actionurl eq '/adm/coursegrp_portfolio')) {  
         my $current_path='/';          my $current_path='/';
         if ($env{'form.currentpath'}) {          if ($env{'form.currentpath'}) {
             $current_path = $env{'form.currentpath'};              $current_path = $env{'form.currentpath'};
         }          }
         if ($actionurl eq '/adm/coursegrp_portfolio') {          if ($actionurl eq '/adm/coursegrp_portfolio') {
             $udom = $cdom;              $udom = $env{'course.'.$env{'request.course.id'}.'.domain'};
             $uname = $cnum;              $uname = $env{'course.'.$env{'request.course.id'}.'.num'};
             $url = '/userfiles/groups/'.$env{'form.group'}.'/portfolio';              $url = '/userfiles/groups/'.$env{'form.group'}.'/portfolio';
         } else {          } else {
             $udom = $env{'user.domain'};              $udom = $env{'user.domain'};
Line 9815  sub ask_for_embedded_content { Line 9364  sub ask_for_embedded_content {
             $toplevel = $url;              $toplevel = $url;
             if ($args->{'context'} eq 'paste') {              if ($args->{'context'} eq 'paste') {
                 ($cdom,$cnum) = ($url =~ m{^\Q/uploaded/\E($match_domain)/($match_courseid)/});                  ($cdom,$cnum) = ($url =~ m{^\Q/uploaded/\E($match_domain)/($match_courseid)/});
                 ($path) =                  ($path) = 
                     ($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/\E(?:docs|supplemental)/(?:default|\d+)/\d+)/});                      ($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/\E(?:docs|supplemental)/(?:default|\d+)/\d+)/});
                 $fileloc = &Apache::lonnet::filelocation('',$toplevel);                  $fileloc = &Apache::lonnet::filelocation('',$toplevel);
                 $fileloc =~ s{^/}{};                  $fileloc =~ s{^/}{};
             }              }
         }          }
     } elsif ($actionurl eq '/adm/dependencies') {      } elsif ($actionurl eq '/adm/dependencies')  {
         if ($env{'request.course.id'} ne '') {          if ($env{'request.course.id'} ne '') {
               $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
               $cnum =  $env{'course.'.$env{'request.course.id'}.'.num'};
             if (ref($args) eq 'HASH') {              if (ref($args) eq 'HASH') {
                 $url = $args->{'docs_url'};                  $url = $args->{'docs_url'};
                 $title = $args->{'docs_title'};                  $title = $args->{'docs_title'};
                 $toplevel = $url;                  $toplevel = "/$url";
                 unless ($toplevel =~ m{^/}) {  
                     $toplevel = "/$url";  
                 }  
                 ($rem) = ($toplevel =~ m{^(.+/)[^/]+$});                  ($rem) = ($toplevel =~ m{^(.+/)[^/]+$});
                 if ($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/portfolio/syllabus\E)}) {                  ($path) =  
                     $path = $1;                      ($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/\E(?:docs|supplemental)/(?:default|\d+)/\d+)/});
                 } else {  
                     ($path) =  
                         ($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/\E(?:docs|supplemental)/(?:default|\d+)/\d+)/});  
                 }  
                 $fileloc = &Apache::lonnet::filelocation('',$toplevel);                  $fileloc = &Apache::lonnet::filelocation('',$toplevel);
                 $fileloc =~ s{^/}{};                  $fileloc =~ s{^/}{};
                 ($filename) = ($fileloc =~ m{.+/([^/]+)$});                  ($filename) = ($fileloc =~ m{.+/([^/]+)$});
                 $heading = &mt('Status of dependencies in [_1]',"$title ($filename)");                  $heading = &mt('Status of dependencies in [_1]',"$title ($filename)");
             }              }
         }          }
     } elsif ($actionurl eq "/public/$cdom/$cnum/syllabus") {      }
         $udom = $cdom;      my $now = time();
         $uname = $cnum;      foreach my $embed_file (keys(%{$allfiles})) {
         $url = "/uploaded/$cdom/$cnum/portfolio/syllabus";  
         $toplevel = $url;  
         $path = $url;  
         $fileloc = &Apache::lonnet::filelocation('',$toplevel).'/';  
         $fileloc =~ s{^/}{};  
     }  
     foreach my $file (keys(%{$allfiles})) {  
         my $embed_file;  
         if (($path eq "/uploaded/$cdom/$cnum/portfolio/syllabus") && ($file =~ m{^\Q$path/\E(.+)$})) {  
             $embed_file = $1;  
         } else {  
             $embed_file = $file;  
         }  
         my $absolutepath;          my $absolutepath;
         my $cleaned_file = &clean_path($embed_file);          if ($embed_file =~ m{^\w+://}) {
         if ($cleaned_file =~ m{^\w+://}) {              $newfiles{$embed_file} = 1;
             $newfiles{$cleaned_file} = 1;              $mapping{$embed_file} = $embed_file;
             $mapping{$cleaned_file} = $embed_file;  
         } else {          } else {
             if ($embed_file =~ m{^/}) {              if ($embed_file =~ m{^/}) {
                 $absolutepath = $embed_file;                  $absolutepath = $embed_file;
                   $embed_file =~ s{^(/+)}{};
             }              }
             if ($cleaned_file =~ m{/}) {              if ($embed_file =~ m{/}) {
                 my ($path,$fname) = ($cleaned_file =~ m{^(.+)/([^/]*)$});                  my ($path,$fname) = ($embed_file =~ m{^(.+)/([^/]*)$});
                 $path = &check_for_traversal($path,$url,$toplevel);                  $path = &check_for_traversal($path,$url,$toplevel);
                 my $item = $fname;                  my $item = $fname;
                 if ($path ne '') {                  if ($path ne '') {
Line 9886  sub ask_for_embedded_content { Line 9417  sub ask_for_embedded_content {
             } else {              } else {
                 $dependencies{$embed_file} = 1;                  $dependencies{$embed_file} = 1;
                 if ($absolutepath) {                  if ($absolutepath) {
                     $mapping{$cleaned_file} = $absolutepath;                      $mapping{$embed_file} = $absolutepath;
                 } else {                  } else {
                     $mapping{$cleaned_file} = $embed_file;                      $mapping{$embed_file} = $embed_file;
                 }                  }
             }              }
         }          }
Line 9896  sub ask_for_embedded_content { Line 9427  sub ask_for_embedded_content {
     my $dirptr = 16384;      my $dirptr = 16384;
     foreach my $path (keys(%subdependencies)) {      foreach my $path (keys(%subdependencies)) {
         $currsubfile{$path} = {};          $currsubfile{$path} = {};
         if (($actionurl eq '/adm/portfolio') ||          if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) { 
             ($actionurl eq '/adm/coursegrp_portfolio')) {   
             my ($sublistref,$listerror) =              my ($sublistref,$listerror) =
                 &Apache::lonnet::dirlist($url.$path,$udom,$uname,$getpropath);                  &Apache::lonnet::dirlist($url.$path,$udom,$uname,$getpropath);
             if (ref($sublistref) eq 'ARRAY') {              if (ref($sublistref) eq 'ARRAY') {
Line 9913  sub ask_for_embedded_content { Line 9443  sub ask_for_embedded_content {
             }              }
         } elsif (($actionurl eq '/adm/dependencies') ||          } elsif (($actionurl eq '/adm/dependencies') ||
                  (($actionurl eq '/adm/coursedocs') && (ref($args) eq 'HASH') &&                   (($actionurl eq '/adm/coursedocs') && (ref($args) eq 'HASH') &&
                   ($args->{'context'} eq 'paste')) ||                    ($args->{'context'} eq 'paste'))) {
                  ($actionurl eq "/public/$cdom/$cnum/syllabus")) {  
             if ($env{'request.course.id'} ne '') {              if ($env{'request.course.id'} ne '') {
                 my $dir;                  my ($dir) = ($fileloc =~ m{^(.+/)[^/]+$});
                 if ($actionurl eq "/public/$cdom/$cnum/syllabus") {  
                     $dir = $fileloc;  
                 } else {  
                     ($dir) = ($fileloc =~ m{^(.+/)[^/]+$});  
                 }  
                 if ($dir ne '') {                  if ($dir ne '') {
                     my ($sublistref,$listerror) =                      my ($sublistref,$listerror) =
                         &Apache::lonnet::dirlist($dir.$path,$cdom,$cnum,$getpropath,undef,'/');                          &Apache::lonnet::dirlist($dir.$path,$cdom,$cnum,$getpropath,undef,'/');
Line 9969  sub ask_for_embedded_content { Line 9493  sub ask_for_embedded_content {
         }          }
     }      }
     my %currfile;      my %currfile;
     if (($actionurl eq '/adm/portfolio') ||      if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {
         ($actionurl eq '/adm/coursegrp_portfolio')) {  
         my ($dirlistref,$listerror) =          my ($dirlistref,$listerror) =
             &Apache::lonnet::dirlist($url,$udom,$uname,$getpropath);              &Apache::lonnet::dirlist($url,$udom,$uname,$getpropath);
         if (ref($dirlistref) eq 'ARRAY') {          if (ref($dirlistref) eq 'ARRAY') {
Line 9986  sub ask_for_embedded_content { Line 9509  sub ask_for_embedded_content {
         }          }
     } elsif (($actionurl eq '/adm/dependencies') ||      } elsif (($actionurl eq '/adm/dependencies') ||
              (($actionurl eq '/adm/coursedocs') && (ref($args) eq 'HASH') &&               (($actionurl eq '/adm/coursedocs') && (ref($args) eq 'HASH') &&
               ($args->{'context'} eq 'paste')) ||                ($args->{'context'} eq 'paste'))) {
              ($actionurl eq "/public/$cdom/$cnum/syllabus")) {  
         if ($env{'request.course.id'} ne '') {          if ($env{'request.course.id'} ne '') {
             my ($dir) = ($fileloc =~ m{^(.+/)[^/]+$});              my ($dir) = ($fileloc =~ m{^(.+/)[^/]+$});
             if ($dir ne '') {              if ($dir ne '') {
Line 10022  sub ask_for_embedded_content { Line 9544  sub ask_for_embedded_content {
                 ($file eq $filename.'.bak') ||                  ($file eq $filename.'.bak') ||
                 ($dependencies{$file})) {                  ($dependencies{$file})) {
             if ($actionurl eq '/adm/dependencies') {              if ($actionurl eq '/adm/dependencies') {
                 unless ($toplevel =~ m{^\Q/uploaded/$cdom/$cnum/portfolio/syllabus\E}) {                  next if (($rem ne '') &&
                     next if (($rem ne '') &&                           (($env{"httpref.$rem".$file} ne '') ||
                              (($env{"httpref.$rem".$file} ne '') ||                            (ref($navmap) &&
                               (ref($navmap) &&                            (($navmap->getResourceByUrl($rem.$file) ne '') ||
                               (($navmap->getResourceByUrl($rem.$file) ne '') ||                             (($file =~ /^(.*\.s?html?)\.bak$/i) &&
                                (($file =~ /^(.*\.s?html?)\.bak$/i) &&                              ($navmap->getResourceByUrl($rem.$1)))))));
                                 ($navmap->getResourceByUrl($rem.$1)))))));  
                 }  
             }              }
             $unused{$file} = 1;              $unused{$file} = 1;
         }          }
Line 10038  sub ask_for_embedded_content { Line 9558  sub ask_for_embedded_content {
         ($args->{'context'} eq 'paste')) {          ($args->{'context'} eq 'paste')) {
         $counter = scalar(keys(%existing));          $counter = scalar(keys(%existing));
         $numpathchg = scalar(keys(%pathchanges));          $numpathchg = scalar(keys(%pathchanges));
         return ($output,$counter,$numpathchg,\%existing);          return ($output,$counter,$numpathchg,\%existing); 
     } elsif (($actionurl eq "/public/$cdom/$cnum/syllabus") &&  
              (ref($args) eq 'HASH') && ($args->{'context'} eq 'rewrites')) {  
         $counter = scalar(keys(%existing));  
         $numpathchg = scalar(keys(%pathchanges));  
         return ($output,$counter,$numpathchg,\%existing,\%mapping);  
     }      }
     foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%newfiles)) {      foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%newfiles)) {
         if ($actionurl eq '/adm/dependencies') {          if ($actionurl eq '/adm/dependencies') {
             next if ($embed_file =~ m{^\w+://});              next if ($embed_file =~ m{^\w+://});
         }          }
         $upload_output .= &start_data_table_row().          $upload_output .= &start_data_table_row().
                           '<td valign="top"><img src="'.&icon($embed_file).'" />&nbsp;'.                            '<td><img src="'.&icon($embed_file).'" />&nbsp;'.
                           '<span class="LC_filename">'.$embed_file.'</span>';                            '<span class="LC_filename">'.$embed_file.'</span>';
         unless ($mapping{$embed_file} eq $embed_file) {          unless ($mapping{$embed_file} eq $embed_file) {
             $upload_output .= '<br /><span class="LC_info" style="font-size:smaller;">'.              $upload_output .= '<br /><span class="LC_info" style="font-size:smaller;">'.&mt('changed from: [_1]',$mapping{$embed_file}).'</span>';
                               &mt('changed from: [_1]',$mapping{$embed_file}).'</span>';  
         }          }
         $upload_output .= '</td>';          $upload_output .= '</td><td>';
         if ($args->{'ignore_remote_references'} && $embed_file =~ m{^\w+://}) {           if ($args->{'ignore_remote_references'} && $embed_file =~ m{^\w+://}) { 
             $upload_output.='<td align="right">'.              $upload_output.='<span class="LC_warning">'.&mt("URL points to other server.").'</span>';
                             '<span class="LC_info LC_fontsize_medium">'.  
                             &mt("URL points to web address").'</span>';  
             $numremref++;              $numremref++;
         } elsif ($args->{'error_on_invalid_names'}          } elsif ($args->{'error_on_invalid_names'}
             && $embed_file ne &Apache::lonnet::clean_filename($embed_file,{'keep_path' => 1,})) {              && $embed_file ne &Apache::lonnet::clean_filename($embed_file,{'keep_path' => 1,})) {
             $upload_output.='<td align="right"><span class="LC_warning">'.              $upload_output.='<span class="LC_warning">'.&mt('Invalid characters').'</span>';
                             &mt('Invalid characters').'</span>';  
             $numinvalid++;              $numinvalid++;
         } else {          } else {
             $upload_output .= '<td>'.              $upload_output .= &embedded_file_element('upload_embedded',$counter,
                               &embedded_file_element('upload_embedded',$counter,  
                                                      $embed_file,\%mapping,                                                       $embed_file,\%mapping,
                                                      $allfiles,$codebase,'upload');                                                       $allfiles,$codebase,'upload');
             $counter ++;              $counter ++;
Line 10098  sub ask_for_embedded_content { Line 9608  sub ask_for_embedded_content {
             $counter ++;              $counter ++;
         } else {          } else {
             $upload_output .= &start_data_table_row().              $upload_output .= &start_data_table_row().
                               '<td valign="top"><img src="'.&icon($embed_file).'" />&nbsp;'.                                '<td><span class="LC_filename">'.$embed_file.'</span></td>';
                               '<span class="LC_filename">'.$embed_file.'</span></td>'.                                '<td><span class="LC_warning">'.&mt('Already exists').'</span></td>'.
                               '<td align="right"><span class="LC_info LC_fontsize_medium">'.&mt('Already exists').'</span></td>'.  
                               &Apache::loncommon::end_data_table_row()."\n";                                &Apache::loncommon::end_data_table_row()."\n";
         }          }
     }      }
Line 10195  sub ask_for_embedded_content { Line 9704  sub ask_for_embedded_content {
         $output = '<b>'.&mt('Referenced files').'</b>:<br />';          $output = '<b>'.&mt('Referenced files').'</b>:<br />';
         if ($applies > 1) {          if ($applies > 1) {
             $output .=                $output .=  
                 &mt('No dependencies need to be uploaded, as one of the following applies to each reference:').'<ul>';                  &mt('No files need to be uploaded, as one of the following applies to each reference:').'<ul>';
             if ($numremref) {              if ($numremref) {
                 $output .= '<li>'.&mt('reference is to a URL which points to another server').'</li>'."\n";                  $output .= '<li>'.&mt('reference is to a URL which points to another server').'</li>'."\n";
             }              }
Line 10238  sub ask_for_embedded_content { Line 9747  sub ask_for_embedded_content {
             $chgcount ++;              $chgcount ++;
         }          }
     }      }
     if (($counter) || ($numunused)) {      if ($counter) {
         if ($numpathchg) {          if ($numpathchg) {
             $output .= '<input type ="hidden" name="number_pathchange_items" value="'.              $output .= '<input type ="hidden" name="number_pathchange_items" value="'.
                        $numpathchg.'" />'."\n";                         $numpathchg.'" />'."\n";
Line 10251  sub ask_for_embedded_content { Line 9760  sub ask_for_embedded_content {
         } elsif ($actionurl eq '/adm/dependencies') {          } elsif ($actionurl eq '/adm/dependencies') {
             $output .= '<input type="hidden" name="action" value="process_changes" />';              $output .= '<input type="hidden" name="action" value="process_changes" />';
         }          }
         $output .= '<input type ="submit" value="'.$buttontext.'" />'."\n".'</form>'."\n";          $output .=  '<input type ="submit" value="'.$buttontext.'" />'."\n".'</form>'."\n";
     } elsif ($numpathchg) {      } elsif ($numpathchg) {
         my %pathchange = ();          my %pathchange = ();
         $output .= &modify_html_form('pathchange',$actionurl,$state,\%pathchange,$pathchange_output);          $output .= &modify_html_form('pathchange',$actionurl,$state,\%pathchange,$pathchange_output);
         if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {          if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {
             $output .= '<p>'.&mt('or').'</p>';               $output .= '<p>'.&mt('or').'</p>'; 
         }          } 
     }      }
     return ($output,$counter,$numpathchg);      return ($output,$counter,$numpathchg);
 }  }
   
   
 =pod  
   
 =item * clean_path($name)  
   
 Performs clean-up of directories, subdirectories and filename in an  
 embedded object, referenced in an HTML file which is being uploaded  
 to a course or portfolio, where  
 "Upload embedded images/multimedia files if HTML file" checkbox was  
 checked.  
   
 Clean-up is similar to replacements in lonnet::clean_filename()  
 except each / between sub-directory and next level is preserved.  
   
 =cut  
   
 sub clean_path {  
     my ($embed_file) = @_;  
     $embed_file =~s{^/+}{};  
     my @contents;  
     if ($embed_file =~ m{/}) {  
         @contents = split(/\//,$embed_file);  
     } else {  
         @contents = ($embed_file);  
     }  
     my $lastidx = scalar(@contents)-1;  
     for (my $i=0; $i<=$lastidx; $i++) {  
         $contents[$i]=~s{\\}{/}g;  
         $contents[$i]=~s/\s+/\_/g;  
         $contents[$i]=~s{[^/\w\.\-]}{}g;  
         if ($i == $lastidx) {  
             $contents[$i]=~s/\.(\d+)(?=\.)/_$1/g;  
         }  
     }  
     if ($lastidx > 0) {  
         return join('/',@contents);  
     } else {  
         return $contents[0];  
     }  
 }  
   
 sub embedded_file_element {  sub embedded_file_element {
     my ($context,$num,$embed_file,$mapping,$allfiles,$codebase,$type) = @_;      my ($context,$num,$embed_file,$mapping,$allfiles,$codebase,$type) = @_;
     return unless ((ref($mapping) eq 'HASH') && (ref($allfiles) eq 'HASH') &&      return unless ((ref($mapping) eq 'HASH') && (ref($allfiles) eq 'HASH') &&
Line 10434  sub upload_embedded { Line 9902  sub upload_embedded {
             $output .= &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1).'<br />';              $output .= &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1).'<br />';
             next;              next;
         } elsif ($fname=~/\.(\d+)\.(\w+)$/) {          } elsif ($fname=~/\.(\d+)\.(\w+)$/) {
             $output .= &mt('Filename not allowed - rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2).'<br />';              $output .= &mt('File name not allowed - rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2).'<br />';
             next;              next;
         }          }
         $env{'form.embedded_item_'.$i.'.filename'}=$fname;          $env{'form.embedded_item_'.$i.'.filename'}=$fname;
         my $subdir = $path;  
         $subdir =~ s{/+$}{};  
         if ($context eq 'portfolio') {          if ($context eq 'portfolio') {
             my $result;              my $result;
             if ($state eq 'existingfile') {              if ($state eq 'existingfile') {
                 $result=                  $result=
                     &Apache::lonnet::userfileupload('embedded_item_'.$i,'existingfile',                      &Apache::lonnet::userfileupload('embedded_item_'.$i,'existingfile',
                                                     $dirpath.$env{'form.currentpath'}.$subdir);                                                      $dirpath.$env{'form.currentpath'}.$path);
             } else {              } else {
                 $result=                  $result=
                     &Apache::lonnet::userfileupload('embedded_item_'.$i,'',                      &Apache::lonnet::userfileupload('embedded_item_'.$i,'',
                                                     $dirpath.                                                      $dirpath.
                                                     $env{'form.currentpath'}.$subdir);                                                      $env{'form.currentpath'}.$path);
                 if ($result !~ m|^/uploaded/|) {                  if ($result !~ m|^/uploaded/|) {
                     $output .= '<span class="LC_error">'                      $output .= '<span class="LC_error">'
                                .&mt('An error occurred ([_1]) while trying to upload [_2] for embedded element [_3].'                                 .&mt('An error occurred ([_1]) while trying to upload [_2] for embedded element [_3].'
Line 10462  sub upload_embedded { Line 9928  sub upload_embedded {
                                $path.$fname.'</span>').'<br />';                                      $path.$fname.'</span>').'<br />';     
                 }                  }
             }              }
         } elsif (($context eq 'coursedoc') || ($context eq 'syllabus')) {          } elsif ($context eq 'coursedoc') {
             my $extendedsubdir = $dirpath.'/'.$subdir;  
             $extendedsubdir =~ s{/+$}{};  
             my $result =              my $result =
                 &Apache::lonnet::userfileupload('embedded_item_'.$i,$context,$extendedsubdir);                  &Apache::lonnet::userfileupload('embedded_item_'.$i,'coursedoc',
                                                   $dirpath.'/'.$path);
             if ($result !~ m|^/uploaded/|) {              if ($result !~ m|^/uploaded/|) {
                 $output .= '<span class="LC_error">'                  $output .= '<span class="LC_error">'
                            .&mt('An error occurred ([_1]) while trying to upload [_2] for embedded element [_3].'                             .&mt('An error occurred ([_1]) while trying to upload [_2] for embedded element [_3].'
Line 10476  sub upload_embedded { Line 9941  sub upload_embedded {
             } else {              } else {
                 $output .= &mt('Uploaded [_1]','<span class="LC_filename">'.                  $output .= &mt('Uploaded [_1]','<span class="LC_filename">'.
                            $path.$fname.'</span>').'<br />';                             $path.$fname.'</span>').'<br />';
                 if ($context eq 'syllabus') {  
                     &Apache::lonnet::make_public_indefinitely($result);  
                 }  
             }              }
         } else {          } else {
 # Save the file  # Save the file
Line 10610  sub modify_html_form { Line 10072  sub modify_html_form {
 }  }
   
 sub modify_html_refs {  sub modify_html_refs {
     my ($context,$dirpath,$uname,$udom,$dir_root,$url) = @_;      my ($context,$dirpath,$uname,$udom,$dir_root) = @_;
     my $container;      my $container;
     if ($context eq 'portfolio') {      if ($context eq 'portfolio') {
         $container = $env{'form.container'};          $container = $env{'form.container'};
Line 10619  sub modify_html_refs { Line 10081  sub modify_html_refs {
     } elsif ($context eq 'manage_dependencies') {      } elsif ($context eq 'manage_dependencies') {
         (undef,undef,$container) = &Apache::lonnet::decode_symb($env{'form.symb'});          (undef,undef,$container) = &Apache::lonnet::decode_symb($env{'form.symb'});
         $container = "/$container";          $container = "/$container";
     } elsif ($context eq 'syllabus') {  
         $container = $url;  
     } else {      } else {
         $container = $Apache::lonnet::perlvar{'lonDocRoot'}.$env{'form.filename'};          $container = $Apache::lonnet::perlvar{'lonDocRoot'}.$env{'form.filename'};
     }      }
     my (%allfiles,%codebase,$output,$content);      my (%allfiles,%codebase,$output,$content);
     my @changes = &get_env_multiple('form.namechange');      my @changes = &get_env_multiple('form.namechange');
     unless ((@changes > 0)  || ($context eq 'syllabus')) {      unless (@changes > 0) {
         if (wantarray) {          if (wantarray) {
             return ('',0,0);               return ('',0,0); 
         } else {          } else {
Line 10634  sub modify_html_refs { Line 10094  sub modify_html_refs {
         }          }
     }      }
     if (($context eq 'portfolio') || ($context eq 'coursedoc') ||       if (($context eq 'portfolio') || ($context eq 'coursedoc') || 
         ($context eq 'manage_dependencies') || ($context eq 'syllabus')) {          ($context eq 'manage_dependencies')) {
         unless ($container =~ m{^/uploaded/\Q$udom\E/\Q$uname\E/}) {          unless ($container =~ m{^/uploaded/\Q$udom\E/\Q$uname\E/}) {
             if (wantarray) {              if (wantarray) {
                 return ('',0,0);                  return ('',0,0);
Line 10690  sub modify_html_refs { Line 10150  sub modify_html_refs {
                     if ($content =~ m{($attrib_regexp\s*=\s*['"]?)\Q$ref\E(['"]?)}) {                      if ($content =~ m{($attrib_regexp\s*=\s*['"]?)\Q$ref\E(['"]?)}) {
                         my $numchg = ($content =~ s{($attrib_regexp\s*=\s*['"]?)\Q$ref\E(['"]?)}{$1$newname$2}gi);                          my $numchg = ($content =~ s{($attrib_regexp\s*=\s*['"]?)\Q$ref\E(['"]?)}{$1$newname$2}gi);
                         $count += $numchg;                          $count += $numchg;
                         $allfiles{$newname} = $allfiles{$ref};  
                         delete($allfiles{$ref});  
                     }                      }
                     if ($env{'form.embedded_codebase_'.$i} ne '') {                      if ($env{'form.embedded_codebase_'.$i} ne '') {
                         $codebase = &unescape($env{'form.embedded_codebase_'.$i});                          $codebase = &unescape($env{'form.embedded_codebase_'.$i});
Line 10700  sub modify_html_refs { Line 10158  sub modify_html_refs {
                     }                      }
                 }                  }
             }              }
             my $skiprewrites;  
             if ($count || $codebasecount) {              if ($count || $codebasecount) {
                 my $saveresult;                  my $saveresult;
                 if (($context eq 'portfolio') || ($context eq 'coursedoc') ||                   if (($context eq 'portfolio') || ($context eq 'coursedoc') || 
                     ($context eq 'manage_dependencies') || ($context eq 'syllabus')) {                      ($context eq 'manage_dependencies')) {
                     my $url = &Apache::lonnet::store_edited_file($container,$content,$udom,$uname,\$saveresult);                      my $url = &Apache::lonnet::store_edited_file($container,$content,$udom,$uname,\$saveresult);
                     if ($url eq $container) {                      if ($url eq $container) {
                         my ($fname) = ($container =~ m{/([^/]+)$});                          my ($fname) = ($container =~ m{/([^/]+)$});
Line 10717  sub modify_html_refs { Line 10174  sub modify_html_refs {
                                    '<span class="LC_filename">'.                                     '<span class="LC_filename">'.
                                    $container.'</span>').'</p>';                                     $container.'</span>').'</p>';
                     }                      }
                     if ($context eq 'syllabus') {  
                         unless ($saveresult eq 'ok') {  
                             $skiprewrites = 1;  
                         }  
                     }  
                 } else {                  } else {
                     if (open(my $fh,">$container")) {                      if (open(my $fh,">$container")) {
                         print $fh $content;                          print $fh $content;
Line 10737  sub modify_html_refs { Line 10189  sub modify_html_refs {
                     }                      }
                 }                  }
             }              }
             if (($context eq 'syllabus') && (!$skiprewrites)) {  
                 my ($actionurl,$state);  
                 $actionurl = "/public/$udom/$uname/syllabus";  
                 my ($ignore,$num,$numpathchanges,$existing,$mapping) =  
                     &ask_for_embedded_content($actionurl,$state,\%allfiles,  
                                               \%codebase,  
                                               {'context' => 'rewrites',  
                                                'ignore_remote_references' => 1,});  
                 if (ref($mapping) eq 'HASH') {  
                     my $rewrites = 0;  
                     foreach my $key (keys(%{$mapping})) {  
                         next if ($key =~ m{^https?://});  
                         my $ref = $mapping->{$key};  
                         my $newname = "/uploaded/$udom/$uname/portfolio/syllabus/$key";  
                         my $attrib;  
                         if (ref($allfiles{$mapping->{$key}}) eq 'ARRAY') {  
                             $attrib = join('|',@{$allfiles{$mapping->{$key}}});  
                         }  
                         if ($content =~ m{($attrib\s*=\s*['"]?)\Q$ref\E(['"]?)}) {  
                             my $numchg = ($content =~ s{($attrib\s*=\s*['"]?)\Q$ref\E(['"]?)}{$1$newname$2}gi);  
                             $rewrites += $numchg;  
                         }  
                     }  
                     if ($rewrites) {  
                         my $saveresult;  
                         my $url = &Apache::lonnet::store_edited_file($container,$content,$udom,$uname,\$saveresult);  
                         if ($url eq $container) {  
                             my ($fname) = ($container =~ m{/([^/]+)$});  
                             $output .= '<p>'.&mt('Rewrote [quant,_1,link] as [quant,_1,absolute link] in [_2].',  
                                             $count,'<span class="LC_filename">'.  
                                             $fname.'</span>').'</p>';  
                         } else {  
                             $output .= '<p class="LC_error">'.  
                                        &mt('Error: could not update links in [_1].',  
                                        '<span class="LC_filename">'.  
                                        $container.'</span>').'</p>';  
   
                         }  
                     }  
                 }  
             }  
         } else {          } else {
             &logthis('Failed to parse '.$container.              &logthis('Failed to parse '.$container.
                      ' to modify references: '.$parse_result);                       ' to modify references: '.$parse_result);
Line 11193  sub process_decompression { Line 10604  sub process_decompression {
     my ($docudom,$docuname,$file,$destination,$dir_root,$hiddenelem) = @_;      my ($docudom,$docuname,$file,$destination,$dir_root,$hiddenelem) = @_;
     my ($dir,$error,$warning,$output);      my ($dir,$error,$warning,$output);
     if ($file !~ /\.(zip|tar|bz2|gz|tar.gz|tar.bz2|tgz)$/) {      if ($file !~ /\.(zip|tar|bz2|gz|tar.gz|tar.bz2|tgz)$/) {
         $error = &mt('Filename not a supported archive file type.').          $error = &mt('File name not a supported archive file type.').
                  '<br />'.&mt('Filename should end with one of: [_1].',                   '<br />'.&mt('File name should end with one of: [_1].',
                               '.zip, .tar, .bz2, .gz, .tar.gz, .tar.bz2, .tgz');                                '.zip, .tar, .bz2, .gz, .tar.gz, .tar.bz2, .tgz');
     } else {      } else {
         my $docuhome = &Apache::lonnet::homeserver($docuname,$docudom);          my $docuhome = &Apache::lonnet::homeserver($docuname,$docudom);
Line 11768  sub process_extracted_files { Line 11179  sub process_extracted_files {
     if ($env{'form.folderpath'}) {      if ($env{'form.folderpath'}) {
         my @items = split('&',$env{'form.folderpath'});          my @items = split('&',$env{'form.folderpath'});
         $folders{'0'} = $items[-2];          $folders{'0'} = $items[-2];
         if ($env{'form.folderpath'} =~ /\:1$/) {          $containers{'0'}='sequence';
             $containers{'0'}='page';      } elsif ($env{'form.pagepath'}) {
         } else {          my @items = split('&',$env{'form.pagepath'});
             $containers{'0'}='sequence';          $folders{'0'} = $items[-2];
         }          $containers{'0'}='page';
     }      }
     my @archdirs = &get_env_multiple('form.archive_directory');      my @archdirs = &get_env_multiple('form.archive_directory');
     if ($numitems) {      if ($numitems) {
Line 11796  sub process_extracted_files { Line 11207  sub process_extracted_files {
     my (%referrer,%orphaned,%todelete,%todeletedir,%newdest,%newseqid);      my (%referrer,%orphaned,%todelete,%todeletedir,%newdest,%newseqid);
     if ($numitems) {      if ($numitems) {
         for (my $i=1; $i<=$numitems; $i++) {          for (my $i=1; $i<=$numitems; $i++) {
             next if ($env{'form.archive_'.$i} eq 'dependency');  
             my $path = $env{'form.archive_content_'.$i};              my $path = $env{'form.archive_content_'.$i};
             if ($path =~ /^\Q$pathtocheck\E/) {              if ($path =~ /^\Q$pathtocheck\E/) {
                 if ($env{'form.archive_'.$i} eq 'discard') {                  if ($env{'form.archive_'.$i} eq 'discard') {
Line 11847  sub process_extracted_files { Line 11257  sub process_extracted_files {
                             my ($outtext,$errtext) =                              my ($outtext,$errtext) =
                                 &LONCAPA::map::storemap('/uploaded/'.$docudom.'/'.                                  &LONCAPA::map::storemap('/uploaded/'.$docudom.'/'.
                                                         $docuname.'/'.$folders{$outer}.                                                          $docuname.'/'.$folders{$outer}.
                                                         '.'.$containers{$outer},1,1);                                                          '.'.$containers{$outer},1);
                             $newseqid{$i} = $newidx;                              $newseqid{$i} = $newidx;
                             unless ($errtext) {                              unless ($errtext) {
                                 $result .=  '<li>'.&mt('Folder: [_1] added to course',$docstitle).'</li>'."\n";                                  $result .=  '<li>'.&mt('Folder: [_1] added to course',$docstitle).'</li>'."\n";
Line 11880  sub process_extracted_files { Line 11290  sub process_extracted_files {
                             my ($outtext,$errtext)=                              my ($outtext,$errtext)=
                                 &LONCAPA::map::storemap('/uploaded/'.$docudom.'/'.                                  &LONCAPA::map::storemap('/uploaded/'.$docudom.'/'.
                                                         $docuname.'/'.$folders{$outer}.                                                          $docuname.'/'.$folders{$outer}.
                                                         '.'.$containers{$outer},1,1);                                                          '.'.$containers{$outer},1);
                             unless ($errtext) {                              unless ($errtext) {
                                 if (-e "$prefix$dir/$docstype/$mapinner{$outer}/$newidx/$title") {                                  if (-e "$prefix$dir/$docstype/$mapinner{$outer}/$newidx/$title") {
                                     $result .= '<li>'.&mt('File: [_1] added to course',$docstitle).'</li>'."\n";                                      $result .= '<li>'.&mt('File: [_1] added to course',$docstitle).'</li>'."\n";
Line 11888  sub process_extracted_files { Line 11298  sub process_extracted_files {
                             }                              }
                         }                          }
                     }                      }
                 }                  } elsif ($env{'form.archive_'.$i} eq 'dependency') {
             } else {                      my ($title) = ($path =~ m{/([^/]+)$});
                 $warning .= &mt('Item extracted from archive: [_1] has unexpected path.',$path).'<br />';                      $referrer{$i} = $env{'form.archive_dependent_on_'.$i};
             }                      if ($env{'form.archive_'.$referrer{$i}} eq 'display') {
         }                          if (ref($dirorder{$i}) eq 'ARRAY') {
         for (my $i=1; $i<=$numitems; $i++) {                              my ($itemidx,$fullpath,$relpath);
             next unless ($env{'form.archive_'.$i} eq 'dependency');  
             my $path = $env{'form.archive_content_'.$i};  
             if ($path =~ /^\Q$pathtocheck\E/) {  
                 my ($title) = ($path =~ m{/([^/]+)$});  
                 $referrer{$i} = $env{'form.archive_dependent_on_'.$i};  
                 if ($env{'form.archive_'.$referrer{$i}} eq 'display') {  
                     if (ref($dirorder{$i}) eq 'ARRAY') {  
                         my ($itemidx,$fullpath,$relpath);  
                         if (ref($dirorder{$referrer{$i}}) eq 'ARRAY') {  
                             my $container = $dirorder{$referrer{$i}}->[-1];  
                             for (my $j=0; $j<@{$dirorder{$i}}; $j++) {                              for (my $j=0; $j<@{$dirorder{$i}}; $j++) {
                                 if ($dirorder{$i}->[$j] eq $container) {                                  if (ref($dirorder{$referrer{$i}}) eq 'ARRAY') {
                                     $itemidx = $j;                                      my $container = $dirorder{$referrer{$i}}->[-1];
                                       for (my $j=0; $j<@{$dirorder{$i}}; $j++) {
                                           if ($dirorder{$i}->[$j] eq $container) {
                                               $itemidx = $j;
                                           }
                                       }
                                 }                                  }
                             }                              }
                         }                              if ($itemidx ne '') {
                         if ($itemidx eq '') {                                  if (grep(/^\Q$referrer{$i}\E$/,@archdirs)) {
                             $itemidx =  0;                                      if ($mapinner{$referrer{$i}}) {
                         }                                          $fullpath = "$prefix$dir/$docstype/$mapinner{$referrer{$i}}";
                         if (grep(/^\Q$referrer{$i}\E$/,@archdirs)) {                                          for (my $j=$itemidx; $j<@{$dirorder{$i}}; $j++) {
                             if ($mapinner{$referrer{$i}}) {                                              if (grep(/^\Q$dirorder{$i}->[$j]\E$/,@archdirs)) {
                                 $fullpath = "$prefix$dir/$docstype/$mapinner{$referrer{$i}}";                                                  unless (defined($newseqid{$dirorder{$i}->[$j]})) {
                                 for (my $j=$itemidx; $j<@{$dirorder{$i}}; $j++) {                                                      $fullpath .= '/'.$titles{$dirorder{$i}->[$j]};
                                     if (grep(/^\Q$dirorder{$i}->[$j]\E$/,@archdirs)) {                                                      $relpath .= '/'.$titles{$dirorder{$i}->[$j]};
                                         unless (defined($newseqid{$dirorder{$i}->[$j]})) {                                                      if (!-e $fullpath) {
                                             $fullpath .= '/'.$titles{$dirorder{$i}->[$j]};                                                          mkdir($fullpath,0755);
                                             $relpath .= '/'.$titles{$dirorder{$i}->[$j]};                                                      }
                                             if (!-e $fullpath) {                                                  }
                                                 mkdir($fullpath,0755);                                              } else {
                                                   last;
                                             }                                              }
                                         }                                          }
                                     } else {  
                                         last;  
                                     }                                      }
                                 }                                  } elsif ($newdest{$referrer{$i}}) {
                             }                                      $fullpath = $newdest{$referrer{$i}};
                         } elsif ($newdest{$referrer{$i}}) {                                      for (my $j=$itemidx; $j<@{$dirorder{$i}}; $j++) {
                             $fullpath = $newdest{$referrer{$i}};                                          if ($env{'form.archive_'.$dirorder{$i}->[$j]} eq 'discard') {
                             for (my $j=$itemidx; $j<@{$dirorder{$i}}; $j++) {                                              $orphaned{$i} = $env{'form.archive_'.$dirorder{$i}->[$j]};
                                 if ($env{'form.archive_'.$dirorder{$i}->[$j]} eq 'discard') {                                              last;
                                     $orphaned{$i} = $env{'form.archive_'.$dirorder{$i}->[$j]};                                          } elsif (grep(/^\Q$dirorder{$i}->[$j]\E$/,@archdirs)) {
                                     last;                                              unless (defined($newseqid{$dirorder{$i}->[$j]})) {
                                 } elsif (grep(/^\Q$dirorder{$i}->[$j]\E$/,@archdirs)) {                                                  $fullpath .= '/'.$titles{$dirorder{$i}->[$j]};
                                     unless (defined($newseqid{$dirorder{$i}->[$j]})) {                                                  $relpath .= '/'.$titles{$dirorder{$i}->[$j]};
                                         $fullpath .= '/'.$titles{$dirorder{$i}->[$j]};                                                  if (!-e $fullpath) {
                                         $relpath .= '/'.$titles{$dirorder{$i}->[$j]};                                                      mkdir($fullpath,0755);
                                         if (!-e $fullpath) {                                                  }
                                             mkdir($fullpath,0755);                                              }
                                           } else {
                                               last;
                                         }                                          }
                                     }                                      }
                                 } else {  
                                     last;  
                                 }                                  }
                             }                                  if ($fullpath ne '') {
                         }                                      if (-e "$prefix$path") {
                         if ($fullpath ne '') {                                          system("mv $prefix$path $fullpath/$title");
                             if (-e "$prefix$path") {                                      }
                                 system("mv $prefix$path $fullpath/$title");                                      if (-e "$fullpath/$title") {
                             }                                          my $showpath;
                             if (-e "$fullpath/$title") {                                          if ($relpath ne '') {
                                 my $showpath;                                              $showpath = "$relpath/$title";
                                 if ($relpath ne '') {                                          } else {
                                     $showpath = "$relpath/$title";                                              $showpath = "/$title";
                                 } else {                                          } 
                                     $showpath = "/$title";                                          $result .= '<li>'.&mt('[_1] included as a dependency',$showpath).'</li>'."\n";
                                       } 
                                       unless ($ishome) {
                                           my $fetch = "$fullpath/$title";
                                           $fetch =~ s/^\Q$prefix$dir\E//; 
                                           $prompttofetch{$fetch} = 1;
                                       }
                                 }                                  }
                                 $result .= '<li>'.&mt('[_1] included as a dependency',$showpath).'</li>'."\n";  
                             }  
                             unless ($ishome) {  
                                 my $fetch = "$fullpath/$title";  
                                 $fetch =~ s/^\Q$prefix$dir\E//;  
                                 $prompttofetch{$fetch} = 1;  
                             }                              }
                         }                          }
                       } elsif ($env{'form.archive_'.$referrer{$i}} eq 'discard') {
                           $warning .= &mt('[_1] is a dependency of [_2], which was discarded.',
                                           $path,$env{'form.archive_content_'.$referrer{$i}}).'<br />';
                     }                      }
                 } elsif ($env{'form.archive_'.$referrer{$i}} eq 'discard') {  
                     $warning .= &mt('[_1] is a dependency of [_2], which was discarded.',  
                                     $path,$env{'form.archive_content_'.$referrer{$i}}).'<br />';  
                 }                  }
             } else {              } else {
                 $warning .= &mt('Item extracted from archive: [_1] has unexpected path.',$path).'<br />';                  $warning .= &mt('Item extracted from archive: [_1] has unexpected path.',$path).'<br />'; 
             }              }
         }          }
         if (keys(%todelete)) {          if (keys(%todelete)) {
Line 12033  sub cleanup_empty_dirs { Line 11437  sub cleanup_empty_dirs {
             my $numitems = 0;              my $numitems = 0;
             foreach my $item (@dircontents) {              foreach my $item (@dircontents) {
                 if (-d "$path/$item") {                  if (-d "$path/$item") {
                     &cleanup_empty_dirs("$path/$item");                      &recurse_dirs("$path/$item");
                     if (-e "$path/$item") {                      if (-e "$path/$item") {
                         $numitems ++;                          $numitems ++;
                     }                      }
Line 12080  sub get_folder_hierarchy { Line 11484  sub get_folder_hierarchy {
                 my @pcs = split(/,/,$pcslist);                  my @pcs = split(/,/,$pcslist);
                 foreach my $pc (@pcs) {                  foreach my $pc (@pcs) {
                     if ($pc == 1) {                      if ($pc == 1) {
                         push(@pathitems,&mt('Main Content'));                          push(@pathitems,&mt('Main Course Documents'));
                     } else {                      } else {
                         my $res = $navmap->getByMapPc($pc);                          my $res = $navmap->getByMapPc($pc);
                         if (ref($res)) {                          if (ref($res)) {
Line 12095  sub get_folder_hierarchy { Line 11499  sub get_folder_hierarchy {
             }              }
             if ($showitem) {              if ($showitem) {
                 if ($mapres->{ID} eq '0.0') {                  if ($mapres->{ID} eq '0.0') {
                     push(@pathitems,&mt('Main Content'));                      push(@pathitems,&mt('Main Course Documents'));
                 } else {                  } else {
                     my $maptitle = $mapres->compTitle();                      my $maptitle = $mapres->compTitle();
                     $maptitle =~ s/\W+/_/g;                      $maptitle =~ s/\W+/_/g;
Line 12162  sub get_turnedin_filepath { Line 11566  sub get_turnedin_filepath {
                             my $title = $res->compTitle();                              my $title = $res->compTitle();
                             $title =~ s/\W+/_/g;                              $title =~ s/\W+/_/g;
                             if ($title ne '') {                              if ($title ne '') {
                                 if (($pc > 1) && (length($title) > 12)) {  
                                     $title = substr($title,0,12);  
                                 }  
                                 push(@pathitems,$title);                                  push(@pathitems,$title);
                             }                              }
                         }                          }
Line 12173  sub get_turnedin_filepath { Line 11574  sub get_turnedin_filepath {
                 my $maptitle = $mapres->compTitle();                  my $maptitle = $mapres->compTitle();
                 $maptitle =~ s/\W+/_/g;                  $maptitle =~ s/\W+/_/g;
                 if ($maptitle ne '') {                  if ($maptitle ne '') {
                     if (length($maptitle) > 12) {  
                         $maptitle = substr($maptitle,0,12);  
                     }  
                     push(@pathitems,$maptitle);                      push(@pathitems,$maptitle);
                 }                  }
                 unless ($env{'request.state'} eq 'construct') {                  unless ($env{'request.state'} eq 'construct') {
Line 12216  sub get_turnedin_filepath { Line 11614  sub get_turnedin_filepath {
                 $restitle = time;                  $restitle = time;
             }              }
         }          }
         if (length($restitle) > 12) {  
             $restitle = substr($restitle,0,12);  
         }  
         push(@pathitems,$restitle);          push(@pathitems,$restitle);
         $path .= join('/',@pathitems);          $path .= join('/',@pathitems);
     }      }
Line 13156  sub restore_settings { Line 12551  sub restore_settings {
   
 =item * &build_recipient_list()  =item * &build_recipient_list()
   
 Build recipient lists for following types of e-mail:  Build recipient lists for five types of e-mail:
 (a) Error Reports, (b) Package Updates, (c) lonstatus warnings/errors  (a) Error Reports, (b) Package Updates, (c) lonstatus warnings/errors
 (d) Help requests, (e) Course requests needing approval, (f) loncapa  (d) Help requests, (e) Course requests needing approval,  generated by
 module change checking, student/employee ID conflict checks, as  lonerrorhandler.pm, CHECKRPMS, loncron, lonsupportreq.pm and
 generated by lonerrorhandler.pm, CHECKRPMS, loncron,  loncoursequeueadmin.pm respectively.
 lonsupportreq.pm, loncoursequeueadmin.pm, searchcat.pl respectively.  
   
 Inputs:  Inputs:
 defmail (scalar - email address of default recipient),  defmail (scalar - email address of default recipient), 
 mailing type (scalar: errormail, packagesmail, helpdeskmail,  mailing type (scalar - errormail, packagesmail, or helpdeskmail), 
 requestsmail, updatesmail, or idconflictsmail).  
   
 defdom (domain for which to retrieve configuration settings),  defdom (domain for which to retrieve configuration settings),
   origmail (scalar - email address of recipient from loncapa.conf, 
 origmail (scalar - email address of recipient from loncapa.conf,  i.e., predates configuration by DC via domainprefs.pm 
 i.e., predates configuration by DC via domainprefs.pm  
   
 Returns: comma separated list of addresses to which to send e-mail.  Returns: comma separated list of addresses to which to send e-mail.
   
Line 13547  sub assign_category_rows { Line 12938  sub assign_category_rows {
             if (ref($cats->[$depth]{$parent}) eq 'ARRAY') {              if (ref($cats->[$depth]{$parent}) eq 'ARRAY') {
                 my $numchildren = @{$cats->[$depth]{$parent}};                  my $numchildren = @{$cats->[$depth]{$parent}};
                 my $css_class = $itemcount%2?' class="LC_odd_row"':'';                  my $css_class = $itemcount%2?' class="LC_odd_row"':'';
                 $text .= '<td><table class="LC_data_table">';                  $text .= '<td><table class="LC_datatable">';
                 for (my $j=0; $j<$numchildren; $j++) {                  for (my $j=0; $j<$numchildren; $j++) {
                     $name = $cats->[$depth]{$parent}[$j];                      $name = $cats->[$depth]{$parent}[$j];
                     $item = &escape($name).':'.&escape($parent).':'.$depth;                      $item = &escape($name).':'.&escape($parent).':'.$depth;
Line 13595  sub commit_customrole { Line 12986  sub commit_customrole {
 }  }
   
 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) = @_;
     my ($output,$logmsg,$linefeed);      my ($output,$logmsg,$linefeed);
     if ($context eq 'auto') {      if ($context eq 'auto') {
         $linefeed = "\n";          $linefeed = "\n";
Line 13604  sub commit_standardrole { Line 12995  sub commit_standardrole {
     }        }  
     if ($three eq 'st') {      if ($three eq 'st') {
         my $result = &commit_studentrole(\$logmsg,$udom,$uname,$url,$three,$start,$end,          my $result = &commit_studentrole(\$logmsg,$udom,$uname,$url,$three,$start,$end,
                                          $one,$two,$sec,$context,$credits);                                           $one,$two,$sec,$context);
         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 13635  sub commit_standardrole { Line 13026  sub commit_standardrole {
 }  }
   
 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) = @_;  
     my ($result,$linefeed,$oldsecurl,$newsecurl);      my ($result,$linefeed,$oldsecurl,$newsecurl);
     if ($context eq 'auto') {      if ($context eq 'auto') {
         $linefeed = "\n";          $linefeed = "\n";
Line 13683  sub commit_studentrole { Line 13073  sub commit_studentrole {
             }              }
         }          }
         if (($expire_role_result eq 'ok') || ($secchange == 0)) {          if (($expire_role_result eq 'ok') || ($secchange == 0)) {
             $modify_section_result =               $modify_section_result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,'','',$cid,'',$context);
                 &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,  
                                                            undef,undef,undef,$sec,  
                                                            $end,$start,'','',$cid,  
                                                            '',$context,$credits);  
             if ($modify_section_result =~ /^ok/) {              if ($modify_section_result =~ /^ok/) {
                 if ($secchange == 1) {                  if ($secchange == 1) {
                     if ($sec eq '') {                      if ($sec eq '') {
Line 13718  sub commit_studentrole { Line 13104  sub commit_studentrole {
             $result = $modify_section_result;              $result = $modify_section_result;
         } elsif ($secchange == 1) {          } elsif ($secchange == 1) {
             if ($oldsec eq '') {              if ($oldsec eq '') {
                 $$logmsg .= &mt('Error when attempting to expire existing role without a section for [_1] in course [_2] -error: ',$uname,$cid).' '.$expire_role_result.$linefeed;                  $$logmsg .= &mt('Error when attempting to expire existing role without a section for [_1] in course [_3] -error: ',$uname,$cid).' '.$expire_role_result.$linefeed;
             } else {              } else {
                 $$logmsg .= &mt('Error when attempting to expire existing role for [_1] in section [_2] in course [_3] -error: ',$uname,$oldsec,$cid).' '.$expire_role_result.$linefeed;                  $$logmsg .= &mt('Error when attempting to expire existing role for [_1] in section [_2] in course [_3] -error: ',$uname,$oldsec,$cid).' '.$expire_role_result.$linefeed;
             }              }
Line 13744  sub commit_studentrole { Line 13130  sub commit_studentrole {
     return $result;      return $result;
 }  }
   
 sub show_role_extent {  
     my ($scope,$context,$role) = @_;  
     $scope =~ s{^/}{};  
     my @courseroles = &Apache::lonuserutils::roles_by_context('course',1);  
     push(@courseroles,'co');  
     my @authorroles = &Apache::lonuserutils::roles_by_context('author');  
     if (($context eq 'course') || (grep(/^\Q$role\E/,@courseroles))) {  
         $scope =~ s{/}{_};  
         return '<span class="LC_cusr_emph">'.$env{'course.'.$scope.'.description'}.'</span>';  
     } elsif (($context eq 'author') || (grep(/^\Q$role\E/,@authorroles))) {  
         my ($audom,$auname) = split(/\//,$scope);  
         return &mt('[_1] Author Space','<span class="LC_cusr_emph">'.  
                    &Apache::loncommon::plainname($auname,$audom).'</span>');  
     } else {  
         $scope =~ s{/$}{};  
         return &mt('Domain: [_1]','<span class="LC_cusr_emph">'.  
                    &Apache::lonnet::domain($scope,'description').'</span>');  
     }  
 }  
   
 ############################################################  ############################################################
 ############################################################  ############################################################
   
Line 13927  sub construct_course { Line 13293  sub construct_course {
                    'pch.users.denied',                     'pch.users.denied',
                    'plc.users.denied',                     'plc.users.denied',
                    'hidefromcat',                     'hidefromcat',
                    'checkforpriv',  
                    'categories'],                     'categories'],
                    $$crsudom,$$crsunum);                     $$crsudom,$$crsunum);
     }      }
Line 13957  sub construct_course { Line 13322  sub construct_course {
     } else {      } else {
         $cenv{'internal.courseowner'} = $args->{'curruser'};          $cenv{'internal.courseowner'} = $args->{'curruser'};
     }      }
     if ($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.
     if ($args->{'crssections'}) {      if ($args->{'crssections'}) {
         $cenv{'internal.sectionnums'} = '';          $cenv{'internal.sectionnums'} = '';
Line 13984  sub construct_course { Line 13346  sub construct_course {
 # do not hide course coordinator from staff listing,   # do not hide course coordinator from staff listing, 
 # even if privileged  # even if privileged
     $cenv{'nothideprivileged'}=$args->{'ccuname'}.':'.$args->{'ccdomain'};      $cenv{'nothideprivileged'}=$args->{'ccuname'}.':'.$args->{'ccdomain'};
 # add course coordinator's domain to domains to check for privileged users  
 # if different to course domain  
     if ($$crsudom ne $args->{'ccdomain'}) {  
         $cenv{'checkforpriv'} = $args->{'ccdomain'};  
     }  
 # add crosslistings  # add crosslistings
     if ($args->{'crsxlist'}) {      if ($args->{'crsxlist'}) {
         $cenv{'internal.crosslistings'}='';          $cenv{'internal.crosslistings'}='';
Line 14345  sub init_user_environment { Line 13702  sub init_user_environment {
 # ------------------------------------ Check browser type and MathML capability  # ------------------------------------ Check browser type and MathML capability
   
     my ($httpbrowser,$clientbrowser,$clientversion,$clientmathml,      my ($httpbrowser,$clientbrowser,$clientversion,$clientmathml,
         $clientunicode,$clientos,$clientmobile,$clientinfo) = &decode_user_agent($r);          $clientunicode,$clientos) = &decode_user_agent($r);
   
 # ------------------------------------------------------------- Get environment  # ------------------------------------------------------------- Get environment
   
Line 14376  sub init_user_environment { Line 13733  sub init_user_environment {
      "browser.mathml"     => $clientmathml,       "browser.mathml"     => $clientmathml,
      "browser.unicode"    => $clientunicode,       "browser.unicode"    => $clientunicode,
      "browser.os"         => $clientos,       "browser.os"         => $clientos,
              "browser.mobile"     => $clientmobile,  
              "browser.info"       => $clientinfo,  
      "server.domain"      => $Apache::lonnet::perlvar{'lonDefDomain'},       "server.domain"      => $Apache::lonnet::perlvar{'lonDefDomain'},
      "request.course.fn"  => '',       "request.course.fn"  => '',
      "request.course.uri" => '',       "request.course.uri" => '',
Line 14416  sub init_user_environment { Line 13771  sub init_user_environment {
                                                   \%userenv,\%domdef,\%is_adv);                                                    \%userenv,\%domdef,\%is_adv);
         }          }
   
         $userenv{'canrequest.author'} =  
             &Apache::lonnet::usertools_access($username,$domain,'requestauthor',  
                                         'reload','requestauthor',  
                                         \%userenv,\%domdef,\%is_adv);  
         my %reqauthor = &Apache::lonnet::get('requestauthor',['author_status','author'],  
                                              $domain,$username);  
         my $reqstatus = $reqauthor{'author_status'};  
         if ($reqstatus eq 'approval' || $reqstatus eq 'approved') {  
             if (ref($reqauthor{'author'}) eq 'HASH') {  
                 $userenv{'requestauthorqueued'} = $reqstatus.':'.  
                                                   $reqauthor{'author'}{'timestamp'};  
             }  
         }  
   
  $env{'user.environment'} = "$lonids/$cookie.id";   $env{'user.environment'} = "$lonids/$cookie.id";
   
  if (tie(my %disk_env,'GDBM_File',"$lonids/$cookie.id",   if (tie(my %disk_env,'GDBM_File',"$lonids/$cookie.id",
Line 14581  sub update_content_constraints { Line 13922  sub update_content_constraints {
     return;      return;
 }  }
   
 sub allmaps_incourse {  
     my ($cdom,$cnum,$chome,$cid) = @_;  
     if ($cdom eq '' || $cnum eq '' || $chome eq '' || $cid eq '') {  
         $cid = $env{'request.course.id'};  
         $cdom = $env{'course.'.$cid.'.domain'};  
         $cnum = $env{'course.'.$cid.'.num'};  
         $chome = $env{'course.'.$cid.'.home'};  
     }  
     my %allmaps = ();  
     my $lastchange =  
         &Apache::lonnet::get_coursechange($cdom,$cnum);  
     if ($lastchange > $env{'request.course.tied'}) {  
         my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum");  
         unless ($ferr) {  
             &update_content_constraints($cdom,$cnum,$chome,$cid);  
         }  
     }  
     my $navmap = Apache::lonnavmaps::navmap->new();  
     if (defined($navmap)) {  
         foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_map() },1,0,1)) {  
             $allmaps{$res->src()} = 1;  
         }  
     }  
     return \%allmaps;  
 }  
   
 sub parse_supplemental_title {  sub parse_supplemental_title {
     my ($title) = @_;      my ($title) = @_;
   
Line 14630  sub parse_supplemental_title { Line 13945  sub parse_supplemental_title {
     return $title;      return $title;
 }  }
   
 sub recurse_supplemental {  
     my ($cnum,$cdom,$suppmap,$numfiles,$errors) = @_;  
     if ($suppmap) {  
         my ($errtext,$fatal) = &LONCAPA::map::mapread('/uploaded/'.$cdom.'/'.$cnum.'/'.$suppmap);  
         if ($fatal) {  
             $errors ++;  
         } else {  
             if ($#LONCAPA::map::resources > 0) {  
                 foreach my $res (@LONCAPA::map::resources) {  
                     my ($title,$src,$ext,$type,$status)=split(/\:/,$res);  
                     if (($src ne '') && ($status eq 'res')) {  
                         if ($src =~ m{^\Q/uploaded/$cdom/$cnum/\E(supplemental_\d+\.sequence)$}) {  
                             ($numfiles,$errors) = &recurse_supplemental($cnum,$cdom,$1,$numfiles,$errors);  
                         } else {  
                             $numfiles ++;  
                         }  
                     }  
                 }  
             }  
         }  
     }  
     return ($numfiles,$errors);  
 }  
   
 sub symb_to_docspath {  
     my ($symb) = @_;  
     return unless ($symb);  
     my ($mapurl,$id,$resurl) = &Apache::lonnet::decode_symb($symb);  
     if ($resurl=~/\.(sequence|page)$/) {  
         $mapurl=$resurl;  
     } elsif ($resurl eq 'adm/navmaps') {  
         $mapurl=$env{'course.'.$env{'request.course.id'}.'.url'};  
     }  
     my $mapresobj;  
     my $navmap = Apache::lonnavmaps::navmap->new();  
     if (ref($navmap)) {  
         $mapresobj = $navmap->getResourceByUrl($mapurl);  
     }  
     $mapurl=~s{^.*/([^/]+)\.(\w+)$}{$1};  
     my $type=$2;  
     my $path;  
     if (ref($mapresobj)) {  
         my $pcslist = $mapresobj->map_hierarchy();  
         if ($pcslist ne '') {  
             foreach my $pc (split(/,/,$pcslist)) {  
                 next if ($pc <= 1);  
                 my $res = $navmap->getByMapPc($pc);  
                 if (ref($res)) {  
                     my $thisurl = $res->src();  
                     $thisurl=~s{^.*/([^/]+)\.\w+$}{$1};  
                     my $thistitle = $res->title();  
                     $path .= '&'.  
                              &Apache::lonhtmlcommon::entity_encode($thisurl).'&'.  
                              &escape($thistitle).  
                              ':'.$res->randompick().  
                              ':'.$res->randomout().  
                              ':'.$res->encrypted().  
                              ':'.$res->randomorder().  
                              ':'.$res->is_page();  
                 }  
             }  
         }  
         $path =~ s/^\&//;  
         my $maptitle = $mapresobj->title();  
         if ($mapurl eq 'default') {  
             $maptitle = 'Main Content';  
         }  
         $path .= (($path ne '')? '&' : '').  
                  &Apache::lonhtmlcommon::entity_encode($mapurl).'&'.  
                  &escape($maptitle).  
                  ':'.$mapresobj->randompick().  
                  ':'.$mapresobj->randomout().  
                  ':'.$mapresobj->encrypted().  
                  ':'.$mapresobj->randomorder().  
                  ':'.$mapresobj->is_page();  
     } else {  
         my $maptitle = &Apache::lonnet::gettitle($mapurl);  
         my $ispage = (($type eq 'page')? 1 : '');  
         if ($mapurl eq 'default') {  
             $maptitle = 'Main Content';  
         }  
         $path = &Apache::lonhtmlcommon::entity_encode($mapurl).'&'.  
                 &escape($maptitle).':::::'.$ispage;  
     }  
     unless ($mapurl eq 'default') {  
         $path = 'default&'.  
                 &escape('Main Content').  
                 ':::::&'.$path;  
     }  
     return $path;  
 }  
   
 sub captcha_display {  
     my ($context,$lonhost) = @_;  
     my ($output,$error);  
     my ($captcha,$pubkey,$privkey) = &get_captcha_config($context,$lonhost);  
     if ($captcha eq 'original') {  
         $output = &create_captcha();  
         unless ($output) {  
             $error = 'captcha';  
         }  
     } elsif ($captcha eq 'recaptcha') {  
         $output = &create_recaptcha($pubkey);  
         unless ($output) {  
             $error = 'recaptcha';  
         }  
     }  
     return ($output,$error);  
 }  
   
 sub captcha_response {  
     my ($context,$lonhost) = @_;  
     my ($captcha_chk,$captcha_error);  
     my ($captcha,$pubkey,$privkey) = &get_captcha_config($context,$lonhost);  
     if ($captcha eq 'original') {  
         ($captcha_chk,$captcha_error) = &check_captcha();  
     } elsif ($captcha eq 'recaptcha') {  
         $captcha_chk = &check_recaptcha($privkey);  
     } else {  
         $captcha_chk = 1;  
     }  
     return ($captcha_chk,$captcha_error);  
 }  
   
 sub get_captcha_config {  
     my ($context,$lonhost) = @_;  
     my ($captcha,$pubkey,$privkey,$hashtocheck);  
     my $hostname = &Apache::lonnet::hostname($lonhost);  
     my $serverhomeID = &Apache::lonnet::get_server_homeID($hostname);  
     my $serverhomedom = &Apache::lonnet::host_domain($serverhomeID);  
     if ($context eq 'usercreation') {  
         my %domconfig = &Apache::lonnet::get_dom('configuration',[$context],$serverhomedom);  
         if (ref($domconfig{$context}) eq 'HASH') {  
             $hashtocheck = $domconfig{$context}{'cancreate'};  
             if (ref($hashtocheck) eq 'HASH') {  
                 if ($hashtocheck->{'captcha'} eq 'recaptcha') {  
                     if (ref($hashtocheck->{'recaptchakeys'}) eq 'HASH') {  
                         $pubkey = $hashtocheck->{'recaptchakeys'}{'public'};  
                         $privkey = $hashtocheck->{'recaptchakeys'}{'private'};  
                     }  
                     if ($privkey && $pubkey) {  
                         $captcha = 'recaptcha';  
                     } else {  
                         $captcha = 'original';  
                     }  
                 } elsif ($hashtocheck->{'captcha'} ne 'notused') {  
                     $captcha = 'original';  
                 }  
             }  
         } else {  
             $captcha = 'captcha';  
         }  
     } elsif ($context eq 'login') {  
         my %domconfhash = &Apache::loncommon::get_domainconf($serverhomedom);  
         if ($domconfhash{$serverhomedom.'.login.captcha'} eq 'recaptcha') {  
             $pubkey = $domconfhash{$serverhomedom.'.login.recaptchakeys_public'};  
             $privkey = $domconfhash{$serverhomedom.'.login.recaptchakeys_private'};  
             if ($privkey && $pubkey) {  
                 $captcha = 'recaptcha';  
             } else {  
                 $captcha = 'original';  
             }  
         } elsif ($domconfhash{$serverhomedom.'.login.captcha'} eq 'original') {  
             $captcha = 'original';  
         }  
     }  
     return ($captcha,$pubkey,$privkey);  
 }  
   
 sub create_captcha {  
     my %captcha_params = &captcha_settings();  
     my ($output,$maxtries,$tries) = ('',10,0);  
     while ($tries < $maxtries) {  
         $tries ++;  
         my $captcha = Authen::Captcha->new (  
                                            output_folder => $captcha_params{'output_dir'},  
                                            data_folder   => $captcha_params{'db_dir'},  
                                           );  
         my $md5sum = $captcha->generate_code($captcha_params{'numchars'});  
   
         if (-e $Apache::lonnet::perlvar{'lonCaptchaDir'}.'/'.$md5sum.'.png') {  
             $output = '<input type="hidden" name="crypt" value="'.$md5sum.'" />'."\n".  
                       &mt('Type in the letters/numbers shown below').'&nbsp;'.  
                      '<input type="text" size="5" name="code" value="" /><br />'.  
                      '<img src="'.$captcha_params{'www_output_dir'}.'/'.$md5sum.'.png" />';  
             last;  
         }  
     }  
     return $output;  
 }  
   
 sub captcha_settings {  
     my %captcha_params = (  
                            output_dir     => $Apache::lonnet::perlvar{'lonCaptchaDir'},  
                            www_output_dir => "/captchaspool",  
                            db_dir         => $Apache::lonnet::perlvar{'lonCaptchaDb'},  
                            numchars       => '5',  
                          );  
     return %captcha_params;  
 }  
   
 sub check_captcha {  
     my ($captcha_chk,$captcha_error);  
     my $code = $env{'form.code'};  
     my $md5sum = $env{'form.crypt'};  
     my %captcha_params = &captcha_settings();  
     my $captcha = Authen::Captcha->new(  
                       output_folder => $captcha_params{'output_dir'},  
                       data_folder   => $captcha_params{'db_dir'},  
                   );  
     $captcha_chk = $captcha->check_code($code,$md5sum);  
     my %captcha_hash = (  
                         0       => 'Code not checked (file error)',  
                        -1      => 'Failed: code expired',  
                        -2      => 'Failed: invalid code (not in database)',  
                        -3      => 'Failed: invalid code (code does not match crypt)',  
     );  
     if ($captcha_chk != 1) {  
         $captcha_error = $captcha_hash{$captcha_chk}  
     }  
     return ($captcha_chk,$captcha_error);  
 }  
   
 sub create_recaptcha {  
     my ($pubkey) = @_;  
     my $captcha = Captcha::reCAPTCHA->new;  
     return $captcha->get_options_setter({theme => 'white'})."\n".  
            $captcha->get_html($pubkey).  
            &mt('If either word is hard to read, [_1] will replace them.',  
                '<img src="/res/adm/pages/refresh.gif" alt="reCAPTCHA refresh" />').  
            '<br /><br />';  
 }  
   
 sub check_recaptcha {  
     my ($privkey) = @_;  
     my $captcha_chk;  
     my $captcha = Captcha::reCAPTCHA->new;  
     my $captcha_result =  
         $captcha->check_answer(  
                                 $privkey,  
                                 $ENV{'REMOTE_ADDR'},  
                                 $env{'form.recaptcha_challenge_field'},  
                                 $env{'form.recaptcha_response_field'},  
                               );  
     if ($captcha_result->{is_valid}) {  
         $captcha_chk = 1;  
     }  
     return $captcha_chk;  
 }  
   
 =pod  =pod
   
 =back  =back

Removed from v.1.1075.2.50  
changed lines
  Added in v.1.1085


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