--- loncom/interface/loncommon.pm	2008/01/04 18:08:11	1.632
+++ loncom/interface/loncommon.pm	2008/03/20 19:46:44	1.647
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.632 2008/01/04 18:08:11 raeburn Exp $
+# $Id: loncommon.pm,v 1.647 2008/03/20 19:46:44 www Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -78,6 +78,58 @@ my $readit;
 ## Global Variables
 ##
 
+
+# ----------------------------------------------- SSI with retries:
+#
+
+=pod
+
+=head1 Server Side incliude with retries:
+
+=over 4
+
+=item * ssi_with_retries(resource, retries form)
+
+Performs an ssi with some number of retries.  Retries continue either
+until the result is ok or until the retry count supplied by the
+caller is exhausted.  
+
+Inputs:
+resource   - Identifies the resource to insert.
+retries    - Count of the number of retries allowed.
+form       - Hash that identifies the rendering options.
+
+Returns: 
+content    - The content of the response.  If retries were exhausted this is empty.
+response   - The response from the last attempt (which may or may not have been successful.
+
+=cut
+
+sub ssi_with_retries {
+    my ($resource, $retries, %form) = @_;
+
+
+    my $ok = 0;			# True if we got a good response.
+    my $content;
+    my $response;
+
+    # Try to get the ssi done. within the retries count:
+
+    do {
+	($content, $response) = &Apache::lonnet::ssi($resource, %form);
+	$ok      = $response->is_success;
+	$retries--;
+    } while (!$ok && ($retries > 0));
+
+    if (!$ok) {
+	$content = '';		# On error return an empty content.
+    }
+    return ($content, $response);
+
+}
+
+
+
 # ----------------------------------------------- Filetypes/Languages/Copyright
 my %language;
 my %supported_language;
@@ -319,7 +371,7 @@ sub storeresurl {
     unless ($resurl=~/^\/res/) { return 0; }
     $resurl=~s/\/$//;
     &Apache::lonnet::put('environment',{'lastresurl' => $resurl});
-    &Apache::lonnet::appenv('environment.lastresurl' => $resurl);
+    &Apache::lonnet::appenv({'environment.lastresurl' => $resurl});
     return 1;
 }
 
@@ -782,10 +834,10 @@ sub helpLatexCheatsheet {
     }
     return '<table><tr><td>'.
 	$addOther .
-	&Apache::loncommon::help_open_topic("Greek_Symbols",'Greek Symbols',
+	&Apache::loncommon::help_open_topic("Greek_Symbols",&mt('Greek Symbols'),
 					    undef,undef,600)
 	.'</td><td>'.
-	&Apache::loncommon::help_open_topic("Other_Symbols",'Other Symbols',
+	&Apache::loncommon::help_open_topic("Other_Symbols",&mt('Other Symbols'),
 					    undef,undef,600)
 	.'</td></tr></table>';
 }
@@ -2242,42 +2294,6 @@ sub get_assignable_auth {
 }
 
 ###############################################################
-##    Get Authentication Defaults for Domain                 ##
-###############################################################
-
-=pod
-
-=head1 Domains and Authentication
-
-Returns default authentication type and an associated argument as
-listed in file 'domain.tab'.
-
-=over 4
-
-=item * get_auth_defaults
-
-get_auth_defaults($target_domain) returns the default authentication
-type and an associated argument (initial password or a kerberos domain).
-These values are stored in lonTabs/domain.tab
-
-($def_auth, $def_arg) = &get_auth_defaults($target_domain);
-
-If target_domain is not found in domain.tab, returns nothing ('').
-
-=cut
-
-#-------------------------------------------
-sub get_auth_defaults {
-    my $domain=shift;
-    return (&Apache::lonnet::domain($domain,'auth_def'),
-	    &Apache::lonnet::domain($domain,'auth_arg_def'));
-	    
-}
-###############################################################
-##   End Get Authentication Defaults for Domain              ##
-###############################################################
-
-###############################################################
 ##    Get Kerberos Defaults for Domain                 ##
 ###############################################################
 ##
@@ -2292,8 +2308,8 @@ sub get_auth_defaults {
 =item * get_kerberos_defaults
 
 get_kerberos_defaults($target_domain) returns the default kerberos
-version and domain. If not found in domain.tabs, it defaults to
-version 4 and the domain of the server.
+version and domain. If not found, it defaults to version 4 and the 
+domain of the server.
 
 ($def_version, $def_krb_domain) = &get_kerberos_defaults($target_domain);
 
@@ -2302,9 +2318,12 @@ version 4 and the domain of the server.
 #-------------------------------------------
 sub get_kerberos_defaults {
     my $domain=shift;
-    my ($krbdef,$krbdefdom) =
-        &Apache::loncommon::get_auth_defaults($domain);
-    unless ($krbdef =~/^krb/ && $krbdefdom) {
+    my ($krbdef,$krbdefdom);
+    my %domdefaults = &Apache::lonnet::get_domain_defaults($domain);
+    if (($domdefaults{'auth_def'} =~/^krb(4|5)$/) && ($domdefaults{'auth_arg_def'} ne '')) {
+        $krbdef = $domdefaults{'auth_def'};
+        $krbdefdom = $domdefaults{'auth_arg_def'};
+    } else {
         $ENV{'SERVER_NAME'}=~/(\w+\.\w+)$/;
         my $krbdefdom=$1;
         $krbdefdom=~tr/a-z/A-Z/;
@@ -2883,21 +2902,15 @@ sub preferred_languages {
 	    map { (split(/\s*;\s*/,$_))[0] } (split(/\s*,\s*/,$browser));
 	push(@languages,@browser);
     }
-    if (&Apache::lonnet::domain($env{'user.domain'},'lang_def')) {
-	@languages=(@languages,
-		    &Apache::lonnet::domain($env{'user.domain'},
-					    'lang_def'));
-    }
-    if (&Apache::lonnet::domain($env{'request.role.domain'},'lang_def')) {
-	@languages=(@languages,
-		    &Apache::lonnet::domain($env{'request.role.domain'},
-					    'lang_def'));
-    }
-    if (&Apache::lonnet::domain($Apache::lonnet::perlvar{'lonDefDomain'},
-				'lang_def')) {
-	@languages=(@languages,
-		    &Apache::lonnet::domain($Apache::lonnet::perlvar{'lonDefDomain'},
-					    'lang_def'));
+
+    foreach my $domtype ($env{'user.domain'},$env{'request.role.domain'},
+                         $Apache::lonnet::perlvar{'lonDefDomain'}) {
+        if ($domtype ne '') {
+            my %domdefs = &Apache::lonnet::get_domain_defaults($domtype);
+            if ($domdefs{'lang_def'} ne '') {
+                push(@languages,$domdefs{'lang_def'});
+            }
+        }
     }
 # turn "en-ca" into "en-ca,en"
     my @genlanguages;
@@ -3791,10 +3804,10 @@ Returns: value of designparamter $which
 sub designparm {
     my ($which,$domain)=@_;
     if ($env{'browser.blackwhite'} eq 'on') {
-	if ($which=~/\.(font|alink|vlink|link)$/) {
+	if ($which=~/\.(font|alink|vlink|link|textcol)$/) {
 	    return '#000000';
 	}
-	if ($which=~/\.(pgbg|sidebg)$/) {
+	if ($which=~/\.(pgbg|sidebg|bgcol)$/) {
 	    return '#FFFFFF';
 	}
 	if ($which=~/\.tabbg$/) {
@@ -3813,7 +3826,7 @@ sub designparm {
         $output = $defaultdesign{$which};
     }
     if (($which =~ /^(student|coordinator|author|admin)\.img$/) ||
-        ($which =~ /login\.(img|logo|domlogo)/)) {
+        ($which =~ /login\.(img|logo|domlogo|login)/)) {
         if ($output =~ m{^/(adm|res)/}) {
 	    if ($output =~ m{^/res/}) {
 		my $local_name = &Apache::lonnet::filelocation('',$output);
@@ -3981,7 +3994,7 @@ ENDROLE
         $dc_info = '('.$dc_info.')';
     }
 
-    if ($env{'environment.remote'} eq 'off') {
+    if (($env{'environment.remote'} eq 'off') || ($args->{'suppress_header_logos'})) {
         # No Remote
 	if ($env{'request.state'} eq 'construct') {
 	    $forcereg=1;
@@ -4004,9 +4017,9 @@ ENDROLE
 		$lastitem = $thisdisfn;
 	    }
 	    $titleinfo = 
-		&Apache::loncommon::help_open_menu('','',3,'Authoring').
-		'<b>Construction Space</b>:&nbsp;'. 
-		'<form name="dirs" method="post" action="'.$formaction
+		&Apache::loncommon::help_open_menu('','',3,'Authoring')
+		.'<b>'.&mt('Construction Space').'</b>:&nbsp;'
+		.'<form name="dirs" method="post" action="'.$formaction
 		.'" target="_top"><tt><b>'
 		.&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,'_top','/priv','','+1',1)."<font size=\"+1\">$lastitem</font></b></tt><br />"
 		.&Apache::lonhtmlcommon::select_recent('construct','recent','this.form.action=this.form.recent.value;this.form.submit()')
@@ -4130,18 +4143,25 @@ sub make_attr_string {
 
 Returns a uniform footer for LON-CAPA web pages.
 
-Inputs: none
+Inputs: 1 - optional reference to an args hash
+If in the hash, key for noredirectlink has a value which evaluates to true,
+a 'Continue' link is not displayed if the page contains an
+internal redirect in the <head></head> section,
+i.e., $env{'internal.head.redirect'} exists   
 
 =cut
 
 sub endbodytag {
+    my ($args) = @_;
     my $endbodytag='</body>';
     $endbodytag=&Apache::lontexconvert::jsMath_process()."\n".$endbodytag;
     if ( exists( $env{'internal.head.redirect'} ) ) {
-	$endbodytag=
-	    "<br /><a href=\"$env{'internal.head.redirect'}\">".
-	    &mt('Continue').'</a>'.
-	    $endbodytag;
+        if (!(ref($args) eq 'HASH' && $args->{'noredirectlink'})) {
+	    $endbodytag=
+	        "<br /><a href=\"$env{'internal.head.redirect'}\">".
+	        &mt('Continue').'</a>'.
+	        $endbodytag;
+        }
     }
     return $endbodytag;
 }
@@ -4404,6 +4424,7 @@ td.LC_menubuttons_img {
 }
 .LC_new_mail {
   font-family: $sans;
+  background: $tabbg;
   font-weight: bold;
 }
 
@@ -4490,6 +4511,10 @@ table.LC_aboutme_port tr.LC_even_row td
 table.LC_data_table tr.LC_data_table_highlight td {
   background-color: $data_table_darker;
 }
+table.LC_data_table tr td.LC_leftcol_header {
+  background-color: $data_table_head;
+  font-weight: bold;
+}
 table.LC_data_table tr.LC_empty_row td,
 table.LC_nested tr.LC_empty_row td {
   background-color: #FFFFFF;
@@ -4765,6 +4790,14 @@ table.LC_pick_box td.LC_pick_box_title {
   width: 184px;
   padding: 8px;
 }
+table.LC_pick_box td.LC_selfenroll_pick_box_title {
+  background: $tabbg;
+  font-weight: bold;
+  text-align: right;
+  width: 350px;
+  padding: 8px;
+}
+
 table.LC_pick_box td.LC_pick_box_value {
   text-align: left;
   padding: 8px;
@@ -4979,6 +5012,11 @@ span.LC_cusr_emph {
   font-style: italic;
 }
 
+span.LC_cusr_subheading {
+  font-weight: normal;
+  font-size: 85%;
+}
+
 table.LC_docs_documents {
   background: #BBBBBB;
   border-width: 0px;
@@ -5304,10 +5342,7 @@ Inputs: none
 
 sub font_settings {
     my $headerstring='';
-    if (($env{'browser.os'} eq 'mac') && (!$env{'browser.mathml'})) { 
-	$headerstring.=
-	    '<meta Content-Type="text/html; charset=x-mac-roman" />';
-    } elsif (!$env{'browser.mathml'} && $env{'browser.unicode'}) {
+    if (!$env{'browser.mathml'} && $env{'browser.unicode'}) {
 	$headerstring.=
 	    '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
     }
@@ -5506,7 +5541,7 @@ sub end_page {
     if ($args->{'frameset'}) {
 	$result .= '</frameset>';
     } else {
-	$result .= &endbodytag();
+	$result .= &endbodytag($args);
     }
     $result .= "\n</html>";
 
@@ -6675,6 +6710,72 @@ sub personal_data_fieldtitles {
     return %fieldtitles;
 }
 
+sub sorted_inst_types {
+    my ($dom) = @_;
+    my ($usertypes,$order) = &Apache::lonnet::retrieve_inst_usertypes($dom);
+    my $othertitle = &mt('All users');
+    if ($env{'request.course.id'}) {
+        $othertitle  = 'any';
+    }
+    my @types;
+    if (ref($order) eq 'ARRAY') {
+        @types = @{$order};
+    }
+    if (@types == 0) {
+        if (ref($usertypes) eq 'HASH') {
+            @types = sort(keys(%{$usertypes}));
+        }
+    }
+    if (keys(%{$usertypes}) > 0) {
+        $othertitle = &mt('Other users');
+        if ($env{'request.course.id'}) {
+            $othertitle = 'other';
+        }
+    }
+    return ($othertitle,$usertypes,\@types);
+}
+
+sub get_institutional_codes {
+    my ($settings,$allcourses,$LC_code) = @_;
+# Get complete list of course sections to update
+    my @currsections = ();
+    my @currxlists = ();
+    my $coursecode = $$settings{'internal.coursecode'};
+
+    if ($$settings{'internal.sectionnums'} ne '') {
+        @currsections = split(/,/,$$settings{'internal.sectionnums'});
+    }
+
+    if ($$settings{'internal.crosslistings'} ne '') {
+        @currxlists = split(/,/,$$settings{'internal.crosslistings'});
+    }
+
+    if (@currxlists > 0) {
+        foreach (@currxlists) {
+            if (m/^([^:]+):(\w*)$/) {
+                unless (grep/^$1$/,@{$allcourses}) {
+                    push @{$allcourses},$1;
+                    $$LC_code{$1} = $2;
+                }
+            }
+        }
+    }
+ 
+    if (@currsections > 0) {
+        foreach (@currsections) {
+            if (m/^(\w+):(\w*)$/) {
+                my $sec = $coursecode.$1;
+                my $lc_sec = $2;
+                unless (grep/^$sec$/,@{$allcourses}) {
+                    push @{$allcourses},$sec;
+                    $$LC_code{$sec} = $lc_sec;
+                }
+            }
+        }
+    }
+    return;
+}
+
 =pod
 
 =back
@@ -7383,7 +7484,7 @@ sub DrawBarGraph {
         $ValuesHash{$id.'.'.$key} = $value;
     }
     #
-    &Apache::lonnet::appenv(%ValuesHash);
+    &Apache::lonnet::appenv(\%ValuesHash);
     return '<img src="/cgi-bin/graph.png?'.$identifier.'" border="1" />';
 }
 
@@ -7473,7 +7574,7 @@ sub DrawXYGraph {
         $ValuesHash{$id.'.'.$key} = $value;
     }
     #
-    &Apache::lonnet::appenv(%ValuesHash);
+    &Apache::lonnet::appenv(\%ValuesHash);
     return '<img src="/cgi-bin/graph.png?'.$identifier.'" border="1" />';
 }
 
@@ -7575,7 +7676,7 @@ sub DrawXYYGraph {
         $ValuesHash{$id.'.'.$key} = $value;
     }
     #
-    &Apache::lonnet::appenv(%ValuesHash);
+    &Apache::lonnet::appenv(\%ValuesHash);
     return '<img src="/cgi-bin/graph.png?'.$identifier.'" border="1" />';
 }
 
@@ -7707,7 +7808,7 @@ sub store_settings {
                                  'got error:'.$put_result);
     }
     # Make sure these settings stick around in this session, too
-    &Apache::lonnet::appenv(%AppHash);
+    &Apache::lonnet::appenv(\%AppHash);
     return;
 }
 
@@ -8070,19 +8171,26 @@ sub construct_course {
 	$outcome .= $clonemsg.$linefeed;
 	my %oldcenv=&Apache::lonnet::dump('environment',$$crsudom,$$crsunum);
 # Copy all files
-	&Apache::lonclonecourse::copycoursefiles($cloneid,$$courseid);
+	&Apache::lonclonecourse::copycoursefiles($cloneid,$$courseid,$args->{'datemode'},$args->{'dateshift'});
 # Restore URL
 	$cenv{'url'}=$oldcenv{'url'};
 # Restore title
 	$cenv{'description'}=$oldcenv{'description'};
-# restore grading mode
-	if (defined($oldcenv{'grading'})) {
-	    $cenv{'grading'}=$oldcenv{'grading'};
-	}
 # Mark as cloned
 	$cenv{'clonedfrom'}=$cloneid;
-	delete($cenv{'default_enrollment_start_date'});
-	delete($cenv{'default_enrollment_end_date'});
+# Need to clone grading mode
+        my %newenv=&Apache::lonnet::get('environment',['grading'],$$crsudom,$$crsunum);
+        $cenv{'grading'}=$newenv{'grading'};
+# Do not clone these environment entries
+        &Apache::lonnet::del('environment',
+                  ['default_enrollment_start_date',
+                   'default_enrollment_end_date',
+                   'question.email',
+                   'policy.email',
+                   'comment.email',
+                   'pch.users.denied',
+                   'plc.users.denied'],
+                   $$crsudom,$$crsunum);
     }
 
 #
@@ -8110,7 +8218,6 @@ sub construct_course {
     } else {
         $cenv{'internal.courseowner'} = $args->{'curruser'};
     }
-
     my @badclasses = (); # Used to accumulate sections/crosslistings that did not pass classlist access check for course owner.
     if ($args->{'crssections'}) {
         $cenv{'internal.sectionnums'} = '';