Diff for /loncom/interface/loncommon.pm between versions 1.476 and 1.539

version 1.476, 2006/11/29 19:33:29 version 1.539, 2007/06/27 22:43:28
Line 59  use Apache::lonnet; Line 59  use Apache::lonnet;
 use GDBM_File;  use GDBM_File;
 use POSIX qw(strftime mktime);  use POSIX qw(strftime mktime);
 use Apache::lonmenu();  use Apache::lonmenu();
   use Apache::lonenc();
 use Apache::lonlocal;  use Apache::lonlocal;
 use HTML::Entities;  use HTML::Entities;
 use Apache::lonhtmlcommon();  use Apache::lonhtmlcommon();
 use Apache::loncoursedata();  use Apache::loncoursedata();
 use Apache::lontexconvert();  use Apache::lontexconvert();
 use Apache::lonclonecourse();  use Apache::lonclonecourse();
 use LONCAPA;  use LONCAPA qw(:DEFAULT :match);
   
   # ---------------------------------------------- Designs
   use vars qw(%defaultdesign);
   
 my $readit;  my $readit;
   
   
 ##  ##
 ## Global Variables  ## Global Variables
 ##  ##
Line 81  my %scprtag; Line 86  my %scprtag;
 my %fe; my %fd; my %fm;  my %fe; my %fd; my %fm;
 my %category_extensions;  my %category_extensions;
   
 # ---------------------------------------------- Designs  
   
 my %designhash;  
   
 # ---------------------------------------------- Thesaurus variables  # ---------------------------------------------- Thesaurus variables
 #  #
 # %Keywords:  # %Keywords:
Line 150  BEGIN { Line 151  BEGIN {
         }          }
     }      }
   
 # -------------------------------------------------------------- domain designs  # -------------------------------------------------------------- default domain designs
   
     my $filename;  
     my $designdir=$Apache::lonnet::perlvar{'lonTabDir'}.'/lonDomColors';      my $designdir=$Apache::lonnet::perlvar{'lonTabDir'}.'/lonDomColors';
     opendir(DIR,$designdir);      my $designfile = $designdir.'/default.tab';
     while ($filename=readdir(DIR)) {      if ( open (my $fh,"<$designfile") ) {
  if ($filename!~/\.tab$/) { next; }          while (my $line = <$fh>) {
  my ($domain)=($filename=~/^(\w+)\./);              next if ($line =~ /^\#/);
  {              chomp($line);
     my $designfile = $designdir.'/'.$filename;              my ($key,$val)=(split(/\=/,$line));
     if ( open (my $fh,"<$designfile") ) {              if ($val) { $defaultdesign{$key}=$val; }
  while (my $line = <$fh>) {          }
     next if ($line =~ /^\#/);          close($fh);
     chomp($line);  
     my ($key,$val)=(split(/\=/,$line));  
     if ($val) { $designhash{$domain.'.'.$key}=$val; }  
  }  
  close($fh);  
     }  
  }  
   
     }      }
     closedir(DIR);  
   
   
 # ------------------------------------------------------------- file categories  # ------------------------------------------------------------- file categories
     {      {
Line 251  Inputs: formname, elementname Line 240  Inputs: formname, elementname
   
 formname and elementname specify the name of the html form and the name  formname and elementname specify the name of the html form and the name
 of the element the selection from the search results will be placed in.  of the element the selection from the search results will be placed in.
   =back
 =cut  =cut
   
 sub browser_and_searcher_javascript {  sub browser_and_searcher_javascript {
Line 389  sub coursebrowser_javascript { Line 378  sub coursebrowser_javascript {
     my ($domainfilter,$sec_element,$formname)=@_;      my ($domainfilter,$sec_element,$formname)=@_;
     my $crs_or_grp_alert = &mt('Please select the type of LON-CAPA entity - Course or Group - for which you wish to add/modify a user role');      my $crs_or_grp_alert = &mt('Please select the type of LON-CAPA entity - Course or Group - for which you wish to add/modify a user role');
    my $output = '     my $output = '
 <script type="text/javascript" language="Javascript" >  <script type="text/javascript">
     var stdeditbrowser;'."\n";      var stdeditbrowser;'."\n";
    $output .= <<"ENDSTDBRW";     $output .= <<"ENDSTDBRW";
     function opencrsbrowser(formname,uname,udom,desc,extra_element,multflag,crstype) {      function opencrsbrowser(formname,uname,udom,desc,extra_element,multflag,crstype) {
Line 515  function setSect(sectionlist) { Line 504  function setSect(sectionlist) {
   
 sub selectcourse_link {  sub selectcourse_link {
    my ($form,$unameele,$udomele,$desc,$extra_element,$multflag,$selecttype)=@_;     my ($form,$unameele,$udomele,$desc,$extra_element,$multflag,$selecttype)=@_;
     return "<a href='".'javascript:opencrsbrowser("'.$form.'","'.$unameele.     return "<a href='".'javascript:opencrsbrowser("'.$form.'","'.$unameele.
         '","'.$udomele.'","'.$desc.'","'.$extra_element.'","'.$multflag.'","'.$selecttype.'");'."'>".&mt('Select [_1]',$selecttype)."</a>";          '","'.$udomele.'","'.$desc.'","'.$extra_element.'","'.$multflag.'","'.$selecttype.'");'."'>".&mt('Select Course')."</a>";
 }  }
   
 sub check_uncheck_jscript {  sub check_uncheck_jscript {
Line 1264  sub create_text_file { Line 1253  sub create_text_file {
 ##        Home server <option> list generating code          ##  ##        Home server <option> list generating code          ##
 ###############################################################  ###############################################################
   
 =pod  
   
 =head1 Home Server option list generating code  
   
 =over 4  
   
 =item * get_domains()  
   
 Returns an array containing each of the domains listed in the hosts.tab  
 file.  
   
 =cut  
   
 #-------------------------------------------  
 sub get_domains {  
     # The code below was stolen from "The Perl Cookbook", p 102, 1st ed.  
     my @domains;  
     my %seen;  
     foreach my $dom (sort(values(%Apache::lonnet::hostdom))) {  
  push(@domains,$dom) unless $seen{$dom}++;  
     }  
     return @domains;  
 }  
   
 # ------------------------------------------  # ------------------------------------------
   
 sub domain_select {  sub domain_select {
     my ($name,$value,$multiple)=@_;      my ($name,$value,$multiple)=@_;
     my %domains=map {       my %domains=map { 
  $_ => $_.' '.$Apache::lonnet::domaindescription{$_}    $_ => $_.' '. &Apache::lonnet::domain($_,'description') 
     } &get_domains;      } &Apache::lonnet::all_domains();
     if ($multiple) {      if ($multiple) {
  $domains{''}=&mt('Any domain');   $domains{''}=&mt('Any domain');
  return &multiple_select_form($name,$value,4,\%domains);   return &multiple_select_form($name,$value,4,\%domains);
Line 1307  sub domain_select { Line 1272  sub domain_select {
   
 =pod  =pod
   
   =head1 Routines for form select boxes
   
   =over 4
   
   =cut
   
 =item * multiple_select_form($name,$value,$size,$hash,$order)  =item * multiple_select_form($name,$value,$size,$hash,$order)
   
 Returns a string containing a <select> element int multiple mode  Returns a string containing a <select> element int multiple mode
Line 1314  Returns a string containing a <select> e Line 1285  Returns a string containing a <select> e
   
 Args:  Args:
   $name - name of the <select> element    $name - name of the <select> element
   $value - sclara or array ref of values that should already be selected    $value - scalar or array ref of values that should already be selected
   $size - number of rows long the select element is    $size - number of rows long the select element is
   $hash - the elements should be 'option' => 'shown text'    $hash - the elements should be 'option' => 'shown text'
           (shown text should already have been &mt())            (shown text should already have been &mt())
   $order - (optional) array ref of the order to show the elments in    $order - (optional) array ref of the order to show the elements in
   
 =cut  =cut
   
Line 1334  sub multiple_select_form { Line 1305  sub multiple_select_form {
         }          }
     }      }
     $output.="\n<select name='$name' size='$size' multiple='1'>";      $output.="\n<select name='$name' size='$size' multiple='1'>";
     my @order = ref($order) ? @$order      my @order;
                             : sort(keys(%$hash));      if (ref($order) eq 'ARRAY')  {
           @order = @{$order};
       } else {
           @order = sort(keys(%$hash));
       }
       if (exists($$hash{'select_form_order'})) {
           @order = @{$$hash{'select_form_order'}};
       }
           
     foreach my $key (@order) {      foreach my $key (@order) {
         $output.='<option value="'.&HTML::Entities::encode($key,'"<>&').'" ';          $output.='<option value="'.&HTML::Entities::encode($key,'"<>&').'" ';
         $output.='selected="selected" ' if ($selected{$key});          $output.='selected="selected" ' if ($selected{$key});
Line 1381  sub select_form { Line 1360  sub select_form {
   
 sub display_filter {  sub display_filter {
     if (!$env{'form.show'}) { $env{'form.show'}=10; }      if (!$env{'form.show'}) { $env{'form.show'}=10; }
       if (!$env{'form.displayfilter'}) { $env{'form.displayfilter'}='currentfolder'; }
     return '<nobr><label>'.&mt('Records [_1]',      return '<nobr><label>'.&mt('Records [_1]',
        &Apache::lonmeta::selectbox('show',$env{'form.show'},undef,         &Apache::lonmeta::selectbox('show',$env{'form.show'},undef,
    (&mt('all'),10,20,50,100,1000,10000))).     (&mt('all'),10,20,50,100,1000,10000))).
    '</label></nobr> <nobr><label>'.     '</label></nobr> <nobr>'.
            &mt('Filter [_1]',             &mt('Filter [_1]',
    &select_form(($env{'form.displayfilter'}?$env{'form.displayfilter'}:'currentfolder'),     &select_form($env{'form.displayfilter'},
  'displayfilter',   'displayfilter',
  ('currentfolder' => 'Current folder',   ('currentfolder' => 'Current folder/page',
  'containing' => 'Containing phrase',   'containing' => 'Containing phrase',
  'none' => 'None'))).   'none' => 'None'))).
    '<input type="text" name="containingphrase" size="30" /></label></nobr>';   '<input type="text" name="containingphrase" size="30" value="'.&HTML::Entities::encode($env{'form.containingphrase'}).'" /></nobr>';
 }  }
   
 sub gradeleveldescription {  sub gradeleveldescription {
Line 1449  selected"); Line 1429  selected");
 #-------------------------------------------  #-------------------------------------------
 sub select_dom_form {  sub select_dom_form {
     my ($defdom,$name,$includeempty) = @_;      my ($defdom,$name,$includeempty) = @_;
     my @domains = get_domains();      my @domains = sort(&Apache::lonnet::all_domains());
     if ($includeempty) { @domains=('',@domains); }      if ($includeempty) { @domains=('',@domains); }
     my $selectdomain = "<select name=\"$name\" size=\"1\">\n";      my $selectdomain = "<select name=\"$name\" size=\"1\">\n";
     foreach my $dom (@domains) {      foreach my $dom (@domains) {
Line 1465  sub select_dom_form { Line 1445  sub select_dom_form {
   
 =pod  =pod
   
 =item * get_library_servers($domain)  
   
 Returns a hash which contains keys like '103l3' and values like   
 'kirk.lite.msu.edu'.  All of the keys will be for machines in the  
 given $domain.  
   
 =cut  
   
 #-------------------------------------------  
 sub get_library_servers {  
     my $domain = shift;  
     my %library_servers;  
     foreach my $hostid (keys(%Apache::lonnet::libserv)) {  
         if ($Apache::lonnet::hostdom{$hostid} eq $domain) {  
             $library_servers{$hostid} = $Apache::lonnet::hostname{$hostid};  
         }  
     }  
     return %library_servers;  
 }  
   
 #-------------------------------------------  
   
 =pod  
   
 =item * home_server_option_list($domain)  =item * home_server_option_list($domain)
   
 returns a string which contains an <option> list to be used in a   returns a string which contains an <option> list to be used in a 
Line 1499  returns a string which contains an <opti Line 1455  returns a string which contains an <opti
 #-------------------------------------------  #-------------------------------------------
 sub home_server_option_list {  sub home_server_option_list {
     my $domain = shift;      my $domain = shift;
     my %servers = &get_library_servers($domain);      my %servers = &Apache::lonnet::get_servers($domain,'library');
     my $result = '';      my $result = '';
     foreach my $hostid (sort(keys(%servers))) {      foreach my $hostid (sort(keys(%servers))) {
         $result.=          $result.=
Line 1511  sub home_server_option_list { Line 1467  sub home_server_option_list {
   
 =pod  =pod
   
 =back  =back 
   
 =cut  =cut
   
Line 1901  If target_domain is not found in domain. Line 1857  If target_domain is not found in domain.
 #-------------------------------------------  #-------------------------------------------
 sub get_auth_defaults {  sub get_auth_defaults {
     my $domain=shift;      my $domain=shift;
     return ($Apache::lonnet::domain_auth_def{$domain},$Apache::lonnet::domain_auth_arg_def{$domain});      return (&Apache::lonnet::domain($domain,'auth_def'),
       &Apache::lonnet::domain($domain,'auth_arg_def'));
       
 }  }
 ###############################################################  ###############################################################
 ##   End Get Authentication Defaults for Domain              ##  ##   End Get Authentication Defaults for Domain              ##
Line 2096  if $first is set to 'lastname' then it r Line 2054  if $first is set to 'lastname' then it r
 ###############################################################  ###############################################################
 sub plainname {  sub plainname {
     my ($uname,$udom,$first)=@_;      my ($uname,$udom,$first)=@_;
       return if (!defined($uname) || !defined($udom));
     my %names=&getnames($uname,$udom);      my %names=&getnames($uname,$udom);
     my $name=&Apache::lonnet::format_name($names{'firstname'},      my $name=&Apache::lonnet::format_name($names{'firstname'},
   $names{'middlename'},    $names{'middlename'},
Line 2127  if the user does not Line 2086  if the user does not
   
 sub nickname {  sub nickname {
     my ($uname,$udom)=@_;      my ($uname,$udom)=@_;
       return if (!defined($uname) || !defined($udom));
     my %names=&getnames($uname,$udom);      my %names=&getnames($uname,$udom);
     my $name=$names{'nickname'};      my $name=$names{'nickname'};
     if ($name) {      if ($name) {
Line 2142  sub nickname { Line 2102  sub nickname {
   
 sub getnames {  sub getnames {
     my ($uname,$udom)=@_;      my ($uname,$udom)=@_;
       return if (!defined($uname) || !defined($udom));
     if ($udom eq 'public' && $uname eq 'public') {      if ($udom eq 'public' && $uname eq 'public') {
  return ('lastname' => &mt('Public'));   return ('lastname' => &mt('Public'));
     }      }
Line 2257  sub track_student_link { Line 2218  sub track_student_link {
  &help_open_topic('View_recent_activity');   &help_open_topic('View_recent_activity');
 }  }
   
   # ===================================================== Display a student photo
   
   
   sub student_image_tag {
       my ($domain,$user)=@_;
       my $imgsrc=&Apache::lonnet::studentphoto($domain,$user,'jpg');
       if (($imgsrc) && ($imgsrc ne '/adm/lonKaputt/lonlogo_broken.gif')) {
    return '<img src="'.$imgsrc.'" align="right" />';
       } else {
    return '';
       }
   }
   
 =pod  =pod
   
 =back  =back
Line 2472  sub preferred_languages { Line 2446  sub preferred_languages {
     if ($browser) {      if ($browser) {
  @languages=(@languages,split(/\s*(\,|\;|\:)\s*/,$browser));   @languages=(@languages,split(/\s*(\,|\;|\:)\s*/,$browser));
     }      }
     if ($Apache::lonnet::domain_lang_def{$env{'user.domain'}}) {      if (&Apache::lonnet::domain($env{'user.domain'},'lang_def')) {
  @languages=(@languages,   @languages=(@languages,
  $Apache::lonnet::domain_lang_def{$env{'user.domain'}});      &Apache::lonnet::domain($env{'user.domain'},
       'lang_def'));
     }      }
     if ($Apache::lonnet::domain_lang_def{$env{'request.role.domain'}}) {      if (&Apache::lonnet::domain($env{'request.role.domain'},'lang_def')) {
  @languages=(@languages,   @languages=(@languages,
  $Apache::lonnet::domain_lang_def{$env{'request.role.domain'}});      &Apache::lonnet::domain($env{'request.role.domain'},
       'lang_def'));
     }      }
     if ($Apache::lonnet::domain_lang_def{      if (&Apache::lonnet::domain($Apache::lonnet::perlvar{'lonDefDomain'},
                           $Apache::lonnet::perlvar{'lonDefDomain'}}) {   'lang_def')) {
  @languages=(@languages,   @languages=(@languages,
  $Apache::lonnet::domain_lang_def{      &Apache::lonnet::domain($Apache::lonnet::perlvar{'lonDefDomain'},
                                   $Apache::lonnet::perlvar{'lonDefDomain'}});      'lang_def'));
     }      }
 # turn "en-ca" into "en-ca,en"  # turn "en-ca" into "en-ca,en"
     my @genlanguages;      my @genlanguages;
Line 2689  sub get_student_answers { Line 2665  sub get_student_answers {
   }    }
   $moreenv{'grade_target'}='answer';    $moreenv{'grade_target'}='answer';
   %moreenv=(%form,%moreenv);    %moreenv=(%form,%moreenv);
   my $userview=&Apache::lonnet::ssi('/res/'.$feedurl,%moreenv);    $feedurl = &Apache::lonnet::clutter($feedurl);
     &Apache::lonenc::check_encrypt(\$feedurl);
     my $userview=&Apache::lonnet::ssi($feedurl,%moreenv);
   return $userview;    return $userview;
 }  }
   
Line 2803  sub maketime { Line 2781  sub maketime {
 #########################################  #########################################
   
 sub findallcourses {  sub findallcourses {
     my ($roles) = @_;      my ($roles,$uname,$udom) = @_;
     my %roles;      my %roles;
     if (ref($roles)) { %roles = map { $_ => 1 } @{$roles}; }      if (ref($roles)) { %roles = map { $_ => 1 } @{$roles}; }
     my %courses;      my %courses;
     my $now=time;      my $now=time;
     foreach my $key (keys(%env)) {      if (!defined($uname)) {
  if ( $key=~m{^user\.role\.(\w+)\./(\w+)/(\w+)/?(\w*)$} ||          $uname = $env{'user.name'};
              $key=~m{^user\.role\.(cr/\w+/\w+/\w+)\./(\w+)/(\w+)}) {      }
     my ($role,$domain,$id,$sec) = ($1,$2,$3,$4);      if (!defined($udom)) {
     next if ($role eq 'ca' || $role eq 'aa');          $udom = $env{'user.domain'};
     next if (%roles && !exists($roles{$role}));      }
     my ($starttime,$endtime)=split(/\./,$env{$key});      if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
             my $active=1;          my %roleshash = &Apache::lonnet::dump('roles',$udom,$uname);
             if ($starttime) {          if (!%roles) {
  if ($now<$starttime) { $active=0; }              %roles = (
             }                         cc => 1,
             if ($endtime) {                         in => 1,
                 if ($now>$endtime) { $active=0; }                         ep => 1,
             }                         ta => 1,
             if ($active) {                         cr => 1,
                 if ($sec eq '') {                         st => 1,
                     $sec = 'none';               );
           }
           foreach my $entry (keys(%roleshash)) {
               my ($trole,$tend,$tstart) = split(/_/,$roleshash{$entry});
               if ($trole =~ /^cr/) { 
                   next if (!exists($roles{$trole}) && !exists($roles{'cr'}));
               } else {
                   next if (!exists($roles{$trole}));
               }
               if ($tend) {
                   next if ($tend < $now);
               }
               if ($tstart) {
                   next if ($tstart > $now);
               }
               my ($cdom,$cnum,$sec,$cnumpart,$secpart,$role,$realsec);
               (undef,$cdom,$cnumpart,$secpart) = split(/\//,$entry);
               if ($secpart eq '') {
                   ($cnum,$role) = split(/_/,$cnumpart); 
                   $sec = 'none';
                   $realsec = '';
               } else {
                   $cnum = $cnumpart;
                   ($sec,$role) = split(/_/,$secpart);
                   $realsec = $sec;
               }
               $courses{$cdom.'_'.$cnum}{$sec} = $trole.'/'.$cdom.'/'.$cnum.'/'.$realsec;
           }
       } else {
           foreach my $key (keys(%env)) {
       if ( $key=~m{^user\.role\.(\w+)\./($match_domain)/($match_courseid)/?(\w*)$} ||
                    $key=~m{^user\.role\.(cr/$match_domain/$match_username/\w+)\./($match_domain)/($match_courseid)/?(\w*)$}) {
           my ($role,$cdom,$cnum,$sec) = ($1,$2,$3,$4);
           next if ($role eq 'ca' || $role eq 'aa');
           next if (%roles && !exists($roles{$role}));
           my ($starttime,$endtime)=split(/\./,$env{$key});
                   my $active=1;
                   if ($starttime) {
       if ($now<$starttime) { $active=0; }
                   }
                   if ($endtime) {
                       if ($now>$endtime) { $active=0; }
                   }
                   if ($active) {
                       if ($sec eq '') {
                           $sec = 'none';
                       }
                       $courses{$cdom.'_'.$cnum}{$sec} = 
                                        $role.'/'.$cdom.'/'.$cnum.'/'.$sec;
                 }                  }
                 $courses{$domain.'_'.$id}{$sec} = 1;  
             }              }
         }          }
     }      }
Line 2836  sub findallcourses { Line 2861  sub findallcourses {
 ###############################################  ###############################################
   
 sub blockcheck {  sub blockcheck {
     my ($setters,$activity) = @_;      my ($setters,$activity,$uname,$udom) = @_;
     # Retrieve active student roles and active course coordinator/instructor roles  
       if (!defined($udom)) {
           $udom = $env{'user.domain'};
       }
       if (!defined($uname)) {
           $uname = $env{'user.name'};
       }
   
     my %live_courses = &findallcourses();      # If uname and udom are for a course, check for blocks in the course.
   
     # Retrieve blocking times and identity of blocker for active courses      if (&Apache::lonnet::is_course($udom,$uname)) {
     # unless user has 'evb' privilege.          my %records = &Apache::lonnet::dump('comm_block',$udom,$uname);
           my ($startblock,$endblock)=&get_blocks($setters,$activity,$udom,$uname);
           return ($startblock,$endblock);
       }
   
     my $startblock = 0;      my $startblock = 0;
     my $endblock = 0;      my $endblock = 0;
       my %live_courses = &findallcourses(undef,$uname,$udom);
   
       # If uname is for a user, and activity is course-specific, i.e.,
       # boards, chat or groups, check for blocking in current course only.
   
       if (($activity eq 'boards' || $activity eq 'chat' ||
            $activity eq 'groups') && ($env{'request.course.id'})) {
           foreach my $key (keys(%live_courses)) {
               if ($key ne $env{'request.course.id'}) {
                   delete($live_courses{$key});
               }
           }
       }
   
       my $otheruser = 0;
       my %own_courses;
       if ((($uname ne $env{'user.name'})) || ($udom ne $env{'user.domain'})) {
           # Resource belongs to user other than current user.
           $otheruser = 1;
           # Gather courses for current user
           %own_courses = 
               &findallcourses(undef,$env{'user.name'},$env{'user.domain'});
       }
   
       # Gather active course roles - course coordinator, instructor, 
       # exam proctor, ta, student, or custom role.
   
     foreach my $course (keys(%live_courses)) {      foreach my $course (keys(%live_courses)) {
         my $cdom = $env{'course.'.$course.'.domain'};          my ($cdom,$cnum);
         my $cnum = $env{'course.'.$course.'.num'};          if ((defined($env{'course.'.$course.'.domain'})) && (defined($env{'course.'.$course.'.num'}))) {
         my $noblock = 0;              $cdom = $env{'course.'.$course.'.domain'};
               $cnum = $env{'course.'.$course.'.num'};
           } else {
               ($cdom,$cnum) = split(/_/,$course); 
           }
           my $no_ownblock = 0;
           my $no_userblock = 0;
           if ($otheruser && $activity ne 'com') {
               # Check if current user has 'evb' priv for this
               if (defined($own_courses{$course})) {
                   foreach my $sec (keys(%{$own_courses{$course}})) {
                       my $checkrole = 'cm./'.$cdom.'/'.$cnum;
                       if ($sec ne 'none') {
                           $checkrole .= '/'.$sec;
                       }
                       if (&Apache::lonnet::allowed('evb',undef,undef,$checkrole)) {
                           $no_ownblock = 1;
                           last;
                       }
                   }
               }
               # if they have 'evb' priv and are currently not playing student
               next if (($no_ownblock) &&
                    ($env{'request.role'} !~ m{^st\./$cdom/$cnum}));
           }
         foreach my $sec (keys(%{$live_courses{$course}})) {          foreach my $sec (keys(%{$live_courses{$course}})) {
             my $role = 'cm./'.$cdom.'/'.$cnum;              my $checkrole = 'cm./'.$cdom.'/'.$cnum;
             if ($sec ne 'none') {              if ($sec ne 'none') {
                 $role .= '/'.$sec;                  $checkrole .= '/'.$sec;
             }              }
             if (&Apache::lonnet::allowed('evb',undef,undef,$role)) {              if ($otheruser) {
                 $noblock = 1;                  # Resource belongs to user other than current user.
                 last;                  # Assemble privs for that user, and check for 'evb' priv.
                   my ($trole,$tdom,$tnum,$tsec);
                   my $entry = $live_courses{$course}{$sec};
                   if ($entry =~ /^cr/) {
                       ($trole,$tdom,$tnum,$tsec) = 
                         ($entry =~ m|^(cr/$match_domain/$match_username/\w+)\./($match_domain)/($match_username)/?(\w*)$|);
                   } else {
                       ($trole,$tdom,$tnum,$tsec) = split(/\//,$entry);
                   }
                   my ($spec,$area,$trest,%allroles,%userroles);
                   $area = '/'.$tdom.'/'.$tnum;
                   $trest = $tnum;
                   if ($tsec ne '') {
                       $area .= '/'.$tsec;
                       $trest .= '/'.$tsec;
                   }
                   $spec = $trole.'.'.$area;
                   if ($trole =~ /^cr/) {
                       &Apache::lonnet::custom_roleprivs(\%allroles,$trole,
                                                         $tdom,$spec,$trest,$area);
                   } else {
                       &Apache::lonnet::standard_roleprivs(\%allroles,$trole,
                                                          $tdom,$spec,$trest,$area);
                   }
                   my ($author,$adv) = &Apache::lonnet::set_userprivs(\%userroles,\%allroles);
                   if ($userroles{'user.priv.'.$checkrole} =~ /evb\&([^\:]*)/) {
                       if ($1) {
                           $no_userblock = 1;
                           last;
                       }
                   }
               } else {
                   # Resource belongs to current user
                   # Check for 'evb' priv via lonnet::allowed().
                   if (&Apache::lonnet::allowed('evb',undef,undef,$checkrole)) {
                       $no_ownblock = 1;
                       last;
                   }
             }              }
         }          }
         # if they have the evb priv and are currently not playing student          # if they have the evb priv and are currently not playing student
         next if (($noblock) &&          next if (($no_ownblock) &&
                  ($env{'request.role'} !~ m{^st\./$cdom/$cnum}));                   ($env{'request.role'} !~ m{^st\./\Q$cdom\E/\Q$cnum\E}));
           next if ($no_userblock);
   
           # Retrieve blocking times and identity of blocker for course
           # of specified user, unless user has 'evb' privilege.
           
           my ($start,$end)=&get_blocks($setters,$activity,$cdom,$cnum);
           if (($start != 0) && 
               (($startblock == 0) || ($startblock > $start))) {
               $startblock = $start;
           }
           if (($end != 0)  &&
               (($endblock == 0) || ($endblock < $end))) {
               $endblock = $end;
           }
       }
       return ($startblock,$endblock);
   }
   
         $setters->{$course} = {};  sub get_blocks {
         $setters->{$course}{'staff'} = [];      my ($setters,$activity,$cdom,$cnum) = @_;
         $setters->{$course}{'times'} = [];      my $startblock = 0;
         my %records = &Apache::lonnet::dump('comm_block',$cdom,$cnum);      my $endblock = 0;
         foreach my $record (keys(%records)) {      my $course = $cdom.'_'.$cnum;
             my ($start,$end) = ($record =~ m/^(\d+)____(\d+)$/);      $setters->{$course} = {};
             if ($start <= time && $end >= time) {      $setters->{$course}{'staff'} = [];
                 my ($staff_name,$staff_dom,$title,$blocks) =      $setters->{$course}{'times'} = [];
                     &parse_block_record($records{$record});      my %records = &Apache::lonnet::dump('comm_block',$cdom,$cnum);
                 if ($blocks->{$activity} eq 'on') {      foreach my $record (keys(%records)) {
                     push(@{$$setters{$course}{'staff'}}, [$staff_name,$staff_dom]);                    push(@{$$setters{$course}{'times'}}, [$start,$end]);          my ($start,$end) = ($record =~ m/^(\d+)____(\d+)$/);
                     if ( ($startblock == 0) || ($startblock > $1) ) {          if ($start <= time && $end >= time) {
                         $startblock = $1;              my ($staff_name,$staff_dom,$title,$blocks) =
                     }                  &parse_block_record($records{$record});
                     if ( ($endblock == 0) || ($endblock < $2) ) {              if ($blocks->{$activity} eq 'on') {
                         $endblock = $2;                  push(@{$$setters{$course}{'staff'}},[$staff_name,$staff_dom]);
                     }                  push(@{$$setters{$course}{'times'}}, [$start,$end]);
                   if ( ($startblock == 0) || ($startblock > $start) ) {
                       $startblock = $start;
                   }
                   if ( ($endblock == 0) || ($endblock < $end) ) {
                       $endblock = $end;
                 }                  }
             }              }
         }          }
Line 2931  sub build_block_table { Line 3074  sub build_block_table {
         my %courseinfo=&Apache::lonnet::coursedescription($course);          my %courseinfo=&Apache::lonnet::coursedescription($course);
         for (my $i=0; $i<@{$$setters{$course}{staff}}; $i++) {          for (my $i=0; $i<@{$$setters{$course}{staff}}; $i++) {
             my ($uname,$udom) = @{$$setters{$course}{staff}[$i]};              my ($uname,$udom) = @{$$setters{$course}{staff}[$i]};
             my $fullname = &aboutmewrapper(&plainname($uname,$udom),$uname,$udom);              my $fullname = &plainname($uname,$udom);
               if (defined($env{'user.name'}) && defined($env{'user.domain'})
                   && $env{'user.name'} ne 'public' 
                   && $env{'user.domain'} ne 'public') {
                   $fullname = &aboutmewrapper($fullname,$uname,$udom);
               }
             my ($openblock,$closeblock) = @{$$setters{$course}{times}[$i]};              my ($openblock,$closeblock) = @{$$setters{$course}{times}[$i]};
             $openblock = &Apache::lonlocal::locallocaltime($openblock);              $openblock = &Apache::lonlocal::locallocaltime($openblock);
             $closeblock= &Apache::lonlocal::locallocaltime($closeblock);              $closeblock= &Apache::lonlocal::locallocaltime($closeblock);
             $output .= &Apache::loncommon::start_data_table_row().              $output .= &Apache::loncommon::start_data_table_row().
                        '<td>'.$courseinfo{'description'}.'</td>'.                         '<td>'.$courseinfo{'description'}.'</td>'.
                        '<td>'.$openblock.' to '.$closeblock.'</td>'.                         '<td>'.$openblock.' to '.$closeblock.'</td>'.
                        '<td>'.$fullname.'.</td>'.                         '<td>'.$fullname.'</td>'.
                         &Apache::loncommon::end_data_table_row();                          &Apache::loncommon::end_data_table_row();
         }          }
     }      }
     $output .= &end_data_table();      $output .= &end_data_table();
 }  }
   
   sub blocking_status {
       my ($activity,$uname,$udom) = @_;
       my %setters;
       my ($blocked,$output,$ownitem,$is_course);
       my ($startblock,$endblock)=&blockcheck(\%setters,$activity,$uname,$udom);
       if ($startblock && $endblock) {
           $blocked = 1;
           if (wantarray) {
               my $category;
               if ($activity eq 'boards') {
                   $category = 'Discussion posts in this course';
               } elsif ($activity eq 'blogs') {
                   $category = 'Blogs';
               } elsif ($activity eq 'port') {
                   if (defined($uname) && defined($udom)) {
                       if ($uname eq $env{'user.name'} &&
                           $udom eq $env{'user.domain'}) {
                           $ownitem = 1;
                       }
                   }
                   $is_course = &Apache::lonnet::is_course($udom,$uname);
                   if ($ownitem) { 
                       $category = 'Your portfolio files';  
                   } elsif ($is_course) {
                       my $coursedesc;
                       foreach my $course (keys(%setters)) {
                           my %courseinfo =
                                &Apache::lonnet::coursedescription($course);
                           $coursedesc = $courseinfo{'description'};
                       }
                       $category = "Group files in the course '$coursedesc'";
                   } else {
                       $category = 'Portfolio files belonging to ';
                       if ($env{'user.name'} eq 'public' && 
                           $env{'user.domain'} eq 'public') {
                           $category .= &plainname($uname,$udom);
                       } else {
                           $category .= &aboutmewrapper(&plainname($uname,$udom),$uname,$udom);  
                       }
                   }
               } elsif ($activity eq 'groups') {
                   $category = 'Groups in this course';
               }
               my $showstart = &Apache::lonlocal::locallocaltime($startblock);
               my $showend = &Apache::lonlocal::locallocaltime($endblock);
               $output = '<br />'.&mt('[_1] will be inaccessible between [_2] and [_3] because communication is being blocked.',$category,$showstart,$showend).'<br />';
               if (!($activity eq 'port' && !($ownitem) && !($is_course))) { 
                   $output .= &build_block_table($startblock,$endblock,\%setters);
               }
           }
       }
       if (wantarray) {
           return ($blocked,$output);
       } else {
           return $blocked;
       }
   }
   
 ###############################################  ###############################################
   
 =pod  =pod
Line 2964  Returns: Determines which domain should Line 3170  Returns: Determines which domain should
 ###############################################  ###############################################
 sub determinedomain {  sub determinedomain {
     my $domain=shift;      my $domain=shift;
    if (! $domain) {      if (! $domain) {
         # Determine domain if we have not been given one          # Determine domain if we have not been given one
         $domain = $Apache::lonnet::perlvar{'lonDefDomain'};          $domain = $Apache::lonnet::perlvar{'lonDefDomain'};
         if ($env{'user.domain'}) { $domain=$env{'user.domain'}; }          if ($env{'user.domain'}) { $domain=$env{'user.domain'}; }
Line 2975  sub determinedomain { Line 3181  sub determinedomain {
     return $domain;      return $domain;
 }  }
 ###############################################  ###############################################
   
   sub devalidate_domconfig_cache {
       my ($udom)=@_;
       &Apache::lonnet::devalidate_cache_new('domainconfig',$udom);
   }
   
   # ---------------------- Get domain configuration for a domain
   sub get_domainconf {
       my ($udom) = @_;
       my $cachetime=1800;
       my ($result,$cached)=&Apache::lonnet::is_cached_new('domainconfig',$udom);
       if (defined($cached)) { return %{$result}; }
   
       my %domconfig = &Apache::lonnet::get_dom('configuration',
        ['login','rolecolors'],$udom);
       my %designhash;
       if (keys(%domconfig) > 0) {
           if (ref($domconfig{'login'}) eq 'HASH') {
               foreach my $key (keys(%{$domconfig{'login'}})) {
                   $designhash{$udom.'.login.'.$key}=$domconfig{'login'}{$key};
               }
           }
           if (ref($domconfig{'rolecolors'}) eq 'HASH') {
               foreach my $role (keys(%{$domconfig{'rolecolors'}})) {
                   if (ref($domconfig{'rolecolors'}{$role}) eq 'HASH') {
                       foreach my $item (keys(%{$domconfig{'rolecolors'}{$role}})) {
                           $designhash{$udom.'.'.$role.'.'.$item}=$domconfig{'rolecolors'}{$role}{$item};
                       }
                   }
               }
           }
       } else {
           my $designdir=$Apache::lonnet::perlvar{'lonTabDir'}.'/lonDomColors';
           my $designfile =  $designdir.'/'.$udom.'.tab';
           if (-e $designfile) {
               if ( open (my $fh,"<$designfile") ) {
                   while (my $line = <$fh>) {
                       next if ($line =~ /^\#/);
                       chomp($line);
                       my ($key,$val)=(split(/\=/,$line));
                       if ($val) { $designhash{$udom.'.'.$key}=$val; }
                   }
                   close($fh);
               }
           }
           if (-e '/home/httpd/html/adm/lonDomLogos/'.$udom.'.gif') {
               $designhash{$udom.'.login.domlogo'} = "/adm/lonDomLogos/$udom.gif";
           }
       }
       &Apache::lonnet::do_cache_new('domainconfig',$udom,\%designhash,
     $cachetime);
       return %designhash;
   }
   
 =pod  =pod
   
 =item * &domainlogo()  =item * &domainlogo()
Line 2988  If the domain logo does not exist, a des Line 3248  If the domain logo does not exist, a des
   
 ###############################################  ###############################################
 sub domainlogo {  sub domainlogo {
     my $domain = &determinedomain(shift);          my $domain = &determinedomain(shift);
      # See if there is a logo      my %designhash = &get_domainconf($domain);    
     if (-e '/home/httpd/html/adm/lonDomLogos/'.$domain.'.gif') {      # See if there is a logo
  my $logo=&lonhttpdurl("/adm/lonDomLogos/$domain.gif");      if ($designhash{$domain.'.login.domlogo'} ne '') {
         return '<img src="'.$logo.'" alt="'.$domain.'" />';          my $imgsrc = $designhash{$domain.'.login.domlogo'};
     } elsif(exists($Apache::lonnet::domaindescription{$domain})) {          if ($imgsrc =~ m{^/(adm|res)/}) {
         return $Apache::lonnet::domaindescription{$domain};      if ($imgsrc =~ m{^/res/}) {
    my $local_name = &Apache::lonnet::filelocation('',$imgsrc);
    &Apache::lonnet::repcopy($local_name);
       }
      $imgsrc = &lonhttpdurl($imgsrc);
           } 
           return '<img src="'.$imgsrc.'" alt="'.$domain.'" />';
       } elsif (defined(&Apache::lonnet::domain($domain,'description'))) {
           return &Apache::lonnet::domain($domain,'description');
     } else {      } else {
         return '';          return '';
     }      }
Line 3030  sub designparm { Line 3298  sub designparm {
  return $env{'environment.color.'.$which};   return $env{'environment.color.'.$which};
     }      }
     $domain=&determinedomain($domain);      $domain=&determinedomain($domain);
     if (exists($designhash{$domain.'.'.$which})) {      my %domdesign = &get_domainconf($domain);
  return $designhash{$domain.'.'.$which};      my $output;
       if ($domdesign{$domain.'.'.$which} ne '') {
    $output = $domdesign{$domain.'.'.$which};
     } else {      } else {
         return $designhash{'default.'.$which};          $output = $defaultdesign{$which};
       }
       if (($which =~ /^(student|coordinator|author|admin)\.img$/) ||
           ($which =~ /login\.(img|logo|domlogo)/)) {
           if ($output =~ m{^/(adm|res)/}) {
       if ($output =~ m{^/res/}) {
    my $local_name = &Apache::lonnet::filelocation('',$output);
    &Apache::lonnet::repcopy($local_name);
       }
               $output = &lonhttpdurl($output);
           }
     }      }
       return $output;
 }  }
   
 ###############################################  ###############################################
Line 3117  sub bodytag { Line 3398  sub bodytag {
  # role and realm   # role and realm
     my ($role,$realm) = split(/\./,$env{'request.role'},2);      my ($role,$realm) = split(/\./,$env{'request.role'},2);
     if ($role  eq 'ca') {      if ($role  eq 'ca') {
         my ($rdom,$rname) = ($realm =~ m-^/(\w+)/(\w+)$-);          my ($rdom,$rname) = ($realm =~ m{^/($match_domain)/($match_username)$});
         $realm = &plainname($rname,$rdom).':'.$rdom;          $realm = &plainname($rname,$rdom);
     }       } 
 # realm  # realm
     if ($env{'request.course.id'}) {      if ($env{'request.course.id'}) {
Line 3143  sub bodytag { Line 3424  sub bodytag {
     my $bodytag = "<body $extra_body_attr>".      my $bodytag = "<body $extra_body_attr>".
  &Apache::lontexconvert::init_math_support();   &Apache::lontexconvert::init_math_support();
   
     if ($bodyonly       if ($bodyonly) {
  || ($env{'request.state'} eq 'construct'   
     && $env{'environment.remote'} ne 'off' )) {  
         return $bodytag;          return $bodytag;
     } elsif ($env{'browser.interface'} eq 'textual') {      } elsif ($env{'browser.interface'} eq 'textual') {
 # Accessibility  # Accessibility
Line 3253  ENDROLE Line 3532  ENDROLE
 # Top frame rendering, Remote is up  # Top frame rendering, Remote is up
 #  #
   
     my $upperleft='<img src="http://'.$ENV{'HTTP_HOST'}.':'.      my $imgsrc = $img;
         $lonhttpdPort.$img.'" alt="'.$function.'" />';      if ($img =~ /^\/adm/) {
           $imgsrc = 'http://'.$ENV{'HTTP_HOST'}.':'.$lonhttpdPort.$img;
       }
       my $upperleft='<img src="'.$imgsrc.'" alt="'.$function.'" />';
   
     # Explicit link to get inline menu      # Explicit link to get inline menu
     my $menu= ($no_inline_link?''      my $menu= ($no_inline_link?''
Line 3414  sub standard_css { Line 3696  sub standard_css {
     my $mail_other           = '#99BBBB';      my $mail_other           = '#99BBBB';
     my $mail_other_hover     = '#669999';      my $mail_other_hover     = '#669999';
     my $table_header         = '#DDDDDD';      my $table_header         = '#DDDDDD';
       my $feedback_link_bg     = '#BBBBBB';
   
     my $border = ($env{'browser.type'} eq 'explorer') ? '0px 2px 0px 2px'      my $border = ($env{'browser.type'} eq 'explorer') ? '0px 2px 0px 2px'
                                               : '0px 3px 0px 4px';                                                : '0px 3px 0px 4px';
   
   
     return <<END;      return <<END;
 h1, h2, h3, th { font-family: $sans }  h1, h2, h3, th { font-family: $sans }
 a:focus { color: red; background: yellow }   a:focus { color: red; background: yellow } 
 table.thinborder { border-collapse: collapse; }  table.thinborder,
 table.thinborder tr th {  border-style: solid; border-width: 1px; background: $tabbg;}  
 table.thinborder tr td { border-style: solid; border-width: 1px}  table.thinborder tr th {
     border-style: solid;
     border-width: 1px;
     background: $tabbg;
   }
   table.thinborder tr td {
     border-style: solid;
     border-width: 1px
   }
   
 form, .inline { display: inline; }  form, .inline { display: inline; }
 .center { text-align: center; }  .center { text-align: center; }
Line 3436  form, .inline { display: inline; } Line 3728  form, .inline { display: inline; }
 .LC_diff_removed {  .LC_diff_removed {
   color: red;    color: red;
 }  }
   
   .LC_info,
 .LC_success,  .LC_success,
 .LC_diff_added {  .LC_diff_added {
   color: green;    color: green;
Line 3443  form, .inline { display: inline; } Line 3737  form, .inline { display: inline; }
 .LC_icon {  .LC_icon {
   border: 0px;    border: 0px;
 }  }
   .LC_indexer_icon {
     border: 0px;
     height: 22px;
   }
   
   .LC_internal_info {
     color: #999;
   }
   
 table.LC_pastsubmission {  table.LC_pastsubmission {
   border: 1px solid black;    border: 1px solid black;
Line 3505  table#LC_title_bar td.LC_title_bar_role_ Line 3807  table#LC_title_bar td.LC_title_bar_role_
 }  }
   
 table#LC_menubuttons_mainmenu {  table#LC_menubuttons_mainmenu {
   background: $pgbg;    width: 100%;
   border: 0px;    border: 0px;
   border-spacing: 1px;    border-spacing: 1px;
   padding: 0px 1px;    padding: 0px 1px;
Line 3560  td.LC_table_cell_checkbox { Line 3862  td.LC_table_cell_checkbox {
   text-align: center;    text-align: center;
 }  }
   
   table#LC_mainmenu td.LC_mainmenu_column {
       vertical-align: top;
   }
   
 .LC_menubuttons_inline_text {  .LC_menubuttons_inline_text {
   color: $font;    color: $font;
   font-family: $sans;    font-family: $sans;
   font-size: smaller;    font-size: smaller;
 }  }
   
   .LC_menubuttons_link {
     text-decoration: none;
   }
   
   .LC_menubuttons_category {
     color: $font;
     background: $pgbg;
     font-family: $sans;
     font-size: larger;
     font-weight: bold;
   }
   
 td.LC_menubuttons_text {  td.LC_menubuttons_text {
     width: 90%;
   color: $font;    color: $font;
   font-family: $sans;    font-family: $sans;
 }  }
   
 td.LC_menubuttons_img {  td.LC_menubuttons_img {
   background: $tabbg;  
 }  }
   
 .LC_current_location {  .LC_current_location {
   font-family: $sans;    font-family: $sans;
   background: $tabbg;    background: $tabbg;
Line 3582  td.LC_menubuttons_img { Line 3902  td.LC_menubuttons_img {
   font-weight: bold;    font-weight: bold;
 }  }
   
   .LC_rolesmenu_is {
     font-family: $sans;
   }
   
   .LC_rolesmenu_selected {
     font-family: $sans;
   }
   
   .LC_rolesmenu_future {
     font-family: $sans;
   }
   
   
   .LC_rolesmenu_will {
     font-family: $sans;
   }
   
   .LC_rolesmenu_will_not {
     font-family: $sans;
   }
   
   .LC_rolesmenu_expired {
     font-family: $sans;
   }
   
   .LC_rolesinfo {
     font-family: $sans;
   }
   
   .LC_dropadd_labeltext {
     font-family: $sans;
     text-align: right;
   }
   
   .LC_preferences_labeltext {
     font-family: $sans;
     text-align: right;
   }
   
 table.LC_aboutme_port {  table.LC_aboutme_port {
   border: 0px;    border: 0px;
   border-collapse: collapse;    border-collapse: collapse;
Line 3595  table.LC_data_table, table.LC_mail_list Line 3954  table.LC_data_table, table.LC_mail_list
 .LC_data_table_dense {  .LC_data_table_dense {
   font-size: small;    font-size: small;
 }  }
 table.LC_data_table tr th, table.LC_calendar tr th, table.LC_mail_list tr th {  table.LC_nested_outer {
     border: 1px solid #000000;
     border-collapse: separate;
     border-spacing: 0px;
     width: 100%;
   }
   table.LC_nested {
     border: 0px;
     border-collapse: separate;
     border-spacing: 0px;
     width: 100%;
   }
   table.LC_data_table tr th, table.LC_calendar tr th, table.LC_mail_list tr th,
   table.LC_prior_tries tr th {
   font-weight: bold;    font-weight: bold;
   background-color: $data_table_head;    background-color: $data_table_head;
   font-size: smaller;    font-size: smaller;
Line 3613  table.LC_data_table tr.LC_data_table_hig Line 3985  table.LC_data_table tr.LC_data_table_hig
   background-color: $data_table_darker;    background-color: $data_table_darker;
 }  }
 table.LC_data_table tr.LC_empty_row td,  table.LC_data_table tr.LC_empty_row td,
 table.LC_whatsnew tr.LC_empty_row td {  table.LC_nested tr.LC_empty_row td {
   background-color: #FFFFFF;    background-color: #FFFFFF;
   font-weight: bold;    font-weight: bold;
   font-style: italic;    font-style: italic;
   text-align: center;    text-align: center;
   padding: 8px;    padding: 8px;
 }  }
 table.LC_whatsnew tr.LC_empty_row td {  table.LC_nested tr.LC_empty_row td {
   padding: 4ex    padding: 4ex
 }  }
   table.LC_nested_outer tr th {
     font-weight: bold;
 table.LC_whatsnew {    background-color: $data_table_head;
     font-size: smaller;
     border-bottom: 1px solid #000000;
 }  }
   table.LC_nested_outer tr td.LC_subheader {
 table.LC_whatsnew tr th,    background-color: $data_table_head;
 table.LC_whatsnew tr.LC_info_row td {  
   background-color: #CCC;  
   font-weight: bold;    font-weight: bold;
   font-size: small;    font-size: small;
     border-bottom: 1px solid #000000;
   text-align: right;    text-align: right;
 }  }
 table.LC_whatsnew tr td {  table.LC_nested tr.LC_info_row td {
   background-color: #FFF;    background-color: #CCC;
     font-weight: bold;
   font-size: small;    font-size: small;
   text-align: right;    text-align: center;
 }  }
 table.LC_whatsnew tr td.LC_first_item {  table.LC_nested tr.LC_info_row td.LC_left_item {
   text-align: left;    text-align: left;
 }  }
   table.LC_nested td {
     background-color: #FFF;
     font-size: small;
   }
   table.LC_nested_outer tr th.LC_right_item,
   table.LC_nested tr.LC_info_row td.LC_right_item,
   table.LC_nested tr.LC_odd_row td.LC_right_item,
   table.LC_nested tr td.LC_right_item {
     text-align: right;
   }
   
 table.LC_whatsnew tr.LC_odd_row td {  table.LC_nested tr.LC_odd_row td {
   background-color: #EEE;    background-color: #EEE;
 }  }
   
Line 3703  table.LC_mail_list tr.LC_mail_other { Line 4087  table.LC_mail_list tr.LC_mail_other {
 table.LC_mail_list tr.LC_mail_other:hover {  table.LC_mail_list tr.LC_mail_other:hover {
   background-color: $mail_other_hover;    background-color: $mail_other_hover;
 }  }
   table.LC_mail_list tr.LC_mail_even {
   }
   table.LC_mail_list tr.LC_mail_odd {
   }
   
   
 table#LC_portfolio_actions {  table#LC_portfolio_actions {
   width: auto;    width: auto;
Line 3947  table.LC_descriptive_input td.LC_descrip Line 4336  table.LC_descriptive_input td.LC_descrip
   text-align: right;    text-align: right;
   font-weight: bold;    font-weight: bold;
 }  }
   table.LC_feedback_link {
       background: $feedback_link_bg;
   }
   span.LC_feedback_link {
       background: $feedback_link_bg;
       font-size: larger;
   }
   
   table.LC_prior_tries {
     border: 1px solid #000000;
     border-collapse: separate;
     border-spacing: 1px;
   }
   
   table.LC_prior_tries td {
     padding: 2px;
   }
   
   .LC_answer_correct {
     background: #AAFFAA;
     color: black;
   }
   .LC_answer_charged_try {
     background: #FFAAAA ! important;
     color: black;
   }
   .LC_answer_not_charged_try, 
   .LC_answer_no_grade,
   .LC_answer_late {
     background: #FFFFAA;
     color: black;
   }
   .LC_answer_previous {
     background: #AAAAFF;
     color: black;
   }
   .LC_answer_no_message {
     background: #FFFFFF;
     color: black;
   }
   .LC_answer_unknown {
     background: orange;
     color: black;
   }
   
   
   span.LC_prior_numerical,
   span.LC_prior_string,
   span.LC_prior_custom,
   span.LC_prior_reaction,
   span.LC_prior_math {
     font-family: monospace;
     white-space: pre;
   }
   
   span.LC_prior_string {
     font-family: monospace;
     white-space: pre;
   }
   
   table.LC_prior_option {
     width: 100%;
     border-collapse: collapse;
   }
   table.LC_prior_rank, table.LC_prior_match {
     border-collapse: collapse;
   }
   table.LC_prior_option tr td,
   table.LC_prior_rank tr td,
   table.LC_prior_match tr td {
     border: 1px solid #000000;
   }
   
   span.LC_nobreak {
       white-space: nowrap;
   }
   
 END  END
 }  }
Line 4239  Inputs:         $args - additional optio Line 4704  Inputs:         $args - additional optio
                                  a html attribute                                   a html attribute
                  frameset     -> if true will start with a <frameset>                   frameset     -> if true will start with a <frameset>
                                  rather than <body>                                   rather than <body>
                    dicsussion   -> if true will get discussion from
                                     lonxml::xmlend
                                    (you can pass the target and parser arguments
                                     through optional 'target' and 'parser' args
                                     to this routine)
   
 =cut  =cut
   
Line 4697  sub get_course_users { Line 5167  sub get_course_users {
                     $usec = 'none';                      $usec = 'none';
                 }                  }
                 if ($uname ne '' && $udom ne '') {                  if ($uname ne '' && $udom ne '') {
                     if ($end < $now) {                      if ($end > 0 && $end < $now) {
                         $status = 'previous';                          $status = 'previous';
                     } elsif ($start > $now) {                      } elsif ($start > $now) {
                         $status = 'future';                          $status = 'future';
Line 4772  Incoming parameters: Line 5242  Incoming parameters:
 2. user's domain  2. user's domain
   
 Returns:  Returns:
 1. Disk quota (in Mb) assigned to student.   1. Disk quota (in Mb) assigned to student.
   2. (Optional) Type of setting: custom or default
      (individually assigned or default for user's 
      institutional status).
   3. (Optional) - User's institutional status (e.g., faculty, staff
      or student - types as defined in localenroll::inst_usertypes 
      for user's domain, which determines default quota for user.
   4. (Optional) - Default quota which would apply to the user.
   
 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 default  it will return that, otherwise it returns the maximal default
 for users in the domain.  defined for the user's instituional status(es) in the domain.
   
 =cut  =cut
   
Line 4785  for users in the domain. Line 5262  for users in the domain.
   
 sub get_user_quota {  sub get_user_quota {
     my ($uname,$udom) = @_;      my ($uname,$udom) = @_;
     my $quota;      my ($quota,$quotatype,$settingstatus,$defquota);
     if (!defined($udom)) {      if (!defined($udom)) {
         $udom = $env{'user.domain'};          $udom = $env{'user.domain'};
     }      }
Line 4795  sub get_user_quota { Line 5272  sub get_user_quota {
     if (($udom eq '' || $uname eq '') ||      if (($udom eq '' || $uname eq '') ||
         ($udom eq 'public') && ($uname eq 'public')) {          ($udom eq 'public') && ($uname eq 'public')) {
         $quota = 0;          $quota = 0;
           $quotatype = 'default';
           $defquota = 0; 
     } else {      } else {
           my $inststatus;
         if ($udom eq $env{'user.domain'} && $uname eq $env{'user.name'}) {          if ($udom eq $env{'user.domain'} && $uname eq $env{'user.name'}) {
             $quota = $env{'environment.portfolioquota'};              $quota = $env{'environment.portfolioquota'};
               $inststatus = $env{'environment.inststatus'};
         } else {          } else {
             my %userenv = &Apache::lonnet::dump('environment',$udom,$uname);              my %userenv = 
                   &Apache::lonnet::get('environment',['portfolioquota',
                                        'inststatus'],$udom,$uname);
             my ($tmp) = keys(%userenv);              my ($tmp) = keys(%userenv);
             if ($tmp !~ /^(con_lost|error|no_such_host)/i) {              if ($tmp !~ /^(con_lost|error|no_such_host)/i) {
                 $quota = $userenv{'portfolioquota'};                  $quota = $userenv{'portfolioquota'};
                   $inststatus = $userenv{'inststatus'};
             } else {              } else {
                 undef(%userenv);                  undef(%userenv);
             }              }
         }          }
           ($defquota,$settingstatus) = &default_quota($udom,$inststatus);
         if ($quota eq '') {          if ($quota eq '') {
             $quota = &default_quota($udom);              $quota = $defquota;
               $quotatype = 'default';
           } else {
               $quotatype = 'custom';
         }          }
     }      }
     return $quota;      if (wantarray) {
           return ($quota,$quotatype,$settingstatus,$defquota);
       } else {
           return $quota;
       }
 }  }
   
 ###############################################  ###############################################
Line 4820  sub get_user_quota { Line 5312  sub get_user_quota {
   
 =item * &default_quota()  =item * &default_quota()
   
 Retrieves default quota assigned for storage of user portfolio files  Retrieves default quota assigned for storage of user portfolio files,
   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 
      status types (e.g., faculty, staff, student etc.)
      which apply to the user for whom the default is being retrieved.
      If the institutional status string in undefined, the domain
      default quota will be returned. 
   
 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
      default quota.
   
 If a value has been stored in the domain's configuration db,  If a value has been stored in the domain's configuration db,
 it will return that, otherwise it returns 20 (for backwards   it will return that, otherwise it returns 20 (for backwards 
 compatibility with domains which have not set up a configuration  compatibility with domains which have not set up a configuration
 db file; the original statically defined portfolio quota was 20 Mb).   db file; the original statically defined portfolio quota was 20 Mb). 
   
   If the user's status includes multiple types (e.g., staff and student),
   the largest default quota which applies to the user determines the
   default quota returned.
   
 =cut  =cut
   
 ###############################################  ###############################################
   
   
 sub default_quota {  sub default_quota {
     my ($udom) = @_;      my ($udom,$inststatus) = @_;
     my %defaults = &Apache::lonnet::get_dom('configuration',      my ($defquota,$settingstatus);
                                             ['portfolioquota'],$udom);      my %quotahash = &Apache::lonnet::get_dom('configuration',
     if ($defaults{'portfolioquota'} ne '') {                                              ['quota'],$udom);
         return $defaults{'portfolioquota'};      if (ref($quotahash{'quota'}) eq 'HASH') {
           if ($inststatus ne '') {
               my @statuses = split(/:/,$inststatus);
               foreach my $item (@statuses) {
                   if ($quotahash{'quota'}{$item} ne '') {
                       if ($defquota eq '') {
                           $defquota = $quotahash{'quota'}{$item};
                           $settingstatus = $item;
                       } elsif ($quotahash{'quota'}{$item} > $defquota) {
                           $defquota = $quotahash{'quota'}{$item};
                           $settingstatus = $item;
                       }
                   }
               }
           }
           if ($defquota eq '') {
               $defquota = $quotahash{'quota'}{'default'};
               $settingstatus = 'default';
           }
       } else {
           $settingstatus = 'default';
           $defquota = 20;
       }
       if (wantarray) {
           return ($defquota,$settingstatus);
     } else {      } else {
         return '20';          return $defquota;
     }      }
 }  }
   
Line 5137  sub record_sep { Line 5665  sub record_sep {
             $i++;              $i++;
         }          }
     } else {      } else {
         my @allfields=split(/\,/,$record);          my @allfields;
           if ($env{'form.upfiletype'} eq 'semisv') {
               @allfields=split(/;/,$record,-1);
           } else {
               @allfields=split(/\,/,$record,-1);
           }
         my $i=0;          my $i=0;
         my $j;          my $j;
         for ($j=0;$j<=$#allfields;$j++) {          for ($j=0;$j<=$#allfields;$j++) {
Line 5175  the file type. Line 5708  the file type.
 sub upfile_select_html {  sub upfile_select_html {
     my %Types = (      my %Types = (
                  csv   => &mt('CSV (comma separated values, spreadsheet)'),                   csv   => &mt('CSV (comma separated values, spreadsheet)'),
                    semisv => &mt('Semicolon separated values'),
                  space => &mt('Space separated'),                   space => &mt('Space separated'),
                  tab   => &mt('Tabulator separated'),                   tab   => &mt('Tabulator separated'),
 #                 xml   => &mt('HTML/XML'),  #                 xml   => &mt('HTML/XML'),
Line 5829  Returns: both routines return nothing Line 6363  Returns: both routines return nothing
 #######################################################  #######################################################
 #######################################################  #######################################################
 sub store_course_settings {  sub store_course_settings {
       return &store_settings($env{'request.course.id'},@_);
   }
   
   sub store_settings {
     # save to the environment      # save to the environment
     # appenv the same items, just to be safe      # appenv the same items, just to be safe
     my $courseid = $env{'request.course.id'};  
     my $udom  = $env{'user.domain'};      my $udom  = $env{'user.domain'};
     my $uname = $env{'user.name'};      my $uname = $env{'user.name'};
     my ($prefix,$Settings) = @_;      my ($context,$prefix,$Settings) = @_;
     my %SaveHash;      my %SaveHash;
     my %AppHash;      my %AppHash;
     while (my ($setting,$type) = each(%$Settings)) {      while (my ($setting,$type) = each(%$Settings)) {
         my $basename = join('.','internal',$courseid,$prefix,$setting);          my $basename = join('.','internal',$context,$prefix,$setting);
         my $envname = 'environment.'.$basename;          my $envname = 'environment.'.$basename;
         if (exists($env{'form.'.$setting})) {          if (exists($env{'form.'.$setting})) {
             # Save this value away              # Save this value away
Line 5878  sub store_course_settings { Line 6415  sub store_course_settings {
 }  }
   
 sub restore_course_settings {  sub restore_course_settings {
     my $courseid = $env{'request.course.id'};      return &restore_settings($env{'request.course.id'},@_);
     my ($prefix,$Settings) = @_;  }
   
   sub restore_settings {
       my ($context,$prefix,$Settings) = @_;
     while (my ($setting,$type) = each(%$Settings)) {      while (my ($setting,$type) = each(%$Settings)) {
         next if (exists($env{'form.'.$setting}));          next if (exists($env{'form.'.$setting}));
         my $envname = 'environment.internal.'.$courseid.'.'.$prefix.          my $envname = 'environment.internal.'.$context.'.'.$prefix.
             '.'.$setting;              '.'.$setting;
         if (exists($env{$envname})) {          if (exists($env{$envname})) {
             if ($type eq 'scalar') {              if ($type eq 'scalar') {
Line 6014  sub construct_course { Line 6554  sub construct_course {
 #  #
 # Check if created correctly  # Check if created correctly
 #  #
     ($$crsudom,$$crsunum)=($$courseid=~/^\/(\w+)\/(\w+)$/);      ($$crsudom,$$crsunum)= &LONCAPA::split_courseid($$courseid);
     my $crsuhome=&Apache::lonnet::homeserver($$crsunum,$$crsudom);      my $crsuhome=&Apache::lonnet::homeserver($$crsunum,$$crsudom);
     $outcome .= &mt('Created on').': '.$crsuhome.'<br>';      $outcome .= &mt('Created on').': '.$crsuhome.'<br>';
 #  #
Line 6023  sub construct_course { Line 6563  sub construct_course {
     my $cloneid='';      my $cloneid='';
     if (($args->{'clonecourse'}) && ($args->{'clonedomain'})) {      if (($args->{'clonecourse'}) && ($args->{'clonedomain'})) {
  $cloneid='/'.$args->{'clonedomain'}.'/'.$args->{'clonecourse'};   $cloneid='/'.$args->{'clonedomain'}.'/'.$args->{'clonecourse'};
         my ($clonecrsudom,$clonecrsunum)=($cloneid=~/^\/(\w+)\/(\w+)$/);          my ($clonecrsudom,$clonecrsunum)= &LONCAPA::split_courseid($cloneid);
  my $clonehome=&Apache::lonnet::homeserver($clonecrsunum,$clonecrsudom);   my $clonehome=&Apache::lonnet::homeserver($clonecrsunum,$clonecrsudom);
  if ($clonehome eq 'no_host') {   if ($clonehome eq 'no_host') {
     $outcome .=      $outcome .=
Line 6196  sub construct_course { Line 6736  sub construct_course {
 # if specified, key authority is not course, but user  # if specified, key authority is not course, but user
 # only active if keyaccess is yes  # only active if keyaccess is yes
     if ($args->{'keyauth'}) {      if ($args->{'keyauth'}) {
  $args->{'keyauth'}=~s/[^\w\@]//g;   my ($user,$domain) = split(':',$args->{'keyauth'});
  if ($args->{'keyauth'}) {   $user = &LONCAPA::clean_username($user);
     $cenv{'keyauth'}=$args->{'keyauth'};   $domain = &LONCAPA::clean_username($domain);
    if ($user ne '' && $domain ne '') {
       $cenv{'keyauth'}=$user.':'.$domain;
  }   }
     }      }
   
Line 6295  sub group_term { Line 6837  sub group_term {
   
 sub icon {  sub icon {
     my ($file)=@_;      my ($file)=@_;
     my $curfext = (split(/\./,$file))[-1];      my $curfext = lc((split(/\./,$file))[-1]);
     my $iconname=$Apache::lonnet::perlvar{'lonIconsURL'}.'/unknown.gif';      my $iconname=$Apache::lonnet::perlvar{'lonIconsURL'}.'/unknown.gif';
     my $embstyle = &Apache::loncommon::fileembstyle($curfext);      my $embstyle = &Apache::loncommon::fileembstyle($curfext);
     if (!(!defined($embstyle) || $embstyle eq 'unk' || $embstyle eq 'hdn')) {      if (!(!defined($embstyle) || $embstyle eq 'unk' || $embstyle eq 'hdn')) {

Removed from v.1.476  
changed lines
  Added in v.1.539


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