Diff for /loncom/interface/loncommon.pm between versions 1.1094 and 1.1154

version 1.1094, 2012/08/25 04:34:44 version 1.1154, 2013/09/07 19:58:01
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;
Line 529  ENDAUTHORBRW Line 531  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 595  sub coursebrowser_javascript {
     }      }
 $id_functions  $id_functions
 ENDSTDBRW  ENDSTDBRW
     if (($sec_element ne '') || ($role_element ne '')) {      if (($sec_element ne '') || ($role_element ne '') || ($credits_element ne '')) {
         $output .= &setsec_javascript($sec_element,$formname,$role_element);          $output .= &setsec_javascript($sec_element,$formname,$role_element,
                                         $credits_element);
     }      }
     $output .= '      $output .= '
 // ]]>  // ]]>
Line 750  ENDUSERBRW Line 754  ENDUSERBRW
 }  }
   
 sub setsec_javascript {  sub setsec_javascript {
     my ($sec_element,$formname,$role_element) = @_;      my ($sec_element,$formname,$role_element,$credits_element) = @_;
     my (@courserolenames,@communityrolenames,$rolestr,$courserolestr,      my (@courserolenames,@communityrolenames,$rolestr,$courserolestr,
         $communityrolestr);          $communityrolestr);
     if ($role_element ne '') {      if ($role_element ne '') {
Line 845  function setRole(crstype) { Line 849  function setRole(crstype) {
 }  }
 |;  |;
     }      }
       if ($credits_element) {
           $setsections .= qq|
   function setCredits(defaultcredits) {
       document.$formname.$credits_element.value = defaultcredits;
       return;
   }
   |;
       }
     return $setsections;      return $setsections;
 }  }
   
Line 999  sub select_language { Line 1011  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 1057  linked_select_forms takes the following Line 1070  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 1110  sub linked_select_forms { Line 1129  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 1166  function select1_changed() { Line 1187  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()\">\n";      $result .= "<select size=\"1\" name=\"$firstselectname\" onchange=\"select1_changed();$onchangefirst\">\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 1179  END Line 1200  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\">\n";      $result .= "<select size=\"1\" name=\"$secondselectname\"";
       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 1368  END Line 1393  END
 }  }
   
 sub help_menu_js {  sub help_menu_js {
     my ($text) = @_;      my ($httphost) = @_;
     my $stayOnPage = 1;      my $stayOnPage = 1;
     my $width = 620;      my $width = 620;
     my $height = 600;      my $height = 600;
     my $helptopic=&general_help();      my $helptopic=&general_help();
     my $details_link = '/adm/help/'.$helptopic.'.hlp';      my $details_link = $httphost.'/adm/help/'.$helptopic.'.hlp';
     my $nothing=&Apache::lonhtmlcommon::javascript_nothing();      my $nothing=&Apache::lonhtmlcommon::javascript_nothing();
     my $start_page =      my $start_page =
         &Apache::loncommon::start_page('Help Menu', undef,          &Apache::loncommon::start_page('Help Menu', undef,
        {'frameset'    => 1,         {'frameset'    => 1,
  'js_ready'    => 1,   'js_ready'    => 1,
                                           'use_absolute' => $httphost,
  'add_entries' => {   'add_entries' => {
     'border' => '0',      'border' => '0',
     'rows'   => "110,*",},});      'rows'   => "110,*",},});
Line 2166  sub select_level_form { Line 2192  sub select_level_form {
   
 =pod  =pod
   
 =item * &select_dom_form($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms)  =item * &select_dom_form($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms,$excdoms)
   
 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 2179  If the $showdomdesc flag is set, the dom Line 2205  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) = @_;      my ($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms,$excdoms) = @_;
     if ($onchange) {      if ($onchange) {
         $onchange = ' onchange="'.$onchange.'"';          $onchange = ' onchange="'.$onchange.'"';
     }      }
     my @domains;      my (@domains,%exclude);
     if (ref($incdoms) eq 'ARRAY') {      if (ref($incdoms) eq 'ARRAY') {
         @domains = sort {lc($a) cmp lc($b)} (@{$incdoms});          @domains = sort {lc($a) cmp lc($b)} (@{$incdoms});
     } 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 2318  Outputs: Line 2350  Outputs:
   
 =item * $clientos  =item * $clientos
   
   =item * $clientmobile
   
   =item * $clientinfo
   
 =back  =back
   
 =back   =back 
Line 2336  sub decode_user_agent { Line 2372  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 2347  sub decode_user_agent { Line 2384  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 2358  sub decode_user_agent { Line 2396  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,);              $clientunicode,$clientos,$clientmobile,$clientinfo);
 }  }
   
 ###############################################################  ###############################################################
Line 2511  END Line 2557  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 2520  sub authform_authorwarning{ Line 2566  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 (keys(%can_assign) == 0) {      if (!$authnum) {
         $result = &mt('Under you current role you are not permitted to change login settings for this user');            $result = &mt('Under your 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 2549  sub authform_kerberos { Line 2595  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 2599  sub authform_kerberos { Line 2645  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="hidden" name="login" value="krb" />';                      $authtype = '<input type="radio" name="login" value="krb" />';
                 }                  }
             }              }
         }          }
Line 2611  sub authform_kerberos { Line 2657  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 2649  sub authform_kerberos { Line 2695  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 2685  sub authform_internal{ Line 2731  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="hidden" name="login" value="int" />';                      $authtype = '<input type="radio" name="login" value="int" />';
                 }                  }
             }              }
         }          }
Line 2704  sub authform_internal{ Line 2750  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 2740  sub authform_local{ Line 2786  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="hidden" name="login" value="loc" />';                      $authtype = '<input type="radio" name="login" value="loc" />';
                 }                  }
             }              }
         }          }
Line 2758  sub authform_local{ Line 2804  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 2791  sub authform_filesystem{ Line 2837  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="hidden" name="login" value="fsys" />';                      $authtype = '<input type="radio" name="login" value="fsys" />';
                 }                  }
             }              }
         }          }
Line 3029  sub get_related_words { Line 3075  sub get_related_words {
   
 =pod  =pod
   
   =back
   
 =head1 Spell checking  =head1 Spell checking
   
 =over 4  =over 4
Line 3062  Note: This sub assumes that aspell is in Line 3110  Note: This sub assumes that aspell is in
 =cut  =cut
   
   
 =pod  
   
 =back  
   
 =cut  
   
 sub check_spelling {  sub check_spelling {
     my ($wordlist, $language) = @_;      my ($wordlist, $language) = @_;
     my @misspellings;      my @misspellings;
Line 3283  sub screenname { Line 3325  sub screenname {
 # ------------------------------------------------------------- Confirm Wrapper  # ------------------------------------------------------------- Confirm Wrapper
 =pod  =pod
   
 =item confirmwrapper  =item * &confirmwrapper($message)
   
 Wrap messages about completion of operation in box  Wrap messages about completion of operation in box
   
Line 3326  sub aboutmewrapper { Line 3368  sub aboutmewrapper {
     if (!defined($username)  && !defined($domain)) {      if (!defined($username)  && !defined($domain)) {
         return;          return;
     }      }
     return '<a href="/adm/'.$domain.'/'.$username.'/aboutme?forcestudent=1"'.      return '<a href="/adm/'.$domain.'/'.$username.'/aboutme"'.
  ($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 4901  sub designparm { Line 4943  sub designparm {
   
 Inputs: $url (usually will be undef).  Inputs: $url (usually will be undef).
   
 Returns: Path to Construction Space containing the resource or   Returns: Path to Authoring 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 4964  Input: (optional) filename from which br Line 5006  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 Construction Space pages           To be included on Authoring Space pages
   
 =cut  =cut
   
Line 4979  sub CSTR_pageheader { Line 5021  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 4995  sub CSTR_pageheader { Line 5037  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('Construction Space:').'</b> '          .'<b>'.&mt('Authoring 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 5060  Inputs: Line 5102  Inputs:
                               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 5071  other decorations will be returned. Line 5117  other decorations will be returned.
   
 sub bodytag {  sub bodytag {
     my ($title,$function,$addentries,$bodyonly,$domain,$forcereg,      my ($title,$function,$addentries,$bodyonly,$domain,$forcereg,
         $no_nav_bar,$bgcolor,$args)=@_;          $no_nav_bar,$bgcolor,$args,$advtoolsref)=@_;
   
     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 5079  sub bodytag { Line 5125  sub bodytag {
         $public = 1;          $public = 1;
     }      }
     if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); }      if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); }
       my $httphost = $args->{'use_absolute'};
   
     $function = &get_users_function() if (!$function);      $function = &get_users_function() if (!$function);
     my $img =    &designparm($function.'.img',$domain);      my $img =    &designparm($function.'.img',$domain);
Line 5120  sub bodytag { Line 5167  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'});
   
     if ($bodyonly) {      &get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['inhibitmenu']);
   
       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 5145  sub bodytag { Line 5190  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 ($no_nav_bar || $env{'form.inhibitmenu'} eq 'yes') {   
             return $bodytag;   
         }   
   
         if ($env{'request.state'} eq 'construct') { $forcereg=1; }          if ($env{'request.state'} eq 'construct') { $forcereg=1; }
   
Line 5157  sub bodytag { Line 5197  sub bodytag {
         #        $titleinfo = &CSTR_pageheader(); #FIXME: Will be removed once all scripts have their own calls          #        $titleinfo = &CSTR_pageheader(); #FIXME: Will be removed once all scripts have their own calls
         #    }          #    }
   
           $bodytag .= Apache::lonhtmlcommon::scripttag(
               Apache::lonmenu::utilityfunctions($httphost), '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">$name $role<br />               $bodytag .= qq|<div id="LC_nav_bar">$left $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">$name $role</div>|;              $bodytag .= qq|<div id="LC_nav_bar">$left $role</div>|;
         }          }
   
         $bodytag .= Apache::lonhtmlcommon::scripttag(          $bodytag .= $right;
             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 5184  sub bodytag { Line 5224  sub bodytag {
   
         #don't show menus for public users          #don't show menus for public users
         if (!$public){          if (!$public){
             $bodytag .= Apache::lonmenu::secondary_menu();              $bodytag .= Apache::lonmenu::secondary_menu($httphost);
             $bodytag .= Apache::lonmenu::serverform();              $bodytag .= Apache::lonmenu::serverform();
             $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end');              $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end');
             if ($env{'request.state'} eq 'construct') {              if ($env{'request.state'} eq 'construct') {
                 $bodytag .= &Apache::lonmenu::innerregister($forcereg,                  $bodytag .= &Apache::lonmenu::innerregister($forcereg,
                                 $args->{'bread_crumbs'});                                  $args->{'bread_crumbs'});
             } elsif ($forcereg) {               } elsif ($forcereg) {
                 $bodytag .= &Apache::lonmenu::innerregister($forcereg);                  $bodytag .= &Apache::lonmenu::innerregister($forcereg,undef,
                                                               $args->{'group'});
               } else {
                   $bodytag .= 
                       &Apache::lonmenu::prepare_functions($env{'request.noversionuri'},
                                                           $forcereg,$args->{'group'},
                                                           $args->{'bread_crumbs'},
                                                           $advtoolsref);
             }              }
         }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 5368  form, .inline { Line 5415  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 5406  form, .inline { Line 5461  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 5572  td.LC_table_cell_checkbox { Line 5629  td.LC_table_cell_checkbox {
   text-align: left;    text-align: left;
 }  }
   
 .LC_head_subbox {  .LC_head_subbox, .LC_actionbox {
   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 5709  table.LC_nested tr.LC_empty_row td { Line 5766  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 6271  div.LC_docs_entry_move { Line 6329  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 6436  div.LC_edit_problem_saves { Line 6493  div.LC_edit_problem_saves {
   padding-bottom: 5px;    padding-bottom: 5px;
 }  }
   
   .LC_edit_opt {
     padding-left: 1em;
     white-space: nowrap;
   }
   
   .LC_edit_problem_latexhelper{
       text-align: right;
   }
   
   #LC_edit_problem_colorful div{
       margin-left: 40px;
   }
   
 img.stift {  img.stift {
   border-width: 0;    border-width: 0;
   vertical-align: middle;    vertical-align: middle;
Line 6450  div.LC_createcourse { Line 6520  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 6547  fieldset > legend { Line 6618  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 6644  ol.LC_docs_parameters li.LC_docs_paramet Line 6714  ol.LC_docs_parameters li.LC_docs_paramet
 }  }
   
 ul#LC_secondary_menu {  ul#LC_secondary_menu {
   clear: both;    clear: right;
   color: $fontmenu;    color: $fontmenu;
   background: $tabbg;    background: $tabbg;
   list-style: none;    list-style: none;
Line 6652  ul#LC_secondary_menu { Line 6722  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;
     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;
   display: inline;    background-color: $data_table_light;
   vertical-align: middle;    list-style:none;
     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 7107  ul.LC_funclist li { Line 7214  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 7143  sub headtag { Line 7271  sub headtag {
     my $function = $args->{'function'} || &get_users_function();      my $function = $args->{'function'} || &get_users_function();
     my $domain   = $args->{'domain'}   || &determinedomain();      my $domain   = $args->{'domain'}   || &determinedomain();
     my $bgcolor  = $args->{'bgcolor'}  || &designparm($function.'.pgbg',$domain);      my $bgcolor  = $args->{'bgcolor'}  || &designparm($function.'.pgbg',$domain);
       my $httphost = $args->{'use_absolute'};
     my $url = join(':',$env{'user.name'},$env{'user.domain'},      my $url = join(':',$env{'user.name'},$env{'user.domain'},
    $Apache::lonnet::perlvar{'lonVersion'},     $Apache::lonnet::perlvar{'lonVersion'},
    #time(),     #time(),
Line 7166  sub headtag { Line 7295  sub headtag {
     if (!$args->{'no_nav_bar'}       if (!$args->{'no_nav_bar'} 
  && !$args->{'only_body'}   && !$args->{'only_body'}
  && !$args->{'frameset'}) {   && !$args->{'frameset'}) {
  $result .= &help_menu_js();   $result .= &help_menu_js($httphost);
         $result.=&modal_window();          $result.=&modal_window();
         $result.=&togglebox_script();          $result.=&togglebox_script();
         $result.=&wishlist_window();          $result.=&wishlist_window();
Line 7204  ADDMETA Line 7333  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 7376  $args - additional optional args support Line 7510  $args - additional optional args support
                                     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 7388  sub start_page { Line 7524  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;      my ($result,@advtools);
   
     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 7405  sub start_page { Line 7541  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);                           $args->{'bgcolor'},        $args,
                            \@advtools);
         }          }
     }      }
   
Line 7434  sub start_page { Line 7571  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 7530  var modalWindow = { Line 7671  var modalWindow = {
  $(".LCmodal-overlay").click(function(){modalWindow.close();});   $(".LCmodal-overlay").click(function(){modalWindow.close();});
  }   }
 };  };
  var openMyModal = function(source,width,height,scrolling)   var openMyModal = function(source,width,height,scrolling,transparency,style)
  {   {
  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='true' src='" + source + "'>&lt/iframe>";   modalWindow.content = "<iframe width='"+width+"' height='"+height+"' frameborder='0' scrolling='"+scrolling+"' allowtransparency='"+transparency+"' src='" + source + "' style='"+style+"'>&lt/iframe>";
  modalWindow.open();   modalWindow.open();
  };   };
 // END LON-CAPA Internal -->  // END LON-CAPA Internal -->
Line 7545  ENDMODAL Line 7686  ENDMODAL
 }  }
   
 sub modal_link {  sub modal_link {
     my ($link,$linktext,$width,$height,$target,$scrolling,$title)=@_;      my ($link,$linktext,$width,$height,$target,$scrolling,$title,$transparency,$style)=@_;
     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'); return false;">  <a href="$link" $target_attr title="$title" onclick="javascript:openMyModal('$link',$width,$height,'$scrolling','$transparency','$style'); return false;">
            $linktext</a>             $linktext</a>
 ENDLINK  ENDLINK
 }  }
Line 7581  sub modal_adhoc_inner { Line 7724  sub modal_adhoc_inner {
     my ($funcname,$width,$height,$content)=@_;      my ($funcname,$width,$height,$content)=@_;
     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').                   &start_scrollbox($width.'px',$innerwidth.'px',$height.'px','myModal','#FFFFFF',undef,1).
                     $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 7704  sub LCprogressbar { Line 7847  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 7804  sub validate_page { Line 7945  sub validate_page {
   
   
 sub start_scrollbox {  sub start_scrollbox {
     my ($outerwidth,$width,$height,$id,$bgcolor)=@_;      my ($outerwidth,$width,$height,$id,$bgcolor,$cursor,$needjsready) = @_;
     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";
 <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>  $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>
 END  END
 }  }
   
Line 7825  sub end_scrollbox { Line 7973  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) = @_;      my ($r,$title,$msg,$args) = @_;
       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).
  &mt($msg).   '<p class="LC_error">'.$msg.'</p>'.
  &Apache::loncommon::end_page();   &Apache::loncommon::end_page();
     if (ref($r)) {      if (ref($r)) {
  $r->print($page);   $r->print($page);
Line 8122  sub get_sections { Line 8357  sub get_sections {
     my %sectioncount;      my %sectioncount;
     my $now = time;      my $now = time;
   
     if (!defined($possible_roles) || (grep(/^st$/,@$possible_roles))) {      my $check_students = 1;
       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 8149  sub get_sections { Line 8396  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 8296  sub get_course_users { Line 8546  sub get_course_users {
                               active   => 'Active',                                active   => 'Active',
                               future   => 'Future',                                future   => 'Future',
                             );                              );
         my %nothide;          my (%nothide,@possdoms);
         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 8306  sub get_course_users { Line 8556  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 8341  sub get_course_users { Line 8595  sub get_course_users {
                 }                  }
                 if ($uname ne '' && $udom ne '') {                  if ($uname ne '' && $udom ne '') {
                     if ($hidepriv) {                      if ($hidepriv) {
                         if ((&Apache::lonnet::privileged($uname,$udom)) &&                          if ((&Apache::lonnet::privileged($uname,$udom,\@possdoms)) &&
                             (!$nothide{$uname.':'.$udom})) {                              (!$nothide{$uname.':'.$udom})) {
                             next;                              next;
                         }                          }
Line 8429  sub get_user_info { Line 8683  sub get_user_info {
   
 =item * &get_user_quota()  =item * &get_user_quota()
   
 Retrieves quota assigned for storage of portfolio files for a user    Retrieves quota assigned for storage of user files.
   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 8447  Returns: Line 8706  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 instituional status(es) in the domain.  defined for the user's institutional status(es) in the domain.
   
 =cut  =cut
   
Line 8455  defined for the user's instituional stat Line 8714  defined for the user's instituional stat
   
   
 sub get_user_quota {  sub get_user_quota {
     my ($uname,$udom) = @_;      my ($uname,$udom,$quotaname,$crstype) = @_;
     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 8470  sub get_user_quota { Line 8729  sub get_user_quota {
         $defquota = 0;           $defquota = 0; 
     } else {      } else {
         my $inststatus;          my $inststatus;
         if ($udom eq $env{'user.domain'} && $uname eq $env{'user.name'}) {          if ($quotaname eq 'course') {
             $quota = $env{'environment.portfolioquota'};              if (($env{'course.'.$udom.'_'.$uname.'.num'} eq $uname) &&
             $inststatus = $env{'environment.inststatus'};                  ($env{'course.'.$udom.'_'.$uname.'.domain'} eq $udom)) {
         } else {                  $quota = $env{'course.'.$udom.'_'.$uname.'.internal.uploadquota'};
             my %userenv =               } else {
                 &Apache::lonnet::get('environment',['portfolioquota',                  my %cenv = &Apache::lonnet::coursedescription("$udom/$uname");
                                      'inststatus'],$udom,$uname);                  $quota = $cenv{'internal.uploadquota'};
             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 {
             $quotatype = 'custom';              if ($udom eq $env{'user.domain'} && $uname eq $env{'user.name'}) {
                   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 8510  Retrieves default quota assigned for sto Line 8799  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 8531  If the user's status includes multiple t Line 8824  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) = @_;      my ($udom,$inststatus,$quotaname) = @_;
     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'}{'defaultquota'}) eq 'HASH') {                  if (ref($quotahash{'quotas'}{$key}) eq 'HASH') {
                     if ($quotahash{'quotas'}{'defaultquota'}{$item} ne '') {                      if ($quotahash{'quotas'}{$key}{$item} ne '') {
                         if ($defquota eq '') {                          if ($defquota eq '') {
                             $defquota = $quotahash{'quotas'}{'defaultquota'}{$item};                              $defquota = $quotahash{'quotas'}{$key}{$item};
                             $settingstatus = $item;                              $settingstatus = $item;
                         } elsif ($quotahash{'quotas'}{'defaultquota'}{$item} > $defquota) {                          } elsif ($quotahash{'quotas'}{$key}{$item} > $defquota) {
                             $defquota = $quotahash{'quotas'}{'defaultquota'}{$item};                              $defquota = $quotahash{'quotas'}{$key}{$item};
                             $settingstatus = $item;                              $settingstatus = $item;
                         }                          }
                     }                      }
                 } else {                  } elsif ($key eq 'defaultquota') {
                     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 8571  sub default_quota { Line 8866  sub default_quota {
             }              }
         }          }
         if ($defquota eq '') {          if ($defquota eq '') {
             if (ref($quotahash{'quotas'}{'defaultquota'}) eq 'HASH') {              if (ref($quotahash{'quotas'}{$key}) eq 'HASH') {
                 $defquota = $quotahash{'quotas'}{'defaultquota'}{'default'};                  $defquota = $quotahash{'quotas'}{$key}{'default'};
             } else {              } elsif ($key eq 'defaultquota') {
                 $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';
         $defquota = 20;          if ($quotaname eq 'author') {
               $defquota = 500;
           } else {
               $defquota = 20;
           }
     }      }
     if (wantarray) {      if (wantarray) {
         return ($defquota,$settingstatus);          return ($defquota,$settingstatus);
Line 8589  sub default_quota { Line 8893  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 8946  sub user_rule_formats { Line 9307  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 />'.&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>';              $output = '<br />'.
                         &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 9429  sub ask_for_embedded_content { Line 9793  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;      my ($navmap,$cdom,$cnum);
     if ($env{'request.course.id'}) {      if ($env{'request.course.id'}) {
         $navmap = Apache::lonnavmaps::navmap->new();          if ($actionurl eq '/adm/dependencies') {
               $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') || ($actionurl eq '/adm/coursegrp_portfolio')) {      if (($actionurl eq '/adm/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 = $env{'course.'.$env{'request.course.id'}.'.domain'};              $udom = $cdom;
             $uname = $env{'course.'.$env{'request.course.id'}.'.num'};              $uname = $cnum;
             $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 9472  sub ask_for_embedded_content { Line 9841  sub ask_for_embedded_content {
         }          }
     } 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{^(.+/)[^/]+$});
                 ($path) =                    if ($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/portfolio/syllabus\E)}) {
                     ($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/\E(?:docs|supplemental)/(?:default|\d+)/\d+)/});                      $path = $1;
                   } 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") {
     my $now = time();          $udom = $cdom;
     foreach my $embed_file (keys(%{$allfiles})) {          $uname = $cnum;
           $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;
         if ($embed_file =~ m{^\w+://}) {          my $cleaned_file = &clean_path($embed_file);
             $newfiles{$embed_file} = 1;          if ($cleaned_file =~ m{^\w+://}) {
             $mapping{$embed_file} = $embed_file;              $newfiles{$cleaned_file} = 1;
               $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 ($embed_file =~ m{/}) {              if ($cleaned_file =~ m{/}) {
                 my ($path,$fname) = ($embed_file =~ m{^(.+)/([^/]*)$});                  my ($path,$fname) = ($cleaned_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 9517  sub ask_for_embedded_content { Line 9904  sub ask_for_embedded_content {
             } else {              } else {
                 $dependencies{$embed_file} = 1;                  $dependencies{$embed_file} = 1;
                 if ($absolutepath) {                  if ($absolutepath) {
                     $mapping{$embed_file} = $absolutepath;                      $mapping{$cleaned_file} = $absolutepath;
                 } else {                  } else {
                     $mapping{$embed_file} = $embed_file;                      $mapping{$cleaned_file} = $embed_file;
                 }                  }
             }              }
         }          }
Line 9527  sub ask_for_embedded_content { Line 9914  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') || ($actionurl eq '/adm/coursegrp_portfolio')) {           if (($actionurl eq '/adm/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 9543  sub ask_for_embedded_content { Line 9931  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;
                   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 9593  sub ask_for_embedded_content { Line 9987  sub ask_for_embedded_content {
         }          }
     }      }
     my %currfile;      my %currfile;
     if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {      if (($actionurl eq '/adm/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 9609  sub ask_for_embedded_content { Line 10004  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 9644  sub ask_for_embedded_content { Line 10040  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') {
                 next if (($rem ne '') &&                  unless ($toplevel =~ m{^\Q/uploaded/$cdom/$cnum/portfolio/syllabus\E}) {
                          (($env{"httpref.$rem".$file} ne '') ||                      next if (($rem ne '') &&
                           (ref($navmap) &&                               (($env{"httpref.$rem".$file} ne '') ||
                           (($navmap->getResourceByUrl($rem.$file) ne '') ||                                (ref($navmap) &&
                            (($file =~ /^(.*\.s?html?)\.bak$/i) &&                                (($navmap->getResourceByUrl($rem.$file) ne '') ||
                             ($navmap->getResourceByUrl($rem.$1)))))));                                 (($file =~ /^(.*\.s?html?)\.bak$/i) &&
                                   ($navmap->getResourceByUrl($rem.$1)))))));
                   }
             }              }
             $unused{$file} = 1;              $unused{$file} = 1;
         }          }
Line 9658  sub ask_for_embedded_content { Line 10056  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><img src="'.&icon($embed_file).'" />&nbsp;'.                            '<td valign="top"><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;">'.&mt('changed from: [_1]',$mapping{$embed_file}).'</span>';              $upload_output .= '<br /><span class="LC_info" style="font-size:smaller;">'.
                                 &mt('changed from: [_1]',$mapping{$embed_file}).'</span>';
         }          }
         $upload_output .= '</td><td>';          $upload_output .= '</td>';
         if ($args->{'ignore_remote_references'} && $embed_file =~ m{^\w+://}) {           if ($args->{'ignore_remote_references'} && $embed_file =~ m{^\w+://}) { 
             $upload_output.='<span class="LC_warning">'.&mt("URL points to other server.").'</span>';              $upload_output.='<td align="right">'.
                               '<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.='<span class="LC_warning">'.&mt('Invalid characters').'</span>';              $upload_output.='<td align="right"><span class="LC_warning">'.
                               &mt('Invalid characters').'</span>';
             $numinvalid++;              $numinvalid++;
         } else {          } else {
             $upload_output .= &embedded_file_element('upload_embedded',$counter,              $upload_output .= '<td>'.
                                 &embedded_file_element('upload_embedded',$counter,
                                                      $embed_file,\%mapping,                                                       $embed_file,\%mapping,
                                                      $allfiles,$codebase,'upload');                                                       $allfiles,$codebase,'upload');
             $counter ++;              $counter ++;
Line 9708  sub ask_for_embedded_content { Line 10116  sub ask_for_embedded_content {
             $counter ++;              $counter ++;
         } else {          } else {
             $upload_output .= &start_data_table_row().              $upload_output .= &start_data_table_row().
                               '<td><span class="LC_filename">'.$embed_file.'</span></td>';                                '<td valign="top"><img src="'.&icon($embed_file).'" />&nbsp;'.
                               '<td><span class="LC_warning">'.&mt('Already exists').'</span></td>'.                                '<span class="LC_filename">'.$embed_file.'</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 9804  sub ask_for_embedded_content { Line 10213  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 files need to be uploaded, as one of the following applies to each reference:').'<ul>';                  &mt('No dependencies 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 9847  sub ask_for_embedded_content { Line 10256  sub ask_for_embedded_content {
             $chgcount ++;              $chgcount ++;
         }          }
     }      }
     if ($counter) {      if (($counter) || ($numunused)) {
         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 9860  sub ask_for_embedded_content { Line 10269  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 10002  sub upload_embedded { Line 10451  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('File name not allowed - rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2).'<br />';              $output .= &mt('Filename 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'}.$path);                                                      $dirpath.$env{'form.currentpath'}.$subdir);
             } else {              } else {
                 $result=                  $result=
                     &Apache::lonnet::userfileupload('embedded_item_'.$i,'',                      &Apache::lonnet::userfileupload('embedded_item_'.$i,'',
                                                     $dirpath.                                                      $dirpath.
                                                     $env{'form.currentpath'}.$path);                                                      $env{'form.currentpath'}.$subdir);
                 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 10028  sub upload_embedded { Line 10479  sub upload_embedded {
                                $path.$fname.'</span>').'<br />';                                      $path.$fname.'</span>').'<br />';     
                 }                  }
             }              }
         } elsif ($context eq 'coursedoc') {          } elsif (($context eq 'coursedoc') || ($context eq 'syllabus')) {
               my $extendedsubdir = $dirpath.'/'.$subdir;
               $extendedsubdir =~ s{/+$}{};
             my $result =              my $result =
                 &Apache::lonnet::userfileupload('embedded_item_'.$i,'coursedoc',                  &Apache::lonnet::userfileupload('embedded_item_'.$i,$context,$extendedsubdir);
                                                 $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 10041  sub upload_embedded { Line 10493  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 10172  sub modify_html_form { Line 10627  sub modify_html_form {
 }  }
   
 sub modify_html_refs {  sub modify_html_refs {
     my ($context,$dirpath,$uname,$udom,$dir_root) = @_;      my ($context,$dirpath,$uname,$udom,$dir_root,$url) = @_;
     my $container;      my $container;
     if ($context eq 'portfolio') {      if ($context eq 'portfolio') {
         $container = $env{'form.container'};          $container = $env{'form.container'};
Line 10181  sub modify_html_refs { Line 10636  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) {      unless ((@changes > 0) || ($context eq 'syllabus')) {
         if (wantarray) {          if (wantarray) {
             return ('',0,0);               return ('',0,0); 
         } else {          } else {
Line 10194  sub modify_html_refs { Line 10651  sub modify_html_refs {
         }          }
     }      }
     if (($context eq 'portfolio') || ($context eq 'coursedoc') ||       if (($context eq 'portfolio') || ($context eq 'coursedoc') || 
         ($context eq 'manage_dependencies')) {          ($context eq 'manage_dependencies') || ($context eq 'syllabus')) {
         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 10250  sub modify_html_refs { Line 10707  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 10258  sub modify_html_refs { Line 10717  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 'manage_dependencies') || ($context eq 'syllabus')) {
                     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 10274  sub modify_html_refs { Line 10734  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 10289  sub modify_html_refs { Line 10754  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 10704  sub process_decompression { Line 11210  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('File name not a supported archive file type.').          $error = &mt('Filename not a supported archive file type.').
                  '<br />'.&mt('File name should end with one of: [_1].',                   '<br />'.&mt('Filename 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 11279  sub process_extracted_files { Line 11785  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];
         $containers{'0'}='sequence';          if ($env{'form.folderpath'} =~ /\:1$/) {
     } elsif ($env{'form.pagepath'}) {              $containers{'0'}='page';
         my @items = split('&',$env{'form.pagepath'});          } else {  
         $folders{'0'} = $items[-2];              $containers{'0'}='sequence';
         $containers{'0'}='page';          }
     }      }
     my @archdirs = &get_env_multiple('form.archive_directory');      my @archdirs = &get_env_multiple('form.archive_directory');
     if ($numitems) {      if ($numitems) {
Line 11544  sub cleanup_empty_dirs { Line 12050  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") {
                     &recurse_dirs("$path/$item");                      &cleanup_empty_dirs("$path/$item");
                     if (-e "$path/$item") {                      if (-e "$path/$item") {
                         $numitems ++;                          $numitems ++;
                     }                      }
Line 11591  sub get_folder_hierarchy { Line 12097  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 Course Documents'));                          push(@pathitems,&mt('Main Content'));
                     } else {                      } else {
                         my $res = $navmap->getByMapPc($pc);                          my $res = $navmap->getByMapPc($pc);
                         if (ref($res)) {                          if (ref($res)) {
Line 11606  sub get_folder_hierarchy { Line 12112  sub get_folder_hierarchy {
             }              }
             if ($showitem) {              if ($showitem) {
                 if ($mapres->{ID} eq '0.0') {                  if ($mapres->{ID} eq '0.0') {
                     push(@pathitems,&mt('Main Course Documents'));                      push(@pathitems,&mt('Main Content'));
                 } else {                  } else {
                     my $maptitle = $mapres->compTitle();                      my $maptitle = $mapres->compTitle();
                     $maptitle =~ s/\W+/_/g;                      $maptitle =~ s/\W+/_/g;
Line 11673  sub get_turnedin_filepath { Line 12179  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 11681  sub get_turnedin_filepath { Line 12190  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 11721  sub get_turnedin_filepath { Line 12233  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 12658  sub restore_settings { Line 13173  sub restore_settings {
   
 =item * &build_recipient_list()  =item * &build_recipient_list()
   
 Build recipient lists for five types of e-mail:  Build recipient lists for following 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,  generated by  (d) Help requests, (e) Course requests needing approval, (f) loncapa
 lonerrorhandler.pm, CHECKRPMS, loncron, lonsupportreq.pm and  module change checking, student/employee ID conflict checks, as
 loncoursequeueadmin.pm respectively.  generated by lonerrorhandler.pm, CHECKRPMS, loncron,
   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, or helpdeskmail),   mailing type (scalar: errormail, packagesmail, 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 
   
Line 13045  sub assign_category_rows { Line 13564  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_datatable">';                  $text .= '<td><table class="LC_data_table">';
                 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 13093  sub commit_customrole { Line 13612  sub commit_customrole {
 }  }
   
 sub commit_standardrole {  sub commit_standardrole {
     my ($udom,$uname,$url,$three,$start,$end,$one,$two,$sec,$context) = @_;      my ($udom,$uname,$url,$three,$start,$end,$one,$two,$sec,$context,$credits) = @_;
     my ($output,$logmsg,$linefeed);      my ($output,$logmsg,$linefeed);
     if ($context eq 'auto') {      if ($context eq 'auto') {
         $linefeed = "\n";          $linefeed = "\n";
Line 13102  sub commit_standardrole { Line 13621  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);                                           $one,$two,$sec,$context,$credits);
         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 13133  sub commit_standardrole { Line 13652  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 13180  sub commit_studentrole { Line 13700  sub commit_studentrole {
             }              }
         }          }
         if (($expire_role_result eq 'ok') || ($secchange == 0)) {          if (($expire_role_result eq 'ok') || ($secchange == 0)) {
             $modify_section_result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,'','',$cid,'',$context);              $modify_section_result = 
                   &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 13202  sub commit_studentrole { Line 13726  sub commit_studentrole {
                     }                      }
                 }                  }
             } else {              } else {
                 if ($secchange) {                         if ($secchange) { 
                     $$logmsg .= &mt('Error when attempting section change for [_1] from old section "[_2]" to new section: "[_3]" in course [_4] -error:',$uname,$oldsec,$sec,$cid).' '.$modify_section_result.$linefeed;                      $$logmsg .= &mt('Error when attempting section change for [_1] from old section "[_2]" to new section: "[_3]" in course [_4] -error:',$uname,$oldsec,$sec,$cid).' '.$modify_section_result.$linefeed;
                 } else {                  } else {
                     $$logmsg .= &mt('Error when attempting to modify role for [_1] for section: "[_2]" in course [_3] -error:',$uname,$sec,$cid).' '.$modify_section_result.$linefeed;                      $$logmsg .= &mt('Error when attempting to modify role for [_1] for section: "[_2]" in course [_3] -error:',$uname,$sec,$cid).' '.$modify_section_result.$linefeed;
Line 13211  sub commit_studentrole { Line 13735  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 [_3] -error: ',$uname,$cid).' '.$expire_role_result.$linefeed;                  $$logmsg .= &mt('Error when attempting to expire existing role without a section for [_1] in course [_2] -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 13237  sub commit_studentrole { Line 13761  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 13400  sub construct_course { Line 13944  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 13429  sub construct_course { Line 13974  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 13453  sub construct_course { Line 14001  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 13809  sub init_user_environment { Line 14362  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) = &decode_user_agent($r);          $clientunicode,$clientos,$clientmobile,$clientinfo) = &decode_user_agent($r);
   
 # ------------------------------------------------------------- Get environment  # ------------------------------------------------------------- Get environment
   
Line 13840  sub init_user_environment { Line 14393  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 14043  sub update_content_constraints { Line 14598  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 14066  sub parse_supplemental_title { Line 14647  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 {  sub captcha_display {
     my ($context,$lonhost) = @_;      my ($context,$lonhost) = @_;
     my ($output,$error);      my ($output,$error);
     my ($captcha,$pubkey,$privkey) = &get_captcha_config($context,$lonhost);      my ($captcha,$pubkey,$privkey) = &get_captcha_config($context,$lonhost);
     if ($captcha eq 'captcha') {      if ($captcha eq 'original') {
         $output = &create_captcha();          $output = &create_captcha();
         unless ($output) {          unless ($output) {
             $error = 'captcha';               $error = 'captcha'; 
Line 14078  sub captcha_display { Line 14751  sub captcha_display {
     } elsif ($captcha eq 'recaptcha') {      } elsif ($captcha eq 'recaptcha') {
         $output = &create_recaptcha($pubkey);          $output = &create_recaptcha($pubkey);
         unless ($output) {          unless ($output) {
             $error = 'recpatcha';               $error = 'recaptcha'; 
         }          }
     }      }
     return ($output,$error);      return ($output,$error);
Line 14088  sub captcha_response { Line 14761  sub captcha_response {
     my ($context,$lonhost) = @_;      my ($context,$lonhost) = @_;
     my ($captcha_chk,$captcha_error);      my ($captcha_chk,$captcha_error);
     my ($captcha,$pubkey,$privkey) = &get_captcha_config($context,$lonhost);      my ($captcha,$pubkey,$privkey) = &get_captcha_config($context,$lonhost);
     if ($captcha eq 'captcha') {      if ($captcha eq 'original') {
         ($captcha_chk,$captcha_error) = &check_captcha();          ($captcha_chk,$captcha_error) = &check_captcha();
     } elsif ($captcha eq 'recaptcha') {      } elsif ($captcha eq 'recaptcha') {
         $captcha_chk = &check_recaptcha($privkey);          $captcha_chk = &check_recaptcha($privkey);
Line 14100  sub captcha_response { Line 14773  sub captcha_response {
   
 sub get_captcha_config {  sub get_captcha_config {
     my ($context,$lonhost) = @_;      my ($context,$lonhost) = @_;
     my ($captcha,$pubkey,$privkey);      my ($captcha,$pubkey,$privkey,$hashtocheck);
     my $hostname = &Apache::lonnet::hostname($lonhost);      my $hostname = &Apache::lonnet::hostname($lonhost);
     my $serverhomeID = &Apache::lonnet::get_server_homeID($hostname);      my $serverhomeID = &Apache::lonnet::get_server_homeID($hostname);
     my $serverhomedom = &Apache::lonnet::host_domain($serverhomeID);      my $serverhomedom = &Apache::lonnet::host_domain($serverhomeID);
     my %domconfig = &Apache::lonnet::get_dom('configuration',[$context],$serverhomedom);      if ($context eq 'usercreation') {
     if (ref($domconfig{$context}) eq 'HASH') {          my %domconfig = &Apache::lonnet::get_dom('configuration',[$context],$serverhomedom);
         if ($domconfig{$context}{'captcha'} eq 'recaptcha') {          if (ref($domconfig{$context}) eq 'HASH') {
             if (ref($domconfig{$context}{'recaptchakeys'}) eq 'HASH') {              $hashtocheck = $domconfig{$context}{'cancreate'};
                 $pubkey = $domconfig{$context}{'recaptchakeys'}{'public'};              if (ref($hashtocheck) eq 'HASH') {
                 $privkey = $domconfig{$context}{'recaptchakeys'}{'private'};                  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) {              if ($privkey && $pubkey) {
                 $captcha = 'recaptcha';                  $captcha = 'recaptcha';
               } else {
                   $captcha = 'original';
             }              }
         } elsif ($domconfig{$context}{'captcha'} eq 'notused') {          } elsif ($domconfhash{$serverhomedom.'.login.captcha'} eq 'original') {
             $captcha = '';              $captcha = 'original';
         } elsif ($domconfig{$context}{'captcha'} eq 'captcha') {  
             $captcha = 'captcha';  
         } else {  
             if ($context eq 'usercreation') {  
                 $captcha = 'captcha';  
             }  
         }          }
     }      }
     return ($captcha,$pubkey,$privkey);      return ($captcha,$pubkey,$privkey);
Line 14168  sub check_captcha { Line 14857  sub check_captcha {
                       output_folder => $captcha_params{'output_dir'},                        output_folder => $captcha_params{'output_dir'},
                       data_folder   => $captcha_params{'db_dir'},                        data_folder   => $captcha_params{'db_dir'},
                   );                    );
     my $captcha_chk = $captcha->check_code($code,$md5sum);      $captcha_chk = $captcha->check_code($code,$md5sum);
     my %captcha_hash = (      my %captcha_hash = (
                         0       => 'Code not checked (file error)',                          0       => 'Code not checked (file error)',
                        -1      => 'Failed: code expired',                         -1      => 'Failed: code expired',
Line 14183  sub check_captcha { Line 14872  sub check_captcha {
   
 sub create_recaptcha {  sub create_recaptcha {
     my ($pubkey) = @_;      my ($pubkey) = @_;
       my $use_ssl;
       if ($ENV{'SERVER_PORT'} == 443) {
           $use_ssl = 1;
       }
     my $captcha = Captcha::reCAPTCHA->new;      my $captcha = Captcha::reCAPTCHA->new;
     return $captcha->get_options_setter({theme => 'white'})."\n".      return $captcha->get_options_setter({theme => 'white'})."\n".
            $captcha->get_html($pubkey).             $captcha->get_html($pubkey,undef,$use_ssl).
            &mt('If either word is hard to read, [_1] will replace them.',             &mt('If either word is hard to read, [_1] will replace them.',
                '<image src="/res/adm/pages/refresh.gif" alt="reCAPTCHA refresh" />').                 '<img src="/res/adm/pages/refresh.gif" alt="reCAPTCHA refresh" />').
            '<br /><br />';             '<br /><br />';
 }  }
   

Removed from v.1.1094  
changed lines
  Added in v.1.1154


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