\n";
my $seconddefault = $hashref->{$firstdefault}->{'default'};
- foreach my $value (sort(keys(%select2))) {
+
+ my @secondorder = sort(keys(%select2));
+ if (ref($hashref->{$firstdefault}->{'order'}) eq 'ARRAY') {
+ @secondorder = @{$hashref->{$firstdefault}->{'order'}};
+ }
+ foreach my $value (@secondorder) {
$result.=" ".&mt($select2{$value})." \n";
@@ -618,7 +877,7 @@ END
=pod
-=item * help_open_topic($topic, $text, $stayOnPage, $width, $height)
+=item * &help_open_topic($topic,$text,$stayOnPage,$width,$height)
Returns a string corresponding to an HTML link to the given help
$topic, where $topic corresponds to the name of a .tex file in
@@ -644,8 +903,7 @@ sub help_open_topic {
my ($topic, $text, $stayOnPage, $width, $height) = @_;
$text = "" if (not defined $text);
$stayOnPage = 0 if (not defined $stayOnPage);
- if ($env{'browser.interface'} eq 'textual' ||
- $env{'environment.remote'} eq 'off' ) {
+ if ($env{'browser.interface'} eq 'textual') {
$stayOnPage=1;
}
$width = 350 if (not defined $width);
@@ -655,33 +913,33 @@ sub help_open_topic {
my $template = "";
my $link;
-
+
$topic=~s/\W/\_/g;
- if (!$stayOnPage)
- {
+ if (!$stayOnPage) {
$link = "javascript:void(open('/adm/help/${filename}.hlp', 'Help_for_$topic', 'menubar=0,toolbar=1,scrollbars=1,width=$width,height=$height,resizable=yes'))";
- }
- else
- {
+ } else {
$link = "/adm/help/${filename}.hlp";
}
# Add the text
- if ($text ne "")
- {
- $template .=
- "".
- "$text ";
+ if ($text ne "") {
+ $template.=''
+ .''
+ .$text.' ';
}
- # Add the graphic
+ # (Always) Add the graphic
my $title = &mt('Online Help');
- my $helpicon=&lonhttpdurl("/adm/help/gif/smallHelp.gif");
- $template .= <<"ENDTEMPLATE";
-
-ENDTEMPLATE
- if ($text ne '') { $template.='
' };
+ my $helpicon=&lonhttpdurl("/adm/help/help.png");
+ $template.=' '
+ .' ';
+ if ($text ne "") {
+ $template.='';
+ }
return $template;
}
@@ -689,21 +947,31 @@ ENDTEMPLATE
# This is a quicky function for Latex cheatsheet editing, since it
# appears in at least four places
sub helpLatexCheatsheet {
- my $other = shift;
+ my ($topic,$text,$not_author) = @_;
+ my $out;
my $addOther = '';
- if ($other) {
- $addOther = Apache::loncommon::help_open_topic($other, shift,
- undef, undef, 600) .
- '';
- }
- return ''.
- $addOther .
- &Apache::loncommon::help_open_topic("Greek_Symbols",'Greek Symbols',
- undef,undef,600)
- .' '.
- &Apache::loncommon::help_open_topic("Other_Symbols",'Other Symbols',
- undef,undef,600)
- .'
';
+ if ($topic) {
+ $addOther = ''.&Apache::loncommon::help_open_topic($topic,&mt($text),
+ undef, undef, 600).
+ ' ';
+ }
+ $out = '' # Start cheatsheet
+ .$addOther
+ .''
+ .&Apache::loncommon::help_open_topic('Greek_Symbols',&mt('Greek Symbols'),
+ undef,undef,600)
+ .' '
+ .&Apache::loncommon::help_open_topic('Other_Symbols',&mt('Other Symbols'),
+ undef,undef,600)
+ .' ';
+ unless ($not_author) {
+ $out .= ' '
+ .&Apache::loncommon::help_open_topic('Authoring_Output_Tags',&mt('Output Tags'),
+ undef,undef,600)
+ .' ';
+ }
+ $out .= ' '; # End cheatsheet
+ return $out;
}
sub general_help {
@@ -712,6 +980,8 @@ sub general_help {
$helptopic='Authoring_Intro';
} elsif ($env{'request.role'}=~/^cc/) {
$helptopic='Course_Coordination_Intro';
+ } elsif ($env{'request.role'}=~/^dc/) {
+ $helptopic='Domain_Coordination_Intro';
}
return $helptopic;
}
@@ -728,9 +998,7 @@ sub update_help_link {
my $banner_link = "/adm/helpmenu?page=banner&topic=$topic&component_help=$component_help&faq=$faq&bug=$bug&origurl=$origurl&stamp=$timestamp&stayonpage=$stayOnPage";
my $output .= <<"ENDOUTPUT";
ENDOUTPUT
return $output;
@@ -739,12 +1007,13 @@ ENDOUTPUT
# now just updates the help link and generates a blue icon
sub help_open_menu {
my ($topic,$component_help,$faq,$bug,$stayOnPage,$width,$height,$text)
- = @_;
-
+ = @_;
$stayOnPage = 0 if (not defined $stayOnPage);
+ # only use pop-up help (stayOnPage == 0)
+ # if environment.remote is on (using remote control UI)
if ($env{'browser.interface'} eq 'textual' ||
- $env{'environment.remote'} eq 'off' ) {
- $stayOnPage=1;
+ $env{'environment.remote'} eq 'off' ) {
+ $stayOnPage=1;
}
my $output;
if ($component_help) {
@@ -765,15 +1034,13 @@ sub help_open_menu {
sub top_nav_help {
my ($text) = @_;
-
$text = &mt($text);
-
- my $stayOnPage =
+ my $stay_on_page =
($env{'browser.interface'} eq 'textual' ||
$env{'environment.remote'} eq 'off' );
- my $link= ($stayOnPage) ? "javascript:helpMenu('display')"
+ my $link = ($stay_on_page) ? "javascript:helpMenu('display')"
: "javascript:helpMenu('open')";
- my $banner_link = &update_help_link(undef,undef,undef,undef,$stayOnPage);
+ my $banner_link = &update_help_link(undef,undef,undef,undef,$stay_on_page);
my $title = &mt('Get help');
@@ -801,7 +1068,7 @@ sub help_menu_js {
'js_ready' => 1,
'add_entries' => {
'border' => '0',
- 'rows' => "105,*",},});
+ 'rows' => "110,*",},});
my $end_page =
&Apache::loncommon::end_page({'frameset' => 1,
'js_ready' => 1,});
@@ -872,7 +1139,7 @@ sub help_open_bug {
{
$template .=
"".
- "$text ";
+ "$text ";
}
# Add the graphic
@@ -917,7 +1184,7 @@ sub help_open_faq {
{
$template .=
"".
- "$text ";
+ "$text ";
}
# Add the graphic
@@ -936,7 +1203,7 @@ ENDTEMPLATE
=pod
-=item * change_content_javascript():
+=item * &change_content_javascript():
This and the next function allow you to create small sections of an
otherwise static HTML page that you can update on the fly with
@@ -991,7 +1258,7 @@ DOMBASED
=pod
-=item * changable_area($name, $origContent):
+=item * &changable_area($name,$origContent):
This provides a "changable area" that can be modified on the fly via
the Javascript code provided in C. $name is
@@ -1015,8 +1282,139 @@ sub changable_area {
=pod
+=item * &viewport_geometry_js
+
+Provides javascript object (Geometry) which can provide information about the viewport geometry for the client browser.
+
+=cut
+
+
+sub viewport_geometry_js {
+ return <<"GEOMETRY";
+var Geometry = {};
+function init_geometry() {
+ if (Geometry.init) { return };
+ Geometry.init=1;
+ if (window.innerHeight) {
+ Geometry.getViewportHeight = function() { return window.innerHeight; };
+ Geometry.getViewportWidth = function() { return window.innerWidth; };
+ Geometry.getHorizontalScroll = function() { return window.pageXOffset; };
+ Geometry.getVerticalScroll = function() { return window.pageYOffset; };
+ }
+ else if (document.documentElement && document.documentElement.clientHeight) {
+ Geometry.getViewportHeight =
+ function() { return document.documentElement.clientHeight; };
+ Geometry.getViewportWidth =
+ function() { return document.documentElement.clientWidth; };
+
+ Geometry.getHorizontalScroll =
+ function() { return document.documentElement.scrollLeft; };
+ Geometry.getVerticalScroll =
+ function() { return document.documentElement.scrollTop; };
+ }
+ else if (document.body.clientHeight) {
+ Geometry.getViewportHeight =
+ function() { return document.body.clientHeight; };
+ Geometry.getViewportWidth =
+ function() { return document.body.clientWidth; };
+ Geometry.getHorizontalScroll =
+ function() { return document.body.scrollLeft; };
+ Geometry.getVerticalScroll =
+ function() { return document.body.scrollTop; };
+ }
+}
+
+GEOMETRY
+}
+
+=pod
+
+=item * &viewport_size_js()
+
+Provides a javascript function to set values of two form elements - width and height (elements are passed in as arguments to the javascript function) to the dimensions of the user's browser window.
+
+=cut
+
+sub viewport_size_js {
+ my $geometry = &viewport_geometry_js();
+ return <<"DIMS";
+
+$geometry
+
+function getViewportDims(width,height) {
+ init_geometry();
+ width.value = Geometry.getViewportWidth();
+ height.value = Geometry.getViewportHeight();
+ return;
+}
+
+DIMS
+}
+
+=pod
+
+=item * &resize_textarea_js()
+
+emits the needed javascript to resize a textarea to be as big as possible
+
+creates a function resize_textrea that takes two IDs first should be
+the id of the element to resize, second should be the id of a div that
+surrounds everything that comes after the textarea, this routine needs
+to be attached to the for the onload and onresize events.
+
=back
+=cut
+
+sub resize_textarea_js {
+ my $geometry = &viewport_geometry_js();
+ return <<"RESIZE";
+
+RESIZE
+
+}
+
+=pod
+
=head1 Excel and CSV file utility routines
=over 4
@@ -1028,7 +1426,7 @@ sub changable_area {
=pod
-=item * csv_translate($text)
+=item * &csv_translate($text)
Translate $text to allow it to be output as a 'comma separated values'
format.
@@ -1049,7 +1447,7 @@ sub csv_translate {
=pod
-=item * define_excel_formats
+=item * &define_excel_formats()
Define some commonly used Excel cell formats.
@@ -1105,7 +1503,7 @@ sub define_excel_formats {
=pod
-=item * create_workbook
+=item * &create_workbook()
Create an Excel worksheet. If it fails, output message on the
request object and return undefs.
@@ -1148,9 +1546,9 @@ sub create_workbook {
=pod
-=item * create_text_file
+=item * &create_text_file()
-Create a file to write to and eventually make available to the usre.
+Create a file to write to and eventually make available to the user.
If file creation fails, outputs an error message on the request object and
return undefs.
@@ -1173,9 +1571,9 @@ sub create_text_file {
$fh = Apache::File->new('>/home/httpd'.$filename);
if (! defined($fh)) {
$r->log_error("Couldn't open $filename for output $!");
- $r->print("Problems occured in creating the output file. ".
- "This error has been logged. ".
- "Please alert your LON-CAPA administrator.");
+ $r->print(&mt('Problems occurred in creating the output file. '
+ .'This error has been logged. '
+ .'Please alert your LON-CAPA administrator.'));
}
return ($fh,$filename)
}
@@ -1191,41 +1589,19 @@ sub create_text_file {
## Home server 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 {
my ($name,$value,$multiple)=@_;
my %domains=map {
- $_ => $_.' '.$Apache::lonnet::domaindescription{$_}
- } &get_domains;
+ $_ => $_.' '. &Apache::lonnet::domain($_,'description')
+ } &Apache::lonnet::all_domains();
if ($multiple) {
$domains{''}=&mt('Any domain');
+ $domains{'select_form_order'} = [sort {lc($a) cmp lc($b) } (keys(%domains))];
return &multiple_select_form($name,$value,4,\%domains);
} else {
+ $domains{'select_form_order'} = [sort {lc($a) cmp lc($b) } (keys(%domains))];
return &select_form($name,$value,%domains);
}
}
@@ -1234,18 +1610,22 @@ sub domain_select {
=pod
-=item * multiple_select_form($name,$value,$size,$hash,$order)
+=head1 Routines for form select boxes
+
+=over 4
+
+=item * &multiple_select_form($name,$value,$size,$hash,$order)
Returns a string containing a element int multiple mode
Args:
$name - name of the 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
$hash - the elements should be 'option' => 'shown text'
(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
@@ -1260,9 +1640,17 @@ sub multiple_select_form {
$size = scalar(keys(%$hash));
}
}
- $output.="\n";
- my @order = ref($order) ? @$order
- : sort(keys(%$hash));
+ $output.="\n".'';
+ my @order;
+ 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) {
$output.='&').'" ';
$output.='selected="selected" ' if ($selected{$key});
@@ -1276,7 +1664,7 @@ sub multiple_select_form {
=pod
-=item * select_form($defdom,$name,%hash)
+=item * &select_form($defdom,$name,%hash)
Returns a string containing a form to
allow a user to select options from a hash option_name => displayed text.
@@ -1304,6 +1692,24 @@ sub select_form {
return $selectform;
}
+# For display filters
+
+sub display_filter {
+ if (!$env{'form.show'}) { $env{'form.show'}=10; }
+ if (!$env{'form.displayfilter'}) { $env{'form.displayfilter'}='currentfolder'; }
+ return ''.&mt('Records [_1]',
+ &Apache::lonmeta::selectbox('show',$env{'form.show'},undef,
+ (&mt('all'),10,20,50,100,1000,10000))).
+ ' '.
+ &mt('Filter [_1]',
+ &select_form($env{'form.displayfilter'},
+ 'displayfilter',
+ ('currentfolder' => 'Current folder/page',
+ 'containing' => 'Containing phrase',
+ 'none' => 'None'))).
+ ' ';
+}
+
sub gradeleveldescription {
my $gradelevel=shift;
my %gradelevels=(0 => 'Not specified',
@@ -1345,7 +1751,7 @@ sub select_level_form {
=pod
-=item * select_dom_form($defdom,$name,$includeempty)
+=item * &select_dom_form($defdom,$name,$includeempty,$showdomdesc,$autosubmit)
Returns a string containing a form to
allow a user to select the domain to preform an operation in.
@@ -1354,18 +1760,34 @@ See loncreateuser.pm for an example invo
If the $includeempty flag is set, it also includes an empty choice ("no domain
selected");
+If the $showdomdesc flag is set, the domain name is followed by the domain description.
+
+If the $autosubmit flag is set, the form containing the domain selector will be auto-submitted by an onchange action.
+
=cut
#-------------------------------------------
sub select_dom_form {
- my ($defdom,$name,$includeempty) = @_;
- my @domains = get_domains();
+ my ($defdom,$name,$includeempty,$showdomdesc,$autosubmit) = @_;
+ my $onchange;
+ if ($autosubmit) {
+ $onchange = ' onchange="this.form.submit()"';
+ }
+ my @domains = sort {lc($a) cmp lc($b)} (&Apache::lonnet::all_domains());
if ($includeempty) { @domains=('',@domains); }
- my $selectdomain = "\n";
+ my $selectdomain = "\n";
foreach my $dom (@domains) {
$selectdomain.="$dom \n";
+ ($dom eq $defdom ? 'selected="selected" ' : '').'>'.$dom;
+ if ($showdomdesc) {
+ if ($dom ne '') {
+ my $domdesc = &Apache::lonnet::domain($dom,'description');
+ if ($domdesc ne '') {
+ $selectdomain .= ' ('.$domdesc.')';
+ }
+ }
+ }
+ $selectdomain .= " \n";
}
$selectdomain.=" ";
return $selectdomain;
@@ -1375,53 +1797,73 @@ sub select_dom_form {
=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.
+=item * &home_server_form_item($domain,$name,$defaultflag)
-=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;
-}
+input: 4 arguments (two required, two optional) -
+ $domain - domain of new user
+ $name - name of form element
+ $default - Value of 'default' causes a default item to be first
+ option, and selected by default.
+ $hide - Value of 'hide' causes hiding of the name of the server,
+ if 1 server found, or default, if 0 found.
+output: returns 2 items:
+(a) form element which contains either:
+ (i)
+ $hostid $servers{$hostid}
+ $hostid $servers{$hostid}
+
+ form item if there are multiple library servers in $domain, or
+ (ii) an form item
+ if there is only one library server in $domain.
-#-------------------------------------------
+(b) number of library servers found.
-=pod
-
-=item * home_server_option_list($domain)
-
-returns a string which contains an list to be used in a
- form input. See loncreateuser.pm for an example.
+See loncreateuser.pm for example of use.
=cut
#-------------------------------------------
-sub home_server_option_list {
- my $domain = shift;
- my %servers = &get_library_servers($domain);
- my $result = '';
- foreach my $hostid (sort(keys(%servers))) {
- $result.=
- ''.
- $hostid.' '.$servers{$hostid}." \n";
+sub home_server_form_item {
+ my ($domain,$name,$default,$hide) = @_;
+ my %servers = &Apache::lonnet::get_servers($domain,'library');
+ my $result;
+ my $numlib = keys(%servers);
+ if ($numlib > 1) {
+ $result .= ' '."\n";
+ if ($default) {
+ $result .= ''.&mt('default').
+ ' '."\n";
+ }
+ foreach my $hostid (sort(keys(%servers))) {
+ $result.= ''.
+ $hostid.' '.$servers{$hostid}." \n";
+ }
+ $result .= ' '."\n";
+ } elsif ($numlib == 1) {
+ my $hostid;
+ foreach my $item (keys(%servers)) {
+ $hostid = $item;
+ }
+ $result .= ' ';
+ if (!$hide) {
+ $result .= $hostid.' '.$servers{$hostid};
+ }
+ $result .= "\n";
+ } elsif ($default) {
+ $result .= ' ';
+ if (!$hide) {
+ $result .= &mt('default');
+ }
+ $result .= "\n";
}
- return $result;
+ return ($result,$numlib);
}
=pod
-=back
+=back
=cut
@@ -1515,14 +1957,12 @@ sub decode_user_agent {
=over 4
-=item * authform_xxxxxx
+=item * &authform_xxxxxx()
The authform_xxxxxx subroutines provide javascript and html forms which
handle some of the conveniences required for authentication forms.
This is not an optimal method, but it works.
-See loncreateuser.pm for invocation and use examples.
-
=over 4
=item * authform_header
@@ -1539,7 +1979,7 @@ See loncreateuser.pm for invocation and
=back
-=back
+See loncreateuser.pm for invocation and use examples.
=cut
@@ -1569,19 +2009,16 @@ END
}
my $radioval = "'nochange'";
- if (exists($in{'curr_authtype'}) &&
- defined($in{'curr_authtype'}) &&
- $in{'curr_authtype'} ne '') {
- $radioval = "'$in{'curr_authtype'}arg'";
+ if (defined($in{'curr_authtype'})) {
+ if ($in{'curr_authtype'} ne '') {
+ $radioval = "'".$in{'curr_authtype'}."arg'";
+ }
}
my $argfield = 'null';
- if ( grep/^mode$/,(keys %in) ) {
+ if (defined($in{'mode'})) {
if ($in{'mode'} eq 'modifycourse') {
- if ( grep/^curr_authtype$/,(keys %in) ) {
- $radioval = "'$in{'curr_authtype'}'";
- }
- if ( grep/^curr_autharg$/,(keys %in) ) {
- unless ($in{'curr_autharg'} eq '') {
+ if (defined($in{'curr_autharg'})) {
+ if ($in{'curr_autharg'} ne '') {
$argfield = "'$in{'curr_autharg'}'";
}
}
@@ -1664,79 +2101,181 @@ sub authform_nochange{
kerb_def_dom => 'MSU.EDU',
@_,
);
- my $result = ''.&mt('[_1] Do not change login data',
- ' ').
' ';
+ }
return $result;
}
-sub authform_kerberos{
+sub authform_kerberos {
my %in = (
formname => 'document.cu',
kerb_def_dom => 'MSU.EDU',
kerb_def_auth => 'krb4',
@_,
);
- my ($check4,$check5,$krbarg);
+ my ($check4,$check5,$krbcheck,$krbarg,$krbver,$result,$authtype,
+ $autharg,$jscall);
+ my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'});
if ($in{'kerb_def_auth'} eq 'krb5') {
- $check5 = " checked=\"on\"";
+ $check5 = ' checked="on"';
} else {
- $check4 = " checked=\"on\"";
+ $check4 = ' checked="on"';
}
$krbarg = $in{'kerb_def_dom'};
-
- my $krbcheck = "";
- if ( grep/^curr_authtype$/,(keys %in) ) {
- if ($in{'curr_authtype'} =~ m/^krb/) {
- $krbcheck = " checked=\"on\"";
- if ( grep/^curr_autharg$/,(keys %in) ) {
+ if (defined($in{'curr_authtype'})) {
+ if ($in{'curr_authtype'} eq 'krb') {
+ $krbcheck = ' checked="on"';
+ if (defined($in{'mode'})) {
+ if ($in{'mode'} eq 'modifyuser') {
+ $krbcheck = '';
+ }
+ }
+ if (defined($in{'curr_kerb_ver'})) {
+ if ($in{'curr_krb_ver'} eq '5') {
+ $check5 = ' checked="on"';
+ $check4 = '';
+ } else {
+ $check4 = ' checked="on"';
+ $check5 = '';
+ }
+ }
+ if (defined($in{'curr_autharg'})) {
$krbarg = $in{'curr_autharg'};
}
+ if (!$can_assign{'krb4'} && !$can_assign{'krb5'}) {
+ if (defined($in{'curr_autharg'})) {
+ $result =
+ &mt('Currently Kerberos authenticated with domain [_1] Version [_2].',
+ $in{'curr_autharg'},$krbver);
+ } else {
+ $result =
+ &mt('Currently Kerberos authenticated, Version [_1].',$krbver);
+ }
+ return $result;
+ }
+ }
+ } else {
+ if ($authnum == 1) {
+ $authtype = ' ';
+ }
+ }
+ if (!$can_assign{'krb4'} && !$can_assign{'krb5'}) {
+ return;
+ } elsif ($authtype eq '') {
+ if (defined($in{'mode'})) {
+ if ($in{'mode'} eq 'modifycourse') {
+ if ($authnum == 1) {
+ $authtype = ' ';
+ }
+ }
}
}
-
- my $jscall = "javascript:changed_radio('krb',$in{'formname'});";
- my $result .= &mt
+ $jscall = "javascript:changed_radio('krb',$in{'formname'});";
+ if ($authtype eq '') {
+ $authtype = ' ';
+ }
+ if (($can_assign{'krb4'} && $can_assign{'krb5'}) ||
+ ($can_assign{'krb4'} && !$can_assign{'krb5'} &&
+ $in{'curr_authtype'} eq 'krb5') ||
+ (!$can_assign{'krb4'} && $can_assign{'krb5'} &&
+ $in{'curr_authtype'} eq 'krb4')) {
+ $result .= &mt
('[_1] Kerberos authenticated with domain [_2] '.
'[_3] Version 4 [_4] Version 5 [_5]',
- ' ',
+ ''.$authtype,
' ',
' ',
' ',
' ');
+ } elsif ($can_assign{'krb4'}) {
+ $result .= &mt
+ ('[_1] Kerberos authenticated with domain [_2] '.
+ '[_3] Version 4 [_4]',
+ ''.$authtype,
+ ' ',
+ ' ',
+ ' ');
+ } elsif ($can_assign{'krb5'}) {
+ $result .= &mt
+ ('[_1] Kerberos authenticated with domain [_2] '.
+ '[_3] Version 5 [_4]',
+ ''.$authtype,
+ ' ',
+ ' ',
+ ' ');
+ }
return $result;
}
sub authform_internal{
- my %args = (
+ my %in = (
formname => 'document.cu',
kerb_def_dom => 'MSU.EDU',
@_,
);
-
- my $intcheck = "";
- my $intarg = 'value=""';
- if ( grep/^curr_authtype$/,(keys %args) ) {
- if ($args{'curr_authtype'} eq 'int') {
- $intcheck = " checked=\"on\"";
- if ( grep/^curr_autharg$/,(keys %args) ) {
- $intarg = "value=\"$args{'curr_autharg'}\"";
+ my ($intcheck,$intarg,$result,$authtype,$autharg,$jscall);
+ my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'});
+ if (defined($in{'curr_authtype'})) {
+ if ($in{'curr_authtype'} eq 'int') {
+ if ($can_assign{'int'}) {
+ $intcheck = 'checked="on" ';
+ if (defined($in{'mode'})) {
+ if ($in{'mode'} eq 'modifyuser') {
+ $intcheck = '';
+ }
+ }
+ if (defined($in{'curr_autharg'})) {
+ $intarg = $in{'curr_autharg'};
+ }
+ } else {
+ $result = &mt('Currently internally authenticated.');
+ return $result;
}
}
+ } else {
+ if ($authnum == 1) {
+ $authtype = ' ';
+ }
}
-
- my $jscall = "javascript:changed_radio('int',$args{'formname'});";
- my $result.=&mt
+ if (!$can_assign{'int'}) {
+ return;
+ } elsif ($authtype eq '') {
+ if (defined($in{'mode'})) {
+ if ($in{'mode'} eq 'modifycourse') {
+ if ($authnum == 1) {
+ $authtype = ' ';
+ }
+ }
+ }
+ }
+ $jscall = "javascript:changed_radio('int',$in{'formname'});";
+ if ($authtype eq '') {
+ $authtype = ' ';
+ }
+ $autharg = ' ';
+ $result = &mt
('[_1] Internally authenticated (with initial password [_2])',
- ' ',
- ' ');
+ ''.$authtype,' '.$autharg);
+ $result.=" ".&mt('Visible input').' ';
return $result;
}
@@ -1746,24 +2285,51 @@ sub authform_local{
kerb_def_dom => 'MSU.EDU',
@_,
);
-
- my $loccheck = "";
- my $locarg = 'value=""';
- if ( grep/^curr_authtype$/,(keys %in) ) {
+ my ($loccheck,$locarg,$result,$authtype,$autharg,$jscall);
+ my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'});
+ if (defined($in{'curr_authtype'})) {
if ($in{'curr_authtype'} eq 'loc') {
- $loccheck = " checked=\"on\"";
- if ( grep/^curr_autharg$/,(keys %in) ) {
- $locarg = "value=\"$in{'curr_autharg'}\"";
+ if ($can_assign{'loc'}) {
+ $loccheck = 'checked="on" ';
+ if (defined($in{'mode'})) {
+ if ($in{'mode'} eq 'modifyuser') {
+ $loccheck = '';
+ }
+ }
+ if (defined($in{'curr_autharg'})) {
+ $locarg = $in{'curr_autharg'};
+ }
+ } else {
+ $result = &mt('Currently using local (institutional) authentication.');
+ return $result;
}
}
+ } else {
+ if ($authnum == 1) {
+ $authtype = ' ';
+ }
}
-
- my $jscall = "javascript:changed_radio('loc',$in{'formname'});";
- my $result.=&mt('[_1] Local Authentication with argument [_2]',
- ' ',
- ' ');
+ if (!$can_assign{'loc'}) {
+ return;
+ } elsif ($authtype eq '') {
+ if (defined($in{'mode'})) {
+ if ($in{'mode'} eq 'modifycourse') {
+ if ($authnum == 1) {
+ $authtype = ' ';
+ }
+ }
+ }
+ }
+ $jscall = "javascript:changed_radio('loc',$in{'formname'});";
+ if ($authtype eq '') {
+ $authtype = ' ';
+ }
+ $autharg = ' ';
+ $result = &mt('[_1] Local Authentication with argument [_2]',
+ ''.$authtype,' '.$autharg);
return $result;
}
@@ -1773,49 +2339,96 @@ sub authform_filesystem{
kerb_def_dom => 'MSU.EDU',
@_,
);
- my $jscall = "javascript:changed_radio('fsys',$in{'formname'});";
- my $result.= &mt
+ my ($fsyscheck,$result,$authtype,$autharg,$jscall);
+ my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'});
+ if (defined($in{'curr_authtype'})) {
+ if ($in{'curr_authtype'} eq 'fsys') {
+ if ($can_assign{'fsys'}) {
+ $fsyscheck = 'checked="on" ';
+ if (defined($in{'mode'})) {
+ if ($in{'mode'} eq 'modifyuser') {
+ $fsyscheck = '';
+ }
+ }
+ } else {
+ $result = &mt('Currently Filesystem Authenticated.');
+ return $result;
+ }
+ }
+ } else {
+ if ($authnum == 1) {
+ $authtype = ' ';
+ }
+ }
+ if (!$can_assign{'fsys'}) {
+ return;
+ } elsif ($authtype eq '') {
+ if (defined($in{'mode'})) {
+ if ($in{'mode'} eq 'modifycourse') {
+ if ($authnum == 1) {
+ $authtype = ' ';
+ }
+ }
+ }
+ }
+ $jscall = "javascript:changed_radio('fsys',$in{'formname'});";
+ if ($authtype eq '') {
+ $authtype = ' ';
+ }
+ $autharg = ' ';
+ $result = &mt
('[_1] Filesystem Authenticated (with initial password [_2])',
' ',
- ' ',
+ ' ');
return $result;
}
-###############################################################
-## 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_auth_def{$domain},$Apache::lonnet::domain_auth_arg_def{$domain});
+sub get_assignable_auth {
+ my ($dom) = @_;
+ if ($dom eq '') {
+ $dom = $env{'request.role.domain'};
+ }
+ my %can_assign = (
+ krb4 => 1,
+ krb5 => 1,
+ int => 1,
+ loc => 1,
+ );
+ my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom);
+ if (ref($domconfig{'usercreation'}) eq 'HASH') {
+ if (ref($domconfig{'usercreation'}{'authtypes'}) eq 'HASH') {
+ my $authhash = $domconfig{'usercreation'}{'authtypes'};
+ my $context;
+ if ($env{'request.role'} =~ /^au/) {
+ $context = 'author';
+ } elsif ($env{'request.role'} =~ /^dc/) {
+ $context = 'domain';
+ } elsif ($env{'request.course.id'}) {
+ $context = 'course';
+ }
+ if ($context) {
+ if (ref($authhash->{$context}) eq 'HASH') {
+ %can_assign = %{$authhash->{$context}};
+ }
+ }
+ }
+ }
+ my $authnum = 0;
+ foreach my $key (keys(%can_assign)) {
+ if ($can_assign{$key}) {
+ $authnum ++;
+ }
+ }
+ if ($can_assign{'krb4'} && $can_assign{'krb5'}) {
+ $authnum --;
+ }
+ return ($authnum,%can_assign);
}
-###############################################################
-## End Get Authentication Defaults for Domain ##
-###############################################################
###############################################################
## Get Kerberos Defaults for Domain ##
@@ -1829,22 +2442,31 @@ sub get_auth_defaults {
=pod
-=item * get_kerberos_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.
+
+=over 4
($def_version, $def_krb_domain) = &get_kerberos_defaults($target_domain);
+=back
+
+=back
+
=cut
#-------------------------------------------
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/;
@@ -1853,11 +2475,6 @@ sub get_kerberos_defaults {
return ($krbdef,$krbdefdom);
}
-=pod
-
-=back
-
-=cut
###############################################################
## Thesaurus Functions ##
@@ -1869,7 +2486,7 @@ sub get_kerberos_defaults {
=over 4
-=item * initialize_keywords
+=item * &initialize_keywords()
Initializes the package variable %Keywords if it is empty. Uses the
package variable $thesaurus_db_file.
@@ -1906,7 +2523,7 @@ sub initialize_keywords {
# Remove special values from %Keywords.
foreach my $value ('total.count','average.count') {
delete($Keywords{$value}) if (exists($Keywords{$value}));
- }
+ }
return 1;
}
@@ -1914,7 +2531,7 @@ sub initialize_keywords {
=pod
-=item * keyword($word)
+=item * &keyword($word)
Returns true if $word is a keyword. A keyword is a word that appears more
than the average number of times in the thesaurus database. Calls
@@ -1935,7 +2552,7 @@ sub keyword {
=pod
-=item * get_related_words
+=item * &get_related_words()
Look up a word in the thesaurus. Takes a scalar argument and returns
an array of words. If the keyword is not in the thesaurus, an empty array
@@ -1993,7 +2610,7 @@ sub get_related_words {
=over 4
-=item * plainname($uname,$udom,$first)
+=item * &plainname($uname,$udom,$first)
Takes a users logon name and returns it as a string in
"first middle last generation" form
@@ -2006,6 +2623,7 @@ if $first is set to 'lastname' then it r
###############################################################
sub plainname {
my ($uname,$udom,$first)=@_;
+ return if (!defined($uname) || !defined($udom));
my %names=&getnames($uname,$udom);
my $name=&Apache::lonnet::format_name($names{'firstname'},
$names{'middlename'},
@@ -2021,7 +2639,7 @@ sub plainname {
# -------------------------------------------------------------------- Nickname
=pod
-=item * nickname($uname,$udom)
+=item * &nickname($uname,$udom)
Gets a users name and returns it as a string as
@@ -2037,6 +2655,7 @@ if the user does not
sub nickname {
my ($uname,$udom)=@_;
+ return if (!defined($uname) || !defined($udom));
my %names=&getnames($uname,$udom);
my $name=$names{'nickname'};
if ($name) {
@@ -2052,6 +2671,7 @@ sub nickname {
sub getnames {
my ($uname,$udom)=@_;
+ return if (!defined($uname) || !defined($udom));
if ($udom eq 'public' && $uname eq 'public') {
return ('lastname' => &mt('Public'));
}
@@ -2068,11 +2688,94 @@ sub getnames {
}
}
+# -------------------------------------------------------------------- getemails
+
+=pod
+
+=item * &getemails($uname,$udom)
+
+Gets a user's email information and returns it as a hash with keys:
+notification, critnotification, permanentemail
+
+For notification and critnotification, values are comma-separated lists
+of e-mail addresses; for permanentemail, value is a single e-mail address.
+
+
+=cut
+
+
+sub getemails {
+ my ($uname,$udom)=@_;
+ if ($udom eq 'public' && $uname eq 'public') {
+ return;
+ }
+ if (!$udom) { $udom=$env{'user.domain'}; }
+ if (!$uname) { $uname=$env{'user.name'}; }
+ my $id=$uname.':'.$udom;
+ my ($names,$cached)=&Apache::lonnet::is_cached_new('emailscache',$id);
+ if ($cached) {
+ return %{$names};
+ } else {
+ my %loadnames=&Apache::lonnet::get('environment',
+ ['notification','critnotification',
+ 'permanentemail'],
+ $udom,$uname);
+ &Apache::lonnet::do_cache_new('emailscache',$id,\%loadnames);
+ return %loadnames;
+ }
+}
+
+sub flush_email_cache {
+ my ($uname,$udom)=@_;
+ if (!$udom) { $udom =$env{'user.domain'}; }
+ if (!$uname) { $uname=$env{'user.name'}; }
+ return if ($udom eq 'public' && $uname eq 'public');
+ my $id=$uname.':'.$udom;
+ &Apache::lonnet::devalidate_cache_new('emailscache',$id);
+}
+
+# -------------------------------------------------------------------- getlangs
+
+=pod
+
+=item * &getlangs($uname,$udom)
+
+Gets a user's language preference and returns it as a hash with key:
+language.
+
+=cut
+
+
+sub getlangs {
+ my ($uname,$udom) = @_;
+ if (!$udom) { $udom =$env{'user.domain'}; }
+ if (!$uname) { $uname=$env{'user.name'}; }
+ my $id=$uname.':'.$udom;
+ my ($langs,$cached)=&Apache::lonnet::is_cached_new('userlangs',$id);
+ if ($cached) {
+ return %{$langs};
+ } else {
+ my %loadlangs=&Apache::lonnet::get('environment',['languages'],
+ $udom,$uname);
+ &Apache::lonnet::do_cache_new('userlangs',$id,\%loadlangs);
+ return %loadlangs;
+ }
+}
+
+sub flush_langs_cache {
+ my ($uname,$udom)=@_;
+ if (!$udom) { $udom =$env{'user.domain'}; }
+ if (!$uname) { $uname=$env{'user.name'}; }
+ return if ($udom eq 'public' && $uname eq 'public');
+ my $id=$uname.':'.$udom;
+ &Apache::lonnet::devalidate_cache_new('userlangs',$id);
+}
+
# ------------------------------------------------------------------ Screenname
=pod
-=item * screenname($uname,$udom)
+=item * &screenname($uname,$udom)
Gets a users screenname and returns it as a string
@@ -2092,9 +2795,9 @@ sub screenname {
sub messagewrapper {
my ($link,$username,$domain,$subject,$text)=@_;
return
- ''.$link.' ';
}
# --------------------------------------------------------------- Notes Wrapper
@@ -2108,18 +2811,18 @@ sub noteswrapper {
sub aboutmewrapper {
my ($link,$username,$domain,$target)=@_;
+ if (!defined($username) && !defined($domain)) {
+ return;
+ }
return ''.$link.' ';
+ ($target?' target="$target"':'').' title="'.&mt("View this user's personal information page").'">'.$link.'';
}
# ------------------------------------------------------------ Syllabus Wrapper
sub syllabuswrapper {
- my ($linktext,$coursedir,$domain,$fontcolor)=@_;
- if ($fontcolor) {
- $linktext=''.$linktext.' ';
- }
+ my ($linktext,$coursedir,$domain)=@_;
return qq{$linktext };
}
@@ -2138,7 +2841,23 @@ sub track_student_link {
$target = '';
}
if ($start) { $link.='&start='.$start; }
- return qq{$linktext };
+ $title = &mt($title);
+ $linktext = &mt($linktext);
+ return qq{$linktext }.
+ &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 ' ';
+ } else {
+ return '';
+ }
}
=pod
@@ -2149,7 +2868,7 @@ sub track_student_link {
=over 4
-=item * languageids()
+=item * &languageids()
returns list of all language ids
@@ -2161,7 +2880,7 @@ sub languageids {
=pod
-=item * languagedescription()
+=item * &languagedescription()
returns description of a specified language id
@@ -2186,7 +2905,7 @@ sub supportedlanguagecode {
=pod
-=item * copyrightids()
+=item * ©rightids()
returns list of all copyrights
@@ -2198,7 +2917,7 @@ sub copyrightids {
=pod
-=item * copyrightdescription()
+=item * ©rightdescription()
returns description of a specified copyright id
@@ -2210,7 +2929,7 @@ sub copyrightdescription {
=pod
-=item * source_copyrightids()
+=item * &source_copyrightids()
returns list of all source copyrights
@@ -2222,7 +2941,7 @@ sub source_copyrightids {
=pod
-=item * source_copyrightdescription()
+=item * &source_copyrightdescription()
returns description of a specified source copyright id
@@ -2234,7 +2953,7 @@ sub source_copyrightdescription {
=pod
-=item * filecategories()
+=item * &filecategories()
returns list of all file categories
@@ -2246,7 +2965,7 @@ sub filecategories {
=pod
-=item * filecategorytypes()
+=item * &filecategorytypes()
returns list of file types belonging to a given file
category
@@ -2260,7 +2979,7 @@ sub filecategorytypes {
=pod
-=item * fileembstyle()
+=item * &fileembstyle()
returns embedding style for a specified file type
@@ -2284,7 +3003,7 @@ sub filecategoryselect {
=pod
-=item * filedescription()
+=item * &filedescription()
returns description for a specified file type
@@ -2298,7 +3017,7 @@ sub filedescription {
=pod
-=item * filedescriptionex()
+=item * &filedescriptionex()
returns description for a specified file type with
extra formatting
@@ -2330,7 +3049,7 @@ sub fileextensions {
sub display_languages {
my %languages=();
- foreach my $lang (&preferred_languages()) {
+ foreach my $lang (&Apache::lonlocal::preferred_languages()) {
$languages{$lang}=1;
}
&get_unprocessed_cgi($ENV{'QUERY_STRING'},['displaylanguage']);
@@ -2342,45 +3061,52 @@ sub display_languages {
return %languages;
}
-sub preferred_languages {
- my @languages=();
- if ($env{'course.'.$env{'request.course.id'}.'.languages'}) {
- @languages=(@languages,split(/\s*(\,|\;|\:)\s*/,
- $env{'course.'.$env{'request.course.id'}.'.languages'}));
- }
- if ($env{'environment.languages'}) {
- @languages=split(/\s*(\,|\;|\:)\s*/,$env{'environment.languages'});
- }
- my $browser=(split(/\;/,$ENV{'HTTP_ACCEPT_LANGUAGE'}))[0];
- if ($browser) {
- @languages=(@languages,split(/\s*(\,|\;|\:)\s*/,$browser));
- }
- if ($Apache::lonnet::domain_lang_def{$env{'user.domain'}}) {
- @languages=(@languages,
- $Apache::lonnet::domain_lang_def{$env{'user.domain'}});
- }
- if ($Apache::lonnet::domain_lang_def{$env{'request.role.domain'}}) {
- @languages=(@languages,
- $Apache::lonnet::domain_lang_def{$env{'request.role.domain'}});
- }
- if ($Apache::lonnet::domain_lang_def{
- $Apache::lonnet::perlvar{'lonDefDomain'}}) {
- @languages=(@languages,
- $Apache::lonnet::domain_lang_def{
- $Apache::lonnet::perlvar{'lonDefDomain'}});
- }
-# turn "en-ca" into "en-ca,en"
- my @genlanguages;
- foreach my $lang (@languages) {
- unless ($lang=~/\w/) { next; }
- push (@genlanguages,$lang);
- if ($lang=~/(\-|\_)/) {
- push(@genlanguages,(split(/(\-|\_)/,$lang))[0]);
+sub languages {
+ my ($possible_langs) = @_;
+ my @preferred_langs = &Apache::lonlocal::preferred_languages();
+ if (!ref($possible_langs)) {
+ if( wantarray ) {
+ return @preferred_langs;
+ } else {
+ return $preferred_langs[0];
}
}
- return @genlanguages;
+ my %possibilities = map { $_ => 1 } (@$possible_langs);
+ my @preferred_possibilities;
+ foreach my $preferred_lang (@preferred_langs) {
+ if (exists($possibilities{$preferred_lang})) {
+ push(@preferred_possibilities, $preferred_lang);
+ }
+ }
+ if( wantarray ) {
+ return @preferred_possibilities;
+ }
+ return $preferred_possibilities[0];
+}
+
+sub user_lang {
+ my ($touname,$toudom,$fromcid) = @_;
+ my @userlangs;
+ if (($fromcid ne '') && ($env{'course.'.$fromcid.'.languages'} ne '')) {
+ @userlangs=(@userlangs,split(/\s*(\,|\;|\:)\s*/,
+ $env{'course.'.$fromcid.'.languages'}));
+ } else {
+ my %langhash = &getlangs($touname,$toudom);
+ if ($langhash{'languages'} ne '') {
+ @userlangs = split(/\s*(\,|\;|\:)\s*/,$langhash{'languages'});
+ } else {
+ my %domdefs = &Apache::lonnet::get_domain_defaults($toudom);
+ if ($domdefs{'lang_def'} ne '') {
+ @userlangs = ($domdefs{'lang_def'});
+ }
+ }
+ }
+ my @languages=&Apache::lonlocal::get_genlanguages(@userlangs);
+ my $user_lh = Apache::localize->get_handle(@languages);
+ return $user_lh;
}
+
###############################################################
## Student Answer Attempts ##
###############################################################
@@ -2391,7 +3117,7 @@ sub preferred_languages {
=over 4
-=item * get_previous_attempt($symb, $username, $domain, $course,
+=item * &get_previous_attempt($symb, $username, $domain, $course,
$getattempt, $regexp, $gradesub)
Return string with previous attempt on problem. Arguments:
@@ -2435,14 +3161,14 @@ sub get_previous_attempt {
$lasthash{$key}=$returnhash{$version.':'.$key};
}
}
- $prevattempts='';
- $prevattempts.='History ';
+ $prevattempts=&start_data_table().&start_data_table_header_row();
+ $prevattempts.=''.&mt('History').' ';
foreach my $key (sort(keys(%lasthash))) {
my ($ign,@parts) = split(/\./,$key);
if ($#parts > 0) {
my $data=$parts[-1];
pop(@parts);
- $prevattempts.='Part '.join('.',@parts).' '.$data.' ';
+ $prevattempts.=''.&mt('Part ').join('.',@parts).' '.$data.' ';
} else {
if ($#parts == 0) {
$prevattempts.=''.$parts[0].' ';
@@ -2451,41 +3177,53 @@ sub get_previous_attempt {
}
}
}
+ $prevattempts.=&end_data_table_header_row();
if ($getattempt eq '') {
for ($version=1;$version<=$returnhash{'version'};$version++) {
- $prevattempts.='Transaction '.$version.' ';
+ $prevattempts.=&start_data_table_row().
+ ''.&mt('Transaction [_1]',$version).' ';
foreach my $key (sort(keys(%lasthash))) {
- my $value;
- if ($key =~ /timestamp/) {
- $value=scalar(localtime($returnhash{$version.':'.$key}));
- } else {
- $value=$returnhash{$version.':'.$key};
- }
- $prevattempts.=''.&unescape($value).' ';
+ my $value = &format_previous_attempt_value($key,
+ $returnhash{$version.':'.$key});
+ $prevattempts.=''.$value.' ';
}
+ $prevattempts.=&end_data_table_row();
}
}
- $prevattempts.='Current ';
+ $prevattempts.=&start_data_table_row().''.&mt('Current').' ';
foreach my $key (sort(keys(%lasthash))) {
- my $value;
- if ($key =~ /timestamp/) {
- $value=scalar(localtime($lasthash{$key}));
- } else {
- $value=$lasthash{$key};
- }
- $value=&unescape($value);
+ my $value = &format_previous_attempt_value($key,$lasthash{$key});
if ($key =~/$regexp$/ && (defined &$gradesub)) {$value = &$gradesub($value)}
$prevattempts.=''.$value.' ';
}
- $prevattempts.='
';
+ $prevattempts.= &end_data_table_row().&end_data_table();
} else {
- $prevattempts='Nothing submitted - no attempts.';
+ $prevattempts=
+ &start_data_table().&start_data_table_row().
+ ''.&mt('Nothing submitted - no attempts.').' '.
+ &end_data_table_row().&end_data_table();
}
} else {
- $prevattempts='No data.';
+ $prevattempts=
+ &start_data_table().&start_data_table_row().
+ ''.&mt('No data.').' '.
+ &end_data_table_row().&end_data_table();
}
}
+sub format_previous_attempt_value {
+ my ($key,$value) = @_;
+ if ($key =~ /timestamp/) {
+ $value = &Apache::lonlocal::locallocaltime($value);
+ } elsif (ref($value) eq 'ARRAY') {
+ $value = '('.join(', ', @{ $value }).')';
+ } else {
+ $value = &unescape($value);
+ }
+ return $value;
+}
+
+
sub relative_to_absolute {
my ($url,$output)=@_;
my $parser=HTML::TokeParser->new(\$output);
@@ -2507,7 +3245,7 @@ sub relative_to_absolute {
}
$thisdir=~s-/[^/]*$--;
foreach my $link (@rlinks) {
- unless (($link=~/^http:\/\//i) ||
+ unless (($link=~/^https?\:\/\//i) ||
($link=~/^\//) ||
($link=~/^javascript:/i) ||
($link=~/^mailto:/i) ||
@@ -2523,7 +3261,7 @@ sub relative_to_absolute {
=pod
-=item * get_student_view
+=item * &get_student_view()
show a snapshot of what student was looking at
@@ -2542,7 +3280,7 @@ sub get_student_view {
}
if (defined($target)) { $form{'grade_target'} = $target; }
$feedurl=&Apache::lonnet::clutter($feedurl);
- my $userview=&Apache::lonnet::ssi_body($feedurl,%form);
+ my ($userview,$response)=&Apache::lonnet::ssi_body($feedurl,%form);
$userview=~s/\]*\>//gi;
$userview=~s/\<\/body\>//gi;
$userview=~s/\//gi;
@@ -2551,12 +3289,44 @@ sub get_student_view {
$userview=~s/\<\/head\>//gi;
$userview=~s/action\s*\=/would_be_action\=/gi;
$userview=&relative_to_absolute($feedurl,$userview);
- return $userview;
+ if (wantarray) {
+ return ($userview,$response);
+ } else {
+ return $userview;
+ }
+}
+
+sub get_student_view_with_retries {
+ my ($symb,$retries,$username,$domain,$courseid,$target,$moreenv) = @_;
+
+ my $ok = 0; # True if we got a good response.
+ my $content;
+ my $response;
+
+ # Try to get the student_view done. within the retries count:
+
+ do {
+ ($content, $response) = &get_student_view($symb,$username,$domain,$courseid,$target,$moreenv);
+ $ok = $response->is_success;
+ if (!$ok) {
+ &Apache::lonnet::logthis("Failed get_student_view_with_retries on $symb: ".$response->is_success.', '.$response->code.', '.$response->message);
+ }
+ $retries--;
+ } while (!$ok && ($retries > 0));
+
+ if (!$ok) {
+ $content = ''; # On error return an empty content.
+ }
+ if (wantarray) {
+ return ($content, $response);
+ } else {
+ return $content;
+ }
}
=pod
-=item * get_student_answers()
+=item * &get_student_answers()
show a snapshot of how student was answering problem
@@ -2572,7 +3342,8 @@ sub get_student_answers {
}
$moreenv{'grade_target'}='answer';
%moreenv=(%form,%moreenv);
- my $userview=&Apache::lonnet::ssi('/res/'.$feedurl,%moreenv);
+ $feedurl = &Apache::lonnet::clutter($feedurl);
+ my $userview=&Apache::lonnet::ssi($feedurl,%moreenv);
return $userview;
}
@@ -2591,7 +3362,7 @@ sub submlink {
my ($text,$uname,$udom,$symb,$target)=@_;
if (!($uname && $udom)) {
(my $cursymb, my $courseid,$udom,$uname)=
- &Apache::lonxml::whichuser($symb);
+ &Apache::lonnet::whichuser($symb);
if (!$symb) { $symb=$cursymb; }
}
if (!$symb) { $symb=&Apache::lonnet::symbread(); }
@@ -2637,15 +3408,15 @@ sub pprmlink {
my ($text,$uname,$udom,$symb,$target)=@_;
if (!($uname && $udom)) {
(my $cursymb, my $courseid,$udom,$uname)=
- &Apache::lonxml::whichuser($symb);
+ &Apache::lonnet::whichuser($symb);
if (!$symb) { $symb=$cursymb; }
}
if (!$symb) { $symb=&Apache::lonnet::symbread(); }
$symb=&escape($symb);
if ($target) { $target="target=\"$target\""; }
- return ''.$text.' ';
+ return ''.$text.' ';
}
##############################################
@@ -2659,16 +3430,21 @@ sub pprmlink {
sub timehash {
- my @ltime=localtime(shift);
- return ( 'seconds' => $ltime[0],
- 'minutes' => $ltime[1],
- 'hours' => $ltime[2],
- 'day' => $ltime[3],
- 'month' => $ltime[4]+1,
- 'year' => $ltime[5]+1900,
- 'weekday' => $ltime[6],
- 'dayyear' => $ltime[7]+1,
- 'dlsav' => $ltime[8] );
+ my ($thistime) = @_;
+ my $timezone = &Apache::lonlocal::gettimezone();
+ my $dt = DateTime->from_epoch(epoch => $thistime)
+ ->set_time_zone($timezone);
+ my $wday = $dt->day_of_week();
+ if ($wday == 7) { $wday = 0; }
+ return ( 'second' => $dt->second(),
+ 'minute' => $dt->minute(),
+ 'hour' => $dt->hour(),
+ 'day' => $dt->day_of_month(),
+ 'month' => $dt->month(),
+ 'year' => $dt->year(),
+ 'weekday' => $wday,
+ 'dayyear' => $dt->day_of_year(),
+ 'dlsav' => $dt->is_dst() );
}
sub utc_string {
@@ -2678,6 +3454,24 @@ sub utc_string {
sub maketime {
my %th=@_;
+ my ($epoch_time,$timezone,$dt);
+ $timezone = &Apache::lonlocal::gettimezone();
+ eval {
+ $dt = DateTime->new( year => $th{'year'},
+ month => $th{'month'},
+ day => $th{'day'},
+ hour => $th{'hour'},
+ minute => $th{'minute'},
+ second => $th{'second'},
+ time_zone => $timezone,
+ );
+ };
+ if (!$@) {
+ $epoch_time = $dt->epoch;
+ if ($epoch_time) {
+ return $epoch_time;
+ }
+ }
return POSIX::mktime(
($th{'seconds'},$th{'minutes'},$th{'hours'},
$th{'day'},$th{'month'}-1,$th{'year'}-1900,0,0,-1));
@@ -2686,31 +3480,430 @@ sub maketime {
#########################################
sub findallcourses {
- my ($roles) = @_;
+ my ($roles,$uname,$udom) = @_;
my %roles;
if (ref($roles)) { %roles = map { $_ => 1 } @{$roles}; }
my %courses;
my $now=time;
- foreach my $key (keys(%env)) {
- if ( $key=~m{^user\.role\.(\w+)\./(\w+)/(\w+)} ) {
- my ($role,$domain,$id) = ($1,$2,$3);
- 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 (!defined($uname)) {
+ $uname = $env{'user.name'};
+ }
+ if (!defined($udom)) {
+ $udom = $env{'user.domain'};
+ }
+ if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
+ my %roleshash = &Apache::lonnet::dump('roles',$udom,$uname);
+ if (!%roles) {
+ %roles = (
+ cc => 1,
+ in => 1,
+ ep => 1,
+ ta => 1,
+ cr => 1,
+ st => 1,
+ );
+ }
+ 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 ($endtime) {
- if ($now>$endtime) { $active=0; }
+ 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;
+ }
}
- if ($active) { $courses{$domain.'_'.$id}=1; }
}
}
- return keys(%courses);
+ return %courses;
}
###############################################
+
+sub blockcheck {
+ my ($setters,$activity,$uname,$udom) = @_;
+
+ if (!defined($udom)) {
+ $udom = $env{'user.domain'};
+ }
+ if (!defined($uname)) {
+ $uname = $env{'user.name'};
+ }
+
+ # If uname and udom are for a course, check for blocks in the course.
+
+ if (&Apache::lonnet::is_course($udom,$uname)) {
+ 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 $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)) {
+ my ($cdom,$cnum);
+ if ((defined($env{'course.'.$course.'.domain'})) && (defined($env{'course.'.$course.'.num'}))) {
+ $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}})) {
+ my $checkrole = 'cm./'.$cdom.'/'.$cnum;
+ if ($sec ne 'none') {
+ $checkrole .= '/'.$sec;
+ }
+ if ($otheruser) {
+ # Resource belongs to user other than current user.
+ # 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
+ next if (($no_ownblock) &&
+ ($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);
+}
+
+sub get_blocks {
+ my ($setters,$activity,$cdom,$cnum) = @_;
+ my $startblock = 0;
+ my $endblock = 0;
+ my $course = $cdom.'_'.$cnum;
+ $setters->{$course} = {};
+ $setters->{$course}{'staff'} = [];
+ $setters->{$course}{'times'} = [];
+ my %records = &Apache::lonnet::dump('comm_block',$cdom,$cnum);
+ foreach my $record (keys(%records)) {
+ my ($start,$end) = ($record =~ m/^(\d+)____(\d+)$/);
+ if ($start <= time && $end >= time) {
+ my ($staff_name,$staff_dom,$title,$blocks) =
+ &parse_block_record($records{$record});
+ if ($blocks->{$activity} eq 'on') {
+ 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;
+ }
+ }
+ }
+ }
+ return ($startblock,$endblock);
+}
+
+sub parse_block_record {
+ my ($record) = @_;
+ my ($setuname,$setudom,$title,$blocks);
+ if (ref($record) eq 'HASH') {
+ ($setuname,$setudom) = split(/:/,$record->{'setter'});
+ $title = &unescape($record->{'event'});
+ $blocks = $record->{'blocks'};
+ } else {
+ my @data = split(/:/,$record,3);
+ if (scalar(@data) eq 2) {
+ $title = $data[1];
+ ($setuname,$setudom) = split(/@/,$data[0]);
+ } else {
+ ($setuname,$setudom,$title) = @data;
+ }
+ $blocks = { 'com' => 'on' };
+ }
+ return ($setuname,$setudom,$title,$blocks);
+}
+
+sub build_block_table {
+ my ($startblock,$endblock,$setters) = @_;
+ my %lt = &Apache::lonlocal::texthash(
+ 'cacb' => 'Currently active communication blocks',
+ 'cour' => 'Course',
+ 'dura' => 'Duration',
+ 'blse' => 'Block set by'
+ );
+ my $output;
+ $output = ' '.$lt{'cacb'}.': ';
+ $output .= &start_data_table();
+ $output .= '
+
+ '.$lt{'cour'}.'
+ '.$lt{'dura'}.'
+ '.$lt{'blse'}.'
+
+';
+ foreach my $course (keys(%{$setters})) {
+ my %courseinfo=&Apache::lonnet::coursedescription($course);
+ for (my $i=0; $i<@{$$setters{$course}{staff}}; $i++) {
+ my ($uname,$udom) = @{$$setters{$course}{staff}[$i]};
+ 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]};
+ $openblock = &Apache::lonlocal::locallocaltime($openblock);
+ $closeblock= &Apache::lonlocal::locallocaltime($closeblock);
+ $output .= &Apache::loncommon::start_data_table_row().
+ ''.$courseinfo{'description'}.' '.
+ ''.$openblock.' to '.$closeblock.' '.
+ ''.$fullname.' '.
+ &Apache::loncommon::end_data_table_row();
+ }
+ }
+ $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 portfolio 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 = ' '.&mt('[_1] will be inaccessible between [_2] and [_3] because communication is being blocked.',$category,$showstart,$showend).' ';
+ if (!($activity eq 'port' && !($ownitem) && !($is_course))) {
+ $output .= &build_block_table($startblock,$endblock,\%setters);
+ }
+ }
+ }
+ if (wantarray) {
+ return ($blocked,$output);
+ } else {
+ return $blocked;
+ }
+}
+
+###############################################
+
+sub check_ip_acc {
+ my ($acc)=@_;
+ &Apache::lonxml::debug("acc is $acc");
+ if (!defined($acc) || $acc =~ /^\s*$/ || $acc =~/^\s*no\s*$/i) {
+ return 1;
+ }
+ my $allowed=0;
+ my $ip=$env{'request.host'} || $ENV{'REMOTE_ADDR'};
+
+ my $name;
+ foreach my $pattern (split(',',$acc)) {
+ $pattern =~ s/^\s*//;
+ $pattern =~ s/\s*$//;
+ if ($pattern =~ /\*$/) {
+ #35.8.*
+ $pattern=~s/\*//;
+ if ($ip =~ /^\Q$pattern\E/) { $allowed=1; }
+ } elsif ($pattern =~ /(\d+\.\d+\.\d+)\.\[(\d+)-(\d+)\]$/) {
+ #35.8.3.[34-56]
+ my $low=$2;
+ my $high=$3;
+ $pattern=$1;
+ if ($ip =~ /^\Q$pattern\E/) {
+ my $last=(split(/\./,$ip))[3];
+ if ($last <=$high && $last >=$low) { $allowed=1; }
+ }
+ } elsif ($pattern =~ /^\*/) {
+ #*.msu.edu
+ $pattern=~s/\*//;
+ if (!defined($name)) {
+ use Socket;
+ my $netaddr=inet_aton($ip);
+ ($name)=gethostbyaddr($netaddr,AF_INET);
+ }
+ if ($name =~ /\Q$pattern\E$/i) { $allowed=1; }
+ } elsif ($pattern =~ /\d+\.\d+\.\d+\.\d+/) {
+ #127.0.0.1
+ if ($ip =~ /^\Q$pattern\E/) { $allowed=1; }
+ } else {
+ #some.name.com
+ if (!defined($name)) {
+ use Socket;
+ my $netaddr=inet_aton($ip);
+ ($name)=gethostbyaddr($netaddr,AF_INET);
+ }
+ if ($name =~ /\Q$pattern\E$/i) { $allowed=1; }
+ }
+ if ($allowed) { last; }
+ }
+ return $allowed;
+}
+
###############################################
=pod
@@ -2730,7 +3923,7 @@ Returns: Determines which domain should
###############################################
sub determinedomain {
my $domain=shift;
- if (! $domain) {
+ if (! $domain) {
# Determine domain if we have not been given one
$domain = $Apache::lonnet::perlvar{'lonDefDomain'};
if ($env{'user.domain'}) { $domain=$env{'user.domain'}; }
@@ -2741,6 +3934,100 @@ sub determinedomain {
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,%legacy);
+ if (keys(%domconfig) > 0) {
+ if (ref($domconfig{'login'}) eq 'HASH') {
+ if (keys(%{$domconfig{'login'}})) {
+ foreach my $key (keys(%{$domconfig{'login'}})) {
+ if (ref($domconfig{'login'}{$key}) eq 'HASH') {
+ foreach my $img (keys(%{$domconfig{'login'}{$key}})) {
+ $designhash{$udom.'.login.'.$key.'_'.$img} =
+ $domconfig{'login'}{$key}{$img};
+ }
+ } else {
+ $designhash{$udom.'.login.'.$key}=$domconfig{'login'}{$key};
+ }
+ }
+ } else {
+ $legacy{'login'} = 1;
+ }
+ } else {
+ $legacy{'login'} = 1;
+ }
+ if (ref($domconfig{'rolecolors'}) eq 'HASH') {
+ if (keys(%{$domconfig{'rolecolors'}})) {
+ 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 {
+ $legacy{'rolecolors'} = 1;
+ }
+ } else {
+ $legacy{'rolecolors'} = 1;
+ }
+ if (keys(%legacy) > 0) {
+ my %legacyhash = &get_legacy_domconf($udom);
+ foreach my $item (keys(%legacyhash)) {
+ if ($item =~ /^\Q$udom\E\.login/) {
+ if ($legacy{'login'}) {
+ $designhash{$item} = $legacyhash{$item};
+ }
+ } else {
+ if ($legacy{'rolecolors'}) {
+ $designhash{$item} = $legacyhash{$item};
+ }
+ }
+ }
+ }
+ } else {
+ %designhash = &get_legacy_domconf($udom);
+ }
+ &Apache::lonnet::do_cache_new('domainconfig',$udom,\%designhash,
+ $cachetime);
+ return %designhash;
+}
+
+sub get_legacy_domconf {
+ my ($udom) = @_;
+ my %legacyhash;
+ 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) { $legacyhash{$udom.'.'.$key}=$val; }
+ }
+ close($fh);
+ }
+ }
+ if (-e '/home/httpd/html/adm/lonDomLogos/'.$udom.'.gif') {
+ $legacyhash{$udom.'.login.domlogo'} = "/adm/lonDomLogos/$udom.gif";
+ }
+ return %legacyhash;
+}
+
=pod
=item * &domainlogo()
@@ -2754,13 +4041,21 @@ If the domain logo does not exist, a des
###############################################
sub domainlogo {
- my $domain = &determinedomain(shift);
- # See if there is a logo
- if (-e '/home/httpd/html/adm/lonDomLogos/'.$domain.'.gif') {
- my $logo=&lonhttpdurl("/adm/lonDomLogos/$domain.gif");
- return ' ';
- } elsif(exists($Apache::lonnet::domaindescription{$domain})) {
- return $Apache::lonnet::domaindescription{$domain};
+ my $domain = &determinedomain(shift);
+ my %designhash = &get_domainconf($domain);
+ # See if there is a logo
+ if ($designhash{$domain.'.login.domlogo'} ne '') {
+ my $imgsrc = $designhash{$domain.'.login.domlogo'};
+ if ($imgsrc =~ m{^/(adm|res)/}) {
+ if ($imgsrc =~ m{^/res/}) {
+ my $local_name = &Apache::lonnet::filelocation('',$imgsrc);
+ &Apache::lonnet::repcopy($local_name);
+ }
+ $imgsrc = &lonhttpdurl($imgsrc);
+ }
+ return ' ';
+ } elsif (defined(&Apache::lonnet::domain($domain,'description'))) {
+ return &Apache::lonnet::domain($domain,'description');
} else {
return '';
}
@@ -2782,10 +4077,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$/) {
@@ -2796,11 +4091,24 @@ sub designparm {
return $env{'environment.color.'.$which};
}
$domain=&determinedomain($domain);
- if (exists($designhash{$domain.'.'.$which})) {
- return $designhash{$domain.'.'.$which};
+ my %domdesign = &get_domainconf($domain);
+ my $output;
+ if ($domdesign{$domain.'.'.$which} ne '') {
+ $output = $domdesign{$domain.'.'.$which};
} else {
- return $designhash{'default.'.$which};
+ $output = $defaultdesign{$which};
}
+ if (($which =~ /^(student|coordinator|author|admin)\.img$/) ||
+ ($which =~ /login\.(img|logo|domlogo|login)/)) {
+ 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;
}
###############################################
@@ -2810,7 +4118,7 @@ sub designparm {
=back
-=head1 HTTP Helpers
+=head1 HTML Helpers
=over 4
@@ -2849,6 +4157,12 @@ Inputs:
=item * $no_inline_link, if true and in remote mode, don't show the
'Switch To Inline Menu' link
+=item * $args, optional argument valid values are
+ 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
+
=back
Returns: A uniform header for LON-CAPA web pages.
@@ -2860,9 +4174,9 @@ other decorations will be returned.
sub bodytag {
my ($title,$function,$addentries,$bodyonly,$domain,$forcereg,$customtitle,
- $notopbar,$bgcolor,$notitle,$no_inline_link)=@_;
+ $notopbar,$bgcolor,$notitle,$no_inline_link,$args)=@_;
- $title=&mt($title);
+ if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); }
$function = &get_users_function() if (!$function);
my $img = &designparm($function.'.img',$domain);
@@ -2880,8 +4194,8 @@ sub bodytag {
# role and realm
my ($role,$realm) = split(/\./,$env{'request.role'},2);
if ($role eq 'ca') {
- my ($rdom,$rname) = ($realm =~ m-^/(\w+)/(\w+)$-);
- $realm = &plainname($rname,$rdom).':'.$rdom;
+ my ($rdom,$rname) = ($realm =~ m{^/($match_domain)/($match_username)$});
+ $realm = &plainname($rname,$rdom);
}
# realm
if ($env{'request.course.id'}) {
@@ -2896,19 +4210,14 @@ sub bodytag {
if (!$realm) { $realm=' '; }
# Set messages
my $messages=&domainlogo($domain);
-# Port for miniserver
- my $lonhttpdPort=$Apache::lonnet::perlvar{'lonhttpdPort'};
- if (!defined($lonhttpdPort)) { $lonhttpdPort='8080'; }
my $extra_body_attr = &make_attr_string($forcereg,\%design);
# construct main body tag
my $bodytag = "".
- &Apache::lontexconvert::init_math_support();
+ &Apache::lontexconvert::init_math_support($args->{'inherit_jsmath'});
- if ($bodyonly
- || ($env{'request.state'} eq 'construct'
- && $env{'environment.remote'} ne 'off' )) {
+ if ($bodyonly) {
return $bodytag;
} elsif ($env{'browser.interface'} eq 'textual') {
# Accessibility
@@ -2942,7 +4251,7 @@ $realm
ENDROLE
- my $titleinfo = ''.$title.' ';
+ my $titleinfo = ''.$title.' ';
if ($customtitle) {
$titleinfo = $customtitle;
}
@@ -2958,7 +4267,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;
@@ -2981,11 +4290,11 @@ ENDROLE
$lastitem = $thisdisfn;
}
$titleinfo =
- &Apache::loncommon::help_open_menu('','',3,'Authoring').
- 'Construction Space : '.
- ''
.&Apache::lonmenu::constspaceform();
@@ -3016,8 +4325,11 @@ ENDROLE
# Top frame rendering, Remote is up
#
- my $upperleft=' ';
+ my $imgsrc = $img;
+ if ($img =~ /^\/adm/) {
+ $imgsrc = &lonhttpdurl($img);
+ }
+ my $upperleft=' ';
# Explicit link to get inline menu
my $menu= ($no_inline_link?''
@@ -3100,38 +4412,35 @@ sub make_attr_string {
=pod
-=back
-
-=head1 HTML Helpers
-
-=over 4
-
=item * &endbodytag()
Returns a uniform footer for LON-CAPA web pages.
-Inputs: none
-
-=back
+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 section,
+i.e., $env{'internal.head.redirect'} exists
=cut
sub endbodytag {
+ my ($args) = @_;
my $endbodytag='';
$endbodytag=&Apache::lontexconvert::jsMath_process()."\n".$endbodytag;
if ( exists( $env{'internal.head.redirect'} ) ) {
- $endbodytag=
- "".
- &mt('Continue').' '.
- $endbodytag;
+ if (!(ref($args) eq 'HASH' && $args->{'noredirectlink'})) {
+ $endbodytag=
+ "".
+ &mt('Continue').' '.
+ $endbodytag;
+ }
}
return $endbodytag;
}
=pod
-=over 4
-
=item * &standard_css()
Returns a style sheet
@@ -3142,8 +4451,6 @@ Inputs: (all optional)
function -> force usage of a specific rolish color scheme
bgcolor -> override the default page bgcolor
-=back
-
=cut
sub standard_css {
@@ -3161,12 +4468,16 @@ sub standard_css {
my $vlink = &designparm($function.'.vlink', $domain);
my $link = &designparm($function.'.link', $domain);
- my $sans = 'Arial,Helvetica,sans-serif';
+ my $loginbg = &designparm('login.sidebg',$domain);
+ my $bgcol = &designparm('login.bgcol',$domain);
+ my $textcol = &designparm('login.textcol',$domain);
+
+ my $sans = 'Verdana,Arial,Helvetica,sans-serif';
my $mono = 'monospace';
my $data_table_head = $tabbg;
my $data_table_light = '#EEEEEE';
- my $data_table_dark = '#DDD';
- my $data_table_darker = '#CCC';
+ my $data_table_dark = '#DDDDDD';
+ my $data_table_darker = '#CCCCCC';
my $data_table_highlight = '#FFFF00';
my $mail_new = '#FFBB77';
my $mail_new_hover = '#DD9955';
@@ -3177,31 +4488,96 @@ sub standard_css {
my $mail_other = '#99BBBB';
my $mail_other_hover = '#669999';
my $table_header = '#DDDDDD';
+ my $feedback_link_bg = '#BBBBBB';
+ my $lg_border_color = '#C8C8C8';
+
+ my $border = ($env{'browser.type'} eq 'explorer' ||
+ $env{'browser.type'} eq 'safari' ) ? '0px 2px 0px 2px'
+ : '0px 3px 0px 4px';
+
- my $border = ($env{'browser.type'} eq 'explorer') ? '0px 2px 0px 2px'
- : '0px 3px 0px 4px';
return < td {
+ background-color: #CCCCCC;
+ font-weight: bold;
+ text-align: left;
+}
+table.LC_data_table tr.LC_odd_row > td,
+table.LC_pick_box tr > td.LC_odd_row,
+table.LC_aboutme_port tr td {
background-color: $data_table_light;
padding: 2px;
}
-table.LC_data_table tr.LC_even_row td {
+table.LC_data_table tr.LC_even_row > td,
+table.LC_pick_box tr > td.LC_even_row,
+table.LC_aboutme_port tr.LC_even_row td {
background-color: $data_table_dark;
+ padding: 2px;
}
table.LC_data_table tr.LC_data_table_highlight td {
background-color: $data_table_darker;
}
-table.LC_data_table tr.LC_empty_row td {
+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;
font-weight: bold;
font-style: italic;
text-align: center;
padding: 8px;
}
+table.LC_nested tr.LC_empty_row td {
+ padding: 4ex
+}
+table.LC_nested_outer tr th {
+ font-weight: bold;
+ background-color: $data_table_head;
+ font-size: small;
+ border-bottom: 1px solid #000000;
+}
+table.LC_nested_outer tr td.LC_subheader {
+ background-color: $data_table_head;
+ font-weight: bold;
+ font-size: small;
+ border-bottom: 1px solid #000000;
+ text-align: right;
+}
+table.LC_nested tr.LC_info_row td {
+ background-color: #CCCCCC;
+ font-weight: bold;
+ font-size: small;
+ text-align: center;
+}
+table.LC_nested tr.LC_info_row td.LC_left_item,
+table.LC_nested_outer tr th.LC_left_item {
+ text-align: left;
+}
+table.LC_nested td {
+ background-color: #FFFFFF;
+ 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_nested tr.LC_odd_row td {
+ background-color: #EEEEEE;
+}
+
+table.LC_createuser {
+}
+
+table.LC_createuser tr.LC_section_row td {
+ font-size: small;
+}
+
+table.LC_createuser tr.LC_info_row td {
+ background-color: #CCCCCC;
+ font-weight: bold;
+ text-align: center;
+}
table.LC_calendar {
border: 1px solid #000000;
@@ -3400,70 +4915,51 @@ table.LC_mail_list tr.LC_mail_other {
table.LC_mail_list tr.LC_mail_other:hover {
background-color: $mail_other_hover;
}
-
-table#LC_portfolio_actions {
- width: auto;
- background: $pgbg;
- border: 0px;
- border-spacing: 2px 2px;
- padding: 0px;
- margin: 0px;
- border-collapse: separate;
-}
-table#LC_portfolio_actions td.LC_label {
- background: $tabbg;
- text-align: right;
+table.LC_mail_list tr.LC_mail_even {
}
-table#LC_portfolio_actions td.LC_value {
- background: $tabbg;
+table.LC_mail_list tr.LC_mail_odd {
}
-table#LC_cstr_controls {
- width: 100%;
- border-collapse: collapse;
+table.LC_data_table tr > td.LC_browser_file,
+table.LC_data_table tr > td.LC_browser_file_published {
+ background: #CCFF88;
}
-table#LC_cstr_controls tr td {
- border: 4px solid $pgbg;
- padding: 4px;
- text-align: center;
- background: $tabbg;
+table.LC_data_table tr > td.LC_browser_file_locked,
+table.LC_data_table tr > td.LC_browser_file_unpublished {
+ background: #FFAA99;
}
-table#LC_cstr_controls tr th {
- border: 4px solid $pgbg;
- background: $table_header;
- text-align: center;
- font-family: $sans;
- font-size: smaller;
+table.LC_data_table tr > td.LC_browser_file_obsolete {
+ background: #AAAAAA;
}
-
-table#LC_browser {
-
+table.LC_data_table tr > td.LC_browser_file_modified,
+table.LC_data_table tr > td.LC_browser_file_metamodified {
+ background: #FFFF77;
}
-table#LC_browser tr th {
- background: $table_header;
+table.LC_data_table tr.LC_browser_folder > td {
+ background: #CCCCFF;
}
-table#LC_browser tr td {
- padding: 2px;
+
+table.LC_data_table tr > td.LC_roles_is {
+/* background: #77FF77; */
}
-table#LC_browser tr.LC_browser_file,
-table#LC_browser tr.LC_browser_file_published {
- background: #CCFF88;
+table.LC_data_table tr > td.LC_roles_future {
+ background: #FFFF77;
}
-table#LC_browser tr.LC_browser_file_locked,
-table#LC_browser tr.LC_browser_file_unpublished {
- background: #FFAA99;
+table.LC_data_table tr > td.LC_roles_will {
+ background: #FFAA77;
}
-table#LC_browser tr.LC_browser_file_obsolete {
- background: #AAAAAA;
+table.LC_data_table tr > td.LC_roles_expired {
+ background: #FF7777;
}
-table#LC_browser tr.LC_browser_file_modified {
- background: #FFFF77;
+table.LC_data_table tr > td.LC_roles_will_not {
+ background: #AAFF77;
}
-table#LC_browser tr.LC_browser_folder {
- background: #CCCCFF;
+table.LC_data_table tr > td.LC_roles_selected {
+ background: #11CC55;
}
+
span.LC_current_location {
- font-size: x-large;
+ font-size:larger;
background: $pgbg;
}
@@ -3552,9 +5048,7 @@ table#LC_helpmenu_links a:hover {
border: 1px solid #8888FF;
background: #CCCCFF;
}
-
table.LC_pick_box {
- width: 100%;
border-collapse: separate;
background: white;
border: 1px solid black;
@@ -3564,9 +5058,26 @@ table.LC_pick_box td.LC_pick_box_title {
background: $tabbg;
font-weight: bold;
text-align: right;
+ vertical-align: top;
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;
+}
+table.LC_pick_box td.LC_pick_box_select {
+ text-align: left;
+ padding: 8px;
+}
table.LC_pick_box td.LC_pick_box_separator {
padding: 0px;
height: 1px;
@@ -3575,7 +5086,48 @@ table.LC_pick_box td.LC_pick_box_separat
table.LC_pick_box td.LC_pick_box_submit {
text-align: right;
}
-
+table.LC_pick_box td.LC_evenrow_value {
+ text-align: left;
+ padding: 8px;
+ background-color: $data_table_light;
+}
+table.LC_pick_box td.LC_oddrow_value {
+ text-align: left;
+ padding: 8px;
+ background-color: $data_table_light;
+}
+table.LC_helpform_receipt {
+ width: 620px;
+ border-collapse: separate;
+ background: white;
+ border: 1px solid black;
+ border-spacing: 1px;
+}
+table.LC_helpform_receipt td.LC_pick_box_title {
+ background: $tabbg;
+ font-weight: bold;
+ text-align: right;
+ width: 184px;
+ padding: 8px;
+}
+table.LC_helpform_receipt td.LC_evenrow_value {
+ text-align: left;
+ padding: 8px;
+ background-color: $data_table_light;
+}
+table.LC_helpform_receipt td.LC_oddrow_value {
+ text-align: left;
+ padding: 8px;
+ background-color: $data_table_light;
+}
+table.LC_helpform_receipt td.LC_pick_box_separator {
+ padding: 0px;
+ height: 1px;
+ background: black;
+}
+span.LC_helpform_receipt_cat {
+ font-weight: bold;
+}
table.LC_group_priv_box {
background: white;
border: 1px solid black;
@@ -3643,14 +5195,816 @@ table.LC_descriptive_input td.LC_descrip
text-align: right;
font-weight: bold;
}
+div.LC_feedback_link {
+ clear: both;
+ background: white;
+ width: 100%;
+}
+span.LC_feedback_link {
+ background: $feedback_link_bg;
+ font-size: larger;
+}
+span.LC_message_link {
+ background: $feedback_link_bg;
+ font-size: larger;
+ position: absolute;
+ right: 1em;
+}
+
+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;
+}
+
+td.LC_nobreak,
+span.LC_nobreak {
+ white-space: nowrap;
+}
+
+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;
+ border-collapse: collapse;
+}
+
+table.LC_docs_documents td.LC_docs_document {
+ border: 2px solid black;
+ padding: 4px;
+}
+
+.LC_docs_entry_move {
+ border: 0px;
+ border-collapse: collapse;
+}
+
+.LC_docs_entry_move td {
+ border: 2px solid #BBBBBB;
+ background: #DDDDDD;
+}
+
+.LC_docs_editor td.LC_docs_entry_commands {
+ background: #DDDDDD;
+ font-size: x-small;
+}
+.LC_docs_copy {
+ color: #000099;
+}
+.LC_docs_cut {
+ color: #550044;
+}
+.LC_docs_rename {
+ color: #009900;
+}
+.LC_docs_remove {
+ color: #990000;
+}
+
+.LC_docs_reinit_warn,
+.LC_docs_ext_edit {
+ font-size: x-small;
+}
+
+.LC_docs_editor td.LC_docs_entry_title,
+.LC_docs_editor td.LC_docs_entry_icon {
+ background: #FFFFBB;
+}
+.LC_docs_editor td.LC_docs_entry_parameter {
+ background: #BBBBFF;
+ font-size: x-small;
+ white-space: nowrap;
+}
+
+table.LC_docs_adddocs td,
+table.LC_docs_adddocs th {
+ border: 1px solid #BBBBBB;
+ padding: 4px;
+ background: #DDDDDD;
+}
+
+table.LC_sty_begin {
+ background: #BBFFBB;
+}
+table.LC_sty_end {
+ background: #FFBBBB;
+}
+
+table.LC_double_column {
+ border-width: 0px;
+ border-collapse: collapse;
+ width: 100%;
+ padding: 2px;
+}
+
+table.LC_double_column tr td.LC_left_col {
+ top: 2px;
+ left: 2px;
+ width: 47%;
+ vertical-align: top;
+}
+
+table.LC_double_column tr td.LC_right_col {
+ top: 2px;
+ right: 2px;
+ width: 47%;
+ vertical-align: top;
+}
+
+span.LC_role_level {
+ font-weight: bold;
+}
+
+div.LC_left_float {
+ float: left;
+ padding-right: 5%;
+ padding-bottom: 4px;
+}
+
+div.LC_clear_float_header {
+ padding-bottom: 2px;
+}
+
+div.LC_clear_float_footer {
+ padding-top: 10px;
+ clear: both;
+}
+
+
+div.LC_grade_show_user {
+ margin-top: 20px;
+ border: 1px solid black;
+}
+div.LC_grade_user_name {
+ background: #DDDDEE;
+ border-bottom: 1px solid black;
+ font-weight: bold;
+ font-size: large;
+}
+div.LC_grade_show_user_odd_row div.LC_grade_user_name {
+ background: #DDEEDD;
+}
+
+div.LC_grade_show_problem,
+div.LC_grade_submissions,
+div.LC_grade_message_center,
+div.LC_grade_info_links,
+div.LC_grade_assign {
+ margin: 5px;
+ width: 99%;
+ background: #FFFFFF;
+}
+div.LC_grade_show_problem_header,
+div.LC_grade_submissions_header,
+div.LC_grade_message_center_header,
+div.LC_grade_assign_header {
+ font-weight: bold;
+ font-size: large;
+}
+div.LC_grade_show_problem_problem,
+div.LC_grade_submissions_body,
+div.LC_grade_message_center_body,
+div.LC_grade_assign_body {
+ border: 1px solid black;
+ width: 99%;
+ background: #FFFFFF;
+}
+span.LC_grade_check_note {
+ font-weight: normal;
+ font-size: medium;
+ display: inline;
+ position: absolute;
+ right: 1em;
+}
+
+table.LC_scantron_action {
+ width: 100%;
+}
+table.LC_scantron_action tr th {
+ font-weight:bold;
+ font-style:normal;
+}
+.LC_edit_problem_header,
+div.LC_edit_problem_footer {
+ font-weight: normal;
+ font-size: medium;
+ margin: 2px;
+}
+div.LC_edit_problem_header,
+div.LC_edit_problem_header div,
+div.LC_edit_problem_footer,
+div.LC_edit_problem_footer div,
+div.LC_edit_problem_editxml_header,
+div.LC_edit_problem_editxml_header div {
+ margin-top: 5px;
+}
+div.LC_edit_problem_header_edit_row {
+ background: $tabbg;
+ padding: 3px;
+ margin-bottom: 5px;
+}
+div.LC_edit_problem_header_title {
+ font-weight: bold;
+ font-size: larger;
+ background: $tabbg;
+ padding: 3px;
+}
+table.LC_edit_problem_header_title {
+ font-size: larger;
+ font-weight: bold;
+ width: 100%;
+ border-color: $pgbg;
+ border-style: solid;
+ border-width: $border;
+
+ background: $tabbg;
+ border-collapse: collapse;
+ padding: 0px
+}
+
+div.LC_edit_problem_discards {
+ float: left;
+ padding-bottom: 5px;
+}
+div.LC_edit_problem_saves {
+ float: right;
+ padding-bottom: 5px;
+}
+hr.LC_edit_problem_divide {
+ clear: both;
+ color: $tabbg;
+ background-color: $tabbg;
+ height: 3px;
+ border: 0px;
+}
+img.stift{
+ border-width:0;
+ vertical-align:middle;
+}
+
+table#LC_mainmenu{
+ margin-top:10px;
+ width:80%;
+
+}
+
+table#LC_mainmenu td.LC_mainmenu_col_fieldset{
+ vertical-align: top;
+ width: 45%;
+}
+.LC_mainmenu_fieldset_category {
+ color: $font;
+ background: $pgbg;
+ font-family: $sans;
+ font-size: small;
+ font-weight: bold;
+}
+
+div.LC_createcourse {
+ margin: 10px 10px 10px 10px;
+}
+
+/* ---- Remove when done ----
+# The following styles is part of the redesign of LON-CAPA and are
+# subject to change during this project.
+# Don't rely on their current functionality as they might be
+# changed or removed.
+# --------------------------*/
+
+a:hover,
+ol.LC_smallMenu a:hover,
+ol#LC_MenuBreadcrumbs a:hover,
+ol#LC_PathBreadcrumbs a:hover,
+ul#LC_TabMainMenuContent a:hover,
+.LC_FormSectionClearButton input:hover
+ul.LC_TabContent li:hover a{
+ color:#BF2317;
+ text-decoration:none;
+}
+
+h1 {
+ padding:5px 10px 5px 20px;
+ line-height:130%;
+}
+
+h2,h3,h4,h5,h6
+{
+ margin:5px 0px 5px 0px;
+ padding:0px;
+ line-height:130%;
+}
+.LC_hcell{
+ padding:3px 15px 3px 15px;
+ margin:0px;
+ background-color:$tabbg;
+ border-bottom:solid 1px $lg_border_color;
+}
+.LC_noBorder {
+ border:0px;
+}
+
+.LC_bgLightGrey{
+ background:URL(/adm/lonIcons/lightGreyBG.png) repeat-x left bottom;
+}
+
+
+/* Main Header with discription of Person, Course, etc. */
+.LC_HeadRight {
+ text-align: right;
+ float: right;
+ margin: 0px;
+ padding: 0px;
+ right:0;
+ position:absolute;
+ overflow:hidden;
+}
+
+.LC_Right {
+ float: right;
+ margin: 0px;
+ padding: 0px;
+}
+
+p, .LC_ContentBox {
+ padding: 10px;
+
+}
+.LC_FormSectionClearButton input {
+ background-color:transparent;
+ border:0px;
+ cursor:pointer;
+ text-decoration:underline;
+}
+
+.LC_help_open_topic {
+ color: #FFFFFF;
+ background-color: #EEEEFF;
+ margin: 1px;
+ padding: 4px;
+ border: 1px solid #000033;
+ white-space: nowrap;
+}
+
+dl,ul,div,fieldset {
+ margin: 10px 10px 10px 0px;
+ overflow:hidden;
+}
+ol.LC_smallMenu, ol#LC_PathBreadcrumbs {
+ margin: 0px;
+}
+
+ol.LC_smallMenu li {
+ display: inline;
+ padding: 5px 5px 0px 10px;
+ vertical-align: top;
+}
+
+ol.LC_smallMenu li img {
+ vertical-align: bottom;
+}
+
+ol.LC_smallMenu a {
+ font-size: 90%;
+ color: RGB(80, 80, 80);
+ text-decoration: none;
+}
+ol#LC_TabMainMenuContent, ul.LC_TabContent ,
+ul.LC_TabContentBigger {
+ display:block;
+ list-style:none;
+ margin: 0px;
+ padding: 0px;
+}
+
+ol#LC_TabMainMenuContent li, ul.LC_TabContent li,
+ul.LC_TabContentBigger li{
+ display: inline;
+ border-right: solid 1px $lg_border_color;
+ float:left;
+ line-height:140%;
+ white-space:nowrap;
+}
+ol#LC_TabMainMenuContent li{
+ vertical-align: bottom;
+ border-bottom: solid 1px RGB(175, 175, 175);
+ padding: 5px 10px 5px 10px;
+ margin-right:5px;
+ margin-bottom:3px;
+ font-weight: bold;
+ background: url(/adm/lonIcons/lightGreyBG.png) repeat-x left top;
+}
+
+ol#LC_TabMainMenuContent li a{
+ color: RGB(47, 47, 47);
+ text-decoration: none;
+}
+ul.LC_TabContent {
+ min-height:1.6em;
+}
+ul.LC_TabContent li{
+ vertical-align:middle;
+ padding:0px 10px 0px 10px;
+ background-color:$tabbg;
+ border-bottom:solid 1px $lg_border_color;
+}
+ul.LC_TabContent li a, ul.LC_TabContent li{
+ color:rgb(47,47,47);
+ text-decoration:none;
+ font-size:95%;
+ font-weight:bold;
+ padding-right: 16px;
+}
+ul.LC_TabContent li:hover, ul.LC_TabContent li.active{
+ background:#FFFFFF url(/adm/lonIcons/open.gif) no-repeat scroll right center;
+ border-bottom:solid 1px #FFFFFF;
+ padding-right: 16px;
+}
+ul.LC_TabContentBigger li{
+ vertical-align:bottom;
+ border-top:solid 1px $lg_border_color;
+ border-left:solid 1px $lg_border_color;
+ padding:5px 10px 5px 10px;
+ margin-left:2px;
+ background:url(/adm/lonIcons/lightGreyBG.png) repeat-x left top;
+}
+ul.LC_TabContentBigger li:hover, ul.LC_TabContentBigger li.active{
+ background:url(/adm/lonIcons/lightGreyBG.png) repeat-x right bottom;
+}
+ul.LC_TabContentBigger li, ul.LC_TabContentBigger li a{
+ font-size:110%;
+ font-weight:bold;
+}
+#LC_CourseDocuments, #LC_SupplementalCourseDocuments
+{
+ margin:0px;
+}
+
+.LC_hideThis
+{
+ display:none;
+ visibility:hidden;
+}
+
+ol#LC_MenuBreadcrumbs, ol#LC_PathBreadcrumbs {
+ border-top: solid 1px RGB(255, 255, 255);
+ height: 20px;
+ line-height: 20px;
+ vertical-align: bottom;
+ margin: 0px 0px 30px 0px;
+ padding-left: 10px;
+ list-style-position: inside;
+ background: url(/adm/lonIcons/lightGreyBG.png) repeat-x left top;
+}
+
+ol#LC_MenuBreadcrumbs li, ol#LC_PathBreadcrumbs li {
+/*
+ background: url(/adm/lonIcons/arrow_white.png) no-repeat left center;
+*/
+ display: inline;
+ padding: 0px 0px 0px 10px;
+ vertical-align: bottom;
+ overflow:hidden;
+}
+
+ol#LC_MenuBreadcrumbs li a {
+ text-decoration: none;
+ font-size:90%;
+}
+ol#LC_PathBreadcrumbs li a{
+ text-decoration:none;
+ font-size:100%;
+ font-weight:bold;
+}
+.LC_ContentBoxSpecial
+{
+ border: solid 1px $lg_border_color;
+}
+.LC_ContentBoxSpecialContactInfo
+{
+ border: solid 1px $lg_border_color;
+ max-width:25%;
+ min-width:25%;
+}
+.LC_AboutMe_Image
+{
+ float:left;
+ margin-right:10px;
+}
+.LC_Clear_AboutMe_Image
+{
+ clear:left;
+}
+dl.LC_ListStyleClean dt {
+ padding-right: 5px;
+ display: table-header-group;
+}
+
+dl.LC_ListStyleClean dd {
+ display: table-row;
+}
+
+.LC_ListStyleClean,
+.LC_ListStyleSimple,
+.LC_ListStyleNormal,
+.LC_ListStyleNormal_Border,
+.LC_ListStyleSpecial
+ {
+ /*display:block; */
+ list-style-position: inside;
+ list-style-type: none;
+ overflow: hidden;
+ padding: 0px;
+}
+
+.LC_ListStyleSimple li,
+.LC_ListStyleSimple dd,
+.LC_ListStyleNormal li,
+.LC_ListStyleNormal dd,
+.LC_ListStyleSpecial li,
+.LC_ListStyleSpecial dd
+ {
+ margin: 0px;
+ padding: 5px 5px 5px 10px;
+ clear: both;
+}
+
+.LC_ListStyleClean li,
+.LC_ListStyleClean dd {
+ padding-top: 0px;
+ padding-bottom: 0px;
+}
+
+.LC_ListStyleSimple dd,
+.LC_ListStyleSimple li{
+ border-bottom: solid 1px $lg_border_color;
+}
+
+.LC_ListStyleSpecial li,
+.LC_ListStyleSpecial dd {
+ list-style-type: none;
+ background-color: RGB(220, 220, 220);
+ margin-bottom: 4px;
+}
+
+table.LC_SimpleTable {
+ margin:5px;
+ border:solid 1px $lg_border_color;
+ }
+
+table.LC_SimpleTable tr {
+ padding:0px;
+ border:solid 1px $lg_border_color;
+}
+table.LC_SimpleTable thead{
+ background:rgb(220,220,220);
+}
+
+div.LC_columnSection {
+ display: block;
+ clear: both;
+ overflow: hidden;
+ margin:0px;
+}
+
+div.LC_columnSection>* {
+ float: left;
+ margin: 10px 20px 10px 0px;
+ overflow:hidden;
+}
+
+.ContentBoxSpecialTemplate
+{
+ border: solid 1px $lg_border_color;
+}
+.ContentBoxTemplate {
+ padding:10px;
+}
+
+div.LC_columnSection > .ContentBoxTemplate,
+div.LC_columnSection > .ContentBoxSpecialTemplate
+ {
+ width: 600px;
+}
+
+.clear{
+ clear: both;
+ line-height: 0px;
+ font-size: 0px;
+ height: 0px;
+}
+
+.LC_loginpage_container {
+ text-align:left;
+ margin : 0 auto;
+ width:65%;
+ padding: 10px;
+ height: auto;
+ background-color:#FFFFFF;
+ border:1px solid #CCCCCC;
+}
+
+
+.LC_loginpage_loginContainer {
+ float:left;
+ width: 182px;
+ border:1px solid #CCCCCC;
+ background-color:$loginbg;
+}
+
+.LC_loginpage_loginContainer h2{
+ margin-top:0;
+ display:block;
+ background:$bgcol;
+ color:$textcol;
+ padding-left:5px;
+}
+.LC_loginpage_loginInfo {
+ margin-left:20px;
+ float:left;
+ width:30%;
+ border:1px solid #CCCCCC;
+ padding:10px;
+}
+
+.LC_loginpage_loginDomain {
+ margin-right:20px;
+ width:20%;
+ float:left;
+ padding:10px;
+}
+
+.LC_loginpage_space {
+ clear: both;
+ margin-bottom: 20px;
+ border-bottom: 1px solid #CCCCCC;
+}
+
+table em{
+ font-weight: bold;
+ font-style: normal;
+}
+
+table.LC_tableOfContent{
+ border:none;
+ border-spacing: 1;
+ padding: 3px;
+ background-color: #FFFFFF;
+ font-size: 90%;
+}
+table.LC_tableOfContent a {
+ background-color:transparent;
+ text-decoration: none;
+}
+
+table.LC_tableOfContent tr.LC_trOdd{
+ background-color: #EEEEEE;
+}
+
+table.LC_tableOfContent img{
+ border: none;
+ height: 1.3em;
+ vertical-align: text-bottom;
+ margin-right: 0.3em;
+}
+
+a#LC_content_toolbar_firsthomework{
+ background-image:url(/res/adm/pages/open-first-problem.gif);
+}
+
+a#LC_content_toolbar_launchnav{
+ background-image:url(/res/adm/pages/start-navigation.gif);
+}
+
+a#LC_content_toolbar_closenav{
+ background-image:url(/res/adm/pages/close-navigation.gif);
+}
+
+a#LC_content_toolbar_everything{
+ background-image:url(/res/adm/pages/show-all.gif);
+}
+
+a#LC_content_toolbar_uncompleted{
+ background-image:url(/res/adm/pages/show-incomplete-problems.gif);
+}
+
+#LC_content_toolbar_clearbubbles{
+ background-image:url(/res/adm/pages/mark-discussionentries-read.gif);
+}
+
+a#LC_content_toolbar_changefolder{
+ background : url(/res/adm/pages/close-all-folders.gif) top center ;
+}
+
+a#LC_content_toolbar_changefolder_toggled{
+ background-image:url(/res/adm/pages/open-all-folders.gif);
+}
+
+ul#LC_toolbar li a:hover{
+ background-position: bottom center;
+}
+
+ul#LC_toolbar{
+ padding:0;
+ margin: 2px;
+ list-style:none;
+ position:relative;
+ background-color:white;
+}
+
+ul#LC_toolbar li{
+ border:1px solid white;
+ padding:0;
+ margin: 0;
+ float: left;
+ display:inline;
+ vertical-align:middle;
+}
+
+a.LC_toolbarItem{
+ display:block;
+ padding:0;
+ margin:0;
+ height: 32px;
+ width: 32px;
+ color:white;
+ border:0 none;
+ background-repeat:no-repeat;
+ background-color:transparent;
+}
+
END
}
=pod
-=over 4
-
=item * &headtag()
Returns a uniform footer for LON-CAPA web pages.
@@ -3671,8 +6025,8 @@ Inputs: $title - optional title for the
domain
function -> force usage of a specific rolish color scheme
bgcolor -> override the default page bgcolor
-
-=back
+ no_auto_mt_title
+ -> prevent &mt()ing the title arg
=cut
@@ -3683,6 +6037,7 @@ sub headtag {
my $domain = $args->{'domain'} || &determinedomain();
my $bgcolor = $args->{'bgcolor'} || &designparm($function.'.pgbg',$domain);
my $url = join(':',$env{'user.name'},$env{'user.domain'},
+ $Apache::lonnet::perlvar{'lonVersion'},
#time(),
$env{'environment.color.timestamp'},
$function,$domain,$bgcolor);
@@ -3691,9 +6046,11 @@ sub headtag {
my $result =
''.
- &font_settings().
- &Apache::lonhtmlcommon::htmlareaheaders();
+ &font_settings();
+ if (!$args->{'frameset'}) {
+ $result .= &Apache::lonhtmlcommon::htmlareaheaders();
+ }
if ($args->{'force_register'}) {
$result .= &Apache::lonmenu::registerurl(1);
}
@@ -3717,8 +6074,8 @@ ADDMETA
if (!defined($title)) {
$title = 'The LearningOnline Network with CAPA';
}
-
- $result .= ' LON-CAPA '.&mt($title).' '
+ if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); }
+ $result .= ' LON-CAPA '.$title.' '
.' '
.$head_extra;
return $result;
@@ -3726,24 +6083,17 @@ ADDMETA
=pod
-=over 4
-
=item * &font_settings()
Returns neccessary to set the proper encoding
Inputs: none
-=back
-
=cut
sub font_settings {
my $headerstring='';
- if (($env{'browser.os'} eq 'mac') && (!$env{'browser.mathml'})) {
- $headerstring.=
- ' ';
- } elsif (!$env{'browser.mathml'} && $env{'browser.unicode'}) {
+ if (!$env{'browser.mathml'} && $env{'browser.unicode'}) {
$headerstring.=
' ';
}
@@ -3752,22 +6102,20 @@ sub font_settings {
=pod
-=over 4
-
=item * &xml_begin()
Returns the needed doctype and
Inputs: none
-=back
-
=cut
sub xml_begin {
my $output='';
- &Apache::lonhtmlcommon::init_htmlareafields();
+ if ($env{'internal.start_page'}==1) {
+ &Apache::lonhtmlcommon::init_htmlareafields();
+ }
if ($env{'browser.mathml'}) {
$output=''
@@ -3786,16 +6134,12 @@ sub xml_begin {
=pod
-=over 4
-
=item * &endheadtag()
Returns a uniform for LON-CAPA web pages.
Inputs: none
-=back
-
=cut
sub endheadtag {
@@ -3804,14 +6148,17 @@ sub endheadtag {
=pod
-=over 4
-
=item * &head()
Returns a uniform complete .. section for LON-CAPA web pages.
-Inputs: $title - optional title for the page
- $head_extra - optional extra HTML to put inside the
+Inputs:
+
+=over 4
+
+$title - optional title for the page
+
+$head_extra - optional extra HTML to put inside the
=back
@@ -3824,43 +6171,55 @@ sub head {
=pod
-=over 4
-
=item * &start_page()
Returns a complete .. section for LON-CAPA web pages.
-Inputs: $title - optional title for the page
- $head_extra - optional extra HTML to incude inside the
- $args - additional optional args supported are:
- only_body -> is true will set &bodytag() onlybodytag
+Inputs:
+
+=over 4
+
+$title - optional title for the page
+
+$head_extra - optional extra HTML to incude inside the
+
+$args - additional optional args supported are:
+
+=over 8
+
+ only_body -> is true will set &bodytag() onlybodytag
arg on
- no_nav_bar -> is true will set &bodytag() notopbar arg on
- add_entries -> additional attributes to add to the
- domain -> force to color decorate a page for a
+ no_nav_bar -> is true will set &bodytag() notopbar arg on
+ add_entries -> additional attributes to add to the
+ domain -> force to color decorate a page for a
specific domain
- function -> force usage of a specific rolish color
+ function -> force usage of a specific rolish color
scheme
- redirect -> see &headtag()
- bgcolor -> override the default page bg color
- js_ready -> return a string ready for being used in
+ redirect -> see &headtag()
+ bgcolor -> override the default page bg color
+ js_ready -> return a string ready for being used in
a javascript writeln
- html_encode -> return a string ready for being used in
+ html_encode -> return a string ready for being used in
a html attribute
- force_register -> if is true will turn on the &bodytag()
+ force_register -> if is true will turn on the &bodytag()
$forcereg arg
- body_title -> alternate text to use instead of $title
+ body_title -> alternate text to use instead of $title
in the title box that appears, this text
is not auto translated like the $title is
- frameset -> if true will start with a
+ frameset -> if true will start with a
rather than
- no_title -> if true the title bar won't be shown
- skip_phases -> hash ref of
+ no_title -> if true the title bar won't be shown
+ skip_phases -> hash ref of
head -> skip the generation
body -> skip all generation
-
- 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
+ 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
+
+=back
=back
@@ -3871,7 +6230,8 @@ sub start_page {
#&Apache::lonnet::logthis("start_page ".join(':',caller(0)));
my %head_args;
foreach my $arg ('redirect','force_register','domain','function',
- 'bgcolor','frameset','no_nav_bar','only_body') {
+ 'bgcolor','frameset','no_nav_bar','only_body',
+ 'no_auto_mt_title') {
if (defined($args->{$arg})) {
$head_args{$arg} = $args->{$arg};
}
@@ -3897,15 +6257,34 @@ sub start_page {
$args->{'only_body'}, $args->{'domain'},
$args->{'force_register'}, $args->{'body_title'},
$args->{'no_nav_bar'}, $args->{'bgcolor'},
- $args->{'no_title'}, $args->{'no_inline_link'});
+ $args->{'no_title'}, $args->{'no_inline_link'},
+ $args);
}
}
if ($args->{'js_ready'}) {
- $result = &js_ready($result);
+ $result = &js_ready($result);
}
if ($args->{'html_encode'}) {
- $result = &html_encode($result);
+ $result = &html_encode($result);
+ }
+
+ #Breadcrumbs
+ if (exists($args->{'bread_crumbs'}) or exists($args->{'bread_crumbs_component'})) {
+ &Apache::lonhtmlcommon::clear_breadcrumbs();
+ #if any br links exists, add them to the breadcrumbs
+ if (exists($args->{'bread_crumbs'}) and ref($args->{'bread_crumbs'}) eq 'ARRAY') {
+ foreach my $crumb (@{$args->{'bread_crumbs'}}){
+ &Apache::lonhtmlcommon::add_breadcrumb($crumb);
+ }
+ }
+
+ #if bread_crumbs_component exists show it as headline else show only the breadcrumbs
+ if(exists($args->{'bread_crumbs_component'})){
+ $result .= &Apache::lonhtmlcommon::breadcrumbs($args->{'bread_crumbs_component'});
+ }else{
+ $result .= &Apache::lonhtmlcommon::breadcrumbs();
+ }
}
return $result;
}
@@ -3913,8 +6292,6 @@ sub start_page {
=pod
-=over 4
-
=item * &head()
Returns a complete section for LON-CAPA web pages.
@@ -3926,6 +6303,11 @@ Inputs: $args - additional optio
a html attribute
frameset -> if true will start with a
rather than
+ 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
@@ -3945,7 +6327,7 @@ sub end_page {
if ($args->{'frameset'}) {
$result .= ' ';
} else {
- $result .= &endbodytag();
+ $result .= &endbodytag($args);
}
$result .= "\n";
@@ -4017,23 +6399,30 @@ sub simple_error_page {
}
{
- my $row_count;
+ my @row_count;
sub start_data_table {
my ($add_class) = @_;
my $css_class = (join(' ','LC_data_table',$add_class));
- undef($row_count);
+ unshift(@row_count,0);
return ''."\n";
}
sub end_data_table {
- undef($row_count);
+ shift(@row_count);
return '
'."\n";;
}
sub start_data_table_row {
my ($add_class) = @_;
- $row_count++;
- my $css_class = ($row_count % 2)?'':'LC_even_row';
+ $row_count[0]++;
+ my $css_class = ($row_count[0] % 2)?'LC_odd_row':'LC_even_row';
+ $css_class = (join(' ',$css_class,$add_class));
+ return ''."\n";;
+ }
+
+ sub continue_data_table_row {
+ my ($add_class) = @_;
+ my $css_class = ($row_count[0] % 2)?'LC_odd_row':'LC_even_row';
$css_class = (join(' ',$css_class,$add_class));
return ' '."\n";;
}
@@ -4043,7 +6432,7 @@ sub simple_error_page {
}
sub start_data_table_empty_row {
- $row_count++;
+# $row_count[0]++;
return ' '."\n";;
}
@@ -4060,10 +6449,61 @@ sub simple_error_page {
}
}
+=pod
+
+=item * &inhibit_menu_check($arg)
+
+Checks for a inhibitmenu state and generates output to preserve it
+
+Inputs: $arg - can be any of
+ - undef - in which case the return value is a string
+ to add into arguments list of a uri
+ - 'input' - in which case the return value is a HTML
+