Diff for /loncom/interface/loncommon.pm between versions 1.1075.2.82 and 1.1075.2.103

version 1.1075.2.82, 2014/08/23 18:43:56 version 1.1075.2.103, 2016/08/06 20:15:00
Line 72  use Apache::lonuserstate(); Line 72  use Apache::lonuserstate();
 use Apache::courseclassifier();  use Apache::courseclassifier();
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
 use DateTime::TimeZone;  use DateTime::TimeZone;
 use DateTime::Locale::Catalog;  use DateTime::Locale;
   use Encode();
 use Authen::Captcha;  use Authen::Captcha;
 use Captcha::reCAPTCHA;  use Captcha::reCAPTCHA;
 use Crypt::DES;  use Crypt::DES;
Line 532  ENDAUTHORBRW Line 533  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) = @_;          $credits_element,$instcode) = @_;
     my $wintitle = 'Course_Browser';      my $wintitle = 'Course_Browser';
     if ($crstype eq 'Community') {      if ($crstype eq 'Community') {
         $wintitle = 'Community_Browser';          $wintitle = 'Community_Browser';
Line 583  sub coursebrowser_javascript { Line 584  sub coursebrowser_javascript {
             var ownername = document.forms[formid].ccuname.value;              var ownername = document.forms[formid].ccuname.value;
             var ownerdom =  document.forms[formid].ccdomain.options[document.forms[formid].ccdomain.selectedIndex].value;              var ownerdom =  document.forms[formid].ccdomain.options[document.forms[formid].ccdomain.selectedIndex].value;
             url += '&cloner='+ownername+':'+ownerdom;              url += '&cloner='+ownername+':'+ownerdom;
               if (type == 'Course') {
                   url += '&crscode='+document.forms[formid].crscode.value;
               }
           }
           if (formname == 'requestcrs') {
               url += '&crsdom=$domainfilter&crscode=$instcode';
         }          }
         if (multflag !=null && multflag != '') {          if (multflag !=null && multflag != '') {
             url += '&multiple='+multflag;              url += '&multiple='+multflag;
Line 958  sub select_datelocale { Line 965  sub select_datelocale {
         }          }
         $output .= '> </option>';          $output .= '> </option>';
     }      }
       my @languages = &Apache::lonlocal::preferred_languages();
     my (@possibles,%locale_names);      my (@possibles,%locale_names);
     my @locales = DateTime::Locale::Catalog::Locales;      my @locales = DateTime::Locale->ids();
     foreach my $locale (@locales) {      foreach my $id (@locales) {
         if (ref($locale) eq 'HASH') {          if ($id ne '') {
             my $id = $locale->{'id'};              my ($en_terr,$native_terr);
             if ($id ne '') {              my $loc = DateTime::Locale->load($id);
                 my $en_terr = $locale->{'en_territory'};              if (ref($loc)) {
                 my $native_terr = $locale->{'native_territory'};                  $en_terr = $loc->name();
                 my @languages = &Apache::lonlocal::preferred_languages();                  $native_terr = $loc->native_name();
                 if (grep(/^en$/,@languages) || !@languages) {                  if (grep(/^en$/,@languages) || !@languages) {
                     if ($en_terr ne '') {                      if ($en_terr ne '') {
                         $locale_names{$id} = '('.$en_terr.')';                          $locale_names{$id} = '('.$en_terr.')';
Line 980  sub select_datelocale { Line 988  sub select_datelocale {
                         $locale_names{$id} = '('.$en_terr.')';                          $locale_names{$id} = '('.$en_terr.')';
                     }                      }
                 }                  }
                 push (@possibles,$id);                  $locale_names{$id} = Encode::encode('UTF-8',$locale_names{$id});
                   push(@possibles,$id);
             }              }
         }          }
     }      }
Line 991  sub select_datelocale { Line 1000  sub select_datelocale {
         }          }
         $output.=">$item";          $output.=">$item";
         if ($locale_names{$item} ne '') {          if ($locale_names{$item} ne '') {
             $output.="  $locale_names{$item}</option>\n";              $output.='  '.$locale_names{$item};
         }          }
         $output.="</option>\n";          $output.="</option>\n";
     }      }
Line 3677  sub user_lang { Line 3686  sub user_lang {
 =over 4  =over 4
   
 =item * &get_previous_attempt($symb, $username, $domain, $course,  =item * &get_previous_attempt($symb, $username, $domain, $course,
     $getattempt, $regexp, $gradesub)      $getattempt, $regexp, $gradesub, $usec, $identifier)
   
 Return string with previous attempt on problem. Arguments:  Return string with previous attempt on problem. Arguments:
   
Line 3699  Return string with previous attempt on p Line 3708  Return string with previous attempt on p
   
 =item * $gradesub: routine that processes the string if it matches $regexp  =item * $gradesub: routine that processes the string if it matches $regexp
   
   =item * $usec: section of the desired student
   
   =item * $identifier: counter for student (multiple students one problem) or
       problem (one student; whole sequence).
   
 =back  =back
   
 The output string is a table containing all desired attempts, if any.  The output string is a table containing all desired attempts, if any.
Line 3706  The output string is a table containing Line 3720  The output string is a table containing
 =cut  =cut
   
 sub get_previous_attempt {  sub get_previous_attempt {
   my ($symb,$username,$domain,$course,$getattempt,$regexp,$gradesub)=@_;    my ($symb,$username,$domain,$course,$getattempt,$regexp,$gradesub,$usec,$identifier)=@_;
   my $prevattempts='';    my $prevattempts='';
   no strict 'refs';    no strict 'refs';
   if ($symb) {    if ($symb) {
Line 3716  sub get_previous_attempt { Line 3730  sub get_previous_attempt {
       my %lasthash=();        my %lasthash=();
       my $version;        my $version;
       for ($version=1;$version<=$returnhash{'version'};$version++) {        for ($version=1;$version<=$returnhash{'version'};$version++) {
         foreach my $key (sort(split(/\:/,$returnhash{$version.':keys'}))) {          foreach my $key (reverse(sort(split(/\:/,$returnhash{$version.':keys'})))) {
   $lasthash{$key}=$returnhash{$version.':'.$key};              if ($key =~ /\.rawrndseed$/) {
                   my ($id) = ($key =~ /^(.+)\.rawrndseed$/);
                   $lasthash{$id.'.rndseed'} = $returnhash{$version.':'.$key};
               } else {
                   $lasthash{$key}=$returnhash{$version.':'.$key};
               }
         }          }
       }        }
       $prevattempts=&start_data_table().&start_data_table_header_row();        $prevattempts=&start_data_table().&start_data_table_header_row();
       $prevattempts.='<th>'.&mt('History').'</th>';        $prevattempts.='<th>'.&mt('History').'</th>';
       my (%typeparts,%lasthidden);        my (%typeparts,%lasthidden,%regraded,%hidestatus);
       my $showsurv=&Apache::lonnet::allowed('vas',$env{'request.course.id'});        my $showsurv=&Apache::lonnet::allowed('vas',$env{'request.course.id'});
       foreach my $key (sort(keys(%lasthash))) {        foreach my $key (sort(keys(%lasthash))) {
  my ($ign,@parts) = split(/\./,$key);   my ($ign,@parts) = split(/\./,$key);
Line 3739  sub get_previous_attempt { Line 3758  sub get_previous_attempt {
                       $lasthidden{$ign.'.'.$id} = 1;                        $lasthidden{$ign.'.'.$id} = 1;
                   }                    }
               }                }
                 if ($identifier ne '') {
                     my $id = join(',',@parts);
                     if (&Apache::lonnet::EXT("resource.$id.problemstatus",$symb,
                                                  $domain,$username,$usec,undef,$course) =~ /^no/) {
                         $hidestatus{$ign.'.'.$id} = 1;
                     }
                 }
             } elsif ($data eq 'regrader') {
                 if (($identifier ne '') && (@parts)) {
                     my $id = join(',',@parts);
                     $regraded{$ign.'.'.$id} = 1;
                 }
           }             } 
  } else {   } else {
   if ($#parts == 0) {    if ($#parts == 0) {
Line 3750  sub get_previous_attempt { Line 3781  sub get_previous_attempt {
       }        }
       $prevattempts.=&end_data_table_header_row();        $prevattempts.=&end_data_table_header_row();
       if ($getattempt eq '') {        if ($getattempt eq '') {
           my (%solved,%resets,%probstatus);
           if (($identifier ne '') && (keys(%regraded) > 0)) {
               for ($version=1;$version<=$returnhash{'version'};$version++) {
                   foreach my $id (keys(%regraded)) {
                       if (($returnhash{$version.':'.$id.'.regrader'}) &&
                           ($returnhash{$version.':'.$id.'.tries'} eq '') &&
                           ($returnhash{$version.':'.$id.'.award'} eq '')) {
                           push(@{$resets{$id}},$version);
                       }
                   }
               }
           }
  for ($version=1;$version<=$returnhash{'version'};$version++) {   for ($version=1;$version<=$returnhash{'version'};$version++) {
             my @hidden;              my (@hidden,@unsolved);
             if (%typeparts) {              if (%typeparts) {
                 foreach my $id (keys(%typeparts)) {                  foreach my $id (keys(%typeparts)) {
                     if (($returnhash{$version.':'.$id.'.type'} eq 'anonsurvey') || ($returnhash{$version.':'.$id.'.type'} eq 'anonsurveycred')) {                      if (($returnhash{$version.':'.$id.'.type'} eq 'anonsurvey') ||
                           ($returnhash{$version.':'.$id.'.type'} eq 'anonsurveycred')) {
                         push(@hidden,$id);                          push(@hidden,$id);
                       } elsif ($identifier ne '') {
                           unless (($returnhash{$version.':'.$id.'.type'} eq 'survey') ||
                                   ($returnhash{$version.':'.$id.'.type'} eq 'surveycred') ||
                                   ($hidestatus{$id})) {
                               next if ((ref($resets{$id}) eq 'ARRAY') && grep(/^\Q$version\E$/,@{$resets{$id}}));
                               if ($returnhash{$version.':'.$id.'.solved'} eq 'correct_by_student') {
                                   push(@{$solved{$id}},$version);
                               } elsif (($returnhash{$version.':'.$id.'.solved'} ne '') &&
                                        (ref($solved{$id}) eq 'ARRAY')) {
                                   my $skip;
                                   if (ref($resets{$id}) eq 'ARRAY') {
                                       foreach my $reset (@{$resets{$id}}) {
                                           if ($reset > $solved{$id}[-1]) {
                                               $skip=1;
                                               last;
                                           }
                                       }
                                   }
                                   unless ($skip) {
                                       my ($ign,$partslist) = split(/\./,$id,2);
                                       push(@unsolved,$partslist);
                                   }
                               }
                           }
                     }                      }
                 }                  }
             }              }
             $prevattempts.=&start_data_table_row().              $prevattempts.=&start_data_table_row().
                            '<td>'.&mt('Transaction [_1]',$version).'</td>';                             '<td>'.&mt('Transaction [_1]',$version);
               if (@unsolved) {
                   $prevattempts .= '<span class="LC_nobreak"><label>'.
                                    '<input type="checkbox" name="HIDE'.$identifier.'" value="'.$version.':'.join('_',@unsolved).'" />'.
                                    &mt('Hide').'</label></span>';
               }
               $prevattempts .= '</td>';
             if (@hidden) {              if (@hidden) {
                 foreach my $key (sort(keys(%lasthash))) {                  foreach my $key (sort(keys(%lasthash))) {
                     next if ($key =~ /\.foilorder$/);                      next if ($key =~ /\.foilorder$/);
Line 3782  sub get_previous_attempt { Line 3856  sub get_previous_attempt {
                         }                          }
                     } else {                      } else {
                         if ($key =~ /\./) {                          if ($key =~ /\./) {
                             my $value = &format_previous_attempt_value($key,                              my $value = $returnhash{$version.':'.$key};
                                               $returnhash{$version.':'.$key});                              if ($key =~ /\.rndseed$/) {
                             $prevattempts.='<td>'.$value.'&nbsp;</td>';                                  my ($id) = ($key =~ /^(.+)\.rndseed$/);
                                   if (exists($returnhash{$version.':'.$id.'.rawrndseed'})) {
                                       $value = $returnhash{$version.':'.$id.'.rawrndseed'};
                                   }
                               }
                               $prevattempts.='<td>'.&format_previous_attempt_value($key,$value).
                                              '&nbsp;</td>';
                         } else {                          } else {
                             $prevattempts.='<td>&nbsp;</td>';                              $prevattempts.='<td>&nbsp;</td>';
                         }                          }
Line 3793  sub get_previous_attempt { Line 3873  sub get_previous_attempt {
             } else {              } else {
         foreach my $key (sort(keys(%lasthash))) {          foreach my $key (sort(keys(%lasthash))) {
                     next if ($key =~ /\.foilorder$/);                      next if ($key =~ /\.foilorder$/);
     my $value = &format_previous_attempt_value($key,                      my $value = $returnhash{$version.':'.$key};
             $returnhash{$version.':'.$key});                      if ($key =~ /\.rndseed$/) {
     $prevattempts.='<td>'.$value.'&nbsp;</td>';                          my ($id) = ($key =~ /^(.+)\.rndseed$/);
                           if (exists($returnhash{$version.':'.$id.'.rawrndseed'})) {
                               $value = $returnhash{$version.':'.$id.'.rawrndseed'};
                           }
                       }
                       $prevattempts.='<td>'.&format_previous_attempt_value($key,$value).
                                      '&nbsp;</td>';
         }          }
             }              }
     $prevattempts.=&end_data_table_row();      $prevattempts.=&end_data_table_row();
Line 4550  sub blocking_status { Line 4636  sub blocking_status {
 # build a link to a popup window containing the details  # build a link to a popup window containing the details
     my $querystring  = "?activity=$activity";      my $querystring  = "?activity=$activity";
 # $uname and $udom decide whose portfolio the user is trying to look at  # $uname and $udom decide whose portfolio the user is trying to look at
     if ($activity eq 'port') {      if (($activity eq 'port') || ($activity eq 'passwd')) {
         $querystring .= "&amp;udom=$udom"      if $udom;          $querystring .= "&amp;udom=$udom"      if ($udom =~ /^$match_domain$/);
         $querystring .= "&amp;uname=$uname"    if $uname;          $querystring .= "&amp;uname=$uname"    if ($uname =~ /^$match_username$/);
     } elsif ($activity eq 'docs') {      } elsif ($activity eq 'docs') {
         $querystring .= '&amp;url='.&HTML::Entities::encode($url,'&"');          $querystring .= '&amp;url='.&HTML::Entities::encode($url,'&"');
     }      }
Line 4571  END_MYBLOCK Line 4657  END_MYBLOCK
       
     my $popupUrl = "/adm/blockingstatus/$querystring";      my $popupUrl = "/adm/blockingstatus/$querystring";
     my $text = &mt('Communication Blocked');      my $text = &mt('Communication Blocked');
       my $class = 'LC_comblock';
     if ($activity eq 'docs') {      if ($activity eq 'docs') {
         $text = &mt('Content Access Blocked');          $text = &mt('Content Access Blocked');
           $class = '';
     } elsif ($activity eq 'printout') {      } elsif ($activity eq 'printout') {
         $text = &mt('Printing Blocked');          $text = &mt('Printing Blocked');
       } elsif ($activity eq 'passwd') {
           $text = &mt('Password Changing Blocked');
     }      }
     $output .= <<"END_BLOCK";      $output .= <<"END_BLOCK";
 <div class='LC_comblock'>  <div class='$class'>
   <a onclick='openWindow("$popupUrl","Blocking Table",600,300,"no","no");return false;' href='/adm/blockingstatus/$querystring'    <a onclick='openWindow("$popupUrl","Blocking Table",600,300,"no","no");return false;' href='/adm/blockingstatus/$querystring'
   title='$text'>    title='$text'>
   <img class='LC_noBorder LC_middle' title='$text' src='/res/adm/pages/comblock.png' alt='$text'/></a>    <img class='LC_noBorder LC_middle' title='$text' src='/res/adm/pages/comblock.png' alt='$text'/></a>
Line 4695  sub get_domainconf { Line 4785  sub get_domainconf {
             if (keys(%{$domconfig{'login'}})) {              if (keys(%{$domconfig{'login'}})) {
                 foreach my $key (keys(%{$domconfig{'login'}})) {                  foreach my $key (keys(%{$domconfig{'login'}})) {
                     if (ref($domconfig{'login'}{$key}) eq 'HASH') {                      if (ref($domconfig{'login'}{$key}) eq 'HASH') {
                         if ($key eq 'loginvia') {                          if (($key eq 'loginvia') || ($key eq 'headtag')) {
                             if (ref($domconfig{'login'}{'loginvia'}) eq 'HASH') {                              if (ref($domconfig{'login'}{$key}) eq 'HASH') {
                                 foreach my $hostname (keys(%{$domconfig{'login'}{'loginvia'}})) {                                  foreach my $hostname (keys(%{$domconfig{'login'}{$key}})) {
                                     if (ref($domconfig{'login'}{'loginvia'}{$hostname}) eq 'HASH') {                                      if (ref($domconfig{'login'}{$key}{$hostname}) eq 'HASH') {
                                         if ($domconfig{'login'}{'loginvia'}{$hostname}{'server'}) {                                          if ($key eq 'loginvia') {
                                             my $server = $domconfig{'login'}{'loginvia'}{$hostname}{'server'};                                              if ($domconfig{'login'}{'loginvia'}{$hostname}{'server'}) {
                                             $designhash{$udom.'.login.loginvia'} = $server;                                                  my $server = $domconfig{'login'}{'loginvia'}{$hostname}{'server'};
                                             if ($domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'} eq 'custom') {                                                  $designhash{$udom.'.login.loginvia'} = $server;
                                                   if ($domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'} eq 'custom') {
                                                 $designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'custompath'};                                                      $designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'custompath'};
                                             } else {                                                  } else {
                                                 $designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'};                                                      $designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'};
                                                   }
                                             }                                              }
                                             if ($domconfig{'login'}{'loginvia'}{$hostname}{'exempt'}) {                                          } elsif ($key eq 'headtag') {
                                                 $designhash{$udom.'.login.loginvia_exempt_'.$hostname} = $domconfig{'login'}{'loginvia'}{$hostname}{'exempt'};                                              if ($domconfig{'login'}{'headtag'}{$hostname}{'url'}) {
                                                   $designhash{$udom.'.login.headtag_'.$hostname} = $domconfig{'login'}{'headtag'}{$hostname}{'url'};
                                             }                                              }
                                         }                                          }
                                           if ($domconfig{'login'}{$key}{$hostname}{'exempt'}) {
                                               $designhash{$udom.'.login.'.$key.'_exempt_'.$hostname} = $domconfig{'login'}{$key}{$hostname}{'exempt'};
                                           }
                                     }                                      }
                                 }                                  }
                             }                              }
Line 5035  Inputs: Line 5130  Inputs:
   
 =item * $args, optional argument valid values are  =item * $args, optional argument valid values are
             no_auto_mt_title -> prevents &mt()ing the title arg              no_auto_mt_title -> prevents &mt()ing the title arg
             inherit_jsmath -> when creating popup window in a page,  
                               should it have jsmath forced on by the  
                               current page  
   
 =item * $advtoolsref, optional argument, ref to an array containing  =item * $advtoolsref, optional argument, ref to an array containing
             inlineremote items to be added in "Functions" menu below              inlineremote items to be added in "Functions" menu below
Line 5105  sub bodytag { Line 5197  sub bodytag {
   
 # construct main body tag  # construct main body tag
     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();
   
     &get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['inhibitmenu']);      &get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['inhibitmenu']);
   
Line 5332  sub endbodytag { Line 5424  sub endbodytag {
     unless ((ref($args) eq 'HASH') && ($args->{'notbody'})) {      unless ((ref($args) eq 'HASH') && ($args->{'notbody'})) {
         $endbodytag='</body>';          $endbodytag='</body>';
     }      }
     $endbodytag=&Apache::lontexconvert::jsMath_process()."\n".$endbodytag;  
     if ( exists( $env{'internal.head.redirect'} ) ) {      if ( exists( $env{'internal.head.redirect'} ) ) {
         if (!(ref($args) eq 'HASH' && $args->{'noredirectlink'})) {          if (!(ref($args) eq 'HASH' && $args->{'noredirectlink'})) {
     $endbodytag=      $endbodytag=
Line 6611  fieldset { Line 6702  fieldset {
   /* overflow: hidden; */    /* overflow: hidden; */
 }  }
   
   article.geogebraweb div {
       margin: 0;
   }
   
 fieldset > legend {  fieldset > legend {
   font-weight: bold;    font-weight: bold;
   padding: 0 5px 0 5px;    padding: 0 5px 0 5px;
Line 7346  sub headtag { Line 7441  sub headtag {
 <meta http-equiv="pragma" content="no-cache" />  <meta http-equiv="pragma" content="no-cache" />
 <meta http-equiv="Refresh" content="$time; url=$url" />  <meta http-equiv="Refresh" content="$time; url=$url" />
 ADDMETA  ADDMETA
       } else {
           unless (($args->{'frameset'}) || ($args->{'js_ready'}) || ($args->{'only_body'}) || ($args->{'no_nav_bar'})) {
               my $requrl = $env{'request.uri'};
               if ($requrl eq '') {
                   $requrl = $ENV{'REQUEST_URI'};
                   $requrl =~ s/\?.+$//;
               }
               unless (($requrl =~ m{^/adm/(?:switchserver|login|authenticate|logout|groupsort|cleanup|helper|slotrequest|grades)(\?|$)}) ||
                       (($requrl =~ m{^/res/}) && (($env{'form.submitted'} eq 'scantron') ||
                        ($env{'form.grade_symb'}) || ($Apache::lonhomework::scantronmode)))) {
                   my $dom_in_use = $Apache::lonnet::perlvar{'lonDefDomain'};
                   unless (&Apache::lonnet::allowed('mau',$dom_in_use)) {
                       my %domdefs = &Apache::lonnet::get_domain_defaults($dom_in_use);
                       if (ref($domdefs{'offloadnow'}) eq 'HASH') {
                           my $lonhost = $Apache::lonnet::perlvar{'lonHostID'};
                           if ($domdefs{'offloadnow'}{$lonhost}) {
                               my $newserver = &Apache::lonnet::spareserver(30000,undef,1,$dom_in_use);
                               if (($newserver) && ($newserver ne $lonhost)) {
                                   my $numsec = 5;
                                   my $timeout = $numsec * 1000;
                                   my ($newurl,$locknum,%locks,$msg);
                                   if ($env{'request.role.adv'}) {
                                       ($locknum,%locks) = &Apache::lonnet::get_locks();
                                   }
                                   my $disable_submit = 0;
                                   if ($requrl =~ /$LONCAPA::assess_re/) {
                                       $disable_submit = 1;
                                   }
                                   if ($locknum) {
                                       my @lockinfo = sort(values(%locks));
                                       $msg = &mt('Once the following tasks are complete: ')."\\n".
                                              join(", ",sort(values(%locks)))."\\n".
                                              &mt('your session will be transferred to a different server, after you click "Roles".');
                                   } else {
                                       if (($requrl =~ m{^/res/}) && ($env{'form.submitted'} =~ /^part_/)) {
                                           $msg = &mt('Your LON-CAPA submission has been recorded')."\\n";
                                       }
                                       $msg .= &mt('Your current LON-CAPA session will be transferred to a different server in [quant,_1,second].',$numsec);
                                       $newurl = '/adm/switchserver?otherserver='.$newserver;
                                       if (($env{'request.role'}) && ($env{'request.role'} ne 'cm')) {
                                           $newurl .= '&role='.$env{'request.role'};
                                       }
                                       if ($env{'request.symb'}) {
                                           $newurl .= '&symb='.$env{'request.symb'};
                                       } else {
                                           $newurl .= '&origurl='.$requrl;
                                       }
                                   }
                                   &js_escape(\$msg);
                                   $result.=<<OFFLOAD
   <meta http-equiv="pragma" content="no-cache" />
   <script type="text/javascript">
   // <![CDATA[
   function LC_Offload_Now() {
       var dest = "$newurl";
       if (dest != '') {
           window.location.href="$newurl";
       }
   }
   \$(document).ready(function () {
       window.alert('$msg');
       if ($disable_submit) {
           \$(".LC_hwk_submit").prop("disabled", true);
           \$( ".LC_textline" ).prop( "readonly", "readonly");
       }
       setTimeout('LC_Offload_Now()', $timeout);
   });
   // ]]>
   </script>
   OFFLOAD
                               }
                           }
                       }
                   }
               }
           }
     }      }
     if (!defined($title)) {      if (!defined($title)) {
  $title = 'The LearningOnline Network with CAPA';   $title = 'The LearningOnline Network with CAPA';
Line 7543  $args - additional optional args support Line 7714  $args - additional optional args support
              no_inline_link -> if true and in remote mode, don't show the               no_inline_link -> if true and in remote mode, don't show the
                                     'Switch To Inline Menu' link                                      'Switch To Inline Menu' link
              no_auto_mt_title -> prevent &mt()ing the title arg               no_auto_mt_title -> prevent &mt()ing the title arg
              inherit_jsmath -> when creating popup window in a page,  
                                     should it have jsmath forced on by the  
                                     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               group          -> includes the current group, if page is for a
Line 7672  function set_wishlistlink(title, path) { Line 7840  function set_wishlistlink(title, path) {
         title = title.replace(/^LON-CAPA /,'');          title = title.replace(/^LON-CAPA /,'');
     }      }
     title = encodeURIComponent(title);      title = encodeURIComponent(title);
       title = title.replace("'","\\\'");
     if (!path) {      if (!path) {
         path = location.pathname;          path = location.pathname;
     }      }
     path = encodeURIComponent(path);      path = encodeURIComponent(path);
       path = path.replace("'","\\\'");
     Win = window.open('/adm/wishlist?mode=newLink&setTitle='+title+'&setPath='+path,      Win = window.open('/adm/wishlist?mode=newLink&setTitle='+title+'&setPath='+path,
                       'wishlistNewLink','width=560,height=350,scrollbars=0');                        'wishlistNewLink','width=560,height=350,scrollbars=0');
 }  }
Line 7718  var modalWindow = { Line 7888  var modalWindow = {
 };  };
  var openMyModal = function(source,width,height,scrolling,transparency,style)   var openMyModal = function(source,width,height,scrolling,transparency,style)
  {   {
                   source = source.replace("'","&#39;");
  modalWindow.windowId = "myModal";   modalWindow.windowId = "myModal";
  modalWindow.width = width;   modalWindow.width = width;
  modalWindow.height = height;   modalWindow.height = height;
  modalWindow.content = "<iframe width='"+width+"' height='"+height+"' frameborder='0' scrolling='"+scrolling+"' allowtransparency='"+transparency+"' src='" + source + "' style='"+style+"'></iframe>";   modalWindow.content = "<iframe width='"+width+"' height='"+height+"' frameborder='0' scrolling='"+scrolling+"' allowtransparency='"+transparency+"' src='" + source + "' style='"+style+"'></iframe>";
  modalWindow.open();   modalWindow.open();
  };   };
 // END LON-CAPA Internal -->  // END LON-CAPA Internal -->
 // ]]>  // ]]>
 </script>  </script>
Line 8325  role status: active, previous or future. Line 8496  role status: active, previous or future.
 sub check_user_status {  sub check_user_status {
     my ($udom,$uname,$cdom,$crs,$role,$sec) = @_;      my ($udom,$uname,$cdom,$crs,$role,$sec) = @_;
     my %userinfo = &Apache::lonnet::dump('roles',$udom,$uname);      my %userinfo = &Apache::lonnet::dump('roles',$udom,$uname);
     my @uroles = keys %userinfo;      my @uroles = keys(%userinfo);
     my $srchstr;      my $srchstr;
     my $active_chk = 'none';      my $active_chk = 'none';
     my $now = time;      my $now = time;
Line 9055  sub user_picker { Line 9226  sub user_picker {
         }          }
         $srchterm = $srch->{'srchterm'};          $srchterm = $srch->{'srchterm'};
     }      }
     my %lt=&Apache::lonlocal::texthash(      my %html_lt=&Apache::lonlocal::texthash(
                     'usr'       => 'Search criteria',                      'usr'       => 'Search criteria',
                     'doma'      => 'Domain/institution to search',                      'doma'      => 'Domain/institution to search',
                     'uname'     => 'username',                      'uname'     => 'username',
Line 9068  sub user_picker { Line 9239  sub user_picker {
                     'exact'     => 'is',                      'exact'     => 'is',
                     'contains'  => 'contains',                      'contains'  => 'contains',
                     'begins'    => 'begins with',                      'begins'    => 'begins with',
                                          );
       my %js_lt=&Apache::lonlocal::texthash(
                     'youm'      => "You must include some text to search for.",                      'youm'      => "You must include some text to search for.",
                     'thte'      => "The text you are searching for must contain at least two characters when using a 'begins' type search.",                      'thte'      => "The text you are searching for must contain at least two characters when using a 'begins' type search.",
                     'thet'      => "The text you are searching for must contain at least three characters when using a 'contains' type search.",                      'thet'      => "The text you are searching for must contain at least three characters when using a 'contains' type search.",
Line 9077  sub user_picker { Line 9250  sub user_picker {
                     'whse'      => "When searching by last,first you must include at least one character in the first name.",                      'whse'      => "When searching by last,first you must include at least one character in the first name.",
                      'thfo'     => "The following need to be corrected before the search can be run:",                       'thfo'     => "The following need to be corrected before the search can be run:",
                                        );                                         );
       &html_escape(\%html_lt);
       &js_escape(\%js_lt);
     my $domform = &select_dom_form($currdom,'srchdomain',1,1);      my $domform = &select_dom_form($currdom,'srchdomain',1,1);
     my $srchinsel = ' <select name="srchin">';      my $srchinsel = ' <select name="srchin">';
   
Line 9091  sub user_picker { Line 9266  sub user_picker {
         next if ($option eq 'crs' && !$env{'request.course.id'});          next if ($option eq 'crs' && !$env{'request.course.id'});
         if ($curr_selected{'srchin'} eq $option) {          if ($curr_selected{'srchin'} eq $option) {
             $srchinsel .= '               $srchinsel .= ' 
    <option value="'.$option.'" selected="selected">'.$lt{$option}.'</option>';     <option value="'.$option.'" selected="selected">'.$html_lt{$option}.'</option>';
         } else {          } else {
             $srchinsel .= '              $srchinsel .= '
    <option value="'.$option.'">'.$lt{$option}.'</option>';     <option value="'.$option.'">'.$html_lt{$option}.'</option>';
         }          }
     }      }
     $srchinsel .= "\n  </select>\n";      $srchinsel .= "\n  </select>\n";
Line 9103  sub user_picker { Line 9278  sub user_picker {
     foreach my $option ('lastname','lastfirst','uname') {      foreach my $option ('lastname','lastfirst','uname') {
         if ($curr_selected{'srchby'} eq $option) {          if ($curr_selected{'srchby'} eq $option) {
             $srchbysel .= '              $srchbysel .= '
    <option value="'.$option.'" selected="selected">'.$lt{$option}.'</option>';     <option value="'.$option.'" selected="selected">'.$html_lt{$option}.'</option>';
         } else {          } else {
             $srchbysel .= '              $srchbysel .= '
    <option value="'.$option.'">'.$lt{$option}.'</option>';     <option value="'.$option.'">'.$html_lt{$option}.'</option>';
          }           }
     }      }
     $srchbysel .= "\n  </select>\n";      $srchbysel .= "\n  </select>\n";
Line 9115  sub user_picker { Line 9290  sub user_picker {
     foreach my $option ('begins','contains','exact') {      foreach my $option ('begins','contains','exact') {
         if ($curr_selected{'srchtype'} eq $option) {          if ($curr_selected{'srchtype'} eq $option) {
             $srchtypesel .= '              $srchtypesel .= '
    <option value="'.$option.'" selected="selected">'.$lt{$option}.'</option>';     <option value="'.$option.'" selected="selected">'.$html_lt{$option}.'</option>';
         } else {          } else {
             $srchtypesel .= '              $srchtypesel .= '
    <option value="'.$option.'">'.$lt{$option}.'</option>';     <option value="'.$option.'">'.$html_lt{$option}.'</option>';
         }          }
     }      }
     $srchtypesel .= "\n  </select>\n";      $srchtypesel .= "\n  </select>\n";
Line 9203  function validateEntry(callingForm) { Line 9378  function validateEntry(callingForm) {
   
     if (srchterm == "") {      if (srchterm == "") {
         checkok = 0;          checkok = 0;
         msg += "$lt{'youm'}\\n";          msg += "$js_lt{'youm'}\\n";
     }      }
   
     if (srchtype== 'begins') {      if (srchtype== 'begins') {
         if (srchterm.length < 2) {          if (srchterm.length < 2) {
             checkok = 0;              checkok = 0;
             msg += "$lt{'thte'}\\n";              msg += "$js_lt{'thte'}\\n";
         }          }
     }      }
   
     if (srchtype== 'contains') {      if (srchtype== 'contains') {
         if (srchterm.length < 3) {          if (srchterm.length < 3) {
             checkok = 0;              checkok = 0;
             msg += "$lt{'thet'}\\n";              msg += "$js_lt{'thet'}\\n";
         }          }
     }      }
     if (srchin == 'instd') {      if (srchin == 'instd') {
         if (srchdomain == '') {          if (srchdomain == '') {
             checkok = 0;              checkok = 0;
             msg += "$lt{'yomc'}\\n";              msg += "$js_lt{'yomc'}\\n";
         }          }
     }      }
     if (srchin == 'dom') {      if (srchin == 'dom') {
         if (srchdomain == '') {          if (srchdomain == '') {
             checkok = 0;              checkok = 0;
             msg += "$lt{'ymcd'}\\n";              msg += "$js_lt{'ymcd'}\\n";
         }          }
     }      }
     if (srchby == 'lastfirst') {      if (srchby == 'lastfirst') {
         if (srchterm.indexOf(",") == -1) {          if (srchterm.indexOf(",") == -1) {
             checkok = 0;              checkok = 0;
             msg += "$lt{'whus'}\\n";              msg += "$js_lt{'whus'}\\n";
         }          }
         if (srchterm.indexOf(",") == srchterm.length -1) {          if (srchterm.indexOf(",") == srchterm.length -1) {
             checkok = 0;              checkok = 0;
             msg += "$lt{'whse'}\\n";              msg += "$js_lt{'whse'}\\n";
         }          }
     }      }
     if (checkok == 0) {      if (checkok == 0) {
         alert("$lt{'thfo'}\\n"+msg);          alert("$js_lt{'thfo'}\\n"+msg);
         return;          return;
     }      }
     if (checkok == 1) {      if (checkok == 1) {
Line 9260  $new_user_create Line 9435  $new_user_create
 END_BLOCK  END_BLOCK
   
     $output .= &Apache::lonhtmlcommon::start_pick_box().      $output .= &Apache::lonhtmlcommon::start_pick_box().
                &Apache::lonhtmlcommon::row_title($lt{'doma'}).                 &Apache::lonhtmlcommon::row_title($html_lt{'doma'}).
                $domform.                 $domform.
                &Apache::lonhtmlcommon::row_closure().                 &Apache::lonhtmlcommon::row_closure().
                &Apache::lonhtmlcommon::row_title($lt{'usr'}).                 &Apache::lonhtmlcommon::row_title($html_lt{'usr'}).
                $srchbysel.                 $srchbysel.
                $srchtypesel.                  $srchtypesel. 
                '<input type="text" size="15" name="srchterm" value="'.$srchterm.'" />'.                 '<input type="text" size="15" name="srchterm" value="'.$srchterm.'" />'.
Line 9276  END_BLOCK Line 9451  END_BLOCK
   
 sub user_rule_check {  sub user_rule_check {
     my ($usershash,$checks,$alerts,$rulematch,$inst_results,$curr_rules,$got_rules) = @_;      my ($usershash,$checks,$alerts,$rulematch,$inst_results,$curr_rules,$got_rules) = @_;
     my $response;      my ($response,%inst_response);
     if (ref($usershash) eq 'HASH') {      if (ref($usershash) eq 'HASH') {
         foreach my $user (keys(%{$usershash})) {          if (keys(%{$usershash}) > 1) {
             my ($uname,$udom) = split(/:/,$user);              my (%by_username,%by_id,%userdoms);
             next if ($udom eq '' || $uname eq '');              my $checkid;
             my ($id,$newuser);  
             if (ref($usershash->{$user}) eq 'HASH') {  
                 $newuser = $usershash->{$user}->{'newuser'};  
                 $id = $usershash->{$user}->{'id'};  
             }  
             my $inst_response;  
             if (ref($checks) eq 'HASH') {              if (ref($checks) eq 'HASH') {
                 if (defined($checks->{'username'})) {                  if ((!defined($checks->{'username'})) && (defined($checks->{'id'}))) {
                     ($inst_response,%{$inst_results->{$user}}) =                       $checkid = 1;
                         &Apache::lonnet::get_instuser($udom,$uname);                  }
                 } elsif (defined($checks->{'id'})) {              }
                     ($inst_response,%{$inst_results->{$user}}) =              foreach my $user (keys(%{$usershash})) {
                         &Apache::lonnet::get_instuser($udom,undef,$id);                  my ($uname,$udom) = split(/:/,$user);
                   if ($checkid) {
                       if (ref($usershash->{$user}) eq 'HASH') {
                           if ($usershash->{$user}->{'id'} ne '') {
                               $by_id{$udom}{$usershash->{$user}->{'id'}} = $uname;
                               $userdoms{$udom} = 1;
                               if (ref($inst_results) eq 'HASH') {
                                   $inst_results->{$uname.':'.$udom} = {};
                               }
                           }
                       }
                   } else {
                       $by_username{$udom}{$uname} = 1;
                       $userdoms{$udom} = 1;
                       if (ref($inst_results) eq 'HASH') {
                           $inst_results->{$uname.':'.$udom} = {};
                       }
                   }
               }
               foreach my $udom (keys(%userdoms)) {
                   if (!$got_rules->{$udom}) {
                       my %domconfig = &Apache::lonnet::get_dom('configuration',
                                                                ['usercreation'],$udom);
                       if (ref($domconfig{'usercreation'}) eq 'HASH') {
                           foreach my $item ('username','id') {
                               if (ref($domconfig{'usercreation'}{$item.'_rule'}) eq 'ARRAY') {
                                   $$curr_rules{$udom}{$item} =
                                       $domconfig{'usercreation'}{$item.'_rule'};
                               }
                           }
                       }
                       $got_rules->{$udom} = 1;
                   }
               }
               if ($checkid) {
                   foreach my $udom (keys(%by_id)) {
                       my ($outcome,$results) = &Apache::lonnet::get_multiple_instusers($udom,$by_id{$udom},'id');
                       if ($outcome eq 'ok') {
                           foreach my $id (keys(%{$by_id{$udom}})) {
                               my $uname = $by_id{$udom}{$id};
                               $inst_response{$uname.':'.$udom} = $outcome;
                           }
                           if (ref($results) eq 'HASH') {
                               foreach my $uname (keys(%{$results})) {
                                   if (exists($inst_response{$uname.':'.$udom})) {
                                       $inst_response{$uname.':'.$udom} = $outcome;
                                       $inst_results->{$uname.':'.$udom} = $results->{$uname};
                                   }
                               }
                           }
                       }
                 }                  }
             } else {              } else {
                 ($inst_response,%{$inst_results->{$user}}) =                  foreach my $udom (keys(%by_username)) {
                     &Apache::lonnet::get_instuser($udom,$uname);                      my ($outcome,$results) = &Apache::lonnet::get_multiple_instusers($udom,$by_username{$udom});
                 return;                      if ($outcome eq 'ok') {
                           foreach my $uname (keys(%{$by_username{$udom}})) {
                               $inst_response{$uname.':'.$udom} = $outcome;
                           }
                           if (ref($results) eq 'HASH') {
                               foreach my $uname (keys(%{$results})) {
                                   $inst_results->{$uname.':'.$udom} = $results->{$uname};
                               }
                           }
                       }
                   }
             }              }
             if (!$got_rules->{$udom}) {          } elsif (keys(%{$usershash}) == 1) {
                 my %domconfig = &Apache::lonnet::get_dom('configuration',              my $user = (keys(%{$usershash}))[0];
                                                   ['usercreation'],$udom);              my ($uname,$udom) = split(/:/,$user);
                 if (ref($domconfig{'usercreation'}) eq 'HASH') {              if (($udom ne '') && ($uname ne '')) {
                     foreach my $item ('username','id') {                  if (ref($usershash->{$user}) eq 'HASH') {
                         if (ref($domconfig{'usercreation'}{$item.'_rule'}) eq 'ARRAY') {                      if (ref($checks) eq 'HASH') {
                             $$curr_rules{$udom}{$item} =                           if (defined($checks->{'username'})) {
                                 $domconfig{'usercreation'}{$item.'_rule'};                              ($inst_response{$user},%{$inst_results->{$user}}) =
                                   &Apache::lonnet::get_instuser($udom,$uname);
                           } elsif (defined($checks->{'id'})) {
                               if ($usershash->{$user}->{'id'} ne '') {
                                   ($inst_response{$user},%{$inst_results->{$user}}) =
                                       &Apache::lonnet::get_instuser($udom,undef,
                                                                     $usershash->{$user}->{'id'});
                               } else {
                                   ($inst_response{$user},%{$inst_results->{$user}}) =
                                       &Apache::lonnet::get_instuser($udom,$uname);
                               }
                           }
                       } else {
                          ($inst_response{$user},%{$inst_results->{$user}}) =
                               &Apache::lonnet::get_instuser($udom,$uname);
                          return;
                       }
                       if (!$got_rules->{$udom}) {
                           my %domconfig = &Apache::lonnet::get_dom('configuration',
                                                                    ['usercreation'],$udom);
                           if (ref($domconfig{'usercreation'}) eq 'HASH') {
                               foreach my $item ('username','id') {
                                   if (ref($domconfig{'usercreation'}{$item.'_rule'}) eq 'ARRAY') {
                                      $$curr_rules{$udom}{$item} =
                                          $domconfig{'usercreation'}{$item.'_rule'};
                                   }
                               }
                         }                          }
                           $got_rules->{$udom} = 1;
                     }                      }
                 }                  }
                 $got_rules->{$udom} = 1;                } else {
                   return;
               }
           } else {
               return;
           }
           foreach my $user (keys(%{$usershash})) {
               my ($uname,$udom) = split(/:/,$user);
               next if (($udom eq '') || ($uname eq ''));
               my $id;
               if (ref($inst_results) eq 'HASH') {
                   if (ref($inst_results->{$user}) eq 'HASH') {
                       $id = $inst_results->{$user}->{'id'};
                   }
               }
               if ($id eq '') {
                   if (ref($usershash->{$user})) {
                       $id = $usershash->{$user}->{'id'};
                   }
             }              }
             foreach my $item (keys(%{$checks})) {              foreach my $item (keys(%{$checks})) {
                 if (ref($$curr_rules{$udom}) eq 'HASH') {                  if (ref($$curr_rules{$udom}) eq 'HASH') {
                     if (ref($$curr_rules{$udom}{$item}) eq 'ARRAY') {                      if (ref($$curr_rules{$udom}{$item}) eq 'ARRAY') {
                         if (@{$$curr_rules{$udom}{$item}} > 0) {                          if (@{$$curr_rules{$udom}{$item}} > 0) {
                             my %rule_check = &Apache::lonnet::inst_rulecheck($udom,$uname,$id,$item,$$curr_rules{$udom}{$item});                              my %rule_check = &Apache::lonnet::inst_rulecheck($udom,$uname,$id,$item,
                                                                                $$curr_rules{$udom}{$item});
                             foreach my $rule (@{$$curr_rules{$udom}{$item}}) {                              foreach my $rule (@{$$curr_rules{$udom}{$item}}) {
                                 if ($rule_check{$rule}) {                                  if ($rule_check{$rule}) {
                                     $$rulematch{$user}{$item} = $rule;                                      $$rulematch{$user}{$item} = $rule;
                                     if ($inst_response eq 'ok') {                                      if ($inst_response{$user} eq 'ok') {
                                         if (ref($inst_results) eq 'HASH') {                                          if (ref($inst_results) eq 'HASH') {
                                             if (ref($inst_results->{$user}) eq 'HASH') {                                              if (ref($inst_results->{$user}) eq 'HASH') {
                                                 if (keys(%{$inst_results->{$user}}) == 0) {                                                  if (keys(%{$inst_results->{$user}}) == 0) {
                                                     $$alerts{$item}{$udom}{$uname} = 1;                                                      $$alerts{$item}{$udom}{$uname} = 1;
                                                   } elsif ($item eq 'id') {
                                                       if ($inst_results->{$user}->{'id'} eq '') {
                                                           $$alerts{$item}{$udom}{$uname} = 1;
                                                       }
                                                 }                                                  }
                                             }                                              }
                                         }                                          }
Line 13933  sub check_clone { Line 14212  sub check_clone {
             (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'}))) {              (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'}))) {
     $can_clone = 1;      $can_clone = 1;
  } else {   } else {
     my %clonehash = &Apache::lonnet::get('environment',['cloners'],      my %clonehash = &Apache::lonnet::get('environment',['cloners','internal.coursecode'],
  $args->{'clonedomain'},$args->{'clonecourse'});   $args->{'clonedomain'},$args->{'clonecourse'});
     my @cloners = split(/,/,$clonehash{'cloners'});              if ($clonehash{'cloners'} eq '') {
             if (grep(/^\*$/,@cloners)) {                  my %domdefs = &Apache::lonnet::get_domain_defaults($args->{'course_domain'});
                 $can_clone = 1;                  if ($domdefs{'canclone'}) {
             } elsif (grep(/^\*\:\Q$args->{'ccdomain'}\E$/,@cloners)) {                      unless ($domdefs{'canclone'} eq 'none') {
                 $can_clone = 1;                          if ($domdefs{'canclone'} eq 'domain') {
                               if ($args->{'ccdomain'} eq $args->{'clonedomain'}) {
                                   $can_clone = 1;
                               }
                           } elsif (($clonehash{'internal.coursecode'}) && ($args->{'crscode'}) &&
                                    ($args->{'clonedomain'} eq  $args->{'course_domain'})) {
                               if (&Apache::lonnet::default_instcode_cloning($args->{'clonedomain'},$domdefs{'canclone'},
                                                                             $clonehash{'internal.coursecode'},$args->{'crscode'})) {
                                   $can_clone = 1;
                               }
                           }
                       }
                   }
             } else {              } else {
           my @cloners = split(/,/,$clonehash{'cloners'});
                   if (grep(/^\*$/,@cloners)) {
                       $can_clone = 1;
                   } elsif (grep(/^\*\:\Q$args->{'ccdomain'}\E$/,@cloners)) {
                       $can_clone = 1;
                   } elsif (grep(/^\Q$args->{'ccuname'}\E:\Q$args->{'ccdomain'}\E$/,@cloners)) {
                       $can_clone = 1;
                   }
                   unless ($can_clone) {
                       if (($clonehash{'internal.coursecode'}) && ($args->{'crscode'}) &&
                           ($args->{'clonedomain'} eq  $args->{'course_domain'})) {
                           my (%gotdomdefaults,%gotcodedefaults);
                           foreach my $cloner (@cloners) {
                               if (($cloner ne '*') && ($cloner !~ /^\*\:$match_domain$/) &&
                                   ($cloner !~ /^$match_username\:$match_domain$/) && ($cloner ne '')) {
                                   my (%codedefaults,@code_order);
                                   if (ref($gotcodedefaults{$args->{'clonedomain'}}) eq 'HASH') {
                                       if (ref($gotcodedefaults{$args->{'clonedomain'}}{'defaults'}) eq 'HASH') {
                                           %codedefaults = %{$gotcodedefaults{$args->{'clonedomain'}}{'defaults'}};
                                       }
                                       if (ref($gotcodedefaults{$args->{'clonedomain'}}{'order'}) eq 'ARRAY') {
                                           @code_order = @{$gotcodedefaults{$args->{'clonedomain'}}{'order'}};
                                       }
                                   } else {
                                       &Apache::lonnet::auto_instcode_defaults($args->{'clonedomain'},
                                                                               \%codedefaults,
                                                                               \@code_order);
                                       $gotcodedefaults{$args->{'clonedomain'}}{'defaults'} = \%codedefaults;
                                       $gotcodedefaults{$args->{'clonedomain'}}{'order'} = \@code_order;
                                   }
                                   if (@code_order > 0) {
                                       if (&Apache::lonnet::check_instcode_cloning(\%codedefaults,\@code_order,
                                                                                   $cloner,$clonehash{'internal.coursecode'},
                                                                                   $args->{'crscode'})) {
                                           $can_clone = 1;
                                           last;
                                       }
                                   }
                               }
                           }
                       }
                   }
               }
               unless ($can_clone) {
                 my $ccrole = 'cc';                  my $ccrole = 'cc';
                 if ($args->{'crstype'} eq 'Community') {                  if ($args->{'crstype'} eq 'Community') {
                     $ccrole = 'co';                      $ccrole = 'co';
                 }                  }
         my %roleshash =                  my %roleshash =
     &Apache::lonnet::get_my_roles($args->{'ccuname'},                      &Apache::lonnet::get_my_roles($args->{'ccuname'},
  $args->{'ccdomain'},                                                    $args->{'ccdomain'},
                                          'userroles',['active'],[$ccrole],                                                    'userroles',['active'],[$ccrole],
  [$args->{'clonedomain'}]);                                                    [$args->{'clonedomain'}]);
         if (($roleshash{$args->{'clonecourse'}.':'.$args->{'clonedomain'}.':'.$ccrole}) || (grep(/^\Q$args->{'ccuname'}\E:\Q$args->{'ccdomain'}\E$/,@cloners))) {                  if ($roleshash{$args->{'clonecourse'}.':'.$args->{'clonedomain'}.':'.$ccrole}) {
                     $can_clone = 1;                      $can_clone = 1;
                 } elsif (&Apache::lonnet::is_course_owner($args->{'clonedomain'},$args->{'clonecourse'},$args->{'ccuname'},$args->{'ccdomain'})) {                  } elsif (&Apache::lonnet::is_course_owner($args->{'clonedomain'},$args->{'clonecourse'},
                                                             $args->{'ccuname'},$args->{'ccdomain'})) {
                     $can_clone = 1;                      $can_clone = 1;
                   }
               }
               unless ($can_clone) {
                   if ($args->{'crstype'} eq 'Community') {
                       $clonemsg = &mt('No new community created.').$linefeed.&mt('The new community could not be cloned from the existing community because the new community owner ([_1]) does not have cloning rights in the existing community ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'});
                 } else {                  } else {
                     if ($args->{'crstype'} eq 'Community') {                      $clonemsg = &mt('No new course created.').$linefeed.&mt('The new course could not be cloned from the existing course because the new course owner ([_1]) does not have cloning rights in the existing course ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'});
                         $clonemsg = &mt('No new community created.').$linefeed.&mt('The new community could not be cloned from the existing community because the new community owner ([_1]) does not have cloning rights in the existing community ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'});  
                     } else {  
                         $clonemsg = &mt('No new course created.').$linefeed.&mt('The new course could not be cloned from the existing course because the new course owner ([_1]) does not have cloning rights in the existing course ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'});  
                     }  
         }          }
     }      }
         }          }
Line 14488  sub escape_url { Line 14825  sub escape_url {
     my ($url)   = @_;      my ($url)   = @_;
     my @urlslices = split(/\//, $url,-1);      my @urlslices = split(/\//, $url,-1);
     my $lastitem = &escape(pop(@urlslices));      my $lastitem = &escape(pop(@urlslices));
     return join('/',@urlslices).'/'.$lastitem;      return &HTML::Entities::encode(join('/',@urlslices),"'").'/'.$lastitem;
 }  }
   
 sub compare_arrays {  sub compare_arrays {
Line 14546  sub init_user_environment { Line 14883  sub init_user_environment {
  }   }
     }      }
     closedir(DIR);      closedir(DIR);
   # If there is a undeleted lockfile for the user's paste buffer remove it.
               my $namespace = 'nohist_courseeditor';
               my $lockingkey = 'paste'."\0".'locked_num';
               my %lockhash = &Apache::lonnet::get($namespace,[$lockingkey],
                                                   $domain,$username);
               if (exists($lockhash{$lockingkey})) {
                   my $delresult = &Apache::lonnet::del($namespace,[$lockingkey],$domain,$username);
                   unless ($delresult eq 'ok') {
                       &Apache::lonnet::logthis("Failed to delete paste buffer locking key in $namespace for ".$username.":".$domain." Result was: $delresult");
                   }
               }
  }   }
 # Give them a new cookie  # Give them a new cookie
  my $id = ($args->{'robot'} ? 'robot'.$args->{'robot'}   my $id = ($args->{'robot'} ? 'robot'.$args->{'robot'}
Line 15162  cloneruname - optional username of new c Line 15510  cloneruname - optional username of new c
   
 clonerudom - optional domain of new course owner  clonerudom - optional domain of new course owner
   
 domcloner - Optional "domcloner" flag; has value=1 if user has ccc priv in domain being filtered by,  domcloner - optional "domcloner" flag; has value=1 if user has ccc priv in domain being filtered by,
             (used when DC is using course creation form)              (used when DC is using course creation form)
   
 codetitles - reference to array of titles of components in institutional codes (official courses).  codetitles - reference to array of titles of components in institutional codes (official courses).
   
   cc_clone - escaped comma separated list of courses for which course cloner has active CC role
              (and so can clone automatically)
   
   reqcrsdom - domain of new course, where search_courses is used to identify potential courses to clone
   
   reqinstcode - institutional code of new course, where search_courses is used to identify potential
                 courses to clone
   
 Returns: %courses - hash of courses satisfying search criteria, keys = course IDs, values are corresponding colon-separated escaped description, institutional code, owner and type.  Returns: %courses - hash of courses satisfying search criteria, keys = course IDs, values are corresponding colon-separated escaped description, institutional code, owner and type.
   
Line 15177  Side Effects: None Line 15532  Side Effects: None
   
   
 sub search_courses {  sub search_courses {
     my ($dom,$type,$filter,$numtitles,$cloneruname,$clonerudom,$domcloner,$codetitles) = @_;      my ($dom,$type,$filter,$numtitles,$cloneruname,$clonerudom,$domcloner,$codetitles,
           $cc_clone,$reqcrsdom,$reqinstcode) = @_;
     my (%courses,%showcourses,$cloner);      my (%courses,%showcourses,$cloner);
     if (($filter->{'ownerfilter'} ne '') ||      if (($filter->{'ownerfilter'} ne '') ||
         ($filter->{'ownerdomfilter'} ne '')) {          ($filter->{'ownerdomfilter'} ne '')) {
Line 15225  sub search_courses { Line 15581  sub search_courses {
                                              $filter->{'combownerfilter'},                                               $filter->{'combownerfilter'},
                                              $filter->{'coursefilter'},                                               $filter->{'coursefilter'},
                                              undef,undef,$type,$regexpok,undef,undef,                                               undef,undef,$type,$regexpok,undef,undef,
                                              undef,undef,$cloner,$env{'form.cc_clone'},                                               undef,undef,$cloner,$cc_clone,
                                              $filter->{'cloneableonly'},                                               $filter->{'cloneableonly'},
                                              $createdbefore,$createdafter,undef,                                               $createdbefore,$createdafter,undef,
                                              $domcloner);                                               $domcloner,undef,$reqcrsdom,$reqinstcode);
     if (($filter->{'personfilter'} ne '') && ($filter->{'persondomfilter'} ne '')) {      if (($filter->{'personfilter'} ne '') && ($filter->{'persondomfilter'} ne '')) {
         my $ccrole;          my $ccrole;
         if ($type eq 'Community') {          if ($type eq 'Community') {
Line 15262  sub search_courses { Line 15618  sub search_courses {
     return %courses;      return %courses;
 }  }
   
   =pod
   
   =back
   
   =head1 Routines for version requirements for current course.
   
   =over 4
   
   =item * &check_release_required()
   
   Compares required LON-CAPA version with version on server, and
   if required version is newer looks for a server with the required version.
   
   Looks first at servers in user's owen domain; if none suitable, looks at
   servers in course's domain are permitted to host sessions for user's domain.
   
   Inputs:
   
   $loncaparev - Version on current server (format: Major.Minor.Subrelease-datestamp)
   
   $courseid - Course ID of current course
   
   $rolecode - User's current role in course (for switchserver query string).
   
   $required - LON-CAPA version needed by course (format: Major.Minor).
   
   
   Returns:
   
   $switchserver - query string tp append to /adm/switchserver call (if
                   current server's LON-CAPA version is too old.
   
   $warning - Message is displayed if no suitable server could be found.
   
   =cut
   
   sub check_release_required {
       my ($loncaparev,$courseid,$rolecode,$required) = @_;
       my ($switchserver,$warning);
       if ($required ne '') {
           my ($reqdmajor,$reqdminor) = ($required =~ /^(\d+)\.(\d+)$/);
           my ($major,$minor) = ($loncaparev =~ /^\'?(\d+)\.(\d+)\.[\w.\-]+\'?$/);
           if ($reqdmajor ne '' && $reqdminor ne '') {
               my $otherserver;
               if (($major eq '' && $minor eq '') ||
                   (($reqdmajor > $major) || (($reqdmajor == $major) && ($reqdminor > $minor)))) {
                   my ($userdomserver) = &Apache::lonnet::choose_server($env{'user.domain'},undef,$required,1);
                   my $switchlcrev =
                       &Apache::lonnet::get_server_loncaparev($env{'user.domain'},
                                                              $userdomserver);
                   my ($swmajor,$swminor) = ($switchlcrev =~ /^\'?(\d+)\.(\d+)\.[\w.\-]+\'?$/);
                   if (($swmajor eq '' && $swminor eq '') || ($reqdmajor > $swmajor) ||
                       (($reqdmajor == $swmajor) && ($reqdminor > $swminor))) {
                       my $cdom = $env{'course.'.$courseid.'.domain'};
                       if ($cdom ne $env{'user.domain'}) {
                           my ($coursedomserver,$coursehostname) = &Apache::lonnet::choose_server($cdom,undef,$required,1);
                           my $serverhomeID = &Apache::lonnet::get_server_homeID($coursehostname);
                           my $serverhomedom = &Apache::lonnet::host_domain($serverhomeID);
                           my %defdomdefaults = &Apache::lonnet::get_domain_defaults($serverhomedom);
                           my %udomdefaults = &Apache::lonnet::get_domain_defaults($env{'user.domain'});
                           my $remoterev = &Apache::lonnet::get_server_loncaparev($serverhomedom,$coursedomserver);
                           my $canhost =
                               &Apache::lonnet::can_host_session($env{'user.domain'},
                                                                 $coursedomserver,
                                                                 $remoterev,
                                                                 $udomdefaults{'remotesessions'},
                                                                 $defdomdefaults{'hostedsessions'});
   
                           if ($canhost) {
                               $otherserver = $coursedomserver;
                           } else {
                               $warning = &mt('Requires LON-CAPA version [_1].',$env{'course.'.$courseid.'.internal.releaserequired'}).'<br />'. &mt("No suitable server could be found amongst servers in either your own domain or in the course's domain.");
                           }
                       } else {
                           $warning = &mt('Requires LON-CAPA version [_1].',$env{'course.'.$courseid.'.internal.releaserequired'}).'<br />'.&mt("No suitable server could be found amongst servers in your own domain (which is also the course's domain).");
                       }
                   } else {
                       $otherserver = $userdomserver;
                   }
               }
               if ($otherserver ne '') {
                   $switchserver = 'otherserver='.$otherserver.'&amp;role='.$rolecode;
               }
           }
       }
       return ($switchserver,$warning);
   }
   
   =pod
   
   =item * &check_release_result()
   
   Inputs:
   
   $switchwarning - Warning message if no suitable server found to host session.
   
   $switchserver - query string to append to /adm/switchserver containing lonHostID
                   and current role.
   
   Returns: HTML to display with information about requirement to switch server.
            Either displaying warning with link to Roles/Courses screen or
            display link to switchserver.
   
   =cut
   
   sub check_release_result {
       my ($switchwarning,$switchserver) = @_;
       my $output = &start_page('Selected course unavailable on this server').
                    '<p class="LC_warning">';
       if ($switchwarning) {
           $output .= $switchwarning.'<br /><a href="/adm/roles">';
           if (&show_course()) {
               $output .= &mt('Display courses');
           } else {
               $output .= &mt('Display roles');
           }
           $output .= '</a>';
       } elsif ($switchserver) {
           $output .= &mt('This course requires a newer version of LON-CAPA than is installed on this server.').
                      '<br />'.
                      '<a href="/adm/switchserver?'.$switchserver.'">'.
                      &mt('Switch Server').
                      '</a>';
       }
       $output .= '</p>'.&end_page();
       return $output;
   }
   
 =pod  =pod
   
   =item * &needs_coursereinit()
   
   Determine if course contents stored for user's session needs to be
   refreshed, because content has changed since "Big Hash" last tied.
   
   Check for change is made if time last checked is more than 10 minutes ago
   (by default).
   
   Inputs:
   
   $loncaparev - Version on current server (format: Major.Minor.Subrelease-datestamp)
   
   $interval (optional) - Time which may elapse (in s) between last check for content
                          change in current course. (default: 600 s).
   
   Returns: an array; first element is:
   
   =over 4
   
   'switch' - if content updates mean user's session
              needs to be switched to a server running a newer LON-CAPA version
   
   'update' - if course session needs to be refreshed (i.e., Big Hash needs to be reloaded)
              on current server hosting user's session
   
   ''       - if no action required.
   
   =back
   
   If first item element is 'switch':
   
   second item is $switchwarning - Warning message if no suitable server found to host session.
   
   third item is $switchserver - query string to append to /adm/switchserver containing lonHostID
                                 and current role.
   
   otherwise: no other elements returned.
   
 =back  =back
   
 =cut  =cut
   
   sub needs_coursereinit {
       my ($loncaparev,$interval) = @_;
       return() unless ($env{'request.course.id'} && $env{'request.course.tied'});
       my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
       my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
       my $now = time;
       if ($interval eq '') {
           $interval = 600;
       }
       if (($now-$env{'request.course.timechecked'})>$interval) {
           my $lastchange = &Apache::lonnet::get_coursechange($cdom,$cnum);
           &Apache::lonnet::appenv({'request.course.timechecked'=>$now});
           if ($lastchange > $env{'request.course.tied'}) {
               my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired');
               if ($curr_reqd_hash{'internal.releaserequired'} ne '') {
                   my $required = $env{'course.'.$cdom.'_'.$cnum.'.internal.releaserequired'};
                   if ($curr_reqd_hash{'internal.releaserequired'} ne $required) {
                       &Apache::lonnet::appenv({'course.'.$cdom.'_'.$cnum.'.internal.releaserequired' =>
                                                $curr_reqd_hash{'internal.releaserequired'}});
                       my ($switchserver,$switchwarning) =
                           &check_release_required($loncaparev,$cdom.'_'.$cnum,$env{'request.role'},
                                                   $curr_reqd_hash{'internal.releaserequired'});
                       if ($switchwarning ne '' || $switchserver ne '') {
                           return ('switch',$switchwarning,$switchserver);
                       }
                   }
               }
               return ('update');
           }
       }
       return ();
   }
   
 sub update_content_constraints {  sub update_content_constraints {
     my ($cdom,$cnum,$chome,$cid) = @_;      my ($cdom,$cnum,$chome,$cid) = @_;
Line 15589  sub create_recaptcha { Line 16142  sub create_recaptcha {
     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,undef,$use_ssl).             $captcha->get_html($pubkey,undef,$use_ssl).
            &mt('If either word is hard to read, [_1] will replace them.',             &mt('If the text is hard to read, [_1] will replace them.',
                '<img src="/res/adm/pages/refresh.gif" alt="reCAPTCHA refresh" />').                 '<img src="/res/adm/pages/refresh.gif" alt="reCAPTCHA refresh" />').
            '<br /><br />';             '<br /><br />';
 }  }
Line 15612  sub check_recaptcha { Line 16165  sub check_recaptcha {
 }  }
   
 sub emailusername_info {  sub emailusername_info {
     my @fields = ('firstname','lastname','institution','web','location','officialemail');      my @fields = ('firstname','lastname','institution','web','location','officialemail','id');
     my %titles = &Apache::lonlocal::texthash (      my %titles = &Apache::lonlocal::texthash (
                      lastname      => 'Last Name',                       lastname      => 'Last Name',
                      firstname     => 'First Name',                       firstname     => 'First Name',
Line 15620  sub emailusername_info { Line 16173  sub emailusername_info {
                      location      => "School's city, state/province, country",                       location      => "School's city, state/province, country",
                      web           => "School's web address",                       web           => "School's web address",
                      officialemail => 'E-mail address at institution (if different)',                       officialemail => 'E-mail address at institution (if different)',
                        id            => 'Student/Employee ID',
                  );                   );
     return (\@fields,\%titles);      return (\@fields,\%titles);
 }  }

Removed from v.1.1075.2.82  
changed lines
  Added in v.1.1075.2.103


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