version 1.1193, 2014/06/16 05:12:31
|
version 1.1348, 2020/10/01 10:16:33
|
Line 71 use Apache::lonuserutils();
|
Line 71 use Apache::lonuserutils();
|
use Apache::lonuserstate(); |
use Apache::lonuserstate(); |
use Apache::courseclassifier(); |
use Apache::courseclassifier(); |
use LONCAPA qw(:DEFAULT :match); |
use LONCAPA qw(:DEFAULT :match); |
|
use LONCAPA::LWPReq; |
|
use HTTP::Request; |
use DateTime::TimeZone; |
use DateTime::TimeZone; |
use DateTime::Locale::Catalog; |
use DateTime::Locale; |
|
use Encode(); |
use Text::Aspell; |
use Text::Aspell; |
use Authen::Captcha; |
use Authen::Captcha; |
use Captcha::reCAPTCHA; |
use Captcha::reCAPTCHA; |
|
use JSON::DWIW; |
use Crypt::DES; |
use Crypt::DES; |
use DynaLoader; # for Crypt::DES version |
use DynaLoader; # for Crypt::DES version |
|
use MIME::Lite; |
|
use MIME::Types; |
|
use File::Copy(); |
|
use File::Path(); |
|
use String::CRC32(); |
|
use Short::URL(); |
|
|
# ---------------------------------------------- Designs |
# ---------------------------------------------- Designs |
use vars qw(%defaultdesign); |
use vars qw(%defaultdesign); |
Line 193 BEGIN {
|
Line 203 BEGIN {
|
{ |
{ |
my $langtabfile = $Apache::lonnet::perlvar{'lonTabDir'}. |
my $langtabfile = $Apache::lonnet::perlvar{'lonTabDir'}. |
'/language.tab'; |
'/language.tab'; |
if ( open(my $fh,"<$langtabfile") ) { |
if ( open(my $fh,'<',$langtabfile) ) { |
while (my $line = <$fh>) { |
while (my $line = <$fh>) { |
next if ($line=~/^\#/); |
next if ($line=~/^\#/); |
chomp($line); |
chomp($line); |
Line 215 BEGIN {
|
Line 225 BEGIN {
|
{ |
{ |
my $copyrightfile = $Apache::lonnet::perlvar{'lonIncludes'}. |
my $copyrightfile = $Apache::lonnet::perlvar{'lonIncludes'}. |
'/copyright.tab'; |
'/copyright.tab'; |
if ( open (my $fh,"<$copyrightfile") ) { |
if ( open (my $fh,'<',$copyrightfile) ) { |
while (my $line = <$fh>) { |
while (my $line = <$fh>) { |
next if ($line=~/^\#/); |
next if ($line=~/^\#/); |
chomp($line); |
chomp($line); |
Line 229 BEGIN {
|
Line 239 BEGIN {
|
{ |
{ |
my $sourcecopyrightfile = $Apache::lonnet::perlvar{'lonIncludes'}. |
my $sourcecopyrightfile = $Apache::lonnet::perlvar{'lonIncludes'}. |
'/source_copyright.tab'; |
'/source_copyright.tab'; |
if ( open (my $fh,"<$sourcecopyrightfile") ) { |
if ( open (my $fh,'<',$sourcecopyrightfile) ) { |
while (my $line = <$fh>) { |
while (my $line = <$fh>) { |
next if ($line =~ /^\#/); |
next if ($line =~ /^\#/); |
chomp($line); |
chomp($line); |
Line 243 BEGIN {
|
Line 253 BEGIN {
|
# -------------------------------------------------------------- default domain designs |
# -------------------------------------------------------------- default domain designs |
my $designdir=$Apache::lonnet::perlvar{'lonTabDir'}.'/lonDomColors'; |
my $designdir=$Apache::lonnet::perlvar{'lonTabDir'}.'/lonDomColors'; |
my $designfile = $designdir.'/default.tab'; |
my $designfile = $designdir.'/default.tab'; |
if ( open (my $fh,"<$designfile") ) { |
if ( open (my $fh,'<',$designfile) ) { |
while (my $line = <$fh>) { |
while (my $line = <$fh>) { |
next if ($line =~ /^\#/); |
next if ($line =~ /^\#/); |
chomp($line); |
chomp($line); |
Line 257 BEGIN {
|
Line 267 BEGIN {
|
{ |
{ |
my $categoryfile = $Apache::lonnet::perlvar{'lonTabDir'}. |
my $categoryfile = $Apache::lonnet::perlvar{'lonTabDir'}. |
'/filecategories.tab'; |
'/filecategories.tab'; |
if ( open (my $fh,"<$categoryfile") ) { |
if ( open (my $fh,'<',$categoryfile) ) { |
while (my $line = <$fh>) { |
while (my $line = <$fh>) { |
next if ($line =~ /^\#/); |
next if ($line =~ /^\#/); |
chomp($line); |
chomp($line); |
my ($extension,$category)=(split(/\s+/,$line,2)); |
my ($extension,$category)=(split(/\s+/,$line,2)); |
push @{$category_extensions{lc($category)}},$extension; |
push(@{$category_extensions{lc($category)}},$extension); |
} |
} |
close($fh); |
close($fh); |
} |
} |
Line 272 BEGIN {
|
Line 282 BEGIN {
|
{ |
{ |
my $typesfile = $Apache::lonnet::perlvar{'lonTabDir'}. |
my $typesfile = $Apache::lonnet::perlvar{'lonTabDir'}. |
'/filetypes.tab'; |
'/filetypes.tab'; |
if ( open (my $fh,"<$typesfile") ) { |
if ( open (my $fh,'<',$typesfile) ) { |
while (my $line = <$fh>) { |
while (my $line = <$fh>) { |
next if ($line =~ /^\#/); |
next if ($line =~ /^\#/); |
chomp($line); |
chomp($line); |
Line 425 sub studentbrowser_javascript {
|
Line 435 sub studentbrowser_javascript {
|
<script type="text/javascript" language="Javascript"> |
<script type="text/javascript" language="Javascript"> |
// <![CDATA[ |
// <![CDATA[ |
var stdeditbrowser; |
var stdeditbrowser; |
function openstdbrowser(formname,uname,udom,clicker,roleflag,ignorefilter,courseadvonly) { |
function openstdbrowser(formname,uname,udom,clicker,roleflag,ignorefilter,courseadv) { |
var url = '/adm/pickstudent?'; |
var url = '/adm/pickstudent?'; |
var filter; |
var filter; |
if (!ignorefilter) { |
if (!ignorefilter) { |
Line 440 sub studentbrowser_javascript {
|
Line 450 sub studentbrowser_javascript {
|
'&udomelement='+udom+ |
'&udomelement='+udom+ |
'&clicker='+clicker; |
'&clicker='+clicker; |
if (roleflag) { url+="&roles=1"; } |
if (roleflag) { url+="&roles=1"; } |
if (courseadvonly) { url+="&courseadvonly=1"; } |
if (courseadv == 'condition') { |
|
if (document.getElementById('courseadv')) { |
|
courseadv = document.getElementById('courseadv').value; |
|
} |
|
} |
|
if ((courseadv == 'only') || (courseadv == 'none')) { url+="&courseadv="+courseadv; } |
var title = 'Student_Browser'; |
var title = 'Student_Browser'; |
var options = 'scrollbars=1,resizable=1,menubar=0'; |
var options = 'scrollbars=1,resizable=1,menubar=0'; |
options += ',width=700,height=600'; |
options += ',width=700,height=600'; |
Line 472 ENDRESBRW
|
Line 487 ENDRESBRW
|
} |
} |
|
|
sub selectstudent_link { |
sub selectstudent_link { |
my ($form,$unameele,$udomele,$courseadvonly,$clickerid)=@_; |
my ($form,$unameele,$udomele,$courseadv,$clickerid)=@_; |
my $callargs = "'".&Apache::lonhtmlcommon::entity_encode($form)."','". |
my $callargs = "'".&Apache::lonhtmlcommon::entity_encode($form)."','". |
&Apache::lonhtmlcommon::entity_encode($unameele)."','". |
&Apache::lonhtmlcommon::entity_encode($unameele)."','". |
&Apache::lonhtmlcommon::entity_encode($udomele)."'"; |
&Apache::lonhtmlcommon::entity_encode($udomele)."'"; |
Line 483 sub selectstudent_link {
|
Line 498 sub selectstudent_link {
|
return ''; |
return ''; |
} |
} |
$callargs.=",'".&Apache::lonhtmlcommon::entity_encode($clickerid)."'"; |
$callargs.=",'".&Apache::lonhtmlcommon::entity_encode($clickerid)."'"; |
if ($courseadvonly) { |
if ($courseadv eq 'only') { |
$callargs .= ",'',1,1"; |
$callargs .= ",'',1,'$courseadv'"; |
|
} elsif ($courseadv eq 'none') { |
|
$callargs .= ",'','','$courseadv'"; |
|
} elsif ($courseadv eq 'condition') { |
|
$callargs .= ",'','','$courseadv'"; |
} |
} |
return '<span class="LC_nobreak">'. |
return '<span class="LC_nobreak">'. |
'<a href="javascript:openstdbrowser('.$callargs.');">'. |
'<a href="javascript:openstdbrowser('.$callargs.');">'. |
Line 535 ENDAUTHORBRW
|
Line 554 ENDAUTHORBRW
|
|
|
sub coursebrowser_javascript { |
sub coursebrowser_javascript { |
my ($domainfilter,$sec_element,$formname,$role_element,$crstype, |
my ($domainfilter,$sec_element,$formname,$role_element,$crstype, |
$credits_element) = @_; |
$credits_element,$instcode) = @_; |
my $wintitle = 'Course_Browser'; |
my $wintitle = 'Course_Browser'; |
if ($crstype eq 'Community') { |
if ($crstype eq 'Community') { |
$wintitle = 'Community_Browser'; |
$wintitle = 'Community_Browser'; |
Line 586 sub coursebrowser_javascript {
|
Line 605 sub coursebrowser_javascript {
|
var ownername = document.forms[formid].ccuname.value; |
var ownername = document.forms[formid].ccuname.value; |
var ownerdom = document.forms[formid].ccdomain.options[document.forms[formid].ccdomain.selectedIndex].value; |
var ownerdom = document.forms[formid].ccdomain.options[document.forms[formid].ccdomain.selectedIndex].value; |
url += '&cloner='+ownername+':'+ownerdom; |
url += '&cloner='+ownername+':'+ownerdom; |
|
if (type == 'Course') { |
|
url += '&crscode='+document.forms[formid].crscode.value; |
|
} |
|
} |
|
if (formname == 'requestcrs') { |
|
url += '&crsdom=$domainfilter&crscode=$instcode'; |
} |
} |
if (multflag !=null && multflag != '') { |
if (multflag !=null && multflag != '') { |
url += '&multiple='+multflag; |
url += '&multiple='+multflag; |
Line 870 sub selectcourse_link {
|
Line 895 sub selectcourse_link {
|
my $linktext = &mt('Select Course'); |
my $linktext = &mt('Select Course'); |
if ($selecttype eq 'Community') { |
if ($selecttype eq 'Community') { |
$linktext = &mt('Select Community'); |
$linktext = &mt('Select Community'); |
|
} elsif ($selecttype eq 'Placement') { |
|
$linktext = &mt('Select Placement Test'); |
} elsif ($selecttype eq 'Course/Community') { |
} elsif ($selecttype eq 'Course/Community') { |
$linktext = &mt('Select Course/Community'); |
$linktext = &mt('Select Course/Community'); |
$type = ''; |
$type = ''; |
Line 930 ENDSCRT
|
Line 957 ENDSCRT
|
} |
} |
|
|
sub select_timezone { |
sub select_timezone { |
my ($name,$selected,$onchange,$includeempty)=@_; |
my ($name,$selected,$onchange,$includeempty,$disabled)=@_; |
my $output='<select name="'.$name.'" '.$onchange.'>'."\n"; |
my $output='<select name="'.$name.'" '.$onchange.$disabled.'>'."\n"; |
if ($includeempty) { |
if ($includeempty) { |
$output .= '<option value=""'; |
$output .= '<option value=""'; |
if (($selected eq '') || ($selected eq 'local')) { |
if (($selected eq '') || ($selected eq 'local')) { |
Line 952 sub select_timezone {
|
Line 979 sub select_timezone {
|
} |
} |
|
|
sub select_datelocale { |
sub select_datelocale { |
my ($name,$selected,$onchange,$includeempty)=@_; |
my ($name,$selected,$onchange,$includeempty,$disabled)=@_; |
my $output='<select name="'.$name.'" '.$onchange.'>'."\n"; |
my $output='<select name="'.$name.'" '.$onchange.$disabled.'>'."\n"; |
if ($includeempty) { |
if ($includeempty) { |
$output .= '<option value=""'; |
$output .= '<option value=""'; |
if ($selected eq '') { |
if ($selected eq '') { |
Line 961 sub select_datelocale {
|
Line 988 sub select_datelocale {
|
} |
} |
$output .= '> </option>'; |
$output .= '> </option>'; |
} |
} |
|
my @languages = &Apache::lonlocal::preferred_languages(); |
my (@possibles,%locale_names); |
my (@possibles,%locale_names); |
my @locales = DateTime::Locale::Catalog::Locales; |
my @locales = DateTime::Locale->ids(); |
foreach my $locale (@locales) { |
foreach my $id (@locales) { |
if (ref($locale) eq 'HASH') { |
if ($id ne '') { |
my $id = $locale->{'id'}; |
my ($en_terr,$native_terr); |
if ($id ne '') { |
my $loc = DateTime::Locale->load($id); |
my $en_terr = $locale->{'en_territory'}; |
if (ref($loc)) { |
my $native_terr = $locale->{'native_territory'}; |
$en_terr = $loc->name(); |
my @languages = &Apache::lonlocal::preferred_languages(); |
$native_terr = $loc->native_name(); |
if (grep(/^en$/,@languages) || !@languages) { |
if (grep(/^en$/,@languages) || !@languages) { |
if ($en_terr ne '') { |
if ($en_terr ne '') { |
$locale_names{$id} = '('.$en_terr.')'; |
$locale_names{$id} = '('.$en_terr.')'; |
Line 983 sub select_datelocale {
|
Line 1011 sub select_datelocale {
|
$locale_names{$id} = '('.$en_terr.')'; |
$locale_names{$id} = '('.$en_terr.')'; |
} |
} |
} |
} |
push (@possibles,$id); |
$locale_names{$id} = Encode::encode('UTF-8',$locale_names{$id}); |
} |
push(@possibles,$id); |
|
} |
} |
} |
} |
} |
foreach my $item (sort(@possibles)) { |
foreach my $item (sort(@possibles)) { |
Line 994 sub select_datelocale {
|
Line 1023 sub select_datelocale {
|
} |
} |
$output.=">$item"; |
$output.=">$item"; |
if ($locale_names{$item} ne '') { |
if ($locale_names{$item} ne '') { |
$output.=" $locale_names{$item}</option>\n"; |
$output.=' '.$locale_names{$item}; |
} |
} |
$output.="</option>\n"; |
$output.="</option>\n"; |
} |
} |
Line 1003 sub select_datelocale {
|
Line 1032 sub select_datelocale {
|
} |
} |
|
|
sub select_language { |
sub select_language { |
my ($name,$selected,$includeempty) = @_; |
my ($name,$selected,$includeempty,$noedit) = @_; |
my %langchoices; |
my %langchoices; |
if ($includeempty) { |
if ($includeempty) { |
%langchoices = ('' => 'No language preference'); |
%langchoices = ('' => 'No language preference'); |
Line 1015 sub select_language {
|
Line 1044 sub select_language {
|
} |
} |
} |
} |
%langchoices = &Apache::lonlocal::texthash(%langchoices); |
%langchoices = &Apache::lonlocal::texthash(%langchoices); |
return &select_form($selected,$name,\%langchoices); |
return &select_form($selected,$name,\%langchoices,undef,$noedit); |
} |
} |
|
|
=pod |
=pod |
Line 1039 sub list_languages {
|
Line 1068 sub list_languages {
|
if ($code) { |
if ($code) { |
my $selector = $supported_codes{$id}; |
my $selector = $supported_codes{$id}; |
my $description = &plainlanguagedescription($id); |
my $description = &plainlanguagedescription($id); |
push (@lang_choices, [$selector, $description]); |
push(@lang_choices, [$selector, $description]); |
} |
} |
} |
} |
return \@lang_choices; |
return \@lang_choices; |
Line 1079 linked_select_forms takes the following
|
Line 1108 linked_select_forms takes the following
|
=item * $onchangesecond, additional javascript call to execute for an onchange |
=item * $onchangesecond, additional javascript call to execute for an onchange |
event for the second <select> tag |
event for the second <select> tag |
|
|
|
=item * $suffix, to differentiate separate uses of select2data javascript |
|
objects in a page. |
|
|
=back |
=back |
|
|
Below is an example of such a hash. Only the 'text', 'default', and |
Below is an example of such a hash. Only the 'text', 'default', and |
Line 1133 sub linked_select_forms {
|
Line 1165 sub linked_select_forms {
|
$hashref, |
$hashref, |
$menuorder, |
$menuorder, |
$onchangefirst, |
$onchangefirst, |
$onchangesecond |
$onchangesecond, |
|
$suffix |
) = @_; |
) = @_; |
my $second = "document.$formname.$secondselectname"; |
my $second = "document.$formname.$secondselectname"; |
my $first = "document.$formname.$firstselectname"; |
my $first = "document.$formname.$firstselectname"; |
Line 1141 sub linked_select_forms {
|
Line 1174 sub linked_select_forms {
|
my $result = ''; |
my $result = ''; |
$result.='<script type="text/javascript" language="JavaScript">'."\n"; |
$result.='<script type="text/javascript" language="JavaScript">'."\n"; |
$result.="// <![CDATA[\n"; |
$result.="// <![CDATA[\n"; |
$result.="var select2data = new Object();\n"; |
$result.="var select2data${suffix} = new Object();\n"; |
$" = '","'; |
$" = '","'; |
my $debug = ''; |
my $debug = ''; |
foreach my $s1 (sort(keys(%$hashref))) { |
foreach my $s1 (sort(keys(%$hashref))) { |
$result.="select2data.d_$s1 = new Object();\n"; |
$result.="select2data${suffix}['d_$s1'] = new Object();\n"; |
$result.="select2data.d_$s1.def = new String('". |
$result.="select2data${suffix}['d_$s1'].def = new String('". |
$hashref->{$s1}->{'default'}."');\n"; |
$hashref->{$s1}->{'default'}."');\n"; |
$result.="select2data.d_$s1.values = new Array("; |
$result.="select2data${suffix}['d_$s1'].values = new Array("; |
my @s2values = sort(keys( %{ $hashref->{$s1}->{'select2'} } )); |
my @s2values = sort(keys( %{ $hashref->{$s1}->{'select2'} } )); |
if (ref($hashref->{$s1}->{'order'}) eq 'ARRAY') { |
if (ref($hashref->{$s1}->{'order'}) eq 'ARRAY') { |
@s2values = @{$hashref->{$s1}->{'order'}}; |
@s2values = @{$hashref->{$s1}->{'order'}}; |
} |
} |
$result.="\"@s2values\");\n"; |
$result.="\"@s2values\");\n"; |
$result.="select2data.d_$s1.texts = new Array("; |
$result.="select2data${suffix}['d_$s1'].texts = new Array("; |
my @s2texts; |
my @s2texts; |
foreach my $value (@s2values) { |
foreach my $value (@s2values) { |
push @s2texts, $hashref->{$s1}->{'select2'}->{$value}; |
push(@s2texts, $hashref->{$s1}->{'select2'}->{$value}); |
} |
} |
$result.="\"@s2texts\");\n"; |
$result.="\"@s2texts\");\n"; |
} |
} |
$"=' '; |
$"=' '; |
$result.= <<"END"; |
$result.= <<"END"; |
|
|
function select1_changed() { |
function select1${suffix}_changed() { |
// Determine new choice |
// Determine new choice |
var newvalue = "d_" + $first.value; |
var newvalue = "d_" + $first.options[$first.selectedIndex].value; |
// update select2 |
// update select2 |
var values = select2data[newvalue].values; |
var values = select2data${suffix}[newvalue].values; |
var texts = select2data[newvalue].texts; |
var texts = select2data${suffix}[newvalue].texts; |
var select2def = select2data[newvalue].def; |
var select2def = select2data${suffix}[newvalue].def; |
var i; |
var i; |
// out with the old |
// out with the old |
for (i = 0; i < $second.options.length; i++) { |
$second.options.length = 0; |
$second.options[i] = null; |
// in with the new |
} |
|
// in with the nuclear |
|
for (i=0;i<values.length; i++) { |
for (i=0;i<values.length; i++) { |
$second.options[i] = new Option(values[i]); |
$second.options[i] = new Option(values[i]); |
$second.options[i].value = values[i]; |
$second.options[i].value = values[i]; |
Line 1190 function select1_changed() {
|
Line 1221 function select1_changed() {
|
</script> |
</script> |
END |
END |
# output the initial values for the selection lists |
# output the initial values for the selection lists |
$result .= "<select size=\"1\" name=\"$firstselectname\" onchange=\"select1_changed();$onchangefirst\">\n"; |
$result .= "<select size=\"1\" name=\"$firstselectname\" onchange=\"select1${suffix}_changed();$onchangefirst\">\n"; |
my @order = sort(keys(%{$hashref})); |
my @order = sort(keys(%{$hashref})); |
if (ref($menuorder) eq 'ARRAY') { |
if (ref($menuorder) eq 'ARRAY') { |
@order = @{$menuorder}; |
@order = @{$menuorder}; |
Line 1275 sub help_open_topic {
|
Line 1306 sub help_open_topic {
|
} |
} |
|
|
# Add the text |
# Add the text |
|
my $target = ' target="_top"'; |
|
if (($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) { |
|
$target = ''; |
|
} |
if ($text ne "") { |
if ($text ne "") { |
$template.='<span class="LC_help_open_topic">' |
$template.='<span class="LC_help_open_topic">' |
.'<a target="_top" href="'.$link.'">' |
.'<a'.$target.' href="'.$link.'">' |
.$text.'</a>'; |
.$text.'</a>'; |
} |
} |
|
|
Line 1287 sub help_open_topic {
|
Line 1322 sub help_open_topic {
|
if ($imgid ne '') { |
if ($imgid ne '') { |
$imgid = ' id="'.$imgid.'"'; |
$imgid = ' id="'.$imgid.'"'; |
} |
} |
$template.=' <a target="_top" href="'.$link.'" title="'.$title.'">' |
$template.=' <a'.$target.' href="'.$link.'" title="'.$title.'">' |
.'<img src="'.$helpicon.'" border="0"' |
.'<img src="'.$helpicon.'" border="0"' |
.' alt="'.&mt('Help: [_1]',$topic).'"' |
.' alt="'.&mt('Help: [_1]',$topic).'"' |
.' title="'.$title.'" style="vertical-align:middle;"'.$imgid |
.' title="'.$title.'" style="vertical-align:middle;"'.$imgid |
Line 1480 sub help_open_bug {
|
Line 1515 sub help_open_bug {
|
{ |
{ |
$link = $url; |
$link = $url; |
} |
} |
|
|
|
my $target = ' target="_top"'; |
|
if (($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) { |
|
$target = ''; |
|
} |
# Add the text |
# Add the text |
if ($text ne "") |
if ($text ne "") |
{ |
{ |
$template .= |
$template .= |
"<table bgcolor='#AA3333' cellspacing='1' cellpadding='1' border='0'><tr>". |
"<table bgcolor='#AA3333' cellspacing='1' cellpadding='1' border='0'><tr>". |
"<td bgcolor='#FF5555'><a target=\"_top\" href=\"$link\"><span style=\"color:#FFFFFF;font-size:10pt;\">$text</span></a>"; |
"<td bgcolor='#FF5555'><a".$target." href=\"$link\"><span style=\"color:#FFFFFF;font-size:10pt;\">$text</span></a>"; |
} |
} |
|
|
# Add the graphic |
# Add the graphic |
my $title = &mt('Report a Bug'); |
my $title = &mt('Report a Bug'); |
my $bugicon=&lonhttpdurl("/adm/lonMisc/smallBug.gif"); |
my $bugicon=&lonhttpdurl("/adm/lonMisc/smallBug.gif"); |
$template .= <<"ENDTEMPLATE"; |
$template .= <<"ENDTEMPLATE"; |
<a target="_top" href="$link" title="$title"><img src="$bugicon" border="0" alt="(Bug: $topic)" /></a> |
<a$target href="$link" title="$title"><img src="$bugicon" border="0" alt="(Bug: $topic)" /></a> |
ENDTEMPLATE |
ENDTEMPLATE |
if ($text ne '') { $template.='</td></tr></table>' }; |
if ($text ne '') { $template.='</td></tr></table>' }; |
return $template; |
return $template; |
Line 1757 RESIZE
|
Line 1797 RESIZE
|
|
|
} |
} |
|
|
|
sub colorfuleditor_js { |
|
my $browse_or_search; |
|
my $respath; |
|
my ($cnum,$cdom) = &crsauthor_url(); |
|
if ($cnum) { |
|
$respath = "/res/$cdom/$cnum/"; |
|
my %js_lt = &Apache::lonlocal::texthash( |
|
sunm => 'Sub-directory name', |
|
save => 'Save page to make this permanent', |
|
); |
|
&js_escape(\%js_lt); |
|
$browse_or_search = <<"END"; |
|
|
|
function toggleChooser(form,element,titleid,only,search) { |
|
var disp = 'none'; |
|
if (document.getElementById('chooser_'+element)) { |
|
var curr = document.getElementById('chooser_'+element).style.display; |
|
if (curr == 'none') { |
|
disp='inline'; |
|
if (form.elements['chooser_'+element].length) { |
|
for (var i=0; i<form.elements['chooser_'+element].length; i++) { |
|
form.elements['chooser_'+element][i].checked = false; |
|
} |
|
} |
|
toggleResImport(form,element); |
|
} |
|
document.getElementById('chooser_'+element).style.display = disp; |
|
} |
|
} |
|
|
|
function toggleCrsFile(form,element,numdirs) { |
|
if (document.getElementById('chooser_'+element+'_crsres')) { |
|
var curr = document.getElementById('chooser_'+element+'_crsres').style.display; |
|
if (curr == 'none') { |
|
if (numdirs) { |
|
form.elements['coursepath_'+element].selectedIndex = 0; |
|
if (numdirs > 1) { |
|
window['select1'+element+'_changed'](); |
|
} |
|
} |
|
} |
|
document.getElementById('chooser_'+element+'_crsres').style.display = 'block'; |
|
|
|
} |
|
if (document.getElementById('chooser_'+element+'_upload')) { |
|
document.getElementById('chooser_'+element+'_upload').style.display = 'none'; |
|
if (document.getElementById('uploadcrsres_'+element)) { |
|
document.getElementById('uploadcrsres_'+element).value = ''; |
|
} |
|
} |
|
return; |
|
} |
|
|
|
function toggleCrsUpload(form,element,numcrsdirs) { |
|
if (document.getElementById('chooser_'+element+'_crsres')) { |
|
document.getElementById('chooser_'+element+'_crsres').style.display = 'none'; |
|
} |
|
if (document.getElementById('chooser_'+element+'_upload')) { |
|
var curr = document.getElementById('chooser_'+element+'_upload').style.display; |
|
if (curr == 'none') { |
|
if (numcrsdirs) { |
|
form.elements['crsauthorpath_'+element].selectedIndex = 0; |
|
form.elements['newsubdir_'+element][0].checked = true; |
|
toggleNewsubdir(form,element); |
|
} |
|
} |
|
document.getElementById('chooser_'+element+'_upload').style.display = 'block'; |
|
} |
|
return; |
|
} |
|
|
|
function toggleResImport(form,element) { |
|
var choices = new Array('crsres','upload'); |
|
for (var i=0; i<choices.length; i++) { |
|
if (document.getElementById('chooser_'+element+'_'+choices[i])) { |
|
document.getElementById('chooser_'+element+'_'+choices[i]).style.display = 'none'; |
|
} |
|
} |
|
} |
|
|
|
function toggleNewsubdir(form,element) { |
|
var newsub = form.elements['newsubdir_'+element]; |
|
if (newsub) { |
|
if (newsub.length) { |
|
for (var j=0; j<newsub.length; j++) { |
|
if (newsub[j].checked) { |
|
if (document.getElementById('newsubdirname_'+element)) { |
|
if (newsub[j].value == '1') { |
|
document.getElementById('newsubdirname_'+element).type = "text"; |
|
if (document.getElementById('newsubdir_'+element)) { |
|
document.getElementById('newsubdir_'+element).innerHTML = '<br />$js_lt{sunm}'; |
|
} |
|
} else { |
|
document.getElementById('newsubdirname_'+element).type = "hidden"; |
|
document.getElementById('newsubdirname_'+element).value = ""; |
|
document.getElementById('newsubdir_'+element).innerHTML = ""; |
|
} |
|
} |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
function updateCrsFile(form,element) { |
|
var directory = form.elements['coursepath_'+element]; |
|
var filename = form.elements['coursefile_'+element]; |
|
var path = directory.options[directory.selectedIndex].value; |
|
var file = filename.options[filename.selectedIndex].value; |
|
form.elements[element].value = '$respath'; |
|
if (path == '/') { |
|
form.elements[element].value += file; |
|
} else { |
|
form.elements[element].value += path+'/'+file; |
|
} |
|
unClean(); |
|
if (document.getElementById('previewimg_'+element)) { |
|
document.getElementById('previewimg_'+element).src = form.elements[element].value; |
|
var newsrc = document.getElementById('previewimg_'+element).src; |
|
} |
|
if (document.getElementById('showimg_'+element)) { |
|
document.getElementById('showimg_'+element).innerHTML = '($js_lt{save})'; |
|
} |
|
toggleChooser(form,element); |
|
return; |
|
} |
|
|
|
function uploadDone(suffix,name) { |
|
if (name) { |
|
document.forms["lonhomework"].elements[suffix].value = name; |
|
unClean(); |
|
toggleChooser(document.forms["lonhomework"],suffix); |
|
} |
|
} |
|
|
|
\$(document).ready(function(){ |
|
|
|
\$(document).delegate('form :submit', 'click', function( event ) { |
|
if ( \$( this ).hasClass( "LC_uploadcrsres" ) ) { |
|
var buttonId = this.id; |
|
var suffix = buttonId.toString(); |
|
suffix = suffix.replace(/^crsupload_/,''); |
|
event.preventDefault(); |
|
document.lonhomework.target = 'crsupload_target_'+suffix; |
|
document.lonhomework.action = '/adm/coursepub?LC_uploadcrsres='+suffix; |
|
\$(this.form).submit(); |
|
document.lonhomework.target = ''; |
|
if (document.getElementById('crsuploadto_'+suffix)) { |
|
document.lonhomework.action = document.getElementById('crsuploadto_'+suffix).value; |
|
} |
|
return false; |
|
} |
|
}); |
|
}); |
|
END |
|
} |
|
return <<"COLORFULEDIT" |
|
<script type="text/javascript"> |
|
// <![CDATA[> |
|
function fold_box(curDepth, lastresource){ |
|
|
|
// we need a list because there can be several blocks you need to fold in one tag |
|
var block = document.getElementsByName('foldblock_'+curDepth); |
|
// but there is only one folding button per tag |
|
var foldbutton = document.getElementById('folding_btn_'+curDepth); |
|
|
|
if(block.item(0).style.display == 'none'){ |
|
|
|
foldbutton.value = '@{[&mt("Hide")]}'; |
|
for (i = 0; i < block.length; i++){ |
|
block.item(i).style.display = ''; |
|
} |
|
}else{ |
|
|
|
foldbutton.value = '@{[&mt("Show")]}'; |
|
for (i = 0; i < block.length; i++){ |
|
// block.item(i).style.visibility = 'collapse'; |
|
block.item(i).style.display = 'none'; |
|
} |
|
}; |
|
saveState(lastresource); |
|
} |
|
|
|
function saveState (lastresource) { |
|
|
|
var tag_list = getTagList(); |
|
if(tag_list != null){ |
|
var timestamp = new Date().getTime(); |
|
var key = lastresource; |
|
|
|
// the value pattern is: 'time;key1,value1;key2,value2; ... ' |
|
// starting with timestamp |
|
var value = timestamp+';'; |
|
|
|
// building the list of key-value pairs |
|
for(var i = 0; i < tag_list.length; i++){ |
|
value += tag_list[i]+','; |
|
value += document.getElementsByName(tag_list[i])[0].style.display+';'; |
|
} |
|
|
|
// only iterate whole storage if nothing to override |
|
if(localStorage.getItem(key) == null){ |
|
|
|
// prevent storage from growing large |
|
if(localStorage.length > 50){ |
|
var regex_getTimestamp = /^(?:\d)+;/; |
|
var oldest_timestamp = regex_getTimestamp.exec(localStorage.key(0)); |
|
var oldest_key; |
|
|
|
for(var i = 1; i < localStorage.length; i++){ |
|
if (regex_getTimestamp.exec(localStorage.key(i)) < oldest_timestamp) { |
|
oldest_key = localStorage.key(i); |
|
oldest_timestamp = regex_getTimestamp.exec(oldest_key); |
|
} |
|
} |
|
localStorage.removeItem(oldest_key); |
|
} |
|
} |
|
localStorage.setItem(key,value); |
|
} |
|
} |
|
|
|
// restore folding status of blocks (on page load) |
|
function restoreState (lastresource) { |
|
if(localStorage.getItem(lastresource) != null){ |
|
var key = lastresource; |
|
var value = localStorage.getItem(key); |
|
var regex_delTimestamp = /^\d+;/; |
|
|
|
value.replace(regex_delTimestamp, ''); |
|
|
|
var valueArr = value.split(';'); |
|
var pairs; |
|
var elements; |
|
for (var i = 0; i < valueArr.length; i++){ |
|
pairs = valueArr[i].split(','); |
|
elements = document.getElementsByName(pairs[0]); |
|
|
|
for (var j = 0; j < elements.length; j++){ |
|
elements[j].style.display = pairs[1]; |
|
if (pairs[1] == "none"){ |
|
var regex_id = /([_\\d]+)\$/; |
|
regex_id.exec(pairs[0]); |
|
document.getElementById("folding_btn"+RegExp.\$1).value = "Show"; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
function getTagList () { |
|
|
|
var stringToSearch = document.lonhomework.innerHTML; |
|
|
|
var ret = new Array(); |
|
var regex_findBlock = /(foldblock_.*?)"/g; |
|
var tag_list = stringToSearch.match(regex_findBlock); |
|
|
|
if(tag_list != null){ |
|
for(var i = 0; i < tag_list.length; i++){ |
|
ret.push(tag_list[i].replace(/"/, '')); |
|
} |
|
} |
|
return ret; |
|
} |
|
|
|
function saveScrollPosition (resource) { |
|
var tag_list = getTagList(); |
|
|
|
// we dont always want to jump to the first block |
|
// 170 is roughly above the "Problem Editing" header. we just want to save if the user scrolled down further than this |
|
if(\$(window).scrollTop() > 170){ |
|
if(tag_list != null){ |
|
var result; |
|
for(var i = 0; i < tag_list.length; i++){ |
|
if(isElementInViewport(tag_list[i])){ |
|
result += tag_list[i]+';'; |
|
} |
|
} |
|
sessionStorage.setItem('anchor_'+resource, result); |
|
} |
|
} else { |
|
// we dont need to save zero, just delete the item to leave everything tidy |
|
sessionStorage.removeItem('anchor_'+resource); |
|
} |
|
} |
|
|
|
function restoreScrollPosition(resource){ |
|
|
|
var elem = sessionStorage.getItem('anchor_'+resource); |
|
if(elem != null){ |
|
var tag_list = elem.split(';'); |
|
var elem_list; |
|
|
|
for(var i = 0; i < tag_list.length; i++){ |
|
elem_list = document.getElementsByName(tag_list[i]); |
|
|
|
if(elem_list.length > 0){ |
|
elem = elem_list[0]; |
|
break; |
|
} |
|
} |
|
elem.scrollIntoView(); |
|
} |
|
} |
|
|
|
function isElementInViewport(el) { |
|
|
|
// change to last element instead of first |
|
var elem = document.getElementsByName(el); |
|
var rect = elem[0].getBoundingClientRect(); |
|
|
|
return ( |
|
rect.top >= 0 && |
|
rect.left >= 0 && |
|
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */ |
|
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */ |
|
); |
|
} |
|
|
|
function autosize(depth){ |
|
var cmInst = window['cm'+depth]; |
|
var fitsizeButton = document.getElementById('fitsize'+depth); |
|
|
|
// is fixed size, switching to dynamic |
|
if (sessionStorage.getItem("autosized_"+depth) == null) { |
|
cmInst.setSize("","auto"); |
|
fitsizeButton.value = "@{[&mt('Fixed size')]}"; |
|
sessionStorage.setItem("autosized_"+depth, "yes"); |
|
|
|
// is dynamic size, switching to fixed |
|
} else { |
|
cmInst.setSize("","300px"); |
|
fitsizeButton.value = "@{[&mt('Dynamic size')]}"; |
|
sessionStorage.removeItem("autosized_"+depth); |
|
} |
|
} |
|
|
|
$browse_or_search |
|
|
|
// ]]> |
|
</script> |
|
COLORFULEDIT |
|
} |
|
|
|
sub xmleditor_js { |
|
return <<XMLEDIT |
|
<script type="text/javascript" src="/adm/jQuery/addons/jquery-scrolltofixed.js"></script> |
|
<script type="text/javascript"> |
|
// <![CDATA[> |
|
|
|
function saveScrollPosition (resource) { |
|
|
|
var scrollPos = \$(window).scrollTop(); |
|
sessionStorage.setItem(resource,scrollPos); |
|
} |
|
|
|
function restoreScrollPosition(resource){ |
|
|
|
var scrollPos = sessionStorage.getItem(resource); |
|
\$(window).scrollTop(scrollPos); |
|
} |
|
|
|
// unless internet explorer |
|
if (!(window.navigator.appName == "Microsoft Internet Explorer" && (document.documentMode || document.compatMode))){ |
|
|
|
\$(document).ready(function() { |
|
\$(".LC_edit_actionbar").scrollToFixed(\{zIndex: 100\}); |
|
}); |
|
} |
|
|
|
// inserts text at cursor position into codemirror (xml editor only) |
|
function insertText(text){ |
|
cm.focus(); |
|
var curPos = cm.getCursor(); |
|
cm.replaceRange(text.replace(/ESCAPEDSCRIPT/g,'script'), {line: curPos.line,ch: curPos.ch}); |
|
} |
|
// ]]> |
|
</script> |
|
XMLEDIT |
|
} |
|
|
|
sub insert_folding_button { |
|
my $curDepth = $Apache::lonxml::curdepth; |
|
my $lastresource = $env{'request.ambiguous'}; |
|
|
|
return "<input type=\"button\" id=\"folding_btn_$curDepth\" |
|
value=\"".&mt('Hide')."\" onclick=\"fold_box('$curDepth','$lastresource')\">"; |
|
} |
|
|
|
sub crsauthor_url { |
|
my ($url) = @_; |
|
if ($url eq '') { |
|
$url = $ENV{'REQUEST_URI'}; |
|
} |
|
my ($cnum,$cdom); |
|
if ($env{'request.course.id'}) { |
|
my ($audom,$auname) = ($url =~ m{^/priv/($match_domain)/($match_name)/}); |
|
if ($audom ne '' && $auname ne '') { |
|
if (($env{'course.'.$env{'request.course.id'}.'.num'} eq $auname) && |
|
($env{'course.'.$env{'request.course.id'}.'.domain'} eq $audom)) { |
|
$cnum = $auname; |
|
$cdom = $audom; |
|
} |
|
} |
|
} |
|
return ($cnum,$cdom); |
|
} |
|
|
|
sub import_crsauthor_form { |
|
my ($form,$firstselectname,$secondselectname,$onchangefirst,$only,$suffix,$disabled) = @_; |
|
return (0) unless ($env{'request.course.id'}); |
|
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
my $crshome = $env{'course.'.$env{'request.course.id'}.'.home'}; |
|
return (0) unless (($cnum ne '') && ($cdom ne '')); |
|
my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'}; |
|
my @ids=&Apache::lonnet::current_machine_ids(); |
|
my ($output,$is_home,$relpath,%subdirs,%files,%selimport_menus); |
|
|
|
if (grep(/^\Q$crshome\E$/,@ids)) { |
|
$is_home = 1; |
|
} |
|
$relpath = "/priv/$cdom/$cnum"; |
|
&Apache::lonnet::recursedirs($is_home,'priv',$londocroot,$relpath,'',\%subdirs,\%files); |
|
my %lt = &Apache::lonlocal::texthash ( |
|
fnam => 'Filename', |
|
dire => 'Directory', |
|
); |
|
my $numdirs = scalar(keys(%files)); |
|
my (%possexts,$singledir,@singledirfiles); |
|
if ($only) { |
|
map { $possexts{$_} = 1; } split(/\s*,\s*/,$only); |
|
} |
|
my (%nonemptydirs,$possdirs); |
|
if ($numdirs > 1) { |
|
my @order; |
|
foreach my $key (sort { lc($a) cmp lc($b) } (keys(%files))) { |
|
if (ref($files{$key}) eq 'HASH') { |
|
my $shown = $key; |
|
if ($key eq '') { |
|
$shown = '/'; |
|
} |
|
my @ordered = (); |
|
foreach my $file (sort { lc($a) cmp lc($b) } (keys(%{$files{$key}}))) { |
|
next if ($file =~ /\.rights$/); |
|
if ($only) { |
|
my ($ext) = ($file =~ /\.([^.]+)$/); |
|
unless ($possexts{lc($ext)}) { |
|
next; |
|
} |
|
} |
|
$selimport_menus{$key}->{'select2'}->{$file} = $file; |
|
push(@ordered,$file); |
|
} |
|
if (@ordered) { |
|
push(@order,$key); |
|
$nonemptydirs{$key} = 1; |
|
$selimport_menus{$key}->{'text'} = $shown; |
|
$selimport_menus{$key}->{'default'} = ''; |
|
$selimport_menus{$key}->{'select2'}->{''} = ''; |
|
$selimport_menus{$key}->{'order'} = \@ordered; |
|
} |
|
} |
|
} |
|
$possdirs = scalar(keys(%nonemptydirs)); |
|
if ($possdirs > 1) { |
|
my @order = sort { lc($a) cmp lc($b) } (keys(%nonemptydirs)); |
|
$output = $lt{'dire'}. |
|
&linked_select_forms($form,'<br />'. |
|
$lt{'fnam'},'', |
|
$firstselectname,$secondselectname, |
|
\%selimport_menus,\@order, |
|
$onchangefirst,'',$suffix).'<br />'; |
|
} elsif ($possdirs == 1) { |
|
$singledir = (keys(%nonemptydirs))[0]; |
|
if (ref($selimport_menus{$singledir}->{'order'}) eq 'ARRAY') { |
|
@singledirfiles = @{$selimport_menus{$singledir}->{'order'}}; |
|
} |
|
delete($selimport_menus{$singledir}); |
|
} |
|
} elsif ($numdirs == 1) { |
|
$singledir = (keys(%files))[0]; |
|
foreach my $file (sort { lc($a) cmp lc($b) } (keys(%{$files{$singledir}}))) { |
|
if ($only) { |
|
my ($ext) = ($file =~ /\.([^.]+)$/); |
|
unless ($possexts{lc($ext)}) { |
|
next; |
|
} |
|
} else { |
|
next if ($file =~ /\.rights$/); |
|
} |
|
push(@singledirfiles,$file); |
|
} |
|
if (@singledirfiles) { |
|
$possdirs = 1; |
|
} |
|
} |
|
if (($possdirs == 1) && (@singledirfiles)) { |
|
my $showdir = $singledir; |
|
if ($singledir eq '') { |
|
$showdir = '/'; |
|
} |
|
$output = $lt{'dire'}. |
|
'<select name="'.$firstselectname.'">'. |
|
'<option value="'.$singledir.'">'.$showdir.'</option>'."\n". |
|
'</select><br />'. |
|
$lt{'fnam'}.'<select name="'.$secondselectname.'">'."\n". |
|
'<option value="" selected="selected">'.$lt{'se'}.'</option>'."\n"; |
|
foreach my $file (@singledirfiles) { |
|
$output .= '<option value="'.$file.'">'.$file.'</option>'."\n"; |
|
} |
|
$output .= '</select><br />'."\n"; |
|
} |
|
return ($possdirs,$output); |
|
} |
|
|
=pod |
=pod |
|
|
=head1 Excel and CSV file utility routines |
=head1 Excel and CSV file utility routines |
Line 1944 sub create_text_file {
|
Line 2502 sub create_text_file {
|
# ------------------------------------------ |
# ------------------------------------------ |
|
|
sub domain_select { |
sub domain_select { |
my ($name,$value,$multiple)=@_; |
my ($name,$value,$multiple,$incdoms,$excdoms)=@_; |
|
my @possdoms; |
|
if (ref($incdoms) eq 'ARRAY') { |
|
@possdoms = @{$incdoms}; |
|
} else { |
|
@possdoms = &Apache::lonnet::all_domains(); |
|
} |
|
|
my %domains=map { |
my %domains=map { |
$_ => $_.' '. &Apache::lonnet::domain($_,'description') |
$_ => $_.' '. &Apache::lonnet::domain($_,'description') |
} &Apache::lonnet::all_domains(); |
} @possdoms; |
|
|
|
if ((ref($excdoms) eq 'ARRAY') && (@{$excdoms} > 0)) { |
|
foreach my $dom (@{$excdoms}) { |
|
delete($domains{$dom}); |
|
} |
|
} |
|
|
if ($multiple) { |
if ($multiple) { |
$domains{''}=&mt('Any domain'); |
$domains{''}=&mt('Any domain'); |
$domains{'select_form_order'} = [sort {lc($a) cmp lc($b) } (keys(%domains))]; |
$domains{'select_form_order'} = [sort {lc($a) cmp lc($b) } (keys(%domains))]; |
Line 2016 sub multiple_select_form {
|
Line 2588 sub multiple_select_form {
|
|
|
=pod |
=pod |
|
|
=item * &select_form($defdom,$name,$hashref,$onchange) |
=item * &select_form($defdom,$name,$hashref,$onchange,$readonly) |
|
|
Returns a string containing a <select name='$name' size='1'> form to |
Returns a string containing a <select name='$name' size='1'> form to |
allow a user to select options from a ref to a hash containing: |
allow a user to select options from a ref to a hash containing: |
option_name => displayed text. An optional $onchange can include |
option_name => displayed text. An optional $onchange can include |
a javascript onchange item, e.g., onchange="this.form.submit();" |
a javascript onchange item, e.g., onchange="this.form.submit();". |
|
An optional arg -- $readonly -- if true will cause the select form |
|
to be disabled, e.g., for the case where an instructor has a section- |
|
specific role, and is viewing/modifying parameters. |
|
|
See lonrights.pm for an example invocation and use. |
See lonrights.pm for an example invocation and use. |
|
|
Line 2029 See lonrights.pm for an example invocati
|
Line 2604 See lonrights.pm for an example invocati
|
|
|
#------------------------------------------- |
#------------------------------------------- |
sub select_form { |
sub select_form { |
my ($def,$name,$hashref,$onchange) = @_; |
my ($def,$name,$hashref,$onchange,$readonly) = @_; |
return unless (ref($hashref) eq 'HASH'); |
return unless (ref($hashref) eq 'HASH'); |
if ($onchange) { |
if ($onchange) { |
$onchange = ' onchange="'.$onchange.'"'; |
$onchange = ' onchange="'.$onchange.'"'; |
} |
} |
my $selectform = "<select name=\"$name\" size=\"1\"$onchange>\n"; |
my $disabled; |
|
if ($readonly) { |
|
$disabled = ' disabled="disabled"'; |
|
} |
|
my $selectform = "<select name=\"$name\" size=\"1\"$onchange$disabled>\n"; |
my @keys; |
my @keys; |
if (exists($hashref->{'select_form_order'})) { |
if (exists($hashref->{'select_form_order'})) { |
@keys=@{$hashref->{'select_form_order'}}; |
@keys=@{$hashref->{'select_form_order'}}; |
Line 2203 sub select_level_form {
|
Line 2782 sub select_level_form {
|
|
|
=pod |
=pod |
|
|
=item * &select_dom_form($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms,$excdoms) |
=item * &select_dom_form($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms,$excdoms,$disabled) |
|
|
Returns a string containing a <select name='$name' size='1'> form to |
Returns a string containing a <select name='$name' size='1'> form to |
allow a user to select the domain to preform an operation in. |
allow a user to select the domain to preform an operation in. |
Line 2220 The optional $incdoms is a reference to
|
Line 2799 The optional $incdoms is a reference to
|
|
|
The optional $excdoms is a reference to an array of domains which will be excluded from the available options. |
The optional $excdoms is a reference to an array of domains which will be excluded from the available options. |
|
|
|
The optional $disabled argument, if true, adds the disabled attribute to the select tag. |
|
|
=cut |
=cut |
|
|
#------------------------------------------- |
#------------------------------------------- |
sub select_dom_form { |
sub select_dom_form { |
my ($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms,$excdoms) = @_; |
my ($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms,$excdoms,$disabled) = @_; |
if ($onchange) { |
if ($onchange) { |
$onchange = ' onchange="'.$onchange.'"'; |
$onchange = ' onchange="'.$onchange.'"'; |
} |
} |
|
if ($disabled) { |
|
$disabled = ' disabled="disabled"'; |
|
} |
my (@domains,%exclude); |
my (@domains,%exclude); |
if (ref($incdoms) eq 'ARRAY') { |
if (ref($incdoms) eq 'ARRAY') { |
@domains = sort {lc($a) cmp lc($b)} (@{$incdoms}); |
@domains = sort {lc($a) cmp lc($b)} (@{$incdoms}); |
Line 2238 sub select_dom_form {
|
Line 2822 sub select_dom_form {
|
if (ref($excdoms) eq 'ARRAY') { |
if (ref($excdoms) eq 'ARRAY') { |
map { $exclude{$_} = 1; } @{$excdoms}; |
map { $exclude{$_} = 1; } @{$excdoms}; |
} |
} |
my $selectdomain = "<select name=\"$name\" size=\"1\"$onchange>\n"; |
my $selectdomain = "<select name=\"$name\" size=\"1\"$onchange$disabled>\n"; |
foreach my $dom (@domains) { |
foreach my $dom (@domains) { |
next if ($exclude{$dom}); |
next if ($exclude{$dom}); |
$selectdomain.="<option value=\"$dom\" ". |
$selectdomain.="<option value=\"$dom\" ". |
Line 2365 Outputs:
|
Line 2949 Outputs:
|
|
|
=item * $clientinfo |
=item * $clientinfo |
|
|
|
=item * $clientosversion |
|
|
=back |
=back |
|
|
=back |
=back |
Line 2384 sub decode_user_agent {
|
Line 2970 sub decode_user_agent {
|
my $clientmathml=''; |
my $clientmathml=''; |
my $clientunicode='0'; |
my $clientunicode='0'; |
my $clientmobile=0; |
my $clientmobile=0; |
|
my $clientosversion=''; |
for (my $i=0;$i<=$#browsertype;$i++) { |
for (my $i=0;$i<=$#browsertype;$i++) { |
my ($bname,$match,$notmatch,$vreg,$minv,$univ)=split(/\%/,$browsertype[$i]); |
my ($bname,$match,$notmatch,$vreg,$minv,$univ)=split(/\%/,$browsertype[$i]); |
if (($httpbrowser=~/$match/i) && ($httpbrowser!~/$notmatch/i)) { |
if (($httpbrowser=~/$match/i) && ($httpbrowser!~/$notmatch/i)) { |
Line 2405 sub decode_user_agent {
|
Line 2992 sub decode_user_agent {
|
if ($httpbrowser=~/next/i) { $clientos='next'; } |
if ($httpbrowser=~/next/i) { $clientos='next'; } |
if (($httpbrowser=~/mac/i) || |
if (($httpbrowser=~/mac/i) || |
($httpbrowser=~/powerpc/i)) { $clientos='mac'; } |
($httpbrowser=~/powerpc/i)) { $clientos='mac'; } |
if ($httpbrowser=~/win/i) { $clientos='win'; } |
if ($httpbrowser=~/win/i) { |
|
$clientos='win'; |
|
if ($httpbrowser =~/Windows\s+NT\s+(\d+\.\d+)/i) { |
|
$clientosversion = $1; |
|
} |
|
} |
if ($httpbrowser=~/embed/i) { $clientos='pda'; } |
if ($httpbrowser=~/embed/i) { $clientos='pda'; } |
if ($httpbrowser=~/(Android|iPod|iPad|iPhone|webOS|Blackberry|Windows Phone|Opera m(?:ob|in)|Fennec)/i) { |
if ($httpbrowser=~/(Android|iPod|iPad|iPhone|webOS|Blackberry|Windows Phone|Opera m(?:ob|in)|Fennec)/i) { |
$clientmobile=lc($1); |
$clientmobile=lc($1); |
Line 2416 sub decode_user_agent {
|
Line 3008 sub decode_user_agent {
|
$clientinfo = 'chromeframe-'.$1; |
$clientinfo = 'chromeframe-'.$1; |
} |
} |
return ($httpbrowser,$clientbrowser,$clientversion,$clientmathml, |
return ($httpbrowser,$clientbrowser,$clientversion,$clientmathml, |
$clientunicode,$clientos,$clientmobile,$clientinfo); |
$clientunicode,$clientos,$clientmobile,$clientinfo, |
|
$clientosversion); |
} |
} |
|
|
############################################################### |
############################################################### |
Line 2455 This is not an optimal method, but it wo
|
Line 3048 This is not an optimal method, but it wo
|
|
|
=item * authform_filesystem |
=item * authform_filesystem |
|
|
|
=item * authform_lti |
|
|
=back |
=back |
|
|
See loncreateuser.pm for invocation and use examples. |
See loncreateuser.pm for invocation and use examples. |
Line 2605 sub authform_kerberos {
|
Line 3200 sub authform_kerberos {
|
@_, |
@_, |
); |
); |
my ($check4,$check5,$krbcheck,$krbarg,$krbver,$result,$authtype, |
my ($check4,$check5,$krbcheck,$krbarg,$krbver,$result,$authtype, |
$autharg,$jscall); |
$autharg,$jscall,$disabled); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
if ($in{'kerb_def_auth'} eq 'krb5') { |
if ($in{'kerb_def_auth'} eq 'krb5') { |
$check5 = ' checked="checked"'; |
$check5 = ' checked="checked"'; |
} else { |
} else { |
$check4 = ' checked="checked"'; |
$check4 = ' checked="checked"'; |
} |
} |
|
if ($in{'readonly'}) { |
|
$disabled = ' disabled="disabled"'; |
|
} |
$krbarg = $in{'kerb_def_dom'}; |
$krbarg = $in{'kerb_def_dom'}; |
if (defined($in{'curr_authtype'})) { |
if (defined($in{'curr_authtype'})) { |
if ($in{'curr_authtype'} eq 'krb') { |
if ($in{'curr_authtype'} eq 'krb') { |
Line 2656 sub authform_kerberos {
|
Line 3254 sub authform_kerberos {
|
if (defined($in{'mode'})) { |
if (defined($in{'mode'})) { |
if ($in{'mode'} eq 'modifycourse') { |
if ($in{'mode'} eq 'modifycourse') { |
if ($authnum == 1) { |
if ($authnum == 1) { |
$authtype = '<input type="radio" name="login" value="krb" />'; |
$authtype = '<input type="radio" name="login" value="krb"'.$disabled.' />'; |
} |
} |
} |
} |
} |
} |
Line 2665 sub authform_kerberos {
|
Line 3263 sub authform_kerberos {
|
if ($authtype eq '') { |
if ($authtype eq '') { |
$authtype = '<input type="radio" name="login" value="krb" '. |
$authtype = '<input type="radio" name="login" value="krb" '. |
'onclick="'.$jscall.'" onchange="'.$jscall.'"'. |
'onclick="'.$jscall.'" onchange="'.$jscall.'"'. |
$krbcheck.' />'; |
$krbcheck.$disabled.' />'; |
} |
} |
if (($can_assign{'krb4'} && $can_assign{'krb5'}) || |
if (($can_assign{'krb4'} && $can_assign{'krb5'}) || |
($can_assign{'krb4'} && !$can_assign{'krb5'} && |
($can_assign{'krb4'} && !$can_assign{'krb5'} && |
Line 2678 sub authform_kerberos {
|
Line 3276 sub authform_kerberos {
|
'<label>'.$authtype, |
'<label>'.$authtype, |
'</label><input type="text" size="10" name="krbarg" '. |
'</label><input type="text" size="10" name="krbarg" '. |
'value="'.$krbarg.'" '. |
'value="'.$krbarg.'" '. |
'onchange="'.$jscall.'" />', |
'onchange="'.$jscall.'"'.$disabled.' />', |
'<label><input type="radio" name="krbver" value="4" '.$check4.' />', |
'<label><input type="radio" name="krbver" value="4" '.$check4.$disabled.' />', |
'</label><label><input type="radio" name="krbver" value="5" '.$check5.' />', |
'</label><label><input type="radio" name="krbver" value="5" '.$check5.$disabled.' />', |
'</label>'); |
'</label>'); |
} elsif ($can_assign{'krb4'}) { |
} elsif ($can_assign{'krb4'}) { |
$result .= &mt |
$result .= &mt |
Line 2689 sub authform_kerberos {
|
Line 3287 sub authform_kerberos {
|
'<label>'.$authtype, |
'<label>'.$authtype, |
'</label><input type="text" size="10" name="krbarg" '. |
'</label><input type="text" size="10" name="krbarg" '. |
'value="'.$krbarg.'" '. |
'value="'.$krbarg.'" '. |
'onchange="'.$jscall.'" />', |
'onchange="'.$jscall.'"'.$disabled.' />', |
'<label><input type="hidden" name="krbver" value="4" />', |
'<label><input type="hidden" name="krbver" value="4" />', |
'</label>'); |
'</label>'); |
} elsif ($can_assign{'krb5'}) { |
} elsif ($can_assign{'krb5'}) { |
Line 2699 sub authform_kerberos {
|
Line 3297 sub authform_kerberos {
|
'<label>'.$authtype, |
'<label>'.$authtype, |
'</label><input type="text" size="10" name="krbarg" '. |
'</label><input type="text" size="10" name="krbarg" '. |
'value="'.$krbarg.'" '. |
'value="'.$krbarg.'" '. |
'onchange="'.$jscall.'" />', |
'onchange="'.$jscall.'"'.$disabled.' />', |
'<label><input type="hidden" name="krbver" value="5" />', |
'<label><input type="hidden" name="krbver" value="5" />', |
'</label>'); |
'</label>'); |
} |
} |
Line 2712 sub authform_internal {
|
Line 3310 sub authform_internal {
|
kerb_def_dom => 'MSU.EDU', |
kerb_def_dom => 'MSU.EDU', |
@_, |
@_, |
); |
); |
my ($intcheck,$intarg,$result,$authtype,$autharg,$jscall); |
my ($intcheck,$intarg,$result,$authtype,$autharg,$jscall,$disabled); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
|
if ($in{'readonly'}) { |
|
$disabled = ' disabled="disabled"'; |
|
} |
if (defined($in{'curr_authtype'})) { |
if (defined($in{'curr_authtype'})) { |
if ($in{'curr_authtype'} eq 'int') { |
if ($in{'curr_authtype'} eq 'int') { |
if ($can_assign{'int'}) { |
if ($can_assign{'int'}) { |
Line 2742 sub authform_internal {
|
Line 3343 sub authform_internal {
|
if (defined($in{'mode'})) { |
if (defined($in{'mode'})) { |
if ($in{'mode'} eq 'modifycourse') { |
if ($in{'mode'} eq 'modifycourse') { |
if ($authnum == 1) { |
if ($authnum == 1) { |
$authtype = '<input type="radio" name="login" value="int" />'; |
$authtype = '<input type="radio" name="login" value="int"'.$disabled.' />'; |
} |
} |
} |
} |
} |
} |
Line 2750 sub authform_internal {
|
Line 3351 sub authform_internal {
|
$jscall = "javascript:changed_radio('int',$in{'formname'});"; |
$jscall = "javascript:changed_radio('int',$in{'formname'});"; |
if ($authtype eq '') { |
if ($authtype eq '') { |
$authtype = '<input type="radio" name="login" value="int" '.$intcheck. |
$authtype = '<input type="radio" name="login" value="int" '.$intcheck. |
' onchange="'.$jscall.'" onclick="'.$jscall.'" />'; |
' onchange="'.$jscall.'" onclick="'.$jscall.'"'.$disabled.' />'; |
} |
} |
$autharg = '<input type="password" size="10" name="intarg" value="'. |
$autharg = '<input type="password" size="10" name="intarg" value="'. |
$intarg.'" onchange="'.$jscall.'" />'; |
$intarg.'" onchange="'.$jscall.'"'.$disabled.' />'; |
$result = &mt |
$result = &mt |
('[_1] Internally authenticated (with initial password [_2])', |
('[_1] Internally authenticated (with initial password [_2])', |
'<label>'.$authtype,'</label>'.$autharg); |
'<label>'.$authtype,'</label>'.$autharg); |
$result.="<label><input type=\"checkbox\" name=\"visible\" onclick='if (this.checked) { this.form.intarg.type=\"text\" } else { this.form.intarg.type=\"password\" }' />".&mt('Visible input').'</label>'; |
$result.='<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.intarg.type='."'text'".' } else { this.form.intarg.type='."'password'".' }"'.$disabled.' />'.&mt('Visible input').'</label>'; |
return $result; |
return $result; |
} |
} |
|
|
Line 2767 sub authform_local {
|
Line 3368 sub authform_local {
|
kerb_def_dom => 'MSU.EDU', |
kerb_def_dom => 'MSU.EDU', |
@_, |
@_, |
); |
); |
my ($loccheck,$locarg,$result,$authtype,$autharg,$jscall); |
my ($loccheck,$locarg,$result,$authtype,$autharg,$jscall,$disabled); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
|
if ($in{'readonly'}) { |
|
$disabled = ' disabled="disabled"'; |
|
} |
if (defined($in{'curr_authtype'})) { |
if (defined($in{'curr_authtype'})) { |
if ($in{'curr_authtype'} eq 'loc') { |
if ($in{'curr_authtype'} eq 'loc') { |
if ($can_assign{'loc'}) { |
if ($can_assign{'loc'}) { |
Line 2797 sub authform_local {
|
Line 3401 sub authform_local {
|
if (defined($in{'mode'})) { |
if (defined($in{'mode'})) { |
if ($in{'mode'} eq 'modifycourse') { |
if ($in{'mode'} eq 'modifycourse') { |
if ($authnum == 1) { |
if ($authnum == 1) { |
$authtype = '<input type="radio" name="login" value="loc" />'; |
$authtype = '<input type="radio" name="login" value="loc"'.$disabled.' />'; |
} |
} |
} |
} |
} |
} |
Line 2806 sub authform_local {
|
Line 3410 sub authform_local {
|
if ($authtype eq '') { |
if ($authtype eq '') { |
$authtype = '<input type="radio" name="login" value="loc" '. |
$authtype = '<input type="radio" name="login" value="loc" '. |
$loccheck.' onchange="'.$jscall.'" onclick="'. |
$loccheck.' onchange="'.$jscall.'" onclick="'. |
$jscall.'" />'; |
$jscall.'"'.$disabled.' />'; |
} |
} |
$autharg = '<input type="text" size="10" name="locarg" value="'. |
$autharg = '<input type="text" size="10" name="locarg" value="'. |
$locarg.'" onchange="'.$jscall.'" />'; |
$locarg.'" onchange="'.$jscall.'"'.$disabled.' />'; |
$result = &mt('[_1] Local Authentication with argument [_2]', |
$result = &mt('[_1] Local Authentication with argument [_2]', |
'<label>'.$authtype,'</label>'.$autharg); |
'<label>'.$authtype,'</label>'.$autharg); |
return $result; |
return $result; |
Line 2821 sub authform_filesystem {
|
Line 3425 sub authform_filesystem {
|
kerb_def_dom => 'MSU.EDU', |
kerb_def_dom => 'MSU.EDU', |
@_, |
@_, |
); |
); |
my ($fsyscheck,$result,$authtype,$autharg,$jscall); |
my ($fsyscheck,$result,$authtype,$autharg,$jscall,$disabled); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
|
if ($in{'readonly'}) { |
|
$disabled = ' disabled="disabled"'; |
|
} |
if (defined($in{'curr_authtype'})) { |
if (defined($in{'curr_authtype'})) { |
if ($in{'curr_authtype'} eq 'fsys') { |
if ($in{'curr_authtype'} eq 'fsys') { |
if ($can_assign{'fsys'}) { |
if ($can_assign{'fsys'}) { |
Line 2835 sub authform_filesystem {
|
Line 3442 sub authform_filesystem {
|
} else { |
} else { |
$result = &mt('Currently Filesystem Authenticated.'); |
$result = &mt('Currently Filesystem Authenticated.'); |
return $result; |
return $result; |
} |
} |
} |
} |
} else { |
} else { |
if ($authnum == 1) { |
if ($authnum == 1) { |
Line 2848 sub authform_filesystem {
|
Line 3455 sub authform_filesystem {
|
if (defined($in{'mode'})) { |
if (defined($in{'mode'})) { |
if ($in{'mode'} eq 'modifycourse') { |
if ($in{'mode'} eq 'modifycourse') { |
if ($authnum == 1) { |
if ($authnum == 1) { |
$authtype = '<input type="radio" name="login" value="fsys" />'; |
$authtype = '<input type="radio" name="login" value="fsys"'.$disabled.' />'; |
} |
} |
} |
} |
} |
} |
Line 2857 sub authform_filesystem {
|
Line 3464 sub authform_filesystem {
|
if ($authtype eq '') { |
if ($authtype eq '') { |
$authtype = '<input type="radio" name="login" value="fsys" '. |
$authtype = '<input type="radio" name="login" value="fsys" '. |
$fsyscheck.' onchange="'.$jscall.'" onclick="'. |
$fsyscheck.' onchange="'.$jscall.'" onclick="'. |
$jscall.'" />'; |
$jscall.'"'.$disabled.' />'; |
} |
} |
$autharg = '<input type="text" size="10" name="fsysarg" value=""'. |
$autharg = '<input type="password" size="10" name="fsysarg" value=""'. |
' onchange="'.$jscall.'" />'; |
' onchange="'.$jscall.'"'.$disabled.' />'; |
$result = &mt |
$result = &mt |
('[_1] Filesystem Authenticated (with initial password [_2])', |
('[_1] Filesystem Authenticated (with initial password [_2])', |
'<label><input type="radio" name="login" value="fsys" '. |
'<label>'.$authtype,'</label>'.$autharg); |
$fsyscheck.'onchange="'.$jscall.'" onclick="'.$jscall.'" />', |
return $result; |
'</label><input type="password" size="10" name="fsysarg" value="" '. |
} |
'onchange="'.$jscall.'" />'); |
|
|
sub authform_lti { |
|
my %in = ( |
|
formname => 'document.cu', |
|
kerb_def_dom => 'MSU.EDU', |
|
@_, |
|
); |
|
my ($lticheck,$result,$authtype,$autharg,$jscall,$disabled); |
|
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
|
if ($in{'readonly'}) { |
|
$disabled = ' disabled="disabled"'; |
|
} |
|
if (defined($in{'curr_authtype'})) { |
|
if ($in{'curr_authtype'} eq 'lti') { |
|
if ($can_assign{'lti'}) { |
|
$lticheck = 'checked="checked" '; |
|
if (defined($in{'mode'})) { |
|
if ($in{'mode'} eq 'modifyuser') { |
|
$lticheck = ''; |
|
} |
|
} |
|
} else { |
|
$result = &mt('Currently LTI Authenticated.'); |
|
return $result; |
|
} |
|
} |
|
} else { |
|
if ($authnum == 1) { |
|
$authtype = '<input type="hidden" name="login" value="lti" />'; |
|
} |
|
} |
|
if (!$can_assign{'lti'}) { |
|
return; |
|
} elsif ($authtype eq '') { |
|
if (defined($in{'mode'})) { |
|
if ($in{'mode'} eq 'modifycourse') { |
|
if ($authnum == 1) { |
|
$authtype = '<input type="radio" name="login" value="lti"'.$disabled.' />'; |
|
} |
|
} |
|
} |
|
} |
|
$jscall = "javascript:changed_radio('lti',$in{'formname'});"; |
|
if (($authtype eq '') && (($in{'mode'} eq 'modifycourse') || ($in{'curr_authtype'} ne 'lti'))) { |
|
$authtype = '<input type="radio" name="login" value="lti" '. |
|
$lticheck.' onchange="'.$jscall.'" onclick="'. |
|
$jscall.'"'.$disabled.' />'; |
|
} |
|
$autharg = '<input type="hidden" name="ltiarg" value="" />'; |
|
if ($authtype) { |
|
$result = &mt('[_1] LTI Authenticated', |
|
'<label>'.$authtype.'</label>'.$autharg); |
|
} else { |
|
$result = '<b>'.&mt('LTI Authenticated').'</b>'. |
|
$autharg; |
|
} |
return $result; |
return $result; |
} |
} |
|
|
Line 2880 sub get_assignable_auth {
|
Line 3542 sub get_assignable_auth {
|
krb5 => 1, |
krb5 => 1, |
int => 1, |
int => 1, |
loc => 1, |
loc => 1, |
|
lti => 1, |
); |
); |
my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom); |
my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom); |
if (ref($domconfig{'usercreation'}) eq 'HASH') { |
if (ref($domconfig{'usercreation'}) eq 'HASH') { |
Line 2888 sub get_assignable_auth {
|
Line 3551 sub get_assignable_auth {
|
my $context; |
my $context; |
if ($env{'request.role'} =~ /^au/) { |
if ($env{'request.role'} =~ /^au/) { |
$context = 'author'; |
$context = 'author'; |
} elsif ($env{'request.role'} =~ /^dc/) { |
} elsif ($env{'request.role'} =~ /^(dc|dh)/) { |
$context = 'domain'; |
$context = 'domain'; |
} elsif ($env{'request.course.id'}) { |
} elsif ($env{'request.course.id'}) { |
$context = 'course'; |
$context = 'course'; |
Line 2912 sub get_assignable_auth {
|
Line 3575 sub get_assignable_auth {
|
return ($authnum,%can_assign); |
return ($authnum,%can_assign); |
} |
} |
|
|
|
sub check_passwd_rules { |
|
my ($domain,$plainpass) = @_; |
|
my %passwdconf = &Apache::lonnet::get_passwdconf($domain); |
|
my ($min,$max,@chars,@brokerule,$warning); |
|
$min = $Apache::lonnet::passwdmin; |
|
if (ref($passwdconf{'chars'}) eq 'ARRAY') { |
|
if ($passwdconf{'min'} =~ /^\d+$/) { |
|
if ($passwdconf{'min'} > $min) { |
|
$min = $passwdconf{'min'}; |
|
} |
|
} |
|
if ($passwdconf{'max'} =~ /^\d+$/) { |
|
$max = $passwdconf{'max'}; |
|
} |
|
@chars = @{$passwdconf{'chars'}}; |
|
} |
|
if (($min) && (length($plainpass) < $min)) { |
|
push(@brokerule,'min'); |
|
} |
|
if (($max) && (length($plainpass) > $max)) { |
|
push(@brokerule,'max'); |
|
} |
|
if (@chars) { |
|
my %rules; |
|
map { $rules{$_} = 1; } @chars; |
|
if ($rules{'uc'}) { |
|
unless ($plainpass =~ /[A-Z]/) { |
|
push(@brokerule,'uc'); |
|
} |
|
} |
|
if ($rules{'lc'}) { |
|
unless ($plainpass =~ /[a-z]/) { |
|
push(@brokerule,'lc'); |
|
} |
|
} |
|
if ($rules{'num'}) { |
|
unless ($plainpass =~ /\d/) { |
|
push(@brokerule,'num'); |
|
} |
|
} |
|
if ($rules{'spec'}) { |
|
unless ($plainpass =~ /[!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~]/) { |
|
push(@brokerule,'spec'); |
|
} |
|
} |
|
} |
|
if (@brokerule) { |
|
my %rulenames = &Apache::lonlocal::texthash( |
|
uc => 'At least one upper case letter', |
|
lc => 'At least one lower case letter', |
|
num => 'At least one number', |
|
spec => 'At least one non-alphanumeric', |
|
); |
|
$rulenames{'uc'} .= ': ABCDEFGHIJKLMNOPQRSTUVWXYZ'; |
|
$rulenames{'lc'} .= ': abcdefghijklmnopqrstuvwxyz'; |
|
$rulenames{'num'} .= ': 0123456789'; |
|
$rulenames{'spec'} .= ': !"\#$%&\'()*+,-./:;<=>?@[\]^_\`{|}~'; |
|
$rulenames{'min'} = &mt('Minimum password length: [_1]',$min); |
|
$rulenames{'max'} = &mt('Maximum password length: [_1]',$max); |
|
$warning = &mt('Password did not satisfy the following:').'<ul>'; |
|
foreach my $rule ('min','max','uc','lc','num','spec') { |
|
if (grep(/^$rule$/,@brokerule)) { |
|
$warning .= '<li>'.$rulenames{$rule}.'</li>'; |
|
} |
|
} |
|
$warning .= '</ul>'; |
|
} |
|
if (wantarray) { |
|
return @brokerule; |
|
} |
|
return $warning; |
|
} |
|
|
############################################################### |
############################################################### |
## Get Kerberos Defaults for Domain ## |
## Get Kerberos Defaults for Domain ## |
############################################################### |
############################################################### |
Line 3609 category
|
Line 4345 category
|
|
|
sub filecategorytypes { |
sub filecategorytypes { |
my ($cat) = @_; |
my ($cat) = @_; |
return @{$category_extensions{lc($cat)}}; |
if (ref($category_extensions{lc($cat)}) eq 'ARRAY') { |
|
return @{$category_extensions{lc($cat)}}; |
|
} else { |
|
return (); |
|
} |
} |
} |
|
|
=pod |
=pod |
Line 3752 sub user_lang {
|
Line 4492 sub user_lang {
|
=over 4 |
=over 4 |
|
|
=item * &get_previous_attempt($symb, $username, $domain, $course, |
=item * &get_previous_attempt($symb, $username, $domain, $course, |
$getattempt, $regexp, $gradesub) |
$getattempt, $regexp, $gradesub, $usec, $identifier) |
|
|
Return string with previous attempt on problem. Arguments: |
Return string with previous attempt on problem. Arguments: |
|
|
Line 3774 Return string with previous attempt on p
|
Line 4514 Return string with previous attempt on p
|
|
|
=item * $gradesub: routine that processes the string if it matches $regexp |
=item * $gradesub: routine that processes the string if it matches $regexp |
|
|
|
=item * $usec: section of the desired student |
|
|
|
=item * $identifier: counter for student (multiple students one problem) or |
|
problem (one student; whole sequence). |
|
|
=back |
=back |
|
|
The output string is a table containing all desired attempts, if any. |
The output string is a table containing all desired attempts, if any. |
Line 3781 The output string is a table containing
|
Line 4526 The output string is a table containing
|
=cut |
=cut |
|
|
sub get_previous_attempt { |
sub get_previous_attempt { |
my ($symb,$username,$domain,$course,$getattempt,$regexp,$gradesub)=@_; |
my ($symb,$username,$domain,$course,$getattempt,$regexp,$gradesub,$usec,$identifier)=@_; |
my $prevattempts=''; |
my $prevattempts=''; |
no strict 'refs'; |
no strict 'refs'; |
if ($symb) { |
if ($symb) { |
Line 3791 sub get_previous_attempt {
|
Line 4536 sub get_previous_attempt {
|
my %lasthash=(); |
my %lasthash=(); |
my $version; |
my $version; |
for ($version=1;$version<=$returnhash{'version'};$version++) { |
for ($version=1;$version<=$returnhash{'version'};$version++) { |
foreach my $key (sort(split(/\:/,$returnhash{$version.':keys'}))) { |
foreach my $key (reverse(sort(split(/\:/,$returnhash{$version.':keys'})))) { |
$lasthash{$key}=$returnhash{$version.':'.$key}; |
if ($key =~ /\.rawrndseed$/) { |
|
my ($id) = ($key =~ /^(.+)\.rawrndseed$/); |
|
$lasthash{$id.'.rndseed'} = $returnhash{$version.':'.$key}; |
|
} else { |
|
$lasthash{$key}=$returnhash{$version.':'.$key}; |
|
} |
} |
} |
} |
} |
$prevattempts=&start_data_table().&start_data_table_header_row(); |
$prevattempts=&start_data_table().&start_data_table_header_row(); |
$prevattempts.='<th>'.&mt('History').'</th>'; |
$prevattempts.='<th>'.&mt('History').'</th>'; |
my (%typeparts,%lasthidden); |
my (%typeparts,%lasthidden,%regraded,%hidestatus); |
my $showsurv=&Apache::lonnet::allowed('vas',$env{'request.course.id'}); |
my $showsurv=&Apache::lonnet::allowed('vas',$env{'request.course.id'}); |
foreach my $key (sort(keys(%lasthash))) { |
foreach my $key (sort(keys(%lasthash))) { |
my ($ign,@parts) = split(/\./,$key); |
my ($ign,@parts) = split(/\./,$key); |
Line 3814 sub get_previous_attempt {
|
Line 4564 sub get_previous_attempt {
|
$lasthidden{$ign.'.'.$id} = 1; |
$lasthidden{$ign.'.'.$id} = 1; |
} |
} |
} |
} |
|
if ($identifier ne '') { |
|
my $id = join(',',@parts); |
|
if (&Apache::lonnet::EXT("resource.$id.problemstatus",$symb, |
|
$domain,$username,$usec,undef,$course) =~ /^no/) { |
|
$hidestatus{$ign.'.'.$id} = 1; |
|
} |
|
} |
|
} elsif ($data eq 'regrader') { |
|
if (($identifier ne '') && (@parts)) { |
|
my $id = join(',',@parts); |
|
$regraded{$ign.'.'.$id} = 1; |
|
} |
} |
} |
} else { |
} else { |
if ($#parts == 0) { |
if ($#parts == 0) { |
Line 3825 sub get_previous_attempt {
|
Line 4587 sub get_previous_attempt {
|
} |
} |
$prevattempts.=&end_data_table_header_row(); |
$prevattempts.=&end_data_table_header_row(); |
if ($getattempt eq '') { |
if ($getattempt eq '') { |
|
my (%solved,%resets,%probstatus); |
|
if (($identifier ne '') && (keys(%regraded) > 0)) { |
|
for ($version=1;$version<=$returnhash{'version'};$version++) { |
|
foreach my $id (keys(%regraded)) { |
|
if (($returnhash{$version.':'.$id.'.regrader'}) && |
|
($returnhash{$version.':'.$id.'.tries'} eq '') && |
|
($returnhash{$version.':'.$id.'.award'} eq '')) { |
|
push(@{$resets{$id}},$version); |
|
} |
|
} |
|
} |
|
} |
for ($version=1;$version<=$returnhash{'version'};$version++) { |
for ($version=1;$version<=$returnhash{'version'};$version++) { |
my @hidden; |
my (@hidden,@unsolved); |
if (%typeparts) { |
if (%typeparts) { |
foreach my $id (keys(%typeparts)) { |
foreach my $id (keys(%typeparts)) { |
if (($returnhash{$version.':'.$id.'.type'} eq 'anonsurvey') || ($returnhash{$version.':'.$id.'.type'} eq 'anonsurveycred')) { |
if (($returnhash{$version.':'.$id.'.type'} eq 'anonsurvey') || |
|
($returnhash{$version.':'.$id.'.type'} eq 'anonsurveycred')) { |
push(@hidden,$id); |
push(@hidden,$id); |
|
} elsif ($identifier ne '') { |
|
unless (($returnhash{$version.':'.$id.'.type'} eq 'survey') || |
|
($returnhash{$version.':'.$id.'.type'} eq 'surveycred') || |
|
($hidestatus{$id})) { |
|
next if ((ref($resets{$id}) eq 'ARRAY') && grep(/^\Q$version\E$/,@{$resets{$id}})); |
|
if ($returnhash{$version.':'.$id.'.solved'} eq 'correct_by_student') { |
|
push(@{$solved{$id}},$version); |
|
} elsif (($returnhash{$version.':'.$id.'.solved'} ne '') && |
|
(ref($solved{$id}) eq 'ARRAY')) { |
|
my $skip; |
|
if (ref($resets{$id}) eq 'ARRAY') { |
|
foreach my $reset (@{$resets{$id}}) { |
|
if ($reset > $solved{$id}[-1]) { |
|
$skip=1; |
|
last; |
|
} |
|
} |
|
} |
|
unless ($skip) { |
|
my ($ign,$partslist) = split(/\./,$id,2); |
|
push(@unsolved,$partslist); |
|
} |
|
} |
|
} |
} |
} |
} |
} |
} |
} |
$prevattempts.=&start_data_table_row(). |
$prevattempts.=&start_data_table_row(). |
'<td>'.&mt('Transaction [_1]',$version).'</td>'; |
'<td>'.&mt('Transaction [_1]',$version); |
|
if (@unsolved) { |
|
$prevattempts .= '<span class="LC_nobreak"><label>'. |
|
'<input type="checkbox" name="HIDE'.$identifier.'" value="'.$version.':'.join('_',@unsolved).'" />'. |
|
&mt('Hide').'</label></span>'; |
|
} |
|
$prevattempts .= '</td>'; |
if (@hidden) { |
if (@hidden) { |
foreach my $key (sort(keys(%lasthash))) { |
foreach my $key (sort(keys(%lasthash))) { |
next if ($key =~ /\.foilorder$/); |
next if ($key =~ /\.foilorder$/); |
Line 3857 sub get_previous_attempt {
|
Line 4662 sub get_previous_attempt {
|
} |
} |
} else { |
} else { |
if ($key =~ /\./) { |
if ($key =~ /\./) { |
my $value = &format_previous_attempt_value($key, |
my $value = $returnhash{$version.':'.$key}; |
$returnhash{$version.':'.$key}); |
if ($key =~ /\.rndseed$/) { |
$prevattempts.='<td>'.$value.' </td>'; |
my ($id) = ($key =~ /^(.+)\.[^.]+$/); |
|
if (exists($returnhash{$version.':'.$id.'.rawrndseed'})) { |
|
$value = $returnhash{$version.':'.$id.'.rawrndseed'}; |
|
} |
|
} |
|
$prevattempts.='<td>'.&format_previous_attempt_value($key,$value). |
|
' </td>'; |
} else { |
} else { |
$prevattempts.='<td> </td>'; |
$prevattempts.='<td> </td>'; |
} |
} |
Line 3868 sub get_previous_attempt {
|
Line 4679 sub get_previous_attempt {
|
} else { |
} else { |
foreach my $key (sort(keys(%lasthash))) { |
foreach my $key (sort(keys(%lasthash))) { |
next if ($key =~ /\.foilorder$/); |
next if ($key =~ /\.foilorder$/); |
my $value = &format_previous_attempt_value($key, |
my $value = $returnhash{$version.':'.$key}; |
$returnhash{$version.':'.$key}); |
if ($key =~ /\.rndseed$/) { |
$prevattempts.='<td>'.$value.' </td>'; |
my ($id) = ($key =~ /^(.+)\.[^.]+$/); |
|
if (exists($returnhash{$version.':'.$id.'.rawrndseed'})) { |
|
$value = $returnhash{$version.':'.$id.'.rawrndseed'}; |
|
} |
|
} |
|
$prevattempts.='<td>'.&format_previous_attempt_value($key,$value). |
|
' </td>'; |
} |
} |
} |
} |
$prevattempts.=&end_data_table_row(); |
$prevattempts.=&end_data_table_row(); |
Line 3916 sub get_previous_attempt {
|
Line 4733 sub get_previous_attempt {
|
} |
} |
$prevattempts.= &end_data_table_row().&end_data_table(); |
$prevattempts.= &end_data_table_row().&end_data_table(); |
} else { |
} else { |
|
my $msg; |
|
if ($symb =~ /ext\.tool$/) { |
|
$msg = &mt('No grade passed back.'); |
|
} else { |
|
$msg = &mt('Nothing submitted - no attempts.'); |
|
} |
$prevattempts= |
$prevattempts= |
&start_data_table().&start_data_table_row(). |
&start_data_table().&start_data_table_row(). |
'<td>'.&mt('Nothing submitted - no attempts.').'</td>'. |
'<td>'.$msg.'</td>'. |
&end_data_table_row().&end_data_table(); |
&end_data_table_row().&end_data_table(); |
} |
} |
} else { |
} else { |
Line 4023 sub get_student_view {
|
Line 4846 sub get_student_view {
|
} |
} |
if (defined($target)) { $form{'grade_target'} = $target; } |
if (defined($target)) { $form{'grade_target'} = $target; } |
$feedurl=&Apache::lonnet::clutter($feedurl); |
$feedurl=&Apache::lonnet::clutter($feedurl); |
|
if (($feedurl =~ /ext\.tool$/) && ($target eq 'tex')) { |
|
$feedurl =~ s{^/adm/wrapper}{}; |
|
} |
my ($userview,$response)=&Apache::lonnet::ssi_body($feedurl,%form); |
my ($userview,$response)=&Apache::lonnet::ssi_body($feedurl,%form); |
$userview=~s/\<body[^\>]*\>//gi; |
$userview=~s/\<body[^\>]*\>//gi; |
$userview=~s/\<\/body\>//gi; |
$userview=~s/\<\/body\>//gi; |
Line 4322 sub findallcourses {
|
Line 5148 sub findallcourses {
|
############################################### |
############################################### |
|
|
sub blockcheck { |
sub blockcheck { |
my ($setters,$activity,$uname,$udom,$url,$is_course) = @_; |
my ($setters,$activity,$uname,$udom,$url,$is_course,$symb,$caller) = @_; |
|
|
if (defined($udom) && defined($uname)) { |
if (defined($udom) && defined($uname)) { |
# If uname and udom are for a course, check for blocks in the course. |
# If uname and udom are for a course, check for blocks in the course. |
if (($is_course) || (&Apache::lonnet::is_course($udom,$uname))) { |
if (($is_course) || (&Apache::lonnet::is_course($udom,$uname))) { |
my ($startblock,$endblock,$triggerblock) = |
my ($startblock,$endblock,$triggerblock) = |
&get_blocks($setters,$activity,$udom,$uname,$url); |
&get_blocks($setters,$activity,$udom,$uname,$url,$symb,$caller); |
return ($startblock,$endblock,$triggerblock); |
return ($startblock,$endblock,$triggerblock); |
} |
} |
} else { |
} else { |
Line 4345 sub blockcheck {
|
Line 5171 sub blockcheck {
|
# boards, chat or groups, check for blocking in current course only. |
# boards, chat or groups, check for blocking in current course only. |
|
|
if (($activity eq 'boards' || $activity eq 'chat' || |
if (($activity eq 'boards' || $activity eq 'chat' || |
$activity eq 'groups' || $activity eq 'printout') && |
$activity eq 'groups' || $activity eq 'printout' || |
|
$activity eq 'search' || $activity eq 'reinit' || |
|
$activity eq 'alert') && |
($env{'request.course.id'})) { |
($env{'request.course.id'})) { |
foreach my $key (keys(%live_courses)) { |
foreach my $key (keys(%live_courses)) { |
if ($key ne $env{'request.course.id'}) { |
if ($key ne $env{'request.course.id'}) { |
Line 4429 sub blockcheck {
|
Line 5257 sub blockcheck {
|
$tdom,$spec,$trest,$area); |
$tdom,$spec,$trest,$area); |
} |
} |
} |
} |
my ($author,$adv) = &Apache::lonnet::set_userprivs(\%userroles,\%allroles); |
my ($author,$adv,$rar) = &Apache::lonnet::set_userprivs(\%userroles,\%allroles); |
if ($userroles{'user.priv.'.$checkrole} =~ /evb\&([^\:]*)/) { |
if ($userroles{'user.priv.'.$checkrole} =~ /evb\&([^\:]*)/) { |
if ($1) { |
if ($1) { |
$no_userblock = 1; |
$no_userblock = 1; |
Line 4451 sub blockcheck {
|
Line 5279 sub blockcheck {
|
($env{'request.role'} !~ m{^st\./\Q$cdom\E/\Q$cnum\E})); |
($env{'request.role'} !~ m{^st\./\Q$cdom\E/\Q$cnum\E})); |
next if ($no_userblock); |
next if ($no_userblock); |
|
|
# Retrieve blocking times and identity of locker for course |
# Retrieve blocking times and identity of blocker for course |
# of specified user, unless user has 'evb' privilege. |
# of specified user, unless user has 'evb' privilege. |
|
|
my ($start,$end,$trigger) = |
my ($start,$end,$trigger) = |
&get_blocks($setters,$activity,$cdom,$cnum,$url); |
&get_blocks($setters,$activity,$cdom,$cnum,$url,$symb,$caller); |
if (($start != 0) && |
if (($start != 0) && |
(($startblock == 0) || ($startblock > $start))) { |
(($startblock == 0) || ($startblock > $start))) { |
$startblock = $start; |
$startblock = $start; |
Line 4475 sub blockcheck {
|
Line 5303 sub blockcheck {
|
} |
} |
|
|
sub get_blocks { |
sub get_blocks { |
my ($setters,$activity,$cdom,$cnum,$url) = @_; |
my ($setters,$activity,$cdom,$cnum,$url,$symb,$caller) = @_; |
my $startblock = 0; |
my $startblock = 0; |
my $endblock = 0; |
my $endblock = 0; |
my $triggerblock = ''; |
my $triggerblock = ''; |
Line 4488 sub get_blocks {
|
Line 5316 sub get_blocks {
|
my $now = time; |
my $now = time; |
my %commblocks = &Apache::lonnet::get_comm_blocks($cdom,$cnum); |
my %commblocks = &Apache::lonnet::get_comm_blocks($cdom,$cnum); |
if ($activity eq 'docs') { |
if ($activity eq 'docs') { |
@blockers = &Apache::lonnet::has_comm_blocking('bre',undef,$url,\%commblocks); |
my ($blocked,$nosymbcache,$noenccheck); |
|
if (($caller eq 'blockedaccess') || ($caller eq 'blockingstatus')) { |
|
$blocked = 1; |
|
$nosymbcache = 1; |
|
$noenccheck = 1; |
|
} |
|
@blockers = &Apache::lonnet::has_comm_blocking('bre',$symb,$url,$nosymbcache,$noenccheck,$blocked,\%commblocks); |
foreach my $block (@blockers) { |
foreach my $block (@blockers) { |
if ($block =~ /^firstaccess____(.+)$/) { |
if ($block =~ /^firstaccess____(.+)$/) { |
my $item = $1; |
my $item = $1; |
Line 4540 sub get_blocks {
|
Line 5374 sub get_blocks {
|
my $end = $start + $env{'course.'.$cdom.'_'.$cnum.'.timerinterval.'.$timersymb}; |
my $end = $start + $env{'course.'.$cdom.'_'.$cnum.'.timerinterval.'.$timersymb}; |
if ($start && $end) { |
if ($start && $end) { |
if (($start <= time) && ($end >= time)) { |
if (($start <= time) && ($end >= time)) { |
unless (grep(/^\Q$block\E$/,@blockers)) { |
if (ref($commblocks{$block}) eq 'HASH') { |
push(@blockers,$block); |
if (ref($commblocks{$block}{'blocks'}) eq 'HASH') { |
$triggered{$block} = { |
if ($commblocks{$block}{'blocks'}{$activity} eq 'on') { |
start => $start, |
unless(grep(/^\Q$block\E$/,@blockers)) { |
end => $end, |
push(@blockers,$block); |
type => $type, |
$triggered{$block} = { |
}; |
start => $start, |
|
end => $end, |
|
type => $type, |
|
}; |
|
} |
|
} |
|
} |
} |
} |
} |
} |
} |
} |
Line 4610 sub parse_block_record {
|
Line 5450 sub parse_block_record {
|
} |
} |
|
|
sub blocking_status { |
sub blocking_status { |
my ($activity,$uname,$udom,$url,$is_course) = @_; |
my ($activity,$uname,$udom,$url,$is_course,$symb,$caller) = @_; |
my %setters; |
my %setters; |
|
|
# check for active blocking |
# check for active blocking |
my ($startblock,$endblock,$triggerblock) = |
my ($startblock,$endblock,$triggerblock) = |
&blockcheck(\%setters,$activity,$uname,$udom,$url,$is_course); |
&blockcheck(\%setters,$activity,$uname,$udom,$url,$is_course,$symb,$caller); |
my $blocked = 0; |
my $blocked = 0; |
if ($startblock && $endblock) { |
if ($startblock && $endblock) { |
$blocked = 1; |
$blocked = 1; |
Line 4627 sub blocking_status {
|
Line 5467 sub blocking_status {
|
# build a link to a popup window containing the details |
# build a link to a popup window containing the details |
my $querystring = "?activity=$activity"; |
my $querystring = "?activity=$activity"; |
# $uname and $udom decide whose portfolio the user is trying to look at |
# $uname and $udom decide whose portfolio the user is trying to look at |
if ($activity eq 'port') { |
if (($activity eq 'port') || ($activity eq 'passwd')) { |
$querystring .= "&udom=$udom" if $udom; |
$querystring .= "&udom=$udom" if ($udom =~ /^$match_domain$/); |
$querystring .= "&uname=$uname" if $uname; |
$querystring .= "&uname=$uname" if ($uname =~ /^$match_username$/); |
} elsif ($activity eq 'docs') { |
} elsif ($activity eq 'docs') { |
$querystring .= '&url='.&HTML::Entities::encode($url,'&"'); |
my $showurl = &Apache::lonenc::check_encrypt($url); |
|
$querystring .= '&url='.&HTML::Entities::encode($showurl,'\'&"<>'); |
|
if ($symb) { |
|
my $showsymb = &Apache::lonenc::check_encrypt($symb); |
|
$querystring .= '&symb='.&HTML::Entities::encode($showsymb,'\'&"<>'); |
|
} |
} |
} |
|
|
my $output .= <<'END_MYBLOCK'; |
my $output .= <<'END_MYBLOCK'; |
Line 4648 END_MYBLOCK
|
Line 5493 END_MYBLOCK
|
|
|
my $popupUrl = "/adm/blockingstatus/$querystring"; |
my $popupUrl = "/adm/blockingstatus/$querystring"; |
my $text = &mt('Communication Blocked'); |
my $text = &mt('Communication Blocked'); |
|
my $class = 'LC_comblock'; |
if ($activity eq 'docs') { |
if ($activity eq 'docs') { |
$text = &mt('Content Access Blocked'); |
$text = &mt('Content Access Blocked'); |
|
$class = ''; |
} elsif ($activity eq 'printout') { |
} elsif ($activity eq 'printout') { |
$text = &mt('Printing Blocked'); |
$text = &mt('Printing Blocked'); |
|
} elsif ($activity eq 'passwd') { |
|
$text = &mt('Password Changing Blocked'); |
|
} elsif ($activity eq 'grades') { |
|
$text = &mt('Gradebook Blocked'); |
|
} elsif ($activity eq 'search') { |
|
$text = &mt('Search Blocked'); |
|
} elsif ($activity eq 'alert') { |
|
$text = &mt('Checking Critical Messages Blocked'); |
|
} elsif ($activity eq 'reinit') { |
|
$text = &mt('Checking Course Update Blocked'); |
} |
} |
$output .= <<"END_BLOCK"; |
$output .= <<"END_BLOCK"; |
<div class='LC_comblock'> |
<div class='$class'> |
<a onclick='openWindow("$popupUrl","Blocking Table",600,300,"no","no");return false;' href='/adm/blockingstatus/$querystring' |
<a onclick='openWindow("$popupUrl","Blocking Table",600,300,"no","no");return false;' href='/adm/blockingstatus/$querystring' |
title='$text'> |
title='$text'> |
<img class='LC_noBorder LC_middle' title='$text' src='/res/adm/pages/comblock.png' alt='$text'/></a> |
<img class='LC_noBorder LC_middle' title='$text' src='/res/adm/pages/comblock.png' alt='$text'/></a> |
Line 4670 END_BLOCK
|
Line 5527 END_BLOCK
|
############################################### |
############################################### |
|
|
sub check_ip_acc { |
sub check_ip_acc { |
my ($acc)=@_; |
my ($acc,$clientip)=@_; |
&Apache::lonxml::debug("acc is $acc"); |
&Apache::lonxml::debug("acc is $acc"); |
if (!defined($acc) || $acc =~ /^\s*$/ || $acc =~/^\s*no\s*$/i) { |
if (!defined($acc) || $acc =~ /^\s*$/ || $acc =~/^\s*no\s*$/i) { |
return 1; |
return 1; |
} |
} |
my $allowed=0; |
my ($ip,$allowed); |
my $ip=$env{'request.host'} || $ENV{'REMOTE_ADDR'}; |
if (($ENV{'REMOTE_ADDR'} eq '127.0.0.1') || |
|
($ENV{'REMOTE_ADDR'} eq &Apache::lonnet::get_host_ip($Apache::lonnet::perlvar{'lonHostID'}))) { |
|
$ip = $env{'request.host'} || $ENV{'REMOTE_ADDR'} || $clientip; |
|
} else { |
|
$ip = $ENV{'REMOTE_ADDR'} || $env{'request.host'} || $clientip; |
|
} |
|
|
my $name; |
my $name; |
foreach my $pattern (split(',',$acc)) { |
my %access = ( |
$pattern =~ s/^\s*//; |
allowfrom => 1, |
$pattern =~ s/\s*$//; |
denyfrom => 0, |
|
); |
|
my @allows; |
|
my @denies; |
|
foreach my $item (split(',',$acc)) { |
|
$item =~ s/^\s*//; |
|
$item =~ s/\s*$//; |
|
my $pattern; |
|
if ($item =~ /^\!(.+)$/) { |
|
push(@denies,$1); |
|
} else { |
|
push(@allows,$item); |
|
} |
|
} |
|
my $numdenies = scalar(@denies); |
|
my $numallows = scalar(@allows); |
|
my $count = 0; |
|
foreach my $pattern (@denies,@allows) { |
|
$count ++; |
|
my $acctype = 'allowfrom'; |
|
if ($count <= $numdenies) { |
|
$acctype = 'denyfrom'; |
|
} |
if ($pattern =~ /\*$/) { |
if ($pattern =~ /\*$/) { |
#35.8.* |
#35.8.* |
$pattern=~s/\*//; |
$pattern=~s/\*//; |
if ($ip =~ /^\Q$pattern\E/) { $allowed=1; } |
if ($ip =~ /^\Q$pattern\E/) { $allowed=$access{$acctype}; } |
} elsif ($pattern =~ /(\d+\.\d+\.\d+)\.\[(\d+)-(\d+)\]$/) { |
} elsif ($pattern =~ /(\d+\.\d+\.\d+)\.\[(\d+)-(\d+)\]$/) { |
#35.8.3.[34-56] |
#35.8.3.[34-56] |
my $low=$2; |
my $low=$2; |
Line 4693 sub check_ip_acc {
|
Line 5577 sub check_ip_acc {
|
$pattern=$1; |
$pattern=$1; |
if ($ip =~ /^\Q$pattern\E/) { |
if ($ip =~ /^\Q$pattern\E/) { |
my $last=(split(/\./,$ip))[3]; |
my $last=(split(/\./,$ip))[3]; |
if ($last <=$high && $last >=$low) { $allowed=1; } |
if ($last <=$high && $last >=$low) { $allowed=$access{$acctype}; } |
} |
} |
} elsif ($pattern =~ /^\*/) { |
} elsif ($pattern =~ /^\*/) { |
#*.msu.edu |
#*.msu.edu |
Line 4703 sub check_ip_acc {
|
Line 5587 sub check_ip_acc {
|
my $netaddr=inet_aton($ip); |
my $netaddr=inet_aton($ip); |
($name)=gethostbyaddr($netaddr,AF_INET); |
($name)=gethostbyaddr($netaddr,AF_INET); |
} |
} |
if ($name =~ /\Q$pattern\E$/i) { $allowed=1; } |
if ($name =~ /\Q$pattern\E$/i) { $allowed=$access{$acctype}; } |
} elsif ($pattern =~ /\d+\.\d+\.\d+\.\d+/) { |
} elsif ($pattern =~ /\d+\.\d+\.\d+\.\d+/) { |
#127.0.0.1 |
#127.0.0.1 |
if ($ip =~ /^\Q$pattern\E/) { $allowed=1; } |
if ($ip =~ /^\Q$pattern\E/) { $allowed=$access{$acctype}; } |
} else { |
} else { |
#some.name.com |
#some.name.com |
if (!defined($name)) { |
if (!defined($name)) { |
Line 4714 sub check_ip_acc {
|
Line 5598 sub check_ip_acc {
|
my $netaddr=inet_aton($ip); |
my $netaddr=inet_aton($ip); |
($name)=gethostbyaddr($netaddr,AF_INET); |
($name)=gethostbyaddr($netaddr,AF_INET); |
} |
} |
if ($name =~ /\Q$pattern\E$/i) { $allowed=1; } |
if ($name =~ /\Q$pattern\E$/i) { $allowed=$access{$acctype}; } |
|
} |
|
if ($allowed =~ /^(0|1)$/) { last; } |
|
} |
|
if ($allowed eq '') { |
|
if ($numdenies && !$numallows) { |
|
$allowed = 1; |
|
} else { |
|
$allowed = 0; |
} |
} |
if ($allowed) { last; } |
|
} |
} |
return $allowed; |
return $allowed; |
} |
} |
Line 4772 sub get_domainconf {
|
Line 5663 sub get_domainconf {
|
if (keys(%{$domconfig{'login'}})) { |
if (keys(%{$domconfig{'login'}})) { |
foreach my $key (keys(%{$domconfig{'login'}})) { |
foreach my $key (keys(%{$domconfig{'login'}})) { |
if (ref($domconfig{'login'}{$key}) eq 'HASH') { |
if (ref($domconfig{'login'}{$key}) eq 'HASH') { |
if ($key eq 'loginvia') { |
if (($key eq 'loginvia') || ($key eq 'headtag')) { |
if (ref($domconfig{'login'}{'loginvia'}) eq 'HASH') { |
if (ref($domconfig{'login'}{$key}) eq 'HASH') { |
foreach my $hostname (keys(%{$domconfig{'login'}{'loginvia'}})) { |
foreach my $hostname (keys(%{$domconfig{'login'}{$key}})) { |
if (ref($domconfig{'login'}{'loginvia'}{$hostname}) eq 'HASH') { |
if (ref($domconfig{'login'}{$key}{$hostname}) eq 'HASH') { |
if ($domconfig{'login'}{'loginvia'}{$hostname}{'server'}) { |
if ($key eq 'loginvia') { |
my $server = $domconfig{'login'}{'loginvia'}{$hostname}{'server'}; |
if ($domconfig{'login'}{'loginvia'}{$hostname}{'server'}) { |
$designhash{$udom.'.login.loginvia'} = $server; |
my $server = $domconfig{'login'}{'loginvia'}{$hostname}{'server'}; |
if ($domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'} eq 'custom') { |
$designhash{$udom.'.login.loginvia'} = $server; |
|
if ($domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'} eq 'custom') { |
$designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'custompath'}; |
|
} else { |
$designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'custompath'}; |
$designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'}; |
} else { |
|
$designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'}; |
|
} |
} |
} |
if ($domconfig{'login'}{'loginvia'}{$hostname}{'exempt'}) { |
} elsif ($key eq 'headtag') { |
$designhash{$udom.'.login.loginvia_exempt_'.$hostname} = $domconfig{'login'}{'loginvia'}{$hostname}{'exempt'}; |
if ($domconfig{'login'}{'headtag'}{$hostname}{'url'}) { |
|
$designhash{$udom.'.login.headtag_'.$hostname} = $domconfig{'login'}{'headtag'}{$hostname}{'url'}; |
} |
} |
} |
} |
|
if ($domconfig{'login'}{$key}{$hostname}{'exempt'}) { |
|
$designhash{$udom.'.login.'.$key.'_exempt_'.$hostname} = $domconfig{'login'}{$key}{$hostname}{'exempt'}; |
|
} |
} |
} |
} |
} |
} |
} |
Line 4856 sub get_legacy_domconf {
|
Line 5753 sub get_legacy_domconf {
|
my $designdir=$Apache::lonnet::perlvar{'lonTabDir'}.'/lonDomColors'; |
my $designdir=$Apache::lonnet::perlvar{'lonTabDir'}.'/lonDomColors'; |
my $designfile = $designdir.'/'.$udom.'.tab'; |
my $designfile = $designdir.'/'.$udom.'.tab'; |
if (-e $designfile) { |
if (-e $designfile) { |
if ( open (my $fh,"<$designfile") ) { |
if ( open (my $fh,'<',$designfile) ) { |
while (my $line = <$fh>) { |
while (my $line = <$fh>) { |
next if ($line =~ /^\#/); |
next if ($line =~ /^\#/); |
chomp($line); |
chomp($line); |
Line 5045 sub CSTR_pageheader {
|
Line 5942 sub CSTR_pageheader {
|
$lastitem = $thisdisfn; |
$lastitem = $thisdisfn; |
} |
} |
|
|
|
my ($crsauthor,$title); |
|
if (($env{'request.course.id'}) && |
|
($env{'course.'.$env{'request.course.id'}.'.num'} eq $uname) && |
|
($env{'course.'.$env{'request.course.id'}.'.domain'} eq $udom)) { |
|
$crsauthor = 1; |
|
$title = &mt('Course Authoring Space'); |
|
} else { |
|
$title = &mt('Authoring Space'); |
|
} |
|
|
|
my ($target,$crumbtarget) = (' target="_top"','_top'); #FIXME lonpubdir: target="_parent" |
|
if (($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) { |
|
$target = ''; |
|
$crumbtarget = ''; |
|
} |
|
|
my $output = |
my $output = |
'<div>' |
'<div>' |
.&Apache::loncommon::help_open_menu('','',3,'Authoring') #FIXME: Broken? Where is it? |
.&Apache::loncommon::help_open_menu('','',3,'Authoring') #FIXME: Broken? Where is it? |
.'<b>'.&mt('Authoring Space:').'</b> ' |
.'<b>'.$title.'</b> ' |
.'<form name="dirs" method="post" action="'.$formaction |
.'<form name="dirs" method="post" action="'.$formaction.'"'.$target.'>' |
.'" target="_top">' #FIXME lonpubdir: target="_parent" |
.&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,$crumbtarget,'/priv/'.$udom,undef,undef); |
.&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,'_top','/priv/'.$udom,undef,undef); |
|
|
|
if ($lastitem) { |
if ($lastitem) { |
$output .= |
$output .= |
Line 5059 sub CSTR_pageheader {
|
Line 5971 sub CSTR_pageheader {
|
.$lastitem |
.$lastitem |
.'</span>'; |
.'</span>'; |
} |
} |
$output .= |
|
'<br />' |
if ($crsauthor) { |
#FIXME lonpubdir: &Apache::lonhtmlcommon::crumbs($uname.$thisdisfn.'/','_top','/priv','','+1',1)."</b></tt><br />" |
$output .= '</form>'.&Apache::lonmenu::constspaceform(); |
.&Apache::lonhtmlcommon::select_recent('construct','recent','this.form.action=this.form.recent.value;this.form.submit()') |
} else { |
.'</form>' |
$output .= |
.&Apache::lonmenu::constspaceform() |
'<br />' |
.'</div>'; |
#FIXME lonpubdir: &Apache::lonhtmlcommon::crumbs($uname.$thisdisfn.'/',$crumbtarget,'/priv','','+1',1)."</b></tt><br />" |
|
.&Apache::lonhtmlcommon::select_recent('construct','recent','this.form.action=this.form.recent.value;this.form.submit()') |
|
.'</form>' |
|
.&Apache::lonmenu::constspaceform(); |
|
} |
|
$output .= '</div>'; |
|
|
return $output; |
return $output; |
} |
} |
Line 5109 Inputs:
|
Line 6026 Inputs:
|
|
|
=item * $args, optional argument valid values are |
=item * $args, optional argument valid values are |
no_auto_mt_title -> prevents &mt()ing the title arg |
no_auto_mt_title -> prevents &mt()ing the title arg |
inherit_jsmath -> when creating popup window in a page, |
use_absolute -> for external resource or syllabus, this will |
should it have jsmath forced on by the |
contain https://<hostname> if server uses |
current page |
https (as per hosts.tab), but request is for http |
|
hostname -> hostname, from $r->hostname(). |
|
|
=item * $advtoolsref, optional argument, ref to an array containing |
=item * $advtoolsref, optional argument, ref to an array containing |
inlineremote items to be added in "Functions" menu below |
inlineremote items to be added in "Functions" menu below |
breadcrumbs. |
breadcrumbs. |
|
|
|
=item * $ltiscope, optional argument, will be one of: resource, map or |
|
course, if LON-CAPA is in LTI Provider context. Value is |
|
the scope of use, i.e., launch was for access to a single, a map |
|
or the entire course. |
|
|
|
=item * $ltiuri, optional argument, if LON-CAPA is in LTI Provider |
|
context, this will contain the URL for the landing item in |
|
the course, after launch from an LTI Consumer |
|
|
|
=item * $ltimenu, optional argument, if LON-CAPA is in LTI Provider |
|
context, this will contain a reference to hash of items |
|
to be included in the page header and/or inline menu. |
|
|
=back |
=back |
|
|
Returns: A uniform header for LON-CAPA web pages. |
Returns: A uniform header for LON-CAPA web pages. |
Line 5128 other decorations will be returned.
|
Line 6059 other decorations will be returned.
|
|
|
sub bodytag { |
sub bodytag { |
my ($title,$function,$addentries,$bodyonly,$domain,$forcereg, |
my ($title,$function,$addentries,$bodyonly,$domain,$forcereg, |
$no_nav_bar,$bgcolor,$args,$advtoolsref)=@_; |
$no_nav_bar,$bgcolor,$args,$advtoolsref,$ltiscope,$ltiuri,$ltimenu)=@_; |
|
|
my $public; |
my $public; |
if ((($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public')) |
if ((($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public')) |
Line 5137 sub bodytag {
|
Line 6068 sub bodytag {
|
} |
} |
if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); } |
if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); } |
my $httphost = $args->{'use_absolute'}; |
my $httphost = $args->{'use_absolute'}; |
|
my $hostname = $args->{'hostname'}; |
|
|
$function = &get_users_function() if (!$function); |
$function = &get_users_function() if (!$function); |
my $img = &designparm($function.'.img',$domain); |
my $img = &designparm($function.'.img',$domain); |
Line 5164 sub bodytag {
|
Line 6096 sub bodytag {
|
if ($env{'request.course.id'}) { |
if ($env{'request.course.id'}) { |
if ($env{'request.role'} !~ /^cr/) { |
if ($env{'request.role'} !~ /^cr/) { |
$role = &Apache::lonnet::plaintext($role,&course_type()); |
$role = &Apache::lonnet::plaintext($role,&course_type()); |
|
} elsif ($role =~ m{^cr/($match_domain)/\1-domainconfig/(\w+)$}) { |
|
if ($env{'request.role.desc'}) { |
|
$role = $env{'request.role.desc'}; |
|
} else { |
|
$role = &mt('Helpdesk[_1]',' '.$2); |
|
} |
|
} else { |
|
$role = (split(/\//,$role,4))[-1]; |
} |
} |
if ($env{'request.course.sec'}) { |
if ($env{'request.course.sec'}) { |
$role .= (' 'x2).'- '.&mt('section:').' '.$env{'request.course.sec'}; |
$role .= (' 'x2).'- '.&mt('section:').' '.$env{'request.course.sec'}; |
Line 5179 sub bodytag {
|
Line 6119 sub bodytag {
|
|
|
# construct main body tag |
# construct main body tag |
my $bodytag = "<body $extra_body_attr>". |
my $bodytag = "<body $extra_body_attr>". |
&Apache::lontexconvert::init_math_support($args->{'inherit_jsmath'}); |
&Apache::lontexconvert::init_math_support(); |
|
|
&get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['inhibitmenu']); |
&get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['inhibitmenu']); |
|
|
Line 5190 sub bodytag {
|
Line 6130 sub bodytag {
|
if ($public) { |
if ($public) { |
undef($role); |
undef($role); |
} |
} |
|
|
|
if (($env{'request.course.id'}) && ($env{'request.lti.login'})) { |
|
if (ref($ltimenu) eq 'HASH') { |
|
unless ($ltimenu->{'role'}) { |
|
undef($role); |
|
} |
|
unless ($ltimenu->{'coursetitle'}) { |
|
$realm=' '; |
|
} |
|
} |
|
} |
|
|
my $titleinfo = '<h1>'.$title.'</h1>'; |
my $titleinfo = '<h1>'.$title.'</h1>'; |
# |
# |
# Extra info if you are the DC |
# Extra info if you are the DC |
Line 5203 sub bodytag {
|
Line 6154 sub bodytag {
|
$dc_info =~ s/\s+$//; |
$dc_info =~ s/\s+$//; |
} |
} |
|
|
$role = '<span class="LC_nobreak">('.$role.')</span>' if $role; |
my $crstype; |
|
if ($env{'request.course.id'}) { |
|
$crstype = $env{'course.'.$env{'request.course.id'}.'.type'}; |
|
} elsif ($args->{'crstype'}) { |
|
$crstype = $args->{'crstype'}; |
|
} |
|
if (($crstype eq 'Placement') && (!$env{'request.role.adv'})) { |
|
undef($role); |
|
} else { |
|
$role = '<span class="LC_nobreak">('.$role.')</span>' if ($role && !$env{'browser.mobile'}); |
|
} |
|
|
if ($env{'request.state'} eq 'construct') { $forcereg=1; } |
if ($env{'request.state'} eq 'construct') { $forcereg=1; } |
|
|
Line 5214 sub bodytag {
|
Line 6175 sub bodytag {
|
$bodytag .= Apache::lonhtmlcommon::scripttag( |
$bodytag .= Apache::lonhtmlcommon::scripttag( |
Apache::lonmenu::utilityfunctions($httphost), 'start'); |
Apache::lonmenu::utilityfunctions($httphost), 'start'); |
|
|
my ($left,$right) = Apache::lonmenu::primary_menu(); |
unless ($args->{'no_primary_menu'}) { |
|
my ($left,$right) = Apache::lonmenu::primary_menu($crstype,$ltimenu); |
|
|
if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { |
if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { |
if ($dc_info) { |
if ($dc_info) { |
$dc_info = qq|<span class="LC_cusr_subheading">$dc_info</span>|; |
$dc_info = qq|<span class="LC_cusr_subheading">$dc_info</span>|; |
} |
} |
$bodytag .= qq|<div id="LC_nav_bar">$left $role<br /> |
$bodytag .= qq|<div id="LC_nav_bar">$left $role<br /> |
<em>$realm</em> $dc_info</div>|; |
<em>$realm</em> $dc_info</div>|; |
return $bodytag; |
return $bodytag; |
} |
} |
|
|
unless ($env{'request.symb'} =~ m/\.page___\d+___/) { |
unless ($env{'request.symb'} =~ m/\.page___\d+___/) { |
$bodytag .= qq|<div id="LC_nav_bar">$left $role</div>|; |
$bodytag .= qq|<div id="LC_nav_bar">$left $role</div>|; |
} |
} |
|
|
$bodytag .= $right; |
$bodytag .= $right; |
|
|
if ($dc_info) { |
if ($dc_info) { |
$dc_info = &dc_courseid_toggle($dc_info); |
$dc_info = &dc_courseid_toggle($dc_info); |
|
} |
|
$bodytag .= qq|<div id="LC_realm">$realm $dc_info</div>|; |
} |
} |
$bodytag .= qq|<div id="LC_realm">$realm $dc_info</div>|; |
|
|
|
#if directed to not display the secondary menu, don't. |
#if directed to not display the secondary menu, don't. |
if ($args->{'no_secondary_menu'}) { |
if ($args->{'no_secondary_menu'}) { |
Line 5242 sub bodytag {
|
Line 6205 sub bodytag {
|
} |
} |
#don't show menus for public users |
#don't show menus for public users |
if (!$public){ |
if (!$public){ |
$bodytag .= Apache::lonmenu::secondary_menu($httphost); |
unless ($args->{'no_inline_menu'}) { |
|
$bodytag .= Apache::lonmenu::secondary_menu($httphost,$ltiscope,$ltimenu, |
|
$args->{'no_primary_menu'}); |
|
} |
$bodytag .= Apache::lonmenu::serverform(); |
$bodytag .= Apache::lonmenu::serverform(); |
$bodytag .= Apache::lonhtmlcommon::scripttag('', 'end'); |
$bodytag .= Apache::lonhtmlcommon::scripttag('', 'end'); |
if ($env{'request.state'} eq 'construct') { |
if ($env{'request.state'} eq 'construct') { |
$bodytag .= &Apache::lonmenu::innerregister($forcereg, |
$bodytag .= &Apache::lonmenu::innerregister($forcereg, |
$args->{'bread_crumbs'}); |
$args->{'bread_crumbs'},'','',$hostname,$ltiscope,$ltiuri); |
} elsif ($forcereg) { |
} elsif ($forcereg) { |
$bodytag .= &Apache::lonmenu::innerregister($forcereg,undef, |
$bodytag .= &Apache::lonmenu::innerregister($forcereg,undef, |
$args->{'group'}); |
$args->{'group'}, |
|
$args->{'hide_buttons'}, |
|
$hostname,$ltiscope,$ltiuri); |
} else { |
} else { |
$bodytag .= |
$bodytag .= |
&Apache::lonmenu::prepare_functions($env{'request.noversionuri'}, |
&Apache::lonmenu::prepare_functions($env{'request.noversionuri'}, |
$forcereg,$args->{'group'}, |
$forcereg,$args->{'group'}, |
$args->{'bread_crumbs'}, |
$args->{'bread_crumbs'}, |
$advtoolsref); |
$advtoolsref,'',$hostname); |
} |
} |
}else{ |
}else{ |
# this is to seperate menu from content when there's no secondary |
# this is to seperate menu from content when there's no secondary |
Line 5332 sub endbodytag {
|
Line 6300 sub endbodytag {
|
unless ((ref($args) eq 'HASH') && ($args->{'notbody'})) { |
unless ((ref($args) eq 'HASH') && ($args->{'notbody'})) { |
$endbodytag='</body>'; |
$endbodytag='</body>'; |
} |
} |
$endbodytag=&Apache::lontexconvert::jsMath_process()."\n".$endbodytag; |
|
if ( exists( $env{'internal.head.redirect'} ) ) { |
if ( exists( $env{'internal.head.redirect'} ) ) { |
if (!(ref($args) eq 'HASH' && $args->{'noredirectlink'})) { |
if (!(ref($args) eq 'HASH' && $args->{'noredirectlink'})) { |
$endbodytag= |
$endbodytag= |
Line 5507 div.LC_confirm_box .LC_success img {
|
Line 6474 div.LC_confirm_box .LC_success img {
|
vertical-align: middle; |
vertical-align: middle; |
} |
} |
|
|
|
.LC_maxwidth { |
|
max-width: 100%; |
|
height: auto; |
|
} |
|
|
|
.LC_textsize_mobile { |
|
\@media only screen and (max-device-width: 480px) { |
|
-webkit-text-size-adjust:100%; -moz-text-size-adjust:100%; -ms-text-size-adjust:100%; |
|
} |
|
} |
|
|
.LC_icon { |
.LC_icon { |
border: none; |
border: none; |
vertical-align: middle; |
vertical-align: middle; |
Line 5612 ul.LC_breadcrumb_tools_outerlist li {
|
Line 6590 ul.LC_breadcrumb_tools_outerlist li {
|
float: right; |
float: right; |
} |
} |
|
|
|
.LC_placement_prog { |
|
padding-right: 20px; |
|
font-weight: bold; |
|
font-size: 90%; |
|
} |
|
|
table#LC_title_bar td { |
table#LC_title_bar td { |
background: $tabbg; |
background: $tabbg; |
} |
} |
Line 5628 table#LC_menubuttons img {
|
Line 6612 table#LC_menubuttons img {
|
vertical-align: middle; |
vertical-align: middle; |
} |
} |
|
|
|
.LC_breadcrumbs_hoverable { |
|
background: $sidebg; |
|
} |
|
|
td.LC_table_cell_checkbox { |
td.LC_table_cell_checkbox { |
text-align: center; |
text-align: center; |
} |
} |
Line 5698 td.LC_menubuttons_text {
|
Line 6686 td.LC_menubuttons_text {
|
background: $tabbg; |
background: $tabbg; |
} |
} |
|
|
|
td.LC_zero_height { |
|
line-height: 0; |
|
cellpadding: 0; |
|
} |
|
|
table.LC_data_table { |
table.LC_data_table { |
border: 1px solid #000000; |
border: 1px solid #000000; |
border-collapse: separate; |
border-collapse: separate; |
Line 6019 td.LC_parm_overview_restrictions {
|
Line 7012 td.LC_parm_overview_restrictions {
|
border-collapse: collapse; |
border-collapse: collapse; |
} |
} |
|
|
|
span.LC_parm_recursive, |
|
td.LC_parm_recursive { |
|
font-weight: bold; |
|
font-size: smaller; |
|
} |
|
|
table.LC_parm_overview_restrictions td { |
table.LC_parm_overview_restrictions td { |
border-width: 1px 4px 1px 4px; |
border-width: 1px 4px 1px 4px; |
border-style: solid; |
border-style: solid; |
Line 6288 table.LC_prior_tries td {
|
Line 7287 table.LC_prior_tries td {
|
padding: 6px; |
padding: 6px; |
} |
} |
|
|
.LC_answer_unknown { |
.LC_answer_unknown, |
|
.LC_answer_warning { |
background: orange; |
background: orange; |
color: black; |
color: black; |
padding: 6px; |
padding: 6px; |
Line 6370 table.LC_data_table tr > td.LC_docs_entr
|
Line 7370 table.LC_data_table tr > td.LC_docs_entr
|
color: #990000; |
color: #990000; |
} |
} |
|
|
|
.LC_docs_alias { |
|
color: #440055; |
|
} |
|
|
|
.LC_domprefs_email, |
|
.LC_docs_alias_name, |
.LC_docs_reinit_warn, |
.LC_docs_reinit_warn, |
.LC_docs_ext_edit { |
.LC_docs_ext_edit { |
font-size: x-small; |
font-size: x-small; |
Line 6485 div.LC_edit_problem_footer,
|
Line 7491 div.LC_edit_problem_footer,
|
div.LC_edit_problem_footer div, |
div.LC_edit_problem_footer div, |
div.LC_edit_problem_editxml_header, |
div.LC_edit_problem_editxml_header, |
div.LC_edit_problem_editxml_header div { |
div.LC_edit_problem_editxml_header div { |
margin-top: 5px; |
z-index: 100; |
} |
} |
|
|
div.LC_edit_problem_header_title { |
div.LC_edit_problem_header_title { |
Line 6501 table.LC_edit_problem_header_title {
|
Line 7507 table.LC_edit_problem_header_title {
|
background: $tabbg; |
background: $tabbg; |
} |
} |
|
|
div.LC_edit_problem_discards { |
div.LC_edit_actionbar { |
float: left; |
background-color: $sidebg; |
padding-bottom: 5px; |
margin: 0; |
|
padding: 0; |
|
line-height: 200%; |
} |
} |
|
|
div.LC_edit_problem_saves { |
div.LC_edit_actionbar div{ |
float: right; |
padding: 0; |
padding-bottom: 5px; |
margin: 0; |
|
display: inline-block; |
} |
} |
|
|
.LC_edit_opt { |
.LC_edit_opt { |
Line 6524 div.LC_edit_problem_saves {
|
Line 7533 div.LC_edit_problem_saves {
|
margin-left: 40px; |
margin-left: 40px; |
} |
} |
|
|
|
#LC_edit_problem_codemirror div{ |
|
margin-left: 0px; |
|
} |
|
|
img.stift { |
img.stift { |
border-width: 0; |
border-width: 0; |
vertical-align: middle; |
vertical-align: middle; |
Line 6611 fieldset {
|
Line 7624 fieldset {
|
/* overflow: hidden; */ |
/* overflow: hidden; */ |
} |
} |
|
|
|
article.geogebraweb div { |
|
margin: 0; |
|
} |
|
|
fieldset > legend { |
fieldset > legend { |
font-weight: bold; |
font-weight: bold; |
padding: 0 5px 0 5px; |
padding: 0 5px 0 5px; |
Line 6638 fieldset > legend {
|
Line 7655 fieldset > legend {
|
ol.LC_primary_menu { |
ol.LC_primary_menu { |
margin: 0; |
margin: 0; |
padding: 0; |
padding: 0; |
background-color: $pgbg_or_bgcolor; |
|
} |
} |
|
|
ol#LC_PathBreadcrumbs { |
ol#LC_PathBreadcrumbs { |
Line 6650 ol.LC_primary_menu li {
|
Line 7666 ol.LC_primary_menu li {
|
vertical-align: middle; |
vertical-align: middle; |
text-align: left; |
text-align: left; |
list-style: none; |
list-style: none; |
|
position: relative; |
float: left; |
float: left; |
|
z-index: 100; /* will be displayed above codemirror and underneath the help-layer */ |
|
line-height: 1.5em; |
} |
} |
|
|
ol.LC_primary_menu li a { |
ol.LC_primary_menu li a, |
|
ol.LC_primary_menu li p { |
display: block; |
display: block; |
margin: 0; |
margin: 0; |
padding: 0 5px 0 10px; |
padding: 0 5px 0 10px; |
text-decoration: none; |
text-decoration: none; |
} |
} |
|
|
ol.LC_primary_menu li ul { |
ol.LC_primary_menu li p span.LC_primary_menu_innertitle { |
|
display: inline-block; |
|
width: 95%; |
|
text-align: left; |
|
} |
|
|
|
ol.LC_primary_menu li p span.LC_primary_menu_innerarrow { |
|
display: inline-block; |
|
width: 5%; |
|
float: right; |
|
text-align: right; |
|
font-size: 70%; |
|
} |
|
|
|
ol.LC_primary_menu ul { |
display: none; |
display: none; |
width: 10em; |
width: 15em; |
background-color: $data_table_light; |
background-color: $data_table_light; |
|
position: absolute; |
|
top: 100%; |
|
} |
|
|
|
ol.LC_primary_menu ul ul { |
|
left: 100%; |
|
top: 0; |
} |
} |
|
|
ol.LC_primary_menu li:hover ul, ol.LC_primary_menu li.hover ul { |
ol.LC_primary_menu li:hover > ul, ol.LC_primary_menu li.hover > ul { |
display: block; |
display: block; |
position: absolute; |
position: absolute; |
margin: 0; |
margin: 0; |
Line 6675 ol.LC_primary_menu li:hover ul, ol.LC_pr
|
Line 7716 ol.LC_primary_menu li:hover ul, ol.LC_pr
|
} |
} |
|
|
ol.LC_primary_menu li:hover li, ol.LC_primary_menu li.hover li { |
ol.LC_primary_menu li:hover li, ol.LC_primary_menu li.hover li { |
|
/* First Submenu -> size should be smaller than the menu title of the whole menu */ |
font-size: 90%; |
font-size: 90%; |
vertical-align: top; |
vertical-align: top; |
float: none; |
float: none; |
border-left: 1px solid black; |
border-left: 1px solid black; |
border-right: 1px solid black; |
border-right: 1px solid black; |
|
/* A dark bottom border to visualize different menu options; |
|
overwritten in the create_submenu routine for the last border-bottom of the menu */ |
|
border-bottom: 1px solid $data_table_dark; |
} |
} |
|
|
ol.LC_primary_menu li:hover li a, ol.LC_primary_menu li.hover li a { |
ol.LC_primary_menu li li p:hover { |
background-color:$data_table_light; |
color:$button_hover; |
|
text-decoration:none; |
|
background-color:$data_table_dark; |
} |
} |
|
|
ol.LC_primary_menu li li a:hover { |
ol.LC_primary_menu li li a:hover { |
Line 6691 ol.LC_primary_menu li li a:hover {
|
Line 7738 ol.LC_primary_menu li li a:hover {
|
background-color:$data_table_dark; |
background-color:$data_table_dark; |
} |
} |
|
|
|
/* Font-size equal to the size of the predecessors*/ |
|
ol.LC_primary_menu li:hover li li { |
|
font-size: 100%; |
|
} |
|
|
ol.LC_primary_menu li img { |
ol.LC_primary_menu li img { |
vertical-align: bottom; |
vertical-align: bottom; |
height: 1.1em; |
height: 1.1em; |
Line 7232 ul.LC_funclist li {
|
Line 8284 ul.LC_funclist li {
|
cursor:pointer; |
cursor:pointer; |
} |
} |
|
|
|
pre.LC_wordwrap { |
|
white-space: pre-wrap; |
|
white-space: -moz-pre-wrap; |
|
white-space: -pre-wrap; |
|
white-space: -o-pre-wrap; |
|
word-wrap: break-word; |
|
} |
|
|
|
/* |
|
styles used for response display |
|
*/ |
|
div.LC_radiofoil, div.LC_rankfoil { |
|
margin: .5em 0em .5em 0em; |
|
} |
|
table.LC_itemgroup { |
|
margin-top: 1em; |
|
} |
|
|
/* |
/* |
styles used by TTH when "Default set of options to pass to tth/m |
styles used by TTH when "Default set of options to pass to tth/m |
when converting TeX" in course settings has been set |
when converting TeX" in course settings has been set |
Line 7253 span.roman {font-family: serif; font-sty
|
Line 8323 span.roman {font-family: serif; font-sty
|
span.overacc2 {position: relative; left: .8em; top: -1.2ex;} |
span.overacc2 {position: relative; left: .8em; top: -1.2ex;} |
span.overacc1 {position: relative; left: .6em; top: -1.2ex;} |
span.overacc1 {position: relative; left: .6em; top: -1.2ex;} |
|
|
|
/* |
|
sections with roles, for content only |
|
*/ |
|
section[class^="role-"] { |
|
padding-left: 10px; |
|
padding-right: 5px; |
|
margin-top: 8px; |
|
margin-bottom: 8px; |
|
border: 1px solid #2A4; |
|
border-radius: 5px; |
|
box-shadow: 0px 1px 1px #BBB; |
|
} |
|
section[class^="role-"]>h1 { |
|
position: relative; |
|
margin: 0px; |
|
padding-top: 10px; |
|
padding-left: 40px; |
|
} |
|
section[class^="role-"]>h1:before { |
|
position: absolute; |
|
left: -5px; |
|
top: 5px; |
|
} |
|
section.role-activity>h1:before { |
|
content:url('/adm/daxe/images/section_icons/activity.png'); |
|
} |
|
section.role-advice>h1:before { |
|
content:url('/adm/daxe/images/section_icons/advice.png'); |
|
} |
|
section.role-bibliography>h1:before { |
|
content:url('/adm/daxe/images/section_icons/bibliography.png'); |
|
} |
|
section.role-citation>h1:before { |
|
content:url('/adm/daxe/images/section_icons/citation.png'); |
|
} |
|
section.role-conclusion>h1:before { |
|
content:url('/adm/daxe/images/section_icons/conclusion.png'); |
|
} |
|
section.role-definition>h1:before { |
|
content:url('/adm/daxe/images/section_icons/definition.png'); |
|
} |
|
section.role-demonstration>h1:before { |
|
content:url('/adm/daxe/images/section_icons/demonstration.png'); |
|
} |
|
section.role-example>h1:before { |
|
content:url('/adm/daxe/images/section_icons/example.png'); |
|
} |
|
section.role-explanation>h1:before { |
|
content:url('/adm/daxe/images/section_icons/explanation.png'); |
|
} |
|
section.role-introduction>h1:before { |
|
content:url('/adm/daxe/images/section_icons/introduction.png'); |
|
} |
|
section.role-method>h1:before { |
|
content:url('/adm/daxe/images/section_icons/method.png'); |
|
} |
|
section.role-more_information>h1:before { |
|
content:url('/adm/daxe/images/section_icons/more_information.png'); |
|
} |
|
section.role-objectives>h1:before { |
|
content:url('/adm/daxe/images/section_icons/objectives.png'); |
|
} |
|
section.role-prerequisites>h1:before { |
|
content:url('/adm/daxe/images/section_icons/prerequisites.png'); |
|
} |
|
section.role-remark>h1:before { |
|
content:url('/adm/daxe/images/section_icons/remark.png'); |
|
} |
|
section.role-reminder>h1:before { |
|
content:url('/adm/daxe/images/section_icons/reminder.png'); |
|
} |
|
section.role-summary>h1:before { |
|
content:url('/adm/daxe/images/section_icons/summary.png'); |
|
} |
|
section.role-syntax>h1:before { |
|
content:url('/adm/daxe/images/section_icons/syntax.png'); |
|
} |
|
section.role-warning>h1:before { |
|
content:url('/adm/daxe/images/section_icons/warning.png'); |
|
} |
|
|
|
#LC_minitab_header { |
|
float:left; |
|
width:100%; |
|
background:#DAE0D2 url("/res/adm/pages/minitabmenu_bg.gif") repeat-x bottom; |
|
font-size:93%; |
|
line-height:normal; |
|
margin: 0.5em 0 0.5em 0; |
|
} |
|
#LC_minitab_header ul { |
|
margin:0; |
|
padding:10px 10px 0; |
|
list-style:none; |
|
} |
|
#LC_minitab_header li { |
|
float:left; |
|
background:url("/res/adm/pages/minitabmenu_left.gif") no-repeat left top; |
|
margin:0; |
|
padding:0 0 0 9px; |
|
} |
|
#LC_minitab_header a { |
|
display:block; |
|
background:url("/res/adm/pages/minitabmenu_right.gif") no-repeat right top; |
|
padding:5px 15px 4px 6px; |
|
} |
|
#LC_minitab_header #LC_current_minitab { |
|
background-image:url("/res/adm/pages/minitabmenu_left_on.gif"); |
|
} |
|
#LC_minitab_header #LC_current_minitab a { |
|
background-image:url("/res/adm/pages/minitabmenu_right_on.gif"); |
|
padding-bottom:5px; |
|
} |
|
|
|
|
END |
END |
} |
} |
|
|
Line 7345 sub headtag {
|
Line 8529 sub headtag {
|
<meta http-equiv="pragma" content="no-cache" /> |
<meta http-equiv="pragma" content="no-cache" /> |
<meta http-equiv="Refresh" content="$time; url=$url" /> |
<meta http-equiv="Refresh" content="$time; url=$url" /> |
ADDMETA |
ADDMETA |
|
} else { |
|
unless (($args->{'frameset'}) || ($args->{'js_ready'}) || ($args->{'only_body'}) || ($args->{'no_nav_bar'})) { |
|
my $requrl = $env{'request.uri'}; |
|
if ($requrl eq '') { |
|
$requrl = $ENV{'REQUEST_URI'}; |
|
$requrl =~ s/\?.+$//; |
|
} |
|
unless (($requrl =~ m{^/adm/(?:switchserver|login|authenticate|logout|groupsort|cleanup|helper|slotrequest|grades)(\?|$)}) || |
|
(($requrl =~ m{^/res/}) && (($env{'form.submitted'} eq 'scantron') || |
|
($env{'form.grade_symb'}) || ($Apache::lonhomework::scantronmode)))) { |
|
my $dom_in_use = $Apache::lonnet::perlvar{'lonDefDomain'}; |
|
unless (&Apache::lonnet::allowed('mau',$dom_in_use)) { |
|
my %domdefs = &Apache::lonnet::get_domain_defaults($dom_in_use); |
|
my $lonhost = $Apache::lonnet::perlvar{'lonHostID'}; |
|
my $offload; |
|
if (ref($domdefs{'offloadnow'}) eq 'HASH') { |
|
if ($domdefs{'offloadnow'}{$lonhost}) { |
|
$offload = 1; |
|
} |
|
} |
|
unless ($offload) { |
|
if (ref($domdefs{'offloadoth'}) eq 'HASH') { |
|
if ($domdefs{'offloadoth'}{$lonhost}) { |
|
if (($env{'user.domain'} ne '') && ($env{'user.domain'} ne $dom_in_use) && |
|
(!(($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public')))) { |
|
unless (&Apache::lonnet::shared_institution($env{'user.domain'})) { |
|
$offload = 1; |
|
$dom_in_use = $env{'user.domain'}; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if ($offload) { |
|
my $newserver = &Apache::lonnet::spareserver(30000,undef,1,$dom_in_use); |
|
if (($newserver) && ($newserver ne $lonhost)) { |
|
my $numsec = 5; |
|
my $timeout = $numsec * 1000; |
|
my ($newurl,$locknum,%locks,$msg); |
|
if ($env{'request.role.adv'}) { |
|
($locknum,%locks) = &Apache::lonnet::get_locks(); |
|
} |
|
my $disable_submit = 0; |
|
if ($requrl =~ /$LONCAPA::assess_re/) { |
|
$disable_submit = 1; |
|
} |
|
if ($locknum) { |
|
my @lockinfo = sort(values(%locks)); |
|
$msg = &mt('Once the following tasks are complete: ')."\n". |
|
join(", ",sort(values(%locks)))."\n"; |
|
if (&show_course()) { |
|
$msg .= &mt('your session will be transferred to a different server, after you click "Courses".'); |
|
} else { |
|
$msg .= &mt('your session will be transferred to a different server, after you click "Roles".'); |
|
} |
|
} else { |
|
if (($requrl =~ m{^/res/}) && ($env{'form.submitted'} =~ /^part_/)) { |
|
$msg = &mt('Your LON-CAPA submission has been recorded')."\n"; |
|
} |
|
$msg .= &mt('Your current LON-CAPA session will be transferred to a different server in [quant,_1,second].',$numsec); |
|
$newurl = '/adm/switchserver?otherserver='.$newserver; |
|
if (($env{'request.role'}) && ($env{'request.role'} ne 'cm')) { |
|
$newurl .= '&role='.$env{'request.role'}; |
|
} |
|
if ($env{'request.symb'}) { |
|
my $shownsymb = &Apache::lonenc::check_encrypt($env{'request.symb'}); |
|
if ($shownsymb =~ m{^/enc/}) { |
|
my $reqdmajor = 2; |
|
my $reqdminor = 11; |
|
my $reqdsubminor = 3; |
|
my $newserverrev = &Apache::lonnet::get_server_loncaparev('',$newserver); |
|
my $remoterev = &Apache::lonnet::get_server_loncaparev(undef,$newserver); |
|
my ($major,$minor,$subminor) = ($remoterev =~ /^\'?(\d+)\.(\d+)\.(\d+|)[\w.\-]+\'?$/); |
|
if (($major eq '' && $minor eq '') || |
|
(($reqdmajor > $major) || (($reqdmajor == $major) && ($reqdminor > $minor)) || |
|
(($reqdmajor == $major) && ($reqdminor == $minor) && (($subminor eq '') || |
|
($reqdsubminor > $subminor))))) { |
|
undef($shownsymb); |
|
} |
|
} |
|
if ($shownsymb) { |
|
&js_escape(\$shownsymb); |
|
$newurl .= '&symb='.$shownsymb; |
|
} |
|
} else { |
|
my $shownurl = &Apache::lonenc::check_encrypt($requrl); |
|
&js_escape(\$shownurl); |
|
$newurl .= '&origurl='.$shownurl; |
|
} |
|
} |
|
&js_escape(\$msg); |
|
$result.=<<OFFLOAD |
|
<meta http-equiv="pragma" content="no-cache" /> |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
function LC_Offload_Now() { |
|
var dest = "$newurl"; |
|
if (dest != '') { |
|
window.location.href="$newurl"; |
|
} |
|
} |
|
\$(document).ready(function () { |
|
window.alert('$msg'); |
|
if ($disable_submit) { |
|
\$(".LC_hwk_submit").prop("disabled", true); |
|
\$( ".LC_textline" ).prop( "readonly", "readonly"); |
|
} |
|
setTimeout('LC_Offload_Now()', $timeout); |
|
}); |
|
// ]]> |
|
</script> |
|
OFFLOAD |
|
} |
|
} |
|
} |
|
} |
|
} |
} |
} |
if (!defined($title)) { |
if (!defined($title)) { |
$title = 'The LearningOnline Network with CAPA'; |
$title = 'The LearningOnline Network with CAPA'; |
Line 7358 ADDMETA
|
Line 8659 ADDMETA
|
$result .= '>' |
$result .= '>' |
.$inhibitprint |
.$inhibitprint |
.$head_extra; |
.$head_extra; |
if ($env{'browser.mobile'}) { |
my $clientmobile; |
|
if (($env{'user.name'} eq '') && ($env{'user.domain'} eq '')) { |
|
(undef,undef,undef,undef,undef,undef,$clientmobile) = &decode_user_agent(); |
|
} else { |
|
$clientmobile = $env{'browser.mobile'}; |
|
} |
|
if ($clientmobile) { |
$result .= ' |
$result .= ' |
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0"> |
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0"> |
<meta name="apple-mobile-web-app-capable" content="yes" />'; |
<meta name="apple-mobile-web-app-capable" content="yes" />'; |
} |
} |
|
$result .= '<meta name="google" content="notranslate" />'."\n"; |
return $result.'</head>'; |
return $result.'</head>'; |
} |
} |
|
|
Line 7540 $args - additional optional args support
|
Line 8848 $args - additional optional args support
|
head -> skip the <html><head> generation |
head -> skip the <html><head> generation |
body -> skip all <body> generation |
body -> skip all <body> generation |
no_auto_mt_title -> prevent &mt()ing the title arg |
no_auto_mt_title -> prevent &mt()ing the title arg |
inherit_jsmath -> when creating popup window in a page, |
|
should it have jsmath forced on by the |
|
current page |
|
bread_crumbs -> Array containing breadcrumbs |
bread_crumbs -> Array containing breadcrumbs |
bread_crumbs_component -> if exists show it as headline else show only the breadcrumbs |
bread_crumbs_component -> if exists show it as headline else show only the breadcrumbs |
|
bread_crumbs_nomenu -> if true will pass false as the value of $menulink |
|
to lonhtmlcommon::breadcrumbs |
group -> includes the current group, if page is for a |
group -> includes the current group, if page is for a |
specific group |
specific group |
|
use_absolute -> for request for external resource or syllabus, this |
|
will contain https://<hostname> if server uses |
|
https (as per hosts.tab), but request is for http |
|
hostname -> hostname, originally from $r->hostname(), (optional). |
|
|
=back |
=back |
|
|
Line 7559 sub start_page {
|
Line 8870 sub start_page {
|
#&Apache::lonnet::logthis("start_page ".join(':',caller(0))); |
#&Apache::lonnet::logthis("start_page ".join(':',caller(0))); |
|
|
$env{'internal.start_page'}++; |
$env{'internal.start_page'}++; |
my ($result,@advtools); |
my ($result,@advtools,$ltiscope,$ltiuri,%ltimenu); |
|
|
if (! exists($args->{'skip_phases'}{'head'}) ) { |
if (! exists($args->{'skip_phases'}{'head'}) ) { |
$result .= &xml_begin($args->{'frameset'}) . &headtag($title, $head_extra, $args); |
$result .= &xml_begin($args->{'frameset'}) . &headtag($title, $head_extra, $args); |
} |
} |
|
|
|
if (($env{'request.course.id'}) && ($env{'request.lti.login'})) { |
|
if ($env{'course.'.$env{'request.course.id'}.'.lti.override'}) { |
|
unless ($env{'course.'.$env{'request.course.id'}.'.lti.topmenu'}) { |
|
$args->{'no_primary_menu'} = 1; |
|
} |
|
unless ($env{'course.'.$env{'request.course.id'}.'.lti.inlinemenu'}) { |
|
$args->{'no_inline_menu'} = 1; |
|
} |
|
if ($env{'course.'.$env{'request.course.id'}.'.lti.lcmenu'}) { |
|
map { $ltimenu{$_} = 1; } split(/,/,$env{'course.'.$env{'request.course.id'}.'.lti.lcmenu'}); |
|
} |
|
} else { |
|
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
my %lti = &Apache::lonnet::get_domain_lti($cdom,'provider'); |
|
if (ref($lti{$env{'request.lti.login'}}) eq 'HASH') { |
|
unless ($lti{$env{'request.lti.login'}}{'topmenu'}) { |
|
$args->{'no_primary_menu'} = 1; |
|
} |
|
unless ($lti{$env{'request.lti.login'}}{'inlinemenu'}) { |
|
$args->{'no_inline_menu'} = 1; |
|
} |
|
if (ref($lti{$env{'request.lti.login'}}{'lcmenu'}) eq 'ARRAY') { |
|
map { $ltimenu{$_} = 1; } @{$lti{$env{'request.lti.login'}}{'lcmenu'}}; |
|
} |
|
} |
|
} |
|
($ltiscope,$ltiuri) = &LONCAPA::ltiutils::lti_provider_scope($env{'request.lti.uri'}, |
|
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
|
$env{'course.'.$env{'request.course.id'}.'.num'}); |
|
} |
|
|
if (! exists($args->{'skip_phases'}{'body'}) ) { |
if (! exists($args->{'skip_phases'}{'body'}) ) { |
if ($args->{'frameset'}) { |
if ($args->{'frameset'}) { |
Line 7577 sub start_page {
|
Line 8919 sub start_page {
|
$args->{'only_body'}, $args->{'domain'}, |
$args->{'only_body'}, $args->{'domain'}, |
$args->{'force_register'}, $args->{'no_nav_bar'}, |
$args->{'force_register'}, $args->{'no_nav_bar'}, |
$args->{'bgcolor'}, $args, |
$args->{'bgcolor'}, $args, |
\@advtools); |
\@advtools,$ltiscope,$ltiuri,\%ltimenu); |
} |
} |
} |
} |
|
|
Line 7610 sub start_page {
|
Line 8952 sub start_page {
|
if (@advtools > 0) { |
if (@advtools > 0) { |
&Apache::lonmenu::advtools_crumbs(@advtools); |
&Apache::lonmenu::advtools_crumbs(@advtools); |
} |
} |
|
my $menulink; |
|
# if arg: bread_crumbs_nomenu is true pass 0 as $menulink item. |
|
if ((exists($args->{'bread_crumbs_nomenu'})) || |
|
($ltiscope eq 'map') || ($ltiscope eq 'resource') || |
|
((($args->{'crstype'} eq 'Placement') || (($env{'request.course.id'}) && |
|
($env{'course.'.$env{'request.course.id'}.'.type'} eq 'Placement'))) && |
|
(!$env{'request.role.adv'}))) { |
|
$menulink = 0; |
|
} else { |
|
undef($menulink); |
|
} |
#if bread_crumbs_component exists show it as headline else show only the breadcrumbs |
#if bread_crumbs_component exists show it as headline else show only the breadcrumbs |
if(exists($args->{'bread_crumbs_component'})){ |
if(exists($args->{'bread_crumbs_component'})){ |
$result .= &Apache::lonhtmlcommon::breadcrumbs($args->{'bread_crumbs_component'}); |
$result .= &Apache::lonhtmlcommon::breadcrumbs($args->{'bread_crumbs_component'},'',$menulink); |
}else{ |
} else { |
$result .= &Apache::lonhtmlcommon::breadcrumbs(); |
$result .= &Apache::lonhtmlcommon::breadcrumbs('','',$menulink); |
} |
} |
} |
} |
return $result; |
return $result; |
Line 7664 function set_wishlistlink(title, path) {
|
Line 9016 function set_wishlistlink(title, path) {
|
title = title.replace(/^LON-CAPA /,''); |
title = title.replace(/^LON-CAPA /,''); |
} |
} |
title = encodeURIComponent(title); |
title = encodeURIComponent(title); |
|
title = title.replace("'","\\\'"); |
if (!path) { |
if (!path) { |
path = location.pathname; |
path = location.pathname; |
} |
} |
path = encodeURIComponent(path); |
path = encodeURIComponent(path); |
|
path = path.replace("'","\\\'"); |
Win = window.open('/adm/wishlist?mode=newLink&setTitle='+title+'&setPath='+path, |
Win = window.open('/adm/wishlist?mode=newLink&setTitle='+title+'&setPath='+path, |
'wishlistNewLink','width=560,height=350,scrollbars=0'); |
'wishlistNewLink','width=560,height=350,scrollbars=0'); |
} |
} |
Line 7710 var modalWindow = {
|
Line 9064 var modalWindow = {
|
}; |
}; |
var openMyModal = function(source,width,height,scrolling,transparency,style) |
var openMyModal = function(source,width,height,scrolling,transparency,style) |
{ |
{ |
|
source = source.replace(/'/g,"'"); |
modalWindow.windowId = "myModal"; |
modalWindow.windowId = "myModal"; |
modalWindow.width = width; |
modalWindow.width = width; |
modalWindow.height = height; |
modalWindow.height = height; |
modalWindow.content = "<iframe width='"+width+"' height='"+height+"' frameborder='0' scrolling='"+scrolling+"' allowtransparency='"+transparency+"' src='" + source + "' style='"+style+"'></iframe>"; |
modalWindow.content = "<iframe width='"+width+"' height='"+height+"' frameborder='0' scrolling='"+scrolling+"' allowtransparency='"+transparency+"' src='" + source + "' style='"+style+"'></iframe>"; |
modalWindow.open(); |
modalWindow.open(); |
}; |
}; |
// END LON-CAPA Internal --> |
// END LON-CAPA Internal --> |
// ]]> |
// ]]> |
</script> |
</script> |
Line 7734 sub modal_link {
|
Line 9089 sub modal_link {
|
$target_attr = 'target="'.$target.'"'; |
$target_attr = 'target="'.$target.'"'; |
} |
} |
return <<"ENDLINK"; |
return <<"ENDLINK"; |
<a href="$link" $target_attr title="$title" onclick="javascript:openMyModal('$link',$width,$height,'$scrolling','$transparency','$style'); return false;"> |
<a href="$link" $target_attr title="$title" onclick="javascript:openMyModal('$link',$width,$height,'$scrolling','$transparency','$style'); return false;">$linktext</a> |
$linktext</a> |
|
ENDLINK |
ENDLINK |
} |
} |
|
|
Line 7838 sub end_togglebox {
|
Line 9192 sub end_togglebox {
|
} |
} |
|
|
sub LCprogressbar_script { |
sub LCprogressbar_script { |
my ($id)=@_; |
my ($id,$number_to_do)=@_; |
return(<<ENDPROGRESS); |
if ($number_to_do) { |
|
return(<<ENDPROGRESS); |
<script type="text/javascript"> |
<script type="text/javascript"> |
// <![CDATA[ |
// <![CDATA[ |
\$('#progressbar$id').progressbar({ |
\$('#progressbar$id').progressbar({ |
Line 7852 sub LCprogressbar_script {
|
Line 9207 sub LCprogressbar_script {
|
// ]]> |
// ]]> |
</script> |
</script> |
ENDPROGRESS |
ENDPROGRESS |
|
} else { |
|
return(<<ENDPROGRESS); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
\$('#progressbar$id').progressbar({ |
|
value: false, |
|
create: function(event, ui) { |
|
\$('.ui-widget-header', this).css({'background':'#F0F0F0'}); |
|
\$('.ui-progressbar-overlay', this).css({'margin':'0'}); |
|
} |
|
}); |
|
// ]]> |
|
</script> |
|
ENDPROGRESS |
|
} |
} |
} |
|
|
sub LCprogressbarUpdate_script { |
sub LCprogressbarUpdate_script { |
return(<<ENDPROGRESSUPDATE); |
return(<<ENDPROGRESSUPDATE); |
<style type="text/css"> |
<style type="text/css"> |
.ui-progressbar { position:relative; } |
.ui-progressbar { position:relative; } |
|
.progress-label {position: absolute; width: 100%; text-align: center; top: 1px; font-weight: bold; text-shadow: 1px 1px 0 #fff;margin: 0; line-height: 200%; } |
.pblabel { position: absolute; width: 100%; text-align: center; line-height: 1.9em; } |
.pblabel { position: absolute; width: 100%; text-align: center; line-height: 1.9em; } |
</style> |
</style> |
<script type="text/javascript"> |
<script type="text/javascript"> |
// <![CDATA[ |
// <![CDATA[ |
var LCprogressTxt='---'; |
var LCprogressTxt='---'; |
|
|
function LCupdateProgress(percent,progresstext,id) { |
function LCupdateProgress(percent,progresstext,id,maxnum) { |
LCprogressTxt=progresstext; |
LCprogressTxt=progresstext; |
\$('#progressbar'+id).progressbar('value',percent); |
if ((maxnum == '') || (maxnum == undefined) || (maxnum == null)) { |
|
\$('#progressbar'+id).find('.progress-label').text(LCprogressTxt); |
|
} else if (percent === \$('#progressbar'+id).progressbar( "value" )) { |
|
\$('#progressbar'+id).find('.pblabel').text(LCprogressTxt); |
|
} else { |
|
\$('#progressbar'+id).progressbar('value',percent); |
|
} |
} |
} |
// ]]> |
// ]]> |
</script> |
</script> |
Line 7878 my $LCidcnt;
|
Line 9255 my $LCidcnt;
|
my $LCcurrentid; |
my $LCcurrentid; |
|
|
sub LCprogressbar { |
sub LCprogressbar { |
my ($r)=(@_); |
my ($r,$number_to_do,$preamble)=@_; |
$LClastpercent=0; |
$LClastpercent=0; |
$LCidcnt++; |
$LCidcnt++; |
$LCcurrentid=$$.'_'.$LCidcnt; |
$LCcurrentid=$$.'_'.$LCidcnt; |
my $starting=&mt('Starting'); |
my ($starting,$content); |
my $content=(<<ENDPROGBAR); |
if ($number_to_do) { |
|
$starting=&mt('Starting'); |
|
$content=(<<ENDPROGBAR); |
|
$preamble |
<div id="progressbar$LCcurrentid"> |
<div id="progressbar$LCcurrentid"> |
<span class="pblabel">$starting</span> |
<span class="pblabel">$starting</span> |
</div> |
</div> |
ENDPROGBAR |
ENDPROGBAR |
&r_print($r,$content.&LCprogressbar_script($LCcurrentid)); |
} else { |
|
$starting=&mt('Loading...'); |
|
$LClastpercent='false'; |
|
$content=(<<ENDPROGBAR); |
|
$preamble |
|
<div id="progressbar$LCcurrentid"> |
|
<div class="progress-label">$starting</div> |
|
</div> |
|
ENDPROGBAR |
|
} |
|
&r_print($r,$content.&LCprogressbar_script($LCcurrentid,$number_to_do)); |
} |
} |
|
|
sub LCprogressbarUpdate { |
sub LCprogressbarUpdate { |
my ($r,$val,$text)=@_; |
my ($r,$val,$text,$number_to_do)=@_; |
unless ($val) { |
if ($number_to_do) { |
if ($LClastpercent) { |
unless ($val) { |
$val=$LClastpercent; |
if ($LClastpercent) { |
} else { |
$val=$LClastpercent; |
$val=0; |
} else { |
} |
$val=0; |
|
} |
|
} |
|
if ($val<0) { $val=0; } |
|
if ($val>100) { $val=0; } |
|
$LClastpercent=$val; |
|
unless ($text) { $text=$val.'%'; } |
|
} else { |
|
$val = 'false'; |
} |
} |
if ($val<0) { $val=0; } |
|
if ($val>100) { $val=0; } |
|
$LClastpercent=$val; |
|
unless ($text) { $text=$val.'%'; } |
|
$text=&js_ready($text); |
$text=&js_ready($text); |
&r_print($r,<<ENDUPDATE); |
&r_print($r,<<ENDUPDATE); |
<script type="text/javascript"> |
<script type="text/javascript"> |
// <![CDATA[ |
// <![CDATA[ |
LCupdateProgress($val,'$text','$LCcurrentid'); |
LCupdateProgress($val,'$text','$LCcurrentid','$number_to_do'); |
// ]]> |
// ]]> |
</script> |
</script> |
ENDUPDATE |
ENDUPDATE |
Line 8093 function expand_div(caller) {
|
Line 9487 function expand_div(caller) {
|
|
|
sub simple_error_page { |
sub simple_error_page { |
my ($r,$title,$msg,$args) = @_; |
my ($r,$title,$msg,$args) = @_; |
|
my %displayargs; |
if (ref($args) eq 'HASH') { |
if (ref($args) eq 'HASH') { |
if (!$args->{'no_auto_mt_msg'}) { $msg = &mt($msg); } |
if (!$args->{'no_auto_mt_msg'}) { $msg = &mt($msg); } |
|
if ($args->{'only_body'}) { |
|
$displayargs{'only_body'} = 1; |
|
} |
|
if ($args->{'no_nav_bar'}) { |
|
$displayargs{'no_nav_bar'} = 1; |
|
} |
} else { |
} else { |
$msg = &mt($msg); |
$msg = &mt($msg); |
} |
} |
|
|
my $page = |
my $page = |
&Apache::loncommon::start_page($title). |
&Apache::loncommon::start_page($title,'',\%displayargs). |
'<p class="LC_error">'.$msg.'</p>'. |
'<p class="LC_error">'.$msg.'</p>'. |
&Apache::loncommon::end_page(); |
&Apache::loncommon::end_page(); |
if (ref($r)) { |
if (ref($r)) { |
Line 8317 role status: active, previous or future.
|
Line 9718 role status: active, previous or future.
|
sub check_user_status { |
sub check_user_status { |
my ($udom,$uname,$cdom,$crs,$role,$sec) = @_; |
my ($udom,$uname,$cdom,$crs,$role,$sec) = @_; |
my %userinfo = &Apache::lonnet::dump('roles',$udom,$uname); |
my %userinfo = &Apache::lonnet::dump('roles',$udom,$uname); |
my @uroles = keys %userinfo; |
my @uroles = keys(%userinfo); |
my $srchstr; |
my $srchstr; |
my $active_chk = 'none'; |
my $active_chk = 'none'; |
my $now = time; |
my $now = time; |
Line 8728 Incoming parameters:
|
Line 10129 Incoming parameters:
|
2. user's domain |
2. user's domain |
3. quota name - portfolio, author, or course |
3. quota name - portfolio, author, or course |
(if no quota name provided, defaults to portfolio). |
(if no quota name provided, defaults to portfolio). |
4. crstype - official, unofficial, textbook or community, if quota name is |
4. crstype - official, unofficial, textbook, placement or community, |
course |
if quota name is course |
|
|
Returns: |
Returns: |
1. Disk quota (in MB) assigned to student. |
1. Disk quota (in MB) assigned to student. |
Line 8803 sub get_user_quota {
|
Line 10204 sub get_user_quota {
|
if ($quotaname eq 'course') { |
if ($quotaname eq 'course') { |
my %domdefs = &Apache::lonnet::get_domain_defaults($udom); |
my %domdefs = &Apache::lonnet::get_domain_defaults($udom); |
if (($crstype eq 'official') || ($crstype eq 'unofficial') || |
if (($crstype eq 'official') || ($crstype eq 'unofficial') || |
($crstype eq 'community') || ($crstype eq 'textbook')) { |
($crstype eq 'community') || ($crstype eq 'textbook') || |
|
($crstype eq 'placement')) { |
$defquota = $domdefs{$crstype.'quota'}; |
$defquota = $domdefs{$crstype.'quota'}; |
} |
} |
if ($defquota eq '') { |
if ($defquota eq '') { |
Line 8951 Inputs: 7
|
Line 10353 Inputs: 7
|
4. filename of file for which action is being requested |
4. filename of file for which action is being requested |
5. filesize (kB) of file |
5. filesize (kB) of file |
6. action being taken: copy or upload. |
6. action being taken: copy or upload. |
7. quotatype (in course context -- official, unofficial, community or textbook). |
7. quotatype (in course context -- official, unofficial, textbook, placement or community). |
|
|
Returns: 1 scalar: HTML to display containing warning if quota would be exceeded, |
Returns: 1 scalar: HTML to display containing warning if quota would be exceeded, |
otherwise return null. |
otherwise return null. |
Line 9027 sub get_secgrprole_info {
|
Line 10429 sub get_secgrprole_info {
|
} |
} |
|
|
sub user_picker { |
sub user_picker { |
my ($dom,$srch,$forcenewuser,$caller,$cancreate,$usertype,$context) = @_; |
my ($dom,$srch,$forcenewuser,$caller,$cancreate,$usertype,$context,$fixeddom,$noinstd) = @_; |
my $currdom = $dom; |
my $currdom = $dom; |
|
my @alldoms = &Apache::lonnet::all_domains(); |
|
if (@alldoms == 1) { |
|
my %domsrch = &Apache::lonnet::get_dom('configuration', |
|
['directorysrch'],$alldoms[0]); |
|
my $domdesc = &Apache::lonnet::domain($alldoms[0],'description'); |
|
my $showdom = $domdesc; |
|
if ($showdom eq '') { |
|
$showdom = $dom; |
|
} |
|
if (ref($domsrch{'directorysrch'}) eq 'HASH') { |
|
if ((!$domsrch{'directorysrch'}{'available'}) && |
|
($domsrch{'directorysrch'}{'lcavailable'} eq '0')) { |
|
return (&mt('LON-CAPA directory search is not available in domain: [_1]',$showdom),0); |
|
} |
|
} |
|
} |
my %curr_selected = ( |
my %curr_selected = ( |
srchin => 'dom', |
srchin => 'dom', |
srchby => 'lastname', |
srchby => 'lastname', |
Line 9049 sub user_picker {
|
Line 10467 sub user_picker {
|
} |
} |
$srchterm = $srch->{'srchterm'}; |
$srchterm = $srch->{'srchterm'}; |
} |
} |
my %lt=&Apache::lonlocal::texthash( |
my %html_lt=&Apache::lonlocal::texthash( |
'usr' => 'Search criteria', |
'usr' => 'Search criteria', |
'doma' => 'Domain/institution to search', |
'doma' => 'Domain/institution to search', |
'uname' => 'username', |
'uname' => 'username', |
Line 9062 sub user_picker {
|
Line 10480 sub user_picker {
|
'exact' => 'is', |
'exact' => 'is', |
'contains' => 'contains', |
'contains' => 'contains', |
'begins' => 'begins with', |
'begins' => 'begins with', |
|
); |
|
my %js_lt=&Apache::lonlocal::texthash( |
'youm' => "You must include some text to search for.", |
'youm' => "You must include some text to search for.", |
'thte' => "The text you are searching for must contain at least two characters when using a 'begins' type search.", |
'thte' => "The text you are searching for must contain at least two characters when using a 'begins' type search.", |
'thet' => "The text you are searching for must contain at least three characters when using a 'contains' type search.", |
'thet' => "The text you are searching for must contain at least three characters when using a 'contains' type search.", |
Line 9071 sub user_picker {
|
Line 10491 sub user_picker {
|
'whse' => "When searching by last,first you must include at least one character in the first name.", |
'whse' => "When searching by last,first you must include at least one character in the first name.", |
'thfo' => "The following need to be corrected before the search can be run:", |
'thfo' => "The following need to be corrected before the search can be run:", |
); |
); |
my $domform = &select_dom_form($currdom,'srchdomain',1,1); |
&html_escape(\%html_lt); |
|
&js_escape(\%js_lt); |
|
my $domform; |
|
my $allow_blank = 1; |
|
if ($fixeddom) { |
|
$allow_blank = 0; |
|
$domform = &select_dom_form($currdom,'srchdomain',$allow_blank,1,undef,[$currdom]); |
|
} else { |
|
my $defdom = $env{'request.role.domain'}; |
|
my ($trusted,$untrusted); |
|
if (($context eq 'requestcrs') || ($context eq 'course')) { |
|
($trusted,$untrusted) = &Apache::lonnet::trusted_domains('enroll',$defdom); |
|
} elsif ($context eq 'author') { |
|
($trusted,$untrusted) = &Apache::lonnet::trusted_domains('othcoau',$defdom); |
|
} elsif ($context eq 'domain') { |
|
($trusted,$untrusted) = &Apache::lonnet::trusted_domains('domroles',$defdom); |
|
} |
|
$domform = &select_dom_form($currdom,'srchdomain',$allow_blank,1,undef,$trusted,$untrusted); |
|
} |
my $srchinsel = ' <select name="srchin">'; |
my $srchinsel = ' <select name="srchin">'; |
|
|
my @srchins = ('crs','dom','alc','instd'); |
my @srchins = ('crs','dom','alc','instd'); |
Line 9083 sub user_picker {
|
Line 10521 sub user_picker {
|
next if ($option eq 'alc'); |
next if ($option eq 'alc'); |
next if (($option eq 'crs') && ($env{'form.form'} eq 'requestcrs')); |
next if (($option eq 'crs') && ($env{'form.form'} eq 'requestcrs')); |
next if ($option eq 'crs' && !$env{'request.course.id'}); |
next if ($option eq 'crs' && !$env{'request.course.id'}); |
|
next if (($option eq 'instd') && ($noinstd)); |
if ($curr_selected{'srchin'} eq $option) { |
if ($curr_selected{'srchin'} eq $option) { |
$srchinsel .= ' |
$srchinsel .= ' |
<option value="'.$option.'" selected="selected">'.$lt{$option}.'</option>'; |
<option value="'.$option.'" selected="selected">'.$html_lt{$option}.'</option>'; |
} else { |
} else { |
$srchinsel .= ' |
$srchinsel .= ' |
<option value="'.$option.'">'.$lt{$option}.'</option>'; |
<option value="'.$option.'">'.$html_lt{$option}.'</option>'; |
} |
} |
} |
} |
$srchinsel .= "\n </select>\n"; |
$srchinsel .= "\n </select>\n"; |
Line 9097 sub user_picker {
|
Line 10536 sub user_picker {
|
foreach my $option ('lastname','lastfirst','uname') { |
foreach my $option ('lastname','lastfirst','uname') { |
if ($curr_selected{'srchby'} eq $option) { |
if ($curr_selected{'srchby'} eq $option) { |
$srchbysel .= ' |
$srchbysel .= ' |
<option value="'.$option.'" selected="selected">'.$lt{$option}.'</option>'; |
<option value="'.$option.'" selected="selected">'.$html_lt{$option}.'</option>'; |
} else { |
} else { |
$srchbysel .= ' |
$srchbysel .= ' |
<option value="'.$option.'">'.$lt{$option}.'</option>'; |
<option value="'.$option.'">'.$html_lt{$option}.'</option>'; |
} |
} |
} |
} |
$srchbysel .= "\n </select>\n"; |
$srchbysel .= "\n </select>\n"; |
Line 9109 sub user_picker {
|
Line 10548 sub user_picker {
|
foreach my $option ('begins','contains','exact') { |
foreach my $option ('begins','contains','exact') { |
if ($curr_selected{'srchtype'} eq $option) { |
if ($curr_selected{'srchtype'} eq $option) { |
$srchtypesel .= ' |
$srchtypesel .= ' |
<option value="'.$option.'" selected="selected">'.$lt{$option}.'</option>'; |
<option value="'.$option.'" selected="selected">'.$html_lt{$option}.'</option>'; |
} else { |
} else { |
$srchtypesel .= ' |
$srchtypesel .= ' |
<option value="'.$option.'">'.$lt{$option}.'</option>'; |
<option value="'.$option.'">'.$html_lt{$option}.'</option>'; |
} |
} |
} |
} |
$srchtypesel .= "\n </select>\n"; |
$srchtypesel .= "\n </select>\n"; |
Line 9197 function validateEntry(callingForm) {
|
Line 10636 function validateEntry(callingForm) {
|
|
|
if (srchterm == "") { |
if (srchterm == "") { |
checkok = 0; |
checkok = 0; |
msg += "$lt{'youm'}\\n"; |
msg += "$js_lt{'youm'}\\n"; |
} |
} |
|
|
if (srchtype== 'begins') { |
if (srchtype== 'begins') { |
if (srchterm.length < 2) { |
if (srchterm.length < 2) { |
checkok = 0; |
checkok = 0; |
msg += "$lt{'thte'}\\n"; |
msg += "$js_lt{'thte'}\\n"; |
} |
} |
} |
} |
|
|
if (srchtype== 'contains') { |
if (srchtype== 'contains') { |
if (srchterm.length < 3) { |
if (srchterm.length < 3) { |
checkok = 0; |
checkok = 0; |
msg += "$lt{'thet'}\\n"; |
msg += "$js_lt{'thet'}\\n"; |
} |
} |
} |
} |
if (srchin == 'instd') { |
if (srchin == 'instd') { |
if (srchdomain == '') { |
if (srchdomain == '') { |
checkok = 0; |
checkok = 0; |
msg += "$lt{'yomc'}\\n"; |
msg += "$js_lt{'yomc'}\\n"; |
} |
} |
} |
} |
if (srchin == 'dom') { |
if (srchin == 'dom') { |
if (srchdomain == '') { |
if (srchdomain == '') { |
checkok = 0; |
checkok = 0; |
msg += "$lt{'ymcd'}\\n"; |
msg += "$js_lt{'ymcd'}\\n"; |
} |
} |
} |
} |
if (srchby == 'lastfirst') { |
if (srchby == 'lastfirst') { |
if (srchterm.indexOf(",") == -1) { |
if (srchterm.indexOf(",") == -1) { |
checkok = 0; |
checkok = 0; |
msg += "$lt{'whus'}\\n"; |
msg += "$js_lt{'whus'}\\n"; |
} |
} |
if (srchterm.indexOf(",") == srchterm.length -1) { |
if (srchterm.indexOf(",") == srchterm.length -1) { |
checkok = 0; |
checkok = 0; |
msg += "$lt{'whse'}\\n"; |
msg += "$js_lt{'whse'}\\n"; |
} |
} |
} |
} |
if (checkok == 0) { |
if (checkok == 0) { |
alert("$lt{'thfo'}\\n"+msg); |
alert("$js_lt{'thfo'}\\n"+msg); |
return; |
return; |
} |
} |
if (checkok == 1) { |
if (checkok == 1) { |
Line 9254 $new_user_create
|
Line 10693 $new_user_create
|
END_BLOCK |
END_BLOCK |
|
|
$output .= &Apache::lonhtmlcommon::start_pick_box(). |
$output .= &Apache::lonhtmlcommon::start_pick_box(). |
&Apache::lonhtmlcommon::row_title($lt{'doma'}). |
&Apache::lonhtmlcommon::row_title($html_lt{'doma'}). |
$domform. |
$domform. |
&Apache::lonhtmlcommon::row_closure(). |
&Apache::lonhtmlcommon::row_closure(). |
&Apache::lonhtmlcommon::row_title($lt{'usr'}). |
&Apache::lonhtmlcommon::row_title($html_lt{'usr'}). |
$srchbysel. |
$srchbysel. |
$srchtypesel. |
$srchtypesel. |
'<input type="text" size="15" name="srchterm" value="'.$srchterm.'" />'. |
'<input type="text" size="15" name="srchterm" value="'.$srchterm.'" />'. |
Line 9265 END_BLOCK
|
Line 10704 END_BLOCK
|
&Apache::lonhtmlcommon::row_closure(1). |
&Apache::lonhtmlcommon::row_closure(1). |
&Apache::lonhtmlcommon::end_pick_box(). |
&Apache::lonhtmlcommon::end_pick_box(). |
'<br />'; |
'<br />'; |
return $output; |
return ($output,1); |
} |
} |
|
|
sub user_rule_check { |
sub user_rule_check { |
my ($usershash,$checks,$alerts,$rulematch,$inst_results,$curr_rules,$got_rules) = @_; |
my ($usershash,$checks,$alerts,$rulematch,$inst_results,$curr_rules,$got_rules) = @_; |
my $response; |
my ($response,%inst_response); |
if (ref($usershash) eq 'HASH') { |
if (ref($usershash) eq 'HASH') { |
foreach my $user (keys(%{$usershash})) { |
if (keys(%{$usershash}) > 1) { |
my ($uname,$udom) = split(/:/,$user); |
my (%by_username,%by_id,%userdoms); |
next if ($udom eq '' || $uname eq ''); |
my $checkid; |
my ($id,$newuser); |
|
if (ref($usershash->{$user}) eq 'HASH') { |
|
$newuser = $usershash->{$user}->{'newuser'}; |
|
$id = $usershash->{$user}->{'id'}; |
|
} |
|
my $inst_response; |
|
if (ref($checks) eq 'HASH') { |
if (ref($checks) eq 'HASH') { |
if (defined($checks->{'username'})) { |
if ((!defined($checks->{'username'})) && (defined($checks->{'id'}))) { |
($inst_response,%{$inst_results->{$user}}) = |
$checkid = 1; |
&Apache::lonnet::get_instuser($udom,$uname); |
} |
} elsif (defined($checks->{'id'})) { |
} |
($inst_response,%{$inst_results->{$user}}) = |
foreach my $user (keys(%{$usershash})) { |
&Apache::lonnet::get_instuser($udom,undef,$id); |
my ($uname,$udom) = split(/:/,$user); |
|
if ($checkid) { |
|
if (ref($usershash->{$user}) eq 'HASH') { |
|
if ($usershash->{$user}->{'id'} ne '') { |
|
$by_id{$udom}{$usershash->{$user}->{'id'}} = $uname; |
|
$userdoms{$udom} = 1; |
|
if (ref($inst_results) eq 'HASH') { |
|
$inst_results->{$uname.':'.$udom} = {}; |
|
} |
|
} |
|
} |
|
} else { |
|
$by_username{$udom}{$uname} = 1; |
|
$userdoms{$udom} = 1; |
|
if (ref($inst_results) eq 'HASH') { |
|
$inst_results->{$uname.':'.$udom} = {}; |
|
} |
|
} |
|
} |
|
foreach my $udom (keys(%userdoms)) { |
|
if (!$got_rules->{$udom}) { |
|
my %domconfig = &Apache::lonnet::get_dom('configuration', |
|
['usercreation'],$udom); |
|
if (ref($domconfig{'usercreation'}) eq 'HASH') { |
|
foreach my $item ('username','id') { |
|
if (ref($domconfig{'usercreation'}{$item.'_rule'}) eq 'ARRAY') { |
|
$$curr_rules{$udom}{$item} = |
|
$domconfig{'usercreation'}{$item.'_rule'}; |
|
} |
|
} |
|
} |
|
$got_rules->{$udom} = 1; |
|
} |
|
} |
|
if ($checkid) { |
|
foreach my $udom (keys(%by_id)) { |
|
my ($outcome,$results) = &Apache::lonnet::get_multiple_instusers($udom,$by_id{$udom},'id'); |
|
if ($outcome eq 'ok') { |
|
foreach my $id (keys(%{$by_id{$udom}})) { |
|
my $uname = $by_id{$udom}{$id}; |
|
$inst_response{$uname.':'.$udom} = $outcome; |
|
} |
|
if (ref($results) eq 'HASH') { |
|
foreach my $uname (keys(%{$results})) { |
|
if (exists($inst_response{$uname.':'.$udom})) { |
|
$inst_response{$uname.':'.$udom} = $outcome; |
|
$inst_results->{$uname.':'.$udom} = $results->{$uname}; |
|
} |
|
} |
|
} |
|
} |
} |
} |
} else { |
} else { |
($inst_response,%{$inst_results->{$user}}) = |
foreach my $udom (keys(%by_username)) { |
&Apache::lonnet::get_instuser($udom,$uname); |
my ($outcome,$results) = &Apache::lonnet::get_multiple_instusers($udom,$by_username{$udom}); |
return; |
if ($outcome eq 'ok') { |
|
foreach my $uname (keys(%{$by_username{$udom}})) { |
|
$inst_response{$uname.':'.$udom} = $outcome; |
|
} |
|
if (ref($results) eq 'HASH') { |
|
foreach my $uname (keys(%{$results})) { |
|
$inst_results->{$uname.':'.$udom} = $results->{$uname}; |
|
} |
|
} |
|
} |
|
} |
} |
} |
if (!$got_rules->{$udom}) { |
} elsif (keys(%{$usershash}) == 1) { |
my %domconfig = &Apache::lonnet::get_dom('configuration', |
my $user = (keys(%{$usershash}))[0]; |
['usercreation'],$udom); |
my ($uname,$udom) = split(/:/,$user); |
if (ref($domconfig{'usercreation'}) eq 'HASH') { |
if (($udom ne '') && ($uname ne '')) { |
foreach my $item ('username','id') { |
if (ref($usershash->{$user}) eq 'HASH') { |
if (ref($domconfig{'usercreation'}{$item.'_rule'}) eq 'ARRAY') { |
if (ref($checks) eq 'HASH') { |
$$curr_rules{$udom}{$item} = |
if (defined($checks->{'username'})) { |
$domconfig{'usercreation'}{$item.'_rule'}; |
($inst_response{$user},%{$inst_results->{$user}}) = |
|
&Apache::lonnet::get_instuser($udom,$uname); |
|
} elsif (defined($checks->{'id'})) { |
|
if ($usershash->{$user}->{'id'} ne '') { |
|
($inst_response{$user},%{$inst_results->{$user}}) = |
|
&Apache::lonnet::get_instuser($udom,undef, |
|
$usershash->{$user}->{'id'}); |
|
} else { |
|
($inst_response{$user},%{$inst_results->{$user}}) = |
|
&Apache::lonnet::get_instuser($udom,$uname); |
|
} |
|
} |
|
} else { |
|
($inst_response{$user},%{$inst_results->{$user}}) = |
|
&Apache::lonnet::get_instuser($udom,$uname); |
|
return; |
|
} |
|
if (!$got_rules->{$udom}) { |
|
my %domconfig = &Apache::lonnet::get_dom('configuration', |
|
['usercreation'],$udom); |
|
if (ref($domconfig{'usercreation'}) eq 'HASH') { |
|
foreach my $item ('username','id') { |
|
if (ref($domconfig{'usercreation'}{$item.'_rule'}) eq 'ARRAY') { |
|
$$curr_rules{$udom}{$item} = |
|
$domconfig{'usercreation'}{$item.'_rule'}; |
|
} |
|
} |
} |
} |
|
$got_rules->{$udom} = 1; |
} |
} |
} |
} |
$got_rules->{$udom} = 1; |
} else { |
|
return; |
|
} |
|
} else { |
|
return; |
|
} |
|
foreach my $user (keys(%{$usershash})) { |
|
my ($uname,$udom) = split(/:/,$user); |
|
next if (($udom eq '') || ($uname eq '')); |
|
my $id; |
|
if (ref($inst_results) eq 'HASH') { |
|
if (ref($inst_results->{$user}) eq 'HASH') { |
|
$id = $inst_results->{$user}->{'id'}; |
|
} |
|
} |
|
if ($id eq '') { |
|
if (ref($usershash->{$user})) { |
|
$id = $usershash->{$user}->{'id'}; |
|
} |
} |
} |
foreach my $item (keys(%{$checks})) { |
foreach my $item (keys(%{$checks})) { |
if (ref($$curr_rules{$udom}) eq 'HASH') { |
if (ref($$curr_rules{$udom}) eq 'HASH') { |
if (ref($$curr_rules{$udom}{$item}) eq 'ARRAY') { |
if (ref($$curr_rules{$udom}{$item}) eq 'ARRAY') { |
if (@{$$curr_rules{$udom}{$item}} > 0) { |
if (@{$$curr_rules{$udom}{$item}} > 0) { |
my %rule_check = &Apache::lonnet::inst_rulecheck($udom,$uname,$id,$item,$$curr_rules{$udom}{$item}); |
my %rule_check = &Apache::lonnet::inst_rulecheck($udom,$uname,$id,$item, |
|
$$curr_rules{$udom}{$item}); |
foreach my $rule (@{$$curr_rules{$udom}{$item}}) { |
foreach my $rule (@{$$curr_rules{$udom}{$item}}) { |
if ($rule_check{$rule}) { |
if ($rule_check{$rule}) { |
$$rulematch{$user}{$item} = $rule; |
$$rulematch{$user}{$item} = $rule; |
if ($inst_response eq 'ok') { |
if ($inst_response{$user} eq 'ok') { |
if (ref($inst_results) eq 'HASH') { |
if (ref($inst_results) eq 'HASH') { |
if (ref($inst_results->{$user}) eq 'HASH') { |
if (ref($inst_results->{$user}) eq 'HASH') { |
if (keys(%{$inst_results->{$user}}) == 0) { |
if (keys(%{$inst_results->{$user}}) == 0) { |
$$alerts{$item}{$udom}{$uname} = 1; |
$$alerts{$item}{$udom}{$uname} = 1; |
|
} elsif ($item eq 'id') { |
|
if ($inst_results->{$user}->{'id'} eq '') { |
|
$$alerts{$item}{$udom}{$uname} = 1; |
|
} |
} |
} |
} |
} |
} |
} |
Line 9476 sub get_institutional_codes {
|
Line 11019 sub get_institutional_codes {
|
foreach (@currxlists) { |
foreach (@currxlists) { |
if (m/^([^:]+):(\w*)$/) { |
if (m/^([^:]+):(\w*)$/) { |
unless (grep/^$1$/,@{$allcourses}) { |
unless (grep/^$1$/,@{$allcourses}) { |
push @{$allcourses},$1; |
push(@{$allcourses},$1); |
$$LC_code{$1} = $2; |
$$LC_code{$1} = $2; |
} |
} |
} |
} |
Line 9489 sub get_institutional_codes {
|
Line 11032 sub get_institutional_codes {
|
my $sec = $coursecode.$1; |
my $sec = $coursecode.$1; |
my $lc_sec = $2; |
my $lc_sec = $2; |
unless (grep/^$sec$/,@{$allcourses}) { |
unless (grep/^$sec$/,@{$allcourses}) { |
push @{$allcourses},$sec; |
push(@{$allcourses},$sec); |
$$LC_code{$sec} = $lc_sec; |
$$LC_code{$sec} = $lc_sec; |
} |
} |
} |
} |
Line 9587 reservable_now - ref to hash of student_
|
Line 11130 reservable_now - ref to hash of student_
|
|
|
Keys in inner hash are: |
Keys in inner hash are: |
(a) symb: either blank or symb to which slot use is restricted. |
(a) symb: either blank or symb to which slot use is restricted. |
(b) endreserve: end date of reservation period. |
(b) endreserve: end date of reservation period. |
|
(c) uniqueperiod: start,end dates when slot is to be uniquely |
|
selected. |
|
|
sorted_future - ref to array of student_schedulable slots reservable in |
sorted_future - ref to array of student_schedulable slots reservable in |
the future, ordered by start date of reservation period. |
the future, ordered by start date of reservation period. |
Line 9597 future_reservable - ref to hash of stude
|
Line 11142 future_reservable - ref to hash of stude
|
|
|
Keys in inner hash are: |
Keys in inner hash are: |
(a) symb: either blank or symb to which slot use is restricted. |
(a) symb: either blank or symb to which slot use is restricted. |
(b) startreserve: start date of reservation period. |
(b) startreserve: start date of reservation period. |
|
(c) uniqueperiod: start,end dates when slot is to be uniquely |
|
selected. |
|
|
=back |
=back |
|
|
Line 9605 future_reservable - ref to hash of stude
|
Line 11152 future_reservable - ref to hash of stude
|
|
|
sub get_future_slots { |
sub get_future_slots { |
my ($cnum,$cdom,$now,$symb) = @_; |
my ($cnum,$cdom,$now,$symb) = @_; |
|
my $map; |
|
if ($symb) { |
|
($map) = &Apache::lonnet::decode_symb($symb); |
|
} |
my (%reservable_now,%future_reservable,@sorted_reservable,@sorted_future); |
my (%reservable_now,%future_reservable,@sorted_reservable,@sorted_future); |
my %slots = &Apache::lonnet::get_course_slots($cnum,$cdom); |
my %slots = &Apache::lonnet::get_course_slots($cnum,$cdom); |
foreach my $slot (keys(%slots)) { |
foreach my $slot (keys(%slots)) { |
next unless($slots{$slot}->{'type'} eq 'schedulable_student'); |
next unless($slots{$slot}->{'type'} eq 'schedulable_student'); |
if ($symb) { |
if ($symb) { |
next if (($slots{$slot}->{'symb'} ne '') && |
if ($slots{$slot}->{'symb'} ne '') { |
($slots{$slot}->{'symb'} ne $symb)); |
my $canuse; |
|
my %oksymbs; |
|
my @slotsymbs = split(/\s*,\s*/,$slots{$slot}->{'symb'}); |
|
map { $oksymbs{$_} = 1; } @slotsymbs; |
|
if ($oksymbs{$symb}) { |
|
$canuse = 1; |
|
} else { |
|
foreach my $item (@slotsymbs) { |
|
if ($item =~ /\.(page|sequence)$/) { |
|
(undef,undef,my $sloturl) = &Apache::lonnet::decode_symb($item); |
|
if (($map ne '') && ($map eq $sloturl)) { |
|
$canuse = 1; |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
next unless ($canuse); |
|
} |
} |
} |
if (($slots{$slot}->{'starttime'} > $now) && |
if (($slots{$slot}->{'starttime'} > $now) && |
($slots{$slot}->{'endtime'} > $now)) { |
($slots{$slot}->{'endtime'} > $now)) { |
Line 9651 sub get_future_slots {
|
Line 11220 sub get_future_slots {
|
my $startreserve = $slots{$slot}->{'startreserve'}; |
my $startreserve = $slots{$slot}->{'startreserve'}; |
my $endreserve = $slots{$slot}->{'endreserve'}; |
my $endreserve = $slots{$slot}->{'endreserve'}; |
my $symb = $slots{$slot}->{'symb'}; |
my $symb = $slots{$slot}->{'symb'}; |
|
my $uniqueperiod; |
|
if (ref($slots{$slot}->{'uniqueperiod'}) eq 'ARRAY') { |
|
$uniqueperiod = join(',',@{$slots{$slot}->{'uniqueperiod'}}); |
|
} |
if (($startreserve < $now) && |
if (($startreserve < $now) && |
(!$endreserve || $endreserve > $now)) { |
(!$endreserve || $endreserve > $now)) { |
my $lastres = $endreserve; |
my $lastres = $endreserve; |
Line 9659 sub get_future_slots {
|
Line 11232 sub get_future_slots {
|
} |
} |
$reservable_now{$slot} = { |
$reservable_now{$slot} = { |
symb => $symb, |
symb => $symb, |
endreserve => $lastres |
endreserve => $lastres, |
|
uniqueperiod => $uniqueperiod, |
}; |
}; |
} elsif (($startreserve > $now) && |
} elsif (($startreserve > $now) && |
(!$endreserve || $endreserve > $startreserve)) { |
(!$endreserve || $endreserve > $startreserve)) { |
$future_reservable{$slot} = { |
$future_reservable{$slot} = { |
symb => $symb, |
symb => $symb, |
startreserve => $startreserve |
startreserve => $startreserve, |
|
uniqueperiod => $uniqueperiod, |
}; |
}; |
} |
} |
} |
} |
Line 9823 sub get_env_multiple {
|
Line 11398 sub get_env_multiple {
|
return(@values); |
return(@values); |
} |
} |
|
|
|
# Looks at given dependencies, and returns something depending on the context. |
|
# For coursedocs paste, returns (undef, $counter, $numpathchg, \%existing). |
|
# For syllabus rewrites, returns (undef, $counter, $numpathchg, \%existing, \%mapping). |
|
# For all other contexts, returns ($output, $counter, $numpathchg). |
|
# $output: string with the HTML output. Can contain missing dependencies with an upload form, existing dependencies, and dependencies no longer in use. |
|
# $counter: integer with the number of existing dependencies when no HTML output is returned, and the number of missing dependencies when an HTML output is returned. |
|
# $numpathchg: integer with the number of cleaned up dependency paths. |
|
# \%existing: hash reference clean path -> 1 only for existing dependencies. |
|
# \%mapping: hash reference clean path -> original path for all dependencies. |
|
# @param {string} actionurl - The path to the handler, indicative of the context. |
|
# @param {string} state - Can contain HTML with hidden inputs that will be added to the output form. |
|
# @param {hash reference} allfiles - List of file info from lonnet::extract_embedded_items |
|
# @param {hash reference} codebase - undef, not modified by lonnet::extract_embedded_items ? |
|
# @param {hash reference} args - More parameters ! Possible keys: error_on_invalid_names (boolean), ignore_remote_references (boolean), current_path (string), docs_url (string), docs_title (string), context (string) |
|
# @return {Array} - array depending on the context (not a reference) |
sub ask_for_embedded_content { |
sub ask_for_embedded_content { |
|
# NOTE: documentation was added afterwards, it could be wrong |
my ($actionurl,$state,$allfiles,$codebase,$args)=@_; |
my ($actionurl,$state,$allfiles,$codebase,$args)=@_; |
my (%subdependencies,%dependencies,%mapping,%existing,%newfiles,%pathchanges, |
my (%subdependencies,%dependencies,%mapping,%existing,%newfiles,%pathchanges, |
%currsubfile,%unused,$rem); |
%currsubfile,%unused,$rem); |
Line 9839 sub ask_for_embedded_content {
|
Line 11430 sub ask_for_embedded_content {
|
my $heading = &mt('Upload embedded files'); |
my $heading = &mt('Upload embedded files'); |
my $buttontext = &mt('Upload'); |
my $buttontext = &mt('Upload'); |
|
|
|
# fills these variables based on the context: |
|
# $navmap, $cdom, $cnum, $udom, $uname, $url, $toplevel, $getpropath, |
|
# $path, $fileloc, $title, $rem, $filename |
if ($env{'request.course.id'}) { |
if ($env{'request.course.id'}) { |
if ($actionurl eq '/adm/dependencies') { |
if ($actionurl eq '/adm/dependencies') { |
$navmap = Apache::lonnavmaps::navmap->new(); |
$navmap = Apache::lonnavmaps::navmap->new(); |
Line 9900 sub ask_for_embedded_content {
|
Line 11494 sub ask_for_embedded_content {
|
($path) = |
($path) = |
($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/\E(?:docs|supplemental)/(?:default|\d+)/\d+)/}); |
($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/\E(?:docs|supplemental)/(?:default|\d+)/\d+)/}); |
} |
} |
$fileloc = &Apache::lonnet::filelocation('',$toplevel); |
if ($toplevel=~/^\/*(uploaded|editupload)/) { |
|
$fileloc = $toplevel; |
|
$fileloc=~ s/^\s*(\S+)\s*$/$1/; |
|
my ($udom,$uname,$fname) = |
|
($fileloc=~ m{^/+(?:uploaded|editupload)/+($match_domain)/+($match_name)/+(.*)$}); |
|
$fileloc = propath($udom,$uname).'/userfiles/'.$fname; |
|
} else { |
|
$fileloc = &Apache::lonnet::filelocation('',$toplevel); |
|
} |
$fileloc =~ s{^/}{}; |
$fileloc =~ s{^/}{}; |
($filename) = ($fileloc =~ m{.+/([^/]+)$}); |
($filename) = ($fileloc =~ m{.+/([^/]+)$}); |
$heading = &mt('Status of dependencies in [_1]',"$title ($filename)"); |
$heading = &mt('Status of dependencies in [_1]',"$title ($filename)"); |
Line 9915 sub ask_for_embedded_content {
|
Line 11517 sub ask_for_embedded_content {
|
$fileloc = &Apache::lonnet::filelocation('',$toplevel).'/'; |
$fileloc = &Apache::lonnet::filelocation('',$toplevel).'/'; |
$fileloc =~ s{^/}{}; |
$fileloc =~ s{^/}{}; |
} |
} |
|
|
|
# parses the dependency paths to get some info |
|
# fills $newfiles, $mapping, $subdependencies, $dependencies |
|
# $newfiles: hash URL -> 1 for new files or external URLs |
|
# (will be completed later) |
|
# $mapping: |
|
# for external URLs: external URL -> external URL |
|
# for relative paths: clean path -> original path |
|
# $subdependencies: hash clean path -> clean file name -> 1 for relative paths in subdirectories |
|
# $dependencies: hash clean or not file name -> 1 for relative paths not in subdirectories |
foreach my $file (keys(%{$allfiles})) { |
foreach my $file (keys(%{$allfiles})) { |
my $embed_file; |
my $embed_file; |
if (($path eq "/uploaded/$cdom/$cnum/portfolio/syllabus") && ($file =~ m{^\Q$path/\E(.+)$})) { |
if (($path eq "/uploaded/$cdom/$cnum/portfolio/syllabus") && ($file =~ m{^\Q$path/\E(.+)$})) { |
Line 9957 sub ask_for_embedded_content {
|
Line 11569 sub ask_for_embedded_content {
|
} |
} |
} |
} |
} |
} |
|
|
|
# looks for all existing files in dependency subdirectories (from $subdependencies filled above) |
|
# and lists |
|
# fills $currsubfile, $pathchanges, $existing, $numexisting, $newfiles, $unused |
|
# $currsubfile: hash clean path -> file name -> 1 for all existing files in the path |
|
# $pathchanges: hash clean path -> 1 if the file in subdirectory exists and |
|
# the path had to be cleaned up |
|
# $existing: hash clean path -> 1 if the file exists |
|
# $numexisting: number of keys in $existing |
|
# $newfiles: updated with clean path -> 1 for files in subdirectories that do not exist |
|
# $unused: only for /adm/dependencies, hash clean path -> 1 for existing files in |
|
# dependency subdirectories that are |
|
# not listed as dependencies, with some exceptions using $rem |
my $dirptr = 16384; |
my $dirptr = 16384; |
foreach my $path (keys(%subdependencies)) { |
foreach my $path (keys(%subdependencies)) { |
$currsubfile{$path} = {}; |
$currsubfile{$path} = {}; |
Line 10032 sub ask_for_embedded_content {
|
Line 11657 sub ask_for_embedded_content {
|
} |
} |
} |
} |
} |
} |
|
|
|
# fills $currfile, hash file name -> 1 or [$size,$mtime] |
|
# for files in $url or $fileloc (target directory) in some contexts |
my %currfile; |
my %currfile; |
if (($actionurl eq '/adm/portfolio') || |
if (($actionurl eq '/adm/portfolio') || |
($actionurl eq '/adm/coursegrp_portfolio')) { |
($actionurl eq '/adm/coursegrp_portfolio')) { |
Line 10070 sub ask_for_embedded_content {
|
Line 11698 sub ask_for_embedded_content {
|
} |
} |
} |
} |
} |
} |
|
# updates $pathchanges, $existing, $numexisting, $newfiles and $unused for files that |
|
# are not in subdirectories, using $currfile |
foreach my $file (keys(%dependencies)) { |
foreach my $file (keys(%dependencies)) { |
if (exists($currfile{$file})) { |
if (exists($currfile{$file})) { |
unless ($mapping{$file} eq $file) { |
unless ($mapping{$file} eq $file) { |
Line 10098 sub ask_for_embedded_content {
|
Line 11728 sub ask_for_embedded_content {
|
$unused{$file} = 1; |
$unused{$file} = 1; |
} |
} |
} |
} |
|
|
|
# returns some results for coursedocs paste and syllabus rewrites ($output is undef) |
if (($actionurl eq '/adm/coursedocs') && (ref($args) eq 'HASH') && |
if (($actionurl eq '/adm/coursedocs') && (ref($args) eq 'HASH') && |
($args->{'context'} eq 'paste')) { |
($args->{'context'} eq 'paste')) { |
$counter = scalar(keys(%existing)); |
$counter = scalar(keys(%existing)); |
Line 10109 sub ask_for_embedded_content {
|
Line 11741 sub ask_for_embedded_content {
|
$numpathchg = scalar(keys(%pathchanges)); |
$numpathchg = scalar(keys(%pathchanges)); |
return ($output,$counter,$numpathchg,\%existing,\%mapping); |
return ($output,$counter,$numpathchg,\%existing,\%mapping); |
} |
} |
|
|
|
# returns HTML otherwise, with dependency results and to ask for more uploads |
|
|
|
# $upload_output: missing dependencies (with upload form) |
|
# $modify_output: uploaded dependencies (in use) |
|
# $delete_output: files no longer in use (unused files are not listed for londocs, bug?) |
foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%newfiles)) { |
foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%newfiles)) { |
if ($actionurl eq '/adm/dependencies') { |
if ($actionurl eq '/adm/dependencies') { |
next if ($embed_file =~ m{^\w+://}); |
next if ($embed_file =~ m{^\w+://}); |
Line 10722 sub modify_html_refs {
|
Line 12360 sub modify_html_refs {
|
return; |
return; |
} |
} |
} |
} |
if (open(my $fh,"<$container")) { |
if (open(my $fh,'<',$container)) { |
$content = join('', <$fh>); |
$content = join('', <$fh>); |
close($fh); |
close($fh); |
} else { |
} else { |
Line 10787 sub modify_html_refs {
|
Line 12425 sub modify_html_refs {
|
} |
} |
} |
} |
} else { |
} else { |
if (open(my $fh,">$container")) { |
if (open(my $fh,'>',$container)) { |
print $fh $content; |
print $fh $content; |
close($fh); |
close($fh); |
$output = '<p>'.&mt('Updated [quant,_1,reference] in [_2].', |
$output = '<p>'.&mt('Updated [quant,_1,reference] in [_2].', |
Line 11056 sub decompress_form {
|
Line 12694 sub decompress_form {
|
"$topdir/media/player.swf", |
"$topdir/media/player.swf", |
"$topdir/media/swfobject.js", |
"$topdir/media/swfobject.js", |
"$topdir/media/expressInstall.swf"); |
"$topdir/media/expressInstall.swf"); |
my @camtasia8 = ("$topdir/","$topdir/$topdir.html", |
my @camtasia8_1 = ("$topdir/","$topdir/$topdir.html", |
"$topdir/$topdir.mp4", |
"$topdir/$topdir.mp4", |
"$topdir/$topdir\_config.xml", |
"$topdir/$topdir\_config.xml", |
"$topdir/$topdir\_controller.swf", |
"$topdir/$topdir\_controller.swf", |
Line 11078 sub decompress_form {
|
Line 12716 sub decompress_form {
|
"$topdir/skins/express_show/", |
"$topdir/skins/express_show/", |
"$topdir/skins/express_show/player-min.css", |
"$topdir/skins/express_show/player-min.css", |
"$topdir/skins/express_show/spritesheet.png"); |
"$topdir/skins/express_show/spritesheet.png"); |
|
my @camtasia8_4 = ("$topdir/","$topdir/$topdir.html", |
|
"$topdir/$topdir.mp4", |
|
"$topdir/$topdir\_config.xml", |
|
"$topdir/$topdir\_controller.swf", |
|
"$topdir/$topdir\_embed.css", |
|
"$topdir/$topdir\_First_Frame.png", |
|
"$topdir/$topdir\_player.html", |
|
"$topdir/$topdir\_Thumbnails.png", |
|
"$topdir/playerProductInstall.swf", |
|
"$topdir/scripts/", |
|
"$topdir/scripts/config_xml.js", |
|
"$topdir/scripts/techsmith-smart-player.min.js", |
|
"$topdir/skins/", |
|
"$topdir/skins/configuration_express.xml", |
|
"$topdir/skins/express_show/", |
|
"$topdir/skins/express_show/spritesheet.min.css", |
|
"$topdir/skins/express_show/spritesheet.png", |
|
"$topdir/skins/express_show/techsmith-smart-player.min.css"); |
my @diffs = &compare_arrays(\@paths,\@camtasia6); |
my @diffs = &compare_arrays(\@paths,\@camtasia6); |
if (@diffs == 0) { |
if (@diffs == 0) { |
$is_camtasia = 6; |
$is_camtasia = 6; |
} else { |
} else { |
@diffs = &compare_arrays(\@paths,\@camtasia8); |
@diffs = &compare_arrays(\@paths,\@camtasia8_1); |
if (@diffs == 0) { |
if (@diffs == 0) { |
$is_camtasia = 8; |
$is_camtasia = 8; |
|
} else { |
|
@diffs = &compare_arrays(\@paths,\@camtasia8_4); |
|
if (@diffs == 0) { |
|
$is_camtasia = 8; |
|
} |
} |
} |
} |
} |
} |
} |
Line 11098 function camtasiaToggle() {
|
Line 12759 function camtasiaToggle() {
|
for (var i=0; i<document.uploaded_decompress.autoextract_camtasia.length; i++) { |
for (var i=0; i<document.uploaded_decompress.autoextract_camtasia.length; i++) { |
if (document.uploaded_decompress.autoextract_camtasia[i].checked) { |
if (document.uploaded_decompress.autoextract_camtasia[i].checked) { |
if (document.uploaded_decompress.autoextract_camtasia[i].value == $is_camtasia) { |
if (document.uploaded_decompress.autoextract_camtasia[i].value == $is_camtasia) { |
|
|
document.getElementById('camtasia_titles').style.display='block'; |
document.getElementById('camtasia_titles').style.display='block'; |
} else { |
} else { |
document.getElementById('camtasia_titles').style.display='none'; |
document.getElementById('camtasia_titles').style.display='none'; |
Line 11282 sub decompress_uploaded_file {
|
Line 12942 sub decompress_uploaded_file {
|
|
|
sub process_decompression { |
sub process_decompression { |
my ($docudom,$docuname,$file,$destination,$dir_root,$hiddenelem) = @_; |
my ($docudom,$docuname,$file,$destination,$dir_root,$hiddenelem) = @_; |
|
unless (($dir_root eq '/userfiles') && ($destination =~ m{^(docs|supplemental)/(default|\d+)/\d+$})) { |
|
return '<p class="LC_error">'.&mt('Not extracted.').'<br />'. |
|
&mt('Unexpected file path.').'</p>'."\n"; |
|
} |
|
unless (($docudom =~ /^$match_domain$/) && ($docuname =~ /^$match_courseid$/)) { |
|
return '<p class="LC_error">'.&mt('Not extracted.').'<br />'. |
|
&mt('Unexpected course context.').'</p>'."\n"; |
|
} |
|
unless ($file eq &Apache::lonnet::clean_filename($file)) { |
|
return '<p class="LC_error">'.&mt('Not extracted.').'<br />'. |
|
&mt('Filename contained unexpected characters.').'</p>'."\n"; |
|
} |
my ($dir,$error,$warning,$output); |
my ($dir,$error,$warning,$output); |
if ($file !~ /\.(zip|tar|bz2|gz|tar.gz|tar.bz2|tgz)$/i) { |
if ($file !~ /\.(zip|tar|bz2|gz|tar.gz|tar.bz2|tgz)$/i) { |
$error = &mt('Filename not a supported archive file type.'). |
$error = &mt('Filename not a supported archive file type.'). |
Line 11316 sub process_decompression {
|
Line 12988 sub process_decompression {
|
} |
} |
} |
} |
my $numskip = scalar(@to_skip); |
my $numskip = scalar(@to_skip); |
if (($numskip > 0) && |
my $numoverwrite = scalar(@to_overwrite); |
($numskip == $env{'form.archive_itemcount'})) { |
if (($numskip) && (!$numoverwrite)) { |
$warning = &mt('All items in the archive file already exist, and no overwriting of existing files has been requested.'); |
$warning = &mt('All items in the archive file already exist, and no overwriting of existing files has been requested.'); |
} elsif ($dir eq '') { |
} elsif ($dir eq '') { |
$error = &mt('Directory containing archive file unavailable.'); |
$error = &mt('Directory containing archive file unavailable.'); |
} elsif (!$error) { |
} elsif (!$error) { |
my ($decompressed,$display); |
my ($decompressed,$display); |
if ($numskip > 0) { |
if (($numskip) || ($numoverwrite)) { |
my $tempdir = time.'_'.$$.int(rand(10000)); |
my $tempdir = time.'_'.$$.int(rand(10000)); |
mkdir("$dir/$tempdir",0755); |
mkdir("$dir/$tempdir",0755); |
system("mv $dir/$file $dir/$tempdir/$file"); |
if (&File::Copy::move("$dir/$file","$dir/$tempdir/$file")) { |
($decompressed,$display) = |
($decompressed,$display) = |
&decompress_uploaded_file($file,"$dir/$tempdir"); |
&decompress_uploaded_file($file,"$dir/$tempdir"); |
foreach my $item (@to_skip) { |
foreach my $item (@to_skip) { |
if (($item ne '') && ($item !~ /\.\./)) { |
if (($item ne '') && ($item !~ /\.\./)) { |
if (-f "$dir/$tempdir/$item") { |
if (-f "$dir/$tempdir/$item") { |
unlink("$dir/$tempdir/$item"); |
unlink("$dir/$tempdir/$item"); |
} elsif (-d "$dir/$tempdir/$item") { |
} elsif (-d "$dir/$tempdir/$item") { |
system("rm -rf $dir/$tempdir/$item"); |
&File::Path::remove_tree("$dir/$tempdir/$item",{ safe => 1 }); |
|
} |
} |
} |
} |
} |
|
foreach my $item (@to_overwrite) { |
|
if ((-e "$dir/$tempdir/$item") && (-e "$dir/$item")) { |
|
if (($item ne '') && ($item !~ /\.\./)) { |
|
if (-f "$dir/$item") { |
|
unlink("$dir/$item"); |
|
} elsif (-d "$dir/$item") { |
|
&File::Path::remove_tree("$dir/$item",{ safe => 1 }); |
|
} |
|
&File::Copy::move("$dir/$tempdir/$item","$dir/$item"); |
|
} |
|
} |
|
} |
|
if (&File::Copy::move("$dir/$tempdir/$file","$dir/$file")) { |
|
&File::Path::remove_tree("$dir/$tempdir",{ safe => 1 }); |
|
} |
} |
} |
system("mv $dir/$tempdir/* $dir"); |
|
rmdir("$dir/$tempdir"); |
|
} else { |
} else { |
($decompressed,$display) = |
($decompressed,$display) = |
&decompress_uploaded_file($file,$dir); |
&decompress_uploaded_file($file,$dir); |
Line 11357 sub process_decompression {
|
Line 13043 sub process_decompression {
|
if (ref($newdirlistref) eq 'ARRAY') { |
if (ref($newdirlistref) eq 'ARRAY') { |
foreach my $dir_line (@{$newdirlistref}) { |
foreach my $dir_line (@{$newdirlistref}) { |
my ($item,undef,undef,$testdir)=split(/\&/,$dir_line,5); |
my ($item,undef,undef,$testdir)=split(/\&/,$dir_line,5); |
unless (($item =~ /^\.+$/) || ($item eq $file) || |
unless (($item =~ /^\.+$/) || ($item eq $file)) { |
((@to_skip > 0) && (grep(/^\Q$item\E$/,@to_skip)))) { |
|
push(@newitems,$item); |
push(@newitems,$item); |
if ($dirptr&$testdir) { |
if ($dirptr&$testdir) { |
$is_dir{$item} = 1; |
$is_dir{$item} = 1; |
Line 11843 END
|
Line 13528 END
|
sub process_extracted_files { |
sub process_extracted_files { |
my ($context,$docudom,$docuname,$destination,$dir_root,$hiddenelem) = @_; |
my ($context,$docudom,$docuname,$destination,$dir_root,$hiddenelem) = @_; |
my $numitems = $env{'form.archive_count'}; |
my $numitems = $env{'form.archive_count'}; |
return unless ($numitems); |
return if ((!$numitems) || ($numitems =~ /\D/)); |
my @ids=&Apache::lonnet::current_machine_ids(); |
my @ids=&Apache::lonnet::current_machine_ids(); |
my ($prefix,$pathtocheck,$dir,$ishome,$error,$warning,%toplevelitems,%is_dir, |
my ($prefix,$pathtocheck,$dir,$ishome,$error,$warning,%toplevelitems,%is_dir, |
%folders,%containers,%mapinner,%prompttofetch); |
%folders,%containers,%mapinner,%prompttofetch); |
Line 11856 sub process_extracted_files {
|
Line 13541 sub process_extracted_files {
|
} else { |
} else { |
$prefix = $Apache::lonnet::perlvar{'lonDocRoot'}; |
$prefix = $Apache::lonnet::perlvar{'lonDocRoot'}; |
$pathtocheck = "$dir_root/$docudom/$docuname/$destination"; |
$pathtocheck = "$dir_root/$docudom/$docuname/$destination"; |
$dir = "$dir_root/$docudom/$docuname"; |
$dir = "$dir_root/$docudom/$docuname"; |
} |
} |
my $currdir = "$dir_root/$destination"; |
my $currdir = "$dir_root/$destination"; |
(my $docstype,$mapinner{'0'}) = ($destination =~ m{^(docs|supplemental)/(\w+)/}); |
(my $docstype,$mapinner{'0'}) = ($destination =~ m{^(docs|supplemental)/(\w+)/}); |
Line 11945 sub process_extracted_files {
|
Line 13630 sub process_extracted_files {
|
'.'.$containers{$outer},1,1); |
'.'.$containers{$outer},1,1); |
$newseqid{$i} = $newidx; |
$newseqid{$i} = $newidx; |
unless ($errtext) { |
unless ($errtext) { |
$result .= '<li>'.&mt('Folder: [_1] added to course',$docstitle).'</li>'."\n"; |
$result .= '<li>'.&mt('Folder: [_1] added to course', |
|
&HTML::Entities::encode($docstitle,'<>&"')). |
|
'</li>'."\n"; |
} |
} |
} |
} |
} else { |
} else { |
Line 11954 sub process_extracted_files {
|
Line 13641 sub process_extracted_files {
|
my $url = '/uploaded/'.$docudom.'/'.$docuname.'/'. |
my $url = '/uploaded/'.$docudom.'/'.$docuname.'/'. |
$docstype.'/'.$mapinner{$outer}.'/'.$newidx.'/'. |
$docstype.'/'.$mapinner{$outer}.'/'.$newidx.'/'. |
$title; |
$title; |
if (!-e "$prefix$dir/$docstype/$mapinner{$outer}") { |
if (($outer !~ /\D/) && ($mapinner{$outer} !~ /\D/) && ($newidx !~ /\D/)) { |
mkdir("$prefix$dir/$docstype/$mapinner{$outer}",0755); |
if (!-e "$prefix$dir/$docstype/$mapinner{$outer}") { |
} |
mkdir("$prefix$dir/$docstype/$mapinner{$outer}",0755); |
if (!-e "$prefix$dir/$docstype/$mapinner{$outer}/$newidx") { |
|
mkdir("$prefix$dir/$docstype/$mapinner{$outer}/$newidx"); |
|
} |
|
if (-e "$prefix$dir/$docstype/$mapinner{$outer}/$newidx") { |
|
system("mv $prefix$path $prefix$dir/$docstype/$mapinner{$outer}/$newidx/$title"); |
|
$newdest{$i} = "$prefix$dir/$docstype/$mapinner{$outer}/$newidx"; |
|
unless ($ishome) { |
|
my $fetch = "$newdest{$i}/$title"; |
|
$fetch =~ s/^\Q$prefix$dir\E//; |
|
$prompttofetch{$fetch} = 1; |
|
} |
} |
} |
if (!-e "$prefix$dir/$docstype/$mapinner{$outer}/$newidx") { |
$LONCAPA::map::resources[$newidx]= |
mkdir("$prefix$dir/$docstype/$mapinner{$outer}/$newidx"); |
$docstitle.':'.$url.':false:normal:res'; |
} |
push(@LONCAPA::map::order, $newidx); |
if (-e "$prefix$dir/$docstype/$mapinner{$outer}/$newidx") { |
my ($outtext,$errtext)= |
if (rename("$prefix$path","$prefix$dir/$docstype/$mapinner{$outer}/$newidx/$title")) { |
&LONCAPA::map::storemap('/uploaded/'.$docudom.'/'. |
$newdest{$i} = "$prefix$dir/$docstype/$mapinner{$outer}/$newidx"; |
$docuname.'/'.$folders{$outer}. |
unless ($ishome) { |
'.'.$containers{$outer},1,1); |
my $fetch = "$newdest{$i}/$title"; |
unless ($errtext) { |
$fetch =~ s/^\Q$prefix$dir\E//; |
if (-e "$prefix$dir/$docstype/$mapinner{$outer}/$newidx/$title") { |
$prompttofetch{$fetch} = 1; |
$result .= '<li>'.&mt('File: [_1] added to course',$docstitle).'</li>'."\n"; |
} |
|
} |
} |
} |
|
$LONCAPA::map::resources[$newidx]= |
|
$docstitle.':'.$url.':false:normal:res'; |
|
push(@LONCAPA::map::order, $newidx); |
|
my ($outtext,$errtext)= |
|
&LONCAPA::map::storemap('/uploaded/'.$docudom.'/'. |
|
$docuname.'/'.$folders{$outer}. |
|
'.'.$containers{$outer},1,1); |
|
unless ($errtext) { |
|
if (-e "$prefix$dir/$docstype/$mapinner{$outer}/$newidx/$title") { |
|
$result .= '<li>'.&mt('File: [_1] added to course', |
|
&HTML::Entities::encode($docstitle,'<>&"')). |
|
'</li>'."\n"; |
|
} |
|
} |
|
} else { |
|
$warning .= &mt('Item extracted from archive: [_1] has unexpected path.', |
|
&HTML::Entities::encode($path,'<>&"')).'<br />'; |
} |
} |
} |
} |
} |
} |
} |
} |
} else { |
} else { |
$warning .= &mt('Item extracted from archive: [_1] has unexpected path.',$path).'<br />'; |
$warning .= &mt('Item extracted from archive: [_1] has unexpected path.', |
|
&HTML::Entities::encode($path,'<>&"')).'<br />'; |
} |
} |
} |
} |
for (my $i=1; $i<=$numitems; $i++) { |
for (my $i=1; $i<=$numitems; $i++) { |
Line 12046 sub process_extracted_files {
|
Line 13742 sub process_extracted_files {
|
} |
} |
if ($fullpath ne '') { |
if ($fullpath ne '') { |
if (-e "$prefix$path") { |
if (-e "$prefix$path") { |
system("mv $prefix$path $fullpath/$title"); |
unless (rename("$prefix$path","$fullpath/$title")) { |
|
$warning .= &mt('Failed to rename dependency').'<br />'; |
|
} |
} |
} |
if (-e "$fullpath/$title") { |
if (-e "$fullpath/$title") { |
my $showpath; |
my $showpath; |
Line 12055 sub process_extracted_files {
|
Line 13753 sub process_extracted_files {
|
} else { |
} else { |
$showpath = "/$title"; |
$showpath = "/$title"; |
} |
} |
$result .= '<li>'.&mt('[_1] included as a dependency',$showpath).'</li>'."\n"; |
$result .= '<li>'.&mt('[_1] included as a dependency', |
} |
&HTML::Entities::encode($showpath,'<>&"')). |
unless ($ishome) { |
'</li>'."\n"; |
my $fetch = "$fullpath/$title"; |
unless ($ishome) { |
$fetch =~ s/^\Q$prefix$dir\E//; |
my $fetch = "$fullpath/$title"; |
$prompttofetch{$fetch} = 1; |
$fetch =~ s/^\Q$prefix$dir\E//; |
|
$prompttofetch{$fetch} = 1; |
|
} |
} |
} |
} |
} |
} |
} |
} elsif ($env{'form.archive_'.$referrer{$i}} eq 'discard') { |
} elsif ($env{'form.archive_'.$referrer{$i}} eq 'discard') { |
$warning .= &mt('[_1] is a dependency of [_2], which was discarded.', |
$warning .= &mt('[_1] is a dependency of [_2], which was discarded.', |
$path,$env{'form.archive_content_'.$referrer{$i}}).'<br />'; |
&HTML::Entities::encode($path,'<>&"'), |
|
&HTML::Entities::encode($env{'form.archive_content_'.$referrer{$i}},'<>&"')). |
|
'<br />'; |
} |
} |
} else { |
} else { |
$warning .= &mt('Item extracted from archive: [_1] has unexpected path.',$path).'<br />'; |
$warning .= &mt('Item extracted from archive: [_1] has unexpected path.', |
|
&HTML::Entities::encode($path)).'<br />'; |
} |
} |
} |
} |
if (keys(%todelete)) { |
if (keys(%todelete)) { |
Line 12343 sub upfile_store {
|
Line 14046 sub upfile_store {
|
$env{'form.upfile'}=~s/\n+/\n/gs; |
$env{'form.upfile'}=~s/\n+/\n/gs; |
$env{'form.upfile'}=~s/\n+$//gs; |
$env{'form.upfile'}=~s/\n+$//gs; |
|
|
my $datatoken=$env{'user.name'}.'_'.$env{'user.domain'}. |
my $datatoken = &valid_datatoken($env{'user.name'}.'_'.$env{'user.domain'}. |
'_enroll_'.$env{'request.course.id'}.'_'.time.'_'.$$; |
'_enroll_'.$env{'request.course.id'}.'_'. |
|
time.'_'.$$); |
|
return if ($datatoken eq ''); |
|
|
{ |
{ |
my $datafile = $r->dir_config('lonDaemons'). |
my $datafile = $r->dir_config('lonDaemons'). |
'/tmp/'.$datatoken.'.tmp'; |
'/tmp/'.$datatoken.'.tmp'; |
if ( open(my $fh,">$datafile") ) { |
if ( open(my $fh,'>',$datafile) ) { |
print $fh $env{'form.upfile'}; |
print $fh $env{'form.upfile'}; |
close($fh); |
close($fh); |
} |
} |
Line 12358 sub upfile_store {
|
Line 14064 sub upfile_store {
|
|
|
=pod |
=pod |
|
|
=item * &load_tmp_file($r) |
=item * &load_tmp_file($r,$datatoken) |
|
|
Load uploaded file from tmp, $r should be the HTTP Request object, |
Load uploaded file from tmp, $r should be the HTTP Request object, |
needs $env{'form.datatoken'}, |
$datatoken is the name to assign to the temporary file. |
sets $env{'form.upfile'} to the contents of the file |
sets $env{'form.upfile'} to the contents of the file |
|
|
=cut |
=cut |
|
|
sub load_tmp_file { |
sub load_tmp_file { |
my $r=shift; |
my ($r,$datatoken) = @_; |
|
return if ($datatoken eq ''); |
my @studentdata=(); |
my @studentdata=(); |
{ |
{ |
my $studentfile = $r->dir_config('lonDaemons'). |
my $studentfile = $r->dir_config('lonDaemons'). |
'/tmp/'.$env{'form.datatoken'}.'.tmp'; |
'/tmp/'.$datatoken.'.tmp'; |
if ( open(my $fh,"<$studentfile") ) { |
if ( open(my $fh,'<',$studentfile) ) { |
@studentdata=<$fh>; |
@studentdata=<$fh>; |
close($fh); |
close($fh); |
} |
} |
Line 12380 sub load_tmp_file {
|
Line 14087 sub load_tmp_file {
|
$env{'form.upfile'}=join('',@studentdata); |
$env{'form.upfile'}=join('',@studentdata); |
} |
} |
|
|
|
sub valid_datatoken { |
|
my ($datatoken) = @_; |
|
if ($datatoken =~ /^$match_username\_$match_domain\_enroll_(|$match_domain\_$match_courseid)\_\d+_\d+$/) { |
|
return $datatoken; |
|
} |
|
return; |
|
} |
|
|
=pod |
=pod |
|
|
=item * &upfile_record_sep() |
=item * &upfile_record_sep() |
Line 12820 sub DrawBarGraph {
|
Line 14535 sub DrawBarGraph {
|
@Labels = @$labels; |
@Labels = @$labels; |
} else { |
} else { |
for (my $i=0;$i<@{$Values[0]};$i++) { |
for (my $i=0;$i<@{$Values[0]};$i++) { |
push (@Labels,$i+1); |
push(@Labels,$i+1); |
} |
} |
} |
} |
# |
# |
Line 13266 requestsmail, updatesmail, or idconflict
|
Line 14981 requestsmail, updatesmail, or idconflict
|
defdom (domain for which to retrieve configuration settings), |
defdom (domain for which to retrieve configuration settings), |
|
|
origmail (scalar - email address of recipient from loncapa.conf, |
origmail (scalar - email address of recipient from loncapa.conf, |
i.e., predates configuration by DC via domainprefs.pm |
i.e., predates configuration by DC via domainprefs.pm |
|
|
|
$requname username of requester (if mailing type is helpdeskmail) |
|
|
|
$requdom domain of requester (if mailing type is helpdeskmail) |
|
|
|
$reqemail e-mail address of requester (if mailing type is helpdeskmail) |
|
|
|
|
Returns: comma separated list of addresses to which to send e-mail. |
Returns: comma separated list of addresses to which to send e-mail. |
|
|
Line 13277 Returns: comma separated list of address
|
Line 14999 Returns: comma separated list of address
|
############################################################ |
############################################################ |
############################################################ |
############################################################ |
sub build_recipient_list { |
sub build_recipient_list { |
my ($defmail,$mailing,$defdom,$origmail) = @_; |
my ($defmail,$mailing,$defdom,$origmail,$requname,$requdom,$reqemail) = @_; |
my @recipients; |
my @recipients; |
my $otheremails; |
my ($otheremails,$lastresort,$allbcc,$addtext); |
my %domconfig = |
my %domconfig = |
&Apache::lonnet::get_dom('configuration',['contacts'],$defdom); |
&Apache::lonnet::get_dom('configuration',['contacts'],$defdom); |
if (ref($domconfig{'contacts'}) eq 'HASH') { |
if (ref($domconfig{'contacts'}) eq 'HASH') { |
if (exists($domconfig{'contacts'}{$mailing})) { |
if (exists($domconfig{'contacts'}{$mailing})) { |
if (ref($domconfig{'contacts'}{$mailing}) eq 'HASH') { |
if (ref($domconfig{'contacts'}{$mailing}) eq 'HASH') { |
Line 13293 sub build_recipient_list {
|
Line 15015 sub build_recipient_list {
|
push(@recipients,$addr); |
push(@recipients,$addr); |
} |
} |
} |
} |
$otheremails = $domconfig{'contacts'}{$mailing}{'others'}; |
} |
|
$otheremails = $domconfig{'contacts'}{$mailing}{'others'}; |
|
if ($mailing eq 'helpdeskmail') { |
|
if ($domconfig{'contacts'}{$mailing}{'bcc'}) { |
|
my @bccs = split(/,/,$domconfig{'contacts'}{$mailing}{'bcc'}); |
|
my @ok_bccs; |
|
foreach my $bcc (@bccs) { |
|
$bcc =~ s/^\s+//g; |
|
$bcc =~ s/\s+$//g; |
|
if ($bcc =~ m/^[^\@]+\@[^\@]+$/) { |
|
if (!(grep(/^\Q$bcc\E$/,@ok_bccs))) { |
|
push(@ok_bccs,$bcc); |
|
} |
|
} |
|
} |
|
if (@ok_bccs > 0) { |
|
$allbcc = join(', ',@ok_bccs); |
|
} |
|
} |
|
$addtext = $domconfig{'contacts'}{$mailing}{'include'}; |
} |
} |
} |
} |
} elsif ($origmail ne '') { |
} elsif ($origmail ne '') { |
push(@recipients,$origmail); |
$lastresort = $origmail; |
|
} |
|
if ($mailing eq 'helpdeskmail') { |
|
if ((ref($domconfig{'contacts'}{'overrides'}) eq 'HASH') && |
|
(keys(%{$domconfig{'contacts'}{'overrides'}}))) { |
|
my ($inststatus,$inststatus_checked); |
|
if (($env{'user.name'} ne '') && ($env{'user.domain'} ne '') && |
|
($env{'user.domain'} ne 'public')) { |
|
$inststatus_checked = 1; |
|
$inststatus = $env{'environment.inststatus'}; |
|
} |
|
unless ($inststatus_checked) { |
|
if (($requname ne '') && ($requdom ne '')) { |
|
if (($requname =~ /^$match_username$/) && |
|
($requdom =~ /^$match_domain$/) && |
|
(&Apache::lonnet::domain($requdom))) { |
|
my $requhome = &Apache::lonnet::homeserver($requname, |
|
$requdom); |
|
unless ($requhome eq 'no_host') { |
|
my %userenv = &Apache::lonnet::userenvironment($requdom,$requname,'inststatus'); |
|
$inststatus = $userenv{'inststatus'}; |
|
$inststatus_checked = 1; |
|
} |
|
} |
|
} |
|
} |
|
unless ($inststatus_checked) { |
|
if ($reqemail =~ /^[^\@]+\@[^\@]+$/) { |
|
my %srch = (srchby => 'email', |
|
srchdomain => $defdom, |
|
srchterm => $reqemail, |
|
srchtype => 'exact'); |
|
my %srch_results = &Apache::lonnet::usersearch(\%srch); |
|
foreach my $uname (keys(%srch_results)) { |
|
if (ref($srch_results{$uname}{'inststatus'}) eq 'ARRAY') { |
|
$inststatus = join(',',@{$srch_results{$uname}{'inststatus'}}); |
|
$inststatus_checked = 1; |
|
last; |
|
} |
|
} |
|
unless ($inststatus_checked) { |
|
my ($dirsrchres,%srch_results) = &Apache::lonnet::inst_directory_query(\%srch); |
|
if ($dirsrchres eq 'ok') { |
|
foreach my $uname (keys(%srch_results)) { |
|
if (ref($srch_results{$uname}{'inststatus'}) eq 'ARRAY') { |
|
$inststatus = join(',',@{$srch_results{$uname}{'inststatus'}}); |
|
$inststatus_checked = 1; |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if ($inststatus ne '') { |
|
foreach my $status (split(/\:/,$inststatus)) { |
|
if (ref($domconfig{'contacts'}{'overrides'}{$status}) eq 'HASH') { |
|
my @contacts = ('adminemail','supportemail'); |
|
foreach my $item (@contacts) { |
|
if ($domconfig{'contacts'}{'overrides'}{$status}{$item}) { |
|
my $addr = $domconfig{'contacts'}{'overrides'}{$status}; |
|
if (!grep(/^\Q$addr\E$/,@recipients)) { |
|
push(@recipients,$addr); |
|
} |
|
} |
|
} |
|
$otheremails = $domconfig{'contacts'}{'overrides'}{$status}{'others'}; |
|
if ($domconfig{'contacts'}{'overrides'}{$status}{'bcc'}) { |
|
my @bccs = split(/,/,$domconfig{'contacts'}{'overrides'}{$status}{'bcc'}); |
|
my @ok_bccs; |
|
foreach my $bcc (@bccs) { |
|
$bcc =~ s/^\s+//g; |
|
$bcc =~ s/\s+$//g; |
|
if ($bcc =~ m/^[^\@]+\@[^\@]+$/) { |
|
if (!(grep(/^\Q$bcc\E$/,@ok_bccs))) { |
|
push(@ok_bccs,$bcc); |
|
} |
|
} |
|
} |
|
if (@ok_bccs > 0) { |
|
$allbcc = join(', ',@ok_bccs); |
|
} |
|
} |
|
$addtext = $domconfig{'contacts'}{'overrides'}{$status}{'include'}; |
|
last; |
|
} |
|
} |
|
} |
|
} |
} |
} |
} elsif ($origmail ne '') { |
} elsif ($origmail ne '') { |
push(@recipients,$origmail); |
$lastresort = $origmail; |
|
} |
|
if (($mailing eq 'helpdeskmail') && ($lastresort ne '')) { |
|
unless (grep(/^\Q$defdom\E$/,&Apache::lonnet::current_machine_domains())) { |
|
my $lonhost = $Apache::lonnet::perlvar{'lonHostID'}; |
|
my $machinedom = $Apache::lonnet::perlvar{'lonDefDomain'}; |
|
my %what = ( |
|
perlvar => 1, |
|
); |
|
my $primary = &Apache::lonnet::domain($defdom,'primary'); |
|
if ($primary) { |
|
my $gotaddr; |
|
my ($result,$returnhash) = |
|
&Apache::lonnet::get_remote_globals($primary,{ perlvar => 1 }); |
|
if (($result eq 'ok') && (ref($returnhash) eq 'HASH')) { |
|
if ($returnhash->{'lonSupportEMail'} =~ /^[^\@]+\@[^\@]+$/) { |
|
$lastresort = $returnhash->{'lonSupportEMail'}; |
|
$gotaddr = 1; |
|
} |
|
} |
|
unless ($gotaddr) { |
|
my $uintdom = &Apache::lonnet::internet_dom($primary); |
|
my $intdom = &Apache::lonnet::internet_dom($lonhost); |
|
unless ($uintdom eq $intdom) { |
|
my %domconfig = |
|
&Apache::lonnet::get_dom('configuration',['contacts'],$machinedom); |
|
if (ref($domconfig{'contacts'}) eq 'HASH') { |
|
if (ref($domconfig{'contacts'}{'otherdomsmail'}) eq 'HASH') { |
|
my @contacts = ('adminemail','supportemail'); |
|
foreach my $item (@contacts) { |
|
if ($domconfig{'contacts'}{'otherdomsmail'}{$item}) { |
|
my $addr = $domconfig{'contacts'}{$item}; |
|
if (!grep(/^\Q$addr\E$/,@recipients)) { |
|
push(@recipients,$addr); |
|
} |
|
} |
|
} |
|
if ($domconfig{'contacts'}{'otherdomsmail'}{'others'}) { |
|
$otheremails = $domconfig{'contacts'}{'otherdomsmail'}{'others'}; |
|
} |
|
if ($domconfig{'contacts'}{'otherdomsmail'}{'bcc'}) { |
|
my @bccs = split(/,/,$domconfig{'contacts'}{'otherdomsmail'}{'bcc'}); |
|
my @ok_bccs; |
|
foreach my $bcc (@bccs) { |
|
$bcc =~ s/^\s+//g; |
|
$bcc =~ s/\s+$//g; |
|
if ($bcc =~ m/^[^\@]+\@[^\@]+$/) { |
|
if (!(grep(/^\Q$bcc\E$/,@ok_bccs))) { |
|
push(@ok_bccs,$bcc); |
|
} |
|
} |
|
} |
|
if (@ok_bccs > 0) { |
|
$allbcc = join(', ',@ok_bccs); |
|
} |
|
} |
|
$addtext = $domconfig{'contacts'}{'otherdomsmail'}{'include'}; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
} |
} |
if (defined($defmail)) { |
if (defined($defmail)) { |
if ($defmail ne '') { |
if ($defmail ne '') { |
Line 13320 sub build_recipient_list {
|
Line 15211 sub build_recipient_list {
|
} |
} |
} |
} |
} |
} |
my $recipientlist = join(',',@recipients); |
if ($mailing eq 'helpdeskmail') { |
return $recipientlist; |
if ((!@recipients) && ($lastresort ne '')) { |
|
push(@recipients,$lastresort); |
|
} |
|
} elsif ($lastresort ne '') { |
|
if (!grep(/^\Q$lastresort\E$/,@recipients)) { |
|
push(@recipients,$lastresort); |
|
} |
|
} |
|
my $recipientlist = join(',',@recipients); |
|
if (wantarray) { |
|
return ($recipientlist,$allbcc,$addtext); |
|
} else { |
|
return $recipientlist; |
|
} |
|
} |
|
|
|
############################################################ |
|
############################################################ |
|
|
|
=pod |
|
|
|
=over 4 |
|
|
|
=item * &mime_email() |
|
|
|
Sends an email with a possible attachment |
|
|
|
Inputs: |
|
|
|
=over 4 |
|
|
|
from - Sender's email address |
|
|
|
replyto - Reply-To email address |
|
|
|
to - Email address of recipient |
|
|
|
subject - Subject of email |
|
|
|
body - Body of email |
|
|
|
cc_string - Carbon copy email address |
|
|
|
bcc - Blind carbon copy email address |
|
|
|
attachment_path - Path of file to be attached |
|
|
|
file_name - Name of file to be attached |
|
|
|
attachment_text - The body of an attachment of type "TEXT" |
|
|
|
=back |
|
|
|
=back |
|
|
|
=cut |
|
|
|
############################################################ |
|
############################################################ |
|
|
|
sub mime_email { |
|
my ($from,$replyto,$to,$subject,$body,$cc_string,$bcc,$attachment_path, |
|
$file_name,$attachment_text) = @_; |
|
|
|
my $msg = MIME::Lite->new( |
|
From => $from, |
|
To => $to, |
|
Subject => $subject, |
|
Type =>'TEXT', |
|
Data => $body, |
|
); |
|
if ($replyto ne '') { |
|
$msg->add("Reply-To" => $replyto); |
|
} |
|
if ($cc_string ne '') { |
|
$msg->add("Cc" => $cc_string); |
|
} |
|
if ($bcc ne '') { |
|
$msg->add("Bcc" => $bcc); |
|
} |
|
$msg->attr("content-type" => "text/plain"); |
|
$msg->attr("content-type.charset" => "UTF-8"); |
|
# Attach file if given |
|
if ($attachment_path) { |
|
unless ($file_name) { |
|
if ($attachment_path =~ m-/([^/]+)$-) { $file_name = $1; } |
|
} |
|
my ($type, $encoding) = MIME::Types::by_suffix($attachment_path); |
|
$msg->attach(Type => $type, |
|
Path => $attachment_path, |
|
Filename => $file_name |
|
); |
|
# Otherwise attach text if given |
|
} elsif ($attachment_text) { |
|
$msg->attach(Type => 'TEXT', |
|
Data => $attachment_text); |
|
} |
|
# Send it |
|
$msg->send('sendmail'); |
} |
} |
|
|
############################################################ |
############################################################ |
Line 13412 jsarray (reference to array of categorie
|
Line 15401 jsarray (reference to array of categorie
|
subcats (reference to hash of arrays containing all subcategories within each |
subcats (reference to hash of arrays containing all subcategories within each |
category, -recursive) |
category, -recursive) |
|
|
|
maxd (reference to hash used to hold max depth for all top-level categories). |
|
|
Returns: nothing |
Returns: nothing |
|
|
Side effects: populates trails and allitems hash references. |
Side effects: populates trails and allitems hash references. |
Line 13419 Side effects: populates trails and allit
|
Line 15410 Side effects: populates trails and allit
|
=cut |
=cut |
|
|
sub extract_categories { |
sub extract_categories { |
my ($categories,$cats,$trails,$allitems,$idx,$jsarray,$subcats) = @_; |
my ($categories,$cats,$trails,$allitems,$idx,$jsarray,$subcats,$maxd) = @_; |
if (ref($categories) eq 'HASH') { |
if (ref($categories) eq 'HASH') { |
&gather_categories($categories,$cats,$idx,$jsarray); |
&gather_categories($categories,$cats,$idx,$jsarray); |
if (ref($cats->[0]) eq 'ARRAY') { |
if (ref($cats->[0]) eq 'ARRAY') { |
Line 13431 sub extract_categories {
|
Line 15422 sub extract_categories {
|
$trailstr = &mt('Official courses (with institutional codes)'); |
$trailstr = &mt('Official courses (with institutional codes)'); |
} elsif ($name eq 'communities') { |
} elsif ($name eq 'communities') { |
$trailstr = &mt('Communities'); |
$trailstr = &mt('Communities'); |
|
} elsif ($name eq 'placement') { |
|
$trailstr = &mt('Placement Tests'); |
} else { |
} else { |
$trailstr = $name; |
$trailstr = $name; |
} |
} |
Line 13445 sub extract_categories {
|
Line 15438 sub extract_categories {
|
if (ref($subcats) eq 'HASH') { |
if (ref($subcats) eq 'HASH') { |
push(@{$subcats->{$item}},&escape($category).':'.&escape($name).':1'); |
push(@{$subcats->{$item}},&escape($category).':'.&escape($name).':1'); |
} |
} |
&recurse_categories($cats,2,$category,$trails,$allitems,\@parents,$subcats); |
&recurse_categories($cats,2,$category,$trails,$allitems,\@parents,$subcats,$maxd); |
} |
} |
} else { |
} else { |
if (ref($subcats) eq 'HASH') { |
if (ref($subcats) eq 'HASH') { |
$subcats->{$item} = []; |
$subcats->{$item} = []; |
} |
} |
|
if (ref($maxd) eq 'HASH') { |
|
$maxd->{$name} = 1; |
|
} |
} |
} |
} |
} |
} |
} |
Line 13488 Side effects: populates trails and allit
|
Line 15484 Side effects: populates trails and allit
|
=cut |
=cut |
|
|
sub recurse_categories { |
sub recurse_categories { |
my ($cats,$depth,$category,$trails,$allitems,$parents,$subcats) = @_; |
my ($cats,$depth,$category,$trails,$allitems,$parents,$subcats,$maxd) = @_; |
my $shallower = $depth - 1; |
my $shallower = $depth - 1; |
if (ref($cats->[$depth]{$category}) eq 'ARRAY') { |
if (ref($cats->[$depth]{$category}) eq 'ARRAY') { |
for (my $k=0; $k<@{$cats->[$depth]{$category}}; $k++) { |
for (my $k=0; $k<@{$cats->[$depth]{$category}}; $k++) { |
my $name = $cats->[$depth]{$category}[$k]; |
my $name = $cats->[$depth]{$category}[$k]; |
my $item = &escape($category).':'.&escape($parents->[-1]).':'.$shallower; |
my $item = &escape($category).':'.&escape($parents->[-1]).':'.$shallower; |
my $trailstr = join(' -> ',(@{$parents},$category)); |
my $trailstr = join(' » ',(@{$parents},$category)); |
if ($allitems->{$item} eq '') { |
if ($allitems->{$item} eq '') { |
push(@{$trails},$trailstr); |
push(@{$trails},$trailstr); |
$allitems->{$item} = scalar(@{$trails})-1; |
$allitems->{$item} = scalar(@{$trails})-1; |
Line 13515 sub recurse_categories {
|
Line 15511 sub recurse_categories {
|
} |
} |
} |
} |
&recurse_categories($cats,$deeper,$name,$trails,$allitems,$parents, |
&recurse_categories($cats,$deeper,$name,$trails,$allitems,$parents, |
$subcats); |
$subcats,$maxd); |
pop(@{$parents}); |
pop(@{$parents}); |
} |
} |
} else { |
} else { |
my $item = &escape($category).':'.&escape($parents->[-1]).':'.$shallower; |
my $item = &escape($category).':'.&escape($parents->[-1]).':'.$shallower; |
my $trailstr = join(' -> ',(@{$parents},$category)); |
my $trailstr = join(' » ',(@{$parents},$category)); |
if ($allitems->{$item} eq '') { |
if ($allitems->{$item} eq '') { |
push(@{$trails},$trailstr); |
push(@{$trails},$trailstr); |
$allitems->{$item} = scalar(@{$trails})-1; |
$allitems->{$item} = scalar(@{$trails})-1; |
} |
} |
|
if (ref($maxd) eq 'HASH') { |
|
if ($depth > $maxd->{$parents->[0]}) { |
|
$maxd->{$parents->[0]} = $depth; |
|
} |
|
} |
} |
} |
return; |
return; |
} |
} |
Line 13545 currcat - scalar with an & separated lis
|
Line 15546 currcat - scalar with an & separated lis
|
|
|
type - scalar contains course type (Course or Community). |
type - scalar contains course type (Course or Community). |
|
|
|
disabled - scalar (optional) contains disabled="disabled" if input elements are |
|
to be readonly (e.g., Domain Helpdesk role viewing course settings). |
|
|
Returns: $output (markup to be displayed) |
Returns: $output (markup to be displayed) |
|
|
=cut |
=cut |
|
|
sub assign_categories_table { |
sub assign_categories_table { |
my ($cathash,$currcat,$type) = @_; |
my ($cathash,$currcat,$type,$disabled) = @_; |
my $output; |
my $output; |
if (ref($cathash) eq 'HASH') { |
if (ref($cathash) eq 'HASH') { |
my (@cats,@trails,%allitems,%idx,@jsarray,@path,$maxdepth); |
my (@cats,@trails,%allitems,%idx,@jsarray,%maxd,@path,$maxdepth); |
&extract_categories($cathash,\@cats,\@trails,\%allitems,\%idx,\@jsarray); |
&extract_categories($cathash,\@cats,\@trails,\%allitems,\%idx,\@jsarray,\%maxd); |
$maxdepth = scalar(@cats); |
$maxdepth = scalar(@cats); |
if (@cats > 0) { |
if (@cats > 0) { |
my $itemcount = 0; |
my $itemcount = 0; |
Line 13569 sub assign_categories_table {
|
Line 15573 sub assign_categories_table {
|
next if ($parent eq 'instcode'); |
next if ($parent eq 'instcode'); |
if ($type eq 'Community') { |
if ($type eq 'Community') { |
next unless ($parent eq 'communities'); |
next unless ($parent eq 'communities'); |
|
} elsif ($type eq 'Placement') { |
|
next unless ($parent eq 'placement'); |
} else { |
} else { |
next if ($parent eq 'communities'); |
next if (($parent eq 'communities') || ($parent eq 'placement')); |
} |
} |
my $css_class = $itemcount%2?' class="LC_odd_row"':''; |
my $css_class = $itemcount%2?' class="LC_odd_row"':''; |
my $item = &escape($parent).'::0'; |
my $item = &escape($parent).'::0'; |
Line 13583 sub assign_categories_table {
|
Line 15589 sub assign_categories_table {
|
my $parent_title = $parent; |
my $parent_title = $parent; |
if ($parent eq 'communities') { |
if ($parent eq 'communities') { |
$parent_title = &mt('Communities'); |
$parent_title = &mt('Communities'); |
|
} elsif ($parent eq 'placement') { |
|
$parent_title = &mt('Placement Tests'); |
} |
} |
$table .= '<tr '.$css_class.'><td><span class="LC_nobreak">'. |
$table .= '<tr '.$css_class.'><td><span class="LC_nobreak">'. |
'<input type="checkbox" name="usecategory" value="'. |
'<input type="checkbox" name="usecategory" value="'. |
$item.'"'.$checked.' />'.$parent_title.'</span>'. |
$item.'"'.$checked.$disabled.' />'.$parent_title.'</span>'. |
'<input type="hidden" name="catname" value="'.$parent.'" /></td>'; |
'<input type="hidden" name="catname" value="'.$parent.'" /></td>'; |
my $depth = 1; |
my $depth = 1; |
push(@path,$parent); |
push(@path,$parent); |
$table .= &assign_category_rows($itemcount,\@cats,$depth,$parent,\@path,\@currcategories); |
$table .= &assign_category_rows($itemcount,\@cats,$depth,$parent,\@path,\@currcategories,$disabled); |
pop(@path); |
pop(@path); |
$table .= '</tr><tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr>'; |
$table .= '</tr><tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr>'; |
$itemcount ++; |
$itemcount ++; |
Line 13629 path - Array containing all categories b
|
Line 15637 path - Array containing all categories b
|
|
|
currcategories - reference to array of current categories assigned to the course |
currcategories - reference to array of current categories assigned to the course |
|
|
|
disabled - scalar (optional) contains disabled="disabled" if input elements are |
|
to be readonly (e.g., Domain Helpdesk role viewing course settings). |
|
|
Returns: $output (markup to be displayed). |
Returns: $output (markup to be displayed). |
|
|
=cut |
=cut |
|
|
sub assign_category_rows { |
sub assign_category_rows { |
my ($itemcount,$cats,$depth,$parent,$path,$currcategories) = @_; |
my ($itemcount,$cats,$depth,$parent,$path,$currcategories,$disabled) = @_; |
my ($text,$name,$item,$chgstr); |
my ($text,$name,$item,$chgstr); |
if (ref($cats) eq 'ARRAY') { |
if (ref($cats) eq 'ARRAY') { |
my $maxdepth = scalar(@{$cats}); |
my $maxdepth = scalar(@{$cats}); |
Line 13657 sub assign_category_rows {
|
Line 15668 sub assign_category_rows {
|
} |
} |
$text .= '<tr><td><span class="LC_nobreak"><label>'. |
$text .= '<tr><td><span class="LC_nobreak"><label>'. |
'<input type="checkbox" name="usecategory" value="'. |
'<input type="checkbox" name="usecategory" value="'. |
$item.'"'.$checked.' />'.$name.'</label></span>'. |
$item.'"'.$checked.$disabled.' />'.$name.'</label></span>'. |
'<input type="hidden" name="catname" value="'.$name.'" />'. |
'<input type="hidden" name="catname" value="'.$name.'" />'. |
'</td><td>'; |
'</td><td>'; |
if (ref($path) eq 'ARRAY') { |
if (ref($path) eq 'ARRAY') { |
push(@{$path},$name); |
push(@{$path},$name); |
$text .= &assign_category_rows($itemcount,$cats,$deeper,$name,$path,$currcategories); |
$text .= &assign_category_rows($itemcount,$cats,$deeper,$name,$path,$currcategories,$disabled); |
pop(@{$path}); |
pop(@{$path}); |
} |
} |
$text .= '</td></tr>'; |
$text .= '</td></tr>'; |
Line 13873 sub check_clone {
|
Line 15884 sub check_clone {
|
my $cloneid='/'.$args->{'clonedomain'}.'/'.$args->{'clonecourse'}; |
my $cloneid='/'.$args->{'clonedomain'}.'/'.$args->{'clonecourse'}; |
my ($clonecrsudom,$clonecrsunum)= &LONCAPA::split_courseid($cloneid); |
my ($clonecrsudom,$clonecrsunum)= &LONCAPA::split_courseid($cloneid); |
my $clonehome=&Apache::lonnet::homeserver($clonecrsunum,$clonecrsudom); |
my $clonehome=&Apache::lonnet::homeserver($clonecrsunum,$clonecrsudom); |
my $clonemsg; |
my $clonetitle; |
|
my @clonemsg; |
my $can_clone = 0; |
my $can_clone = 0; |
my $lctype = lc($args->{'crstype'}); |
my $lctype = lc($args->{'crstype'}); |
if ($lctype ne 'community') { |
if ($lctype ne 'community') { |
Line 13881 sub check_clone {
|
Line 15893 sub check_clone {
|
} |
} |
if ($clonehome eq 'no_host') { |
if ($clonehome eq 'no_host') { |
if ($args->{'crstype'} eq 'Community') { |
if ($args->{'crstype'} eq 'Community') { |
$clonemsg = &mt('No new community created.').$linefeed.&mt('A new community could not be cloned from the specified original - [_1] - because it is a non-existent community.',$args->{'clonecourse'}.':'.$args->{'clonedomain'}); |
push(@clonemsg,({ |
|
mt => 'No new community created.', |
|
args => [], |
|
}, |
|
{ |
|
mt => 'A new community could not be cloned from the specified original - [_1] - because it is a non-existent community.', |
|
args => [$args->{'clonedomain'}.':'.$args->{'clonedomain'}], |
|
})); |
} else { |
} else { |
$clonemsg = &mt('No new course created.').$linefeed.&mt('A new course could not be cloned from the specified original - [_1] - because it is a non-existent course.',$args->{'clonecourse'}.':'.$args->{'clonedomain'}); |
push(@clonemsg,({ |
} |
mt => 'No new course created.', |
|
args => [], |
|
}, |
|
{ |
|
mt => 'A new course could not be cloned from the specified original - [_1] - because it is a non-existent course.', |
|
args => [$args->{'clonecourse'}.':'.$args->{'clonedomain'}], |
|
})); |
|
} |
} else { |
} else { |
my %clonedesc = &Apache::lonnet::coursedescription($cloneid,{'one_time' => 1}); |
my %clonedesc = &Apache::lonnet::coursedescription($cloneid,{'one_time' => 1}); |
|
$clonetitle = $clonedesc{'description'}; |
if ($args->{'crstype'} eq 'Community') { |
if ($args->{'crstype'} eq 'Community') { |
if ($clonedesc{'type'} ne 'Community') { |
if ($clonedesc{'type'} ne 'Community') { |
$clonemsg = &mt('No new community created.').$linefeed.&mt('A new community could not be cloned from the specified original - [_1] - because it is a course not a community.',$args->{'clonecourse'}.':'.$args->{'clonedomain'}); |
push(@clonemsg,({ |
return ($can_clone, $clonemsg, $cloneid, $clonehome); |
mt => 'No new community created.', |
|
args => [], |
|
}, |
|
{ |
|
mt => 'A new community could not be cloned from the specified original - [_1] - because it is a course not a community.', |
|
args => [$args->{'clonecourse'}.':'.$args->{'clonedomain'}], |
|
})); |
|
return ($can_clone,\@clonemsg,$cloneid,$clonehome); |
} |
} |
} |
} |
if (($env{'request.role.domain'} eq $args->{'clonedomain'}) && |
if (($env{'request.role.domain'} eq $args->{'clonedomain'}) && |
(&Apache::lonnet::allowed('ccc',$env{'request.role.domain'}))) { |
(&Apache::lonnet::allowed('ccc',$env{'request.role.domain'}))) { |
$can_clone = 1; |
$can_clone = 1; |
} else { |
} else { |
my %clonehash = &Apache::lonnet::get('environment',['cloners'], |
my %clonehash = &Apache::lonnet::get('environment',['cloners','internal.coursecode'], |
$args->{'clonedomain'},$args->{'clonecourse'}); |
$args->{'clonedomain'},$args->{'clonecourse'}); |
my @cloners = split(/,/,$clonehash{'cloners'}); |
if ($clonehash{'cloners'} eq '') { |
if (grep(/^\*$/,@cloners)) { |
my %domdefs = &Apache::lonnet::get_domain_defaults($args->{'course_domain'}); |
$can_clone = 1; |
if ($domdefs{'canclone'}) { |
} elsif (grep(/^\*\:\Q$args->{'ccdomain'}\E$/,@cloners)) { |
unless ($domdefs{'canclone'} eq 'none') { |
$can_clone = 1; |
if ($domdefs{'canclone'} eq 'domain') { |
|
if ($args->{'ccdomain'} eq $args->{'clonedomain'}) { |
|
$can_clone = 1; |
|
} |
|
} elsif (($clonehash{'internal.coursecode'}) && ($args->{'crscode'}) && |
|
($args->{'clonedomain'} eq $args->{'course_domain'})) { |
|
if (&Apache::lonnet::default_instcode_cloning($args->{'clonedomain'},$domdefs{'canclone'}, |
|
$clonehash{'internal.coursecode'},$args->{'crscode'})) { |
|
$can_clone = 1; |
|
} |
|
} |
|
} |
|
} |
} else { |
} else { |
|
my @cloners = split(/,/,$clonehash{'cloners'}); |
|
if (grep(/^\*$/,@cloners)) { |
|
$can_clone = 1; |
|
} elsif (grep(/^\*\:\Q$args->{'ccdomain'}\E$/,@cloners)) { |
|
$can_clone = 1; |
|
} elsif (grep(/^\Q$args->{'ccuname'}\E:\Q$args->{'ccdomain'}\E$/,@cloners)) { |
|
$can_clone = 1; |
|
} |
|
unless ($can_clone) { |
|
if (($clonehash{'internal.coursecode'}) && ($args->{'crscode'}) && |
|
($args->{'clonedomain'} eq $args->{'course_domain'})) { |
|
my (%gotdomdefaults,%gotcodedefaults); |
|
foreach my $cloner (@cloners) { |
|
if (($cloner ne '*') && ($cloner !~ /^\*\:$match_domain$/) && |
|
($cloner !~ /^$match_username\:$match_domain$/) && ($cloner ne '')) { |
|
my (%codedefaults,@code_order); |
|
if (ref($gotcodedefaults{$args->{'clonedomain'}}) eq 'HASH') { |
|
if (ref($gotcodedefaults{$args->{'clonedomain'}}{'defaults'}) eq 'HASH') { |
|
%codedefaults = %{$gotcodedefaults{$args->{'clonedomain'}}{'defaults'}}; |
|
} |
|
if (ref($gotcodedefaults{$args->{'clonedomain'}}{'order'}) eq 'ARRAY') { |
|
@code_order = @{$gotcodedefaults{$args->{'clonedomain'}}{'order'}}; |
|
} |
|
} else { |
|
&Apache::lonnet::auto_instcode_defaults($args->{'clonedomain'}, |
|
\%codedefaults, |
|
\@code_order); |
|
$gotcodedefaults{$args->{'clonedomain'}}{'defaults'} = \%codedefaults; |
|
$gotcodedefaults{$args->{'clonedomain'}}{'order'} = \@code_order; |
|
} |
|
if (@code_order > 0) { |
|
if (&Apache::lonnet::check_instcode_cloning(\%codedefaults,\@code_order, |
|
$cloner,$clonehash{'internal.coursecode'}, |
|
$args->{'crscode'})) { |
|
$can_clone = 1; |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
unless ($can_clone) { |
my $ccrole = 'cc'; |
my $ccrole = 'cc'; |
if ($args->{'crstype'} eq 'Community') { |
if ($args->{'crstype'} eq 'Community') { |
$ccrole = 'co'; |
$ccrole = 'co'; |
} |
} |
my %roleshash = |
my %roleshash = |
&Apache::lonnet::get_my_roles($args->{'ccuname'}, |
&Apache::lonnet::get_my_roles($args->{'ccuname'}, |
$args->{'ccdomain'}, |
$args->{'ccdomain'}, |
'userroles',['active'],[$ccrole], |
'userroles',['active'],[$ccrole], |
[$args->{'clonedomain'}]); |
[$args->{'clonedomain'}]); |
if (($roleshash{$args->{'clonecourse'}.':'.$args->{'clonedomain'}.':'.$ccrole}) || (grep(/^\Q$args->{'ccuname'}\E:\Q$args->{'ccdomain'}\E$/,@cloners))) { |
if ($roleshash{$args->{'clonecourse'}.':'.$args->{'clonedomain'}.':'.$ccrole}) { |
$can_clone = 1; |
$can_clone = 1; |
} elsif (&Apache::lonnet::is_course_owner($args->{'clonedomain'},$args->{'clonecourse'},$args->{'ccuname'},$args->{'ccdomain'})) { |
} elsif (&Apache::lonnet::is_course_owner($args->{'clonedomain'},$args->{'clonecourse'}, |
|
$args->{'ccuname'},$args->{'ccdomain'})) { |
$can_clone = 1; |
$can_clone = 1; |
|
} |
|
} |
|
unless ($can_clone) { |
|
if ($args->{'crstype'} eq 'Community') { |
|
push(@clonemsg,({ |
|
mt => 'No new community created.', |
|
args => [], |
|
}, |
|
{ |
|
mt => 'The new community could not be cloned from the existing community because the new community owner ([_1]) does not have cloning rights in the existing community ([_2]).', |
|
args => [$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'}], |
|
})); |
} else { |
} else { |
if ($args->{'crstype'} eq 'Community') { |
push(@clonemsg,({ |
$clonemsg = &mt('No new community created.').$linefeed.&mt('The new community could not be cloned from the existing community because the new community owner ([_1]) does not have cloning rights in the existing community ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'}); |
mt => 'No new course created.', |
} else { |
args => [], |
$clonemsg = &mt('No new course created.').$linefeed.&mt('The new course could not be cloned from the existing course because the new course owner ([_1]) does not have cloning rights in the existing course ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'}); |
}, |
} |
{ |
} |
mt => 'The new course could not be cloned from the existing course because the new course owner ([_1]) does not have cloning rights in the existing course ([_2]).', |
|
args => [$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'}], |
|
})); |
|
} |
} |
} |
} |
} |
} |
} |
return ($can_clone, $clonemsg, $cloneid, $clonehome); |
return ($can_clone,\@clonemsg,$cloneid,$clonehome,$clonetitle); |
} |
} |
|
|
sub construct_course { |
sub construct_course { |
my ($args,$logmsg,$courseid,$crsudom,$crsunum,$udom,$uname,$context,$cnum,$category,$coderef) = @_; |
my ($args,$logmsg,$courseid,$crsudom,$crsunum,$udom,$uname,$context, |
my $outcome; |
$cnum,$category,$coderef,$callercontext,$user_lh) = @_; |
|
my ($outcome,$msgref,$clonemsgref); |
my $linefeed = '<br />'."\n"; |
my $linefeed = '<br />'."\n"; |
if ($context eq 'auto') { |
if ($context eq 'auto') { |
$linefeed = "\n"; |
$linefeed = "\n"; |
Line 13942 sub construct_course {
|
Line 16049 sub construct_course {
|
# |
# |
# Are we cloning? |
# Are we cloning? |
# |
# |
my ($can_clone, $clonemsg, $cloneid, $clonehome); |
my ($can_clone,$cloneid,$clonehome,$clonetitle); |
if (($args->{'clonecourse'}) && ($args->{'clonedomain'})) { |
if (($args->{'clonecourse'}) && ($args->{'clonedomain'})) { |
($can_clone, $clonemsg, $cloneid, $clonehome) = &check_clone($args,$linefeed); |
($can_clone,$clonemsgref,$cloneid,$clonehome,$clonetitle) = &check_clone($args,$linefeed); |
if ($context ne 'auto') { |
|
if ($clonemsg ne '') { |
|
$clonemsg = '<span class="LC_error">'.$clonemsg.'</span>'; |
|
} |
|
} |
|
$outcome .= $clonemsg.$linefeed; |
|
|
|
if (!$can_clone) { |
if (!$can_clone) { |
return (0,$outcome); |
return (0,$outcome,$clonemsgref); |
} |
} |
} |
} |
|
|
# |
# |
# Open course |
# Open course |
# |
# |
my $crstype = lc($args->{'crstype'}); |
my $showncrstype; |
|
if ($args->{'crstype'} eq 'Placement') { |
|
$showncrstype = 'placement test'; |
|
} else { |
|
$showncrstype = lc($args->{'crstype'}); |
|
} |
my %cenv=(); |
my %cenv=(); |
$$courseid=&Apache::lonnet::createcourse($args->{'course_domain'}, |
$$courseid=&Apache::lonnet::createcourse($args->{'course_domain'}, |
$args->{'cdescr'}, |
$args->{'cdescr'}, |
Line 13971 sub construct_course {
|
Line 16076 sub construct_course {
|
$args->{'ccuname'}.':'. |
$args->{'ccuname'}.':'. |
$args->{'ccdomain'}, |
$args->{'ccdomain'}, |
$args->{'crstype'}, |
$args->{'crstype'}, |
$cnum,$context,$category); |
$cnum,$context,$category, |
|
$callercontext); |
|
|
# Note: The testing routines depend on this being output; see |
# Note: The testing routines depend on this being output; see |
# Utils::Course. This needs to at least be output as a comment |
# Utils::Course. This needs to at least be output as a comment |
# if anyone ever decides to not show this, and Utils::Course::new |
# if anyone ever decides to not show this, and Utils::Course::new |
# will need to be suitably modified. |
# will need to be suitably modified. |
$outcome .= &mt('New LON-CAPA [_1] ID: [_2]',$crstype,$$courseid).$linefeed; |
if (($callercontext eq 'auto') && ($user_lh ne '')) { |
|
$outcome .= &mt_user($user_lh,'New LON-CAPA [_1] ID: [_2]',$showncrstype,$$courseid).$linefeed; |
|
} else { |
|
$outcome .= &mt('New LON-CAPA [_1] ID: [_2]',$showncrstype,$$courseid).$linefeed; |
|
} |
if ($$courseid =~ /^error:/) { |
if ($$courseid =~ /^error:/) { |
return (0,$outcome); |
return (0,$outcome,$clonemsgref); |
} |
} |
|
|
# |
# |
Line 13988 sub construct_course {
|
Line 16098 sub construct_course {
|
($$crsudom,$$crsunum)= &LONCAPA::split_courseid($$courseid); |
($$crsudom,$$crsunum)= &LONCAPA::split_courseid($$courseid); |
my $crsuhome=&Apache::lonnet::homeserver($$crsunum,$$crsudom); |
my $crsuhome=&Apache::lonnet::homeserver($$crsunum,$$crsudom); |
if ($crsuhome eq 'no_host') { |
if ($crsuhome eq 'no_host') { |
$outcome .= &mt('Course creation failed, unrecognized course home server.').$linefeed; |
if (($callercontext eq 'auto') && ($user_lh ne '')) { |
return (0,$outcome); |
$outcome .= &mt_user($user_lh, |
|
'Course creation failed, unrecognized course home server.'); |
|
} else { |
|
$outcome .= &mt('Course creation failed, unrecognized course home server.'); |
|
} |
|
$outcome .= $linefeed; |
|
return (0,$outcome,$clonemsgref); |
} |
} |
$outcome .= &mt('Created on').': '.$crsuhome.$linefeed; |
$outcome .= &mt('Created on').': '.$crsuhome.$linefeed; |
|
|
# |
# |
# Do the cloning |
# Do the cloning |
# |
# |
|
my @clonemsg; |
if ($can_clone && $cloneid) { |
if ($can_clone && $cloneid) { |
$clonemsg = &mt('Cloning [_1] from [_2]',$crstype,$clonehome); |
push(@clonemsg, |
if ($context ne 'auto') { |
{ |
$clonemsg = '<span class="LC_success">'.$clonemsg.'</span>'; |
mt => 'Created [_1] by cloning from [_2]', |
} |
args => [$showncrstype,$clonetitle], |
$outcome .= $clonemsg.$linefeed; |
}); |
my %oldcenv=&Apache::lonnet::dump('environment',$$crsudom,$$crsunum); |
my %oldcenv=&Apache::lonnet::dump('environment',$$crsudom,$$crsunum); |
# Copy all files |
# Copy all files |
&Apache::lonclonecourse::copycoursefiles($cloneid,$$courseid,$args->{'datemode'},$args->{'dateshift'}); |
my @info = |
|
&Apache::lonclonecourse::copycoursefiles($cloneid,$$courseid,$args->{'datemode'}, |
|
$args->{'dateshift'},$args->{'crscode'}, |
|
$args->{'ccuname'}.':'.$args->{'ccdomain'}, |
|
$args->{'tinyurls'}); |
|
if (@info) { |
|
push(@clonemsg,@info); |
|
} |
# Restore URL |
# Restore URL |
$cenv{'url'}=$oldcenv{'url'}; |
$cenv{'url'}=$oldcenv{'url'}; |
# Restore title |
# Restore title |
Line 14080 sub construct_course {
|
Line 16204 sub construct_course {
|
my $addcheck = &Apache::lonnet::auto_new_course($$crsunum,$$crsudom,$class,$cenv{'internal.courseowner'}); |
my $addcheck = &Apache::lonnet::auto_new_course($$crsunum,$$crsudom,$class,$cenv{'internal.courseowner'}); |
$cenv{'internal.sectionnums'} .= $item.','; |
$cenv{'internal.sectionnums'} .= $item.','; |
unless ($addcheck eq 'ok') { |
unless ($addcheck eq 'ok') { |
push @badclasses, $class; |
push(@badclasses,$class); |
} |
} |
} |
} |
$cenv{'internal.sectionnums'} =~ s/,$//; |
$cenv{'internal.sectionnums'} =~ s/,$//; |
Line 14108 sub construct_course {
|
Line 16232 sub construct_course {
|
my $addcheck = &Apache::lonnet::auto_new_course($$crsunum,$$crsudom,$xl,$cenv{'internal.courseowner'}); |
my $addcheck = &Apache::lonnet::auto_new_course($$crsunum,$$crsudom,$xl,$cenv{'internal.courseowner'}); |
$cenv{'internal.crosslistings'} .= $item.','; |
$cenv{'internal.crosslistings'} .= $item.','; |
unless ($addcheck eq 'ok') { |
unless ($addcheck eq 'ok') { |
push @badclasses, $xl; |
push(@badclasses,$xl); |
} |
} |
} |
} |
$cenv{'internal.crosslistings'} =~ s/,$//; |
$cenv{'internal.crosslistings'} =~ s/,$//; |
Line 14143 sub construct_course {
|
Line 16267 sub construct_course {
|
} |
} |
if (@badclasses > 0) { |
if (@badclasses > 0) { |
my %lt=&Apache::lonlocal::texthash( |
my %lt=&Apache::lonlocal::texthash( |
'tclb' => 'The courses listed below were included as sections or crosslistings affiliated with your new LON-CAPA course. However, if automated course roster updates are enabled for this class, these particular sections/crosslistings will not contribute towards enrollment, because the user identified as the course owner for this LON-CAPA course', |
'tclb' => 'The courses listed below were included as sections or crosslistings affiliated with your new LON-CAPA course.', |
'dnhr' => 'does not have rights to access enrollment in these classes', |
'howi' => 'However, if automated course roster updates are enabled for this class, these particular sections/crosslistings are not guaranteed to contribute towards enrollment.', |
'adby' => 'as determined by the policies of your institution on access to official classlists' |
'itis' => 'It is possible that rights to access enrollment for these classes will be available through assignment of co-owners.', |
); |
); |
my $badclass_msg = $cenv{'internal.courseowner'}.') - '.$lt{'dnhr'}. |
my $badclass_msg = $lt{'tclb'}.$linefeed.$lt{'howi'}.$linefeed. |
' ('.$lt{'adby'}.')'; |
&mt('That is because the user identified as the course owner ([_1]) does not have rights to access enrollment in these classes, as determined by the policies of your institution on access to official classlists',$cenv{'internal.courseowner'}).$linefeed.$lt{'itis'}; |
if ($context eq 'auto') { |
if ($context eq 'auto') { |
$outcome .= $badclass_msg.$linefeed; |
$outcome .= $badclass_msg.$linefeed; |
|
} else { |
$outcome .= '<div class="LC_warning">'.$badclass_msg.$linefeed.'<ul>'."\n"; |
$outcome .= '<div class="LC_warning">'.$badclass_msg.$linefeed.'<ul>'."\n"; |
foreach my $item (@badclasses) { |
} |
if ($context eq 'auto') { |
foreach my $item (@badclasses) { |
$outcome .= " - $item\n"; |
|
} else { |
|
$outcome .= "<li>$item</li>\n"; |
|
} |
|
} |
|
if ($context eq 'auto') { |
if ($context eq 'auto') { |
$outcome .= $linefeed; |
$outcome .= " - $item\n"; |
} else { |
} else { |
$outcome .= "</ul><br /><br /></div>\n"; |
$outcome .= "<li>$item</li>\n"; |
} |
} |
|
} |
|
if ($context eq 'auto') { |
|
$outcome .= $linefeed; |
|
} else { |
|
$outcome .= "</ul><br /><br /></div>\n"; |
} |
} |
} |
} |
if ($args->{'no_end_date'}) { |
if ($args->{'no_end_date'}) { |
Line 14196 sub construct_course {
|
Line 16321 sub construct_course {
|
if ($args->{'setcontent'}) { |
if ($args->{'setcontent'}) { |
$cenv{'question.email'}=$args->{'ccuname'}.':'.$args->{'ccdomain'}; |
$cenv{'question.email'}=$args->{'ccuname'}.':'.$args->{'ccdomain'}; |
} |
} |
|
if ($args->{'setcomment'}) { |
|
$cenv{'comment.email'}=$args->{'ccuname'}.':'.$args->{'ccdomain'}; |
|
} |
} |
} |
if ($args->{'reshome'}) { |
if ($args->{'reshome'}) { |
$cenv{'reshome'}=$args->{'reshome'}.'/'; |
$cenv{'reshome'}=$args->{'reshome'}.'/'; |
Line 14267 sub construct_course {
|
Line 16395 sub construct_course {
|
# Open all assignments |
# Open all assignments |
# |
# |
if ($args->{'openall'}) { |
if ($args->{'openall'}) { |
|
my $opendate = time; |
|
if ($args->{'openallfrom'} =~ /^\d+$/) { |
|
$opendate = $args->{'openallfrom'}; |
|
} |
my $storeunder=$$crsudom.'_'.$$crsunum.'.0.opendate'; |
my $storeunder=$$crsudom.'_'.$$crsunum.'.0.opendate'; |
my %storecontent = ($storeunder => time, |
my %storecontent = ($storeunder => $opendate, |
$storeunder.'.type' => 'date_start'); |
$storeunder.'.type' => 'date_start'); |
|
$outcome .= &mt('All assignments open starting [_1]', |
$outcome .= &mt('Opening all assignments').': '.&Apache::lonnet::cput |
&Apache::lonlocal::locallocaltime($opendate)).': '. |
('resourcedata',\%storecontent,$$crsudom,$$crsunum).$linefeed; |
&Apache::lonnet::cput |
|
('resourcedata',\%storecontent,$$crsudom,$$crsunum).$linefeed; |
} |
} |
# |
# |
# Set first page |
# Set first page |
Line 14302 sub construct_course {
|
Line 16435 sub construct_course {
|
$outcome .= ($fatal?$errtext:'write ok').$linefeed; |
$outcome .= ($fatal?$errtext:'write ok').$linefeed; |
} |
} |
|
|
return (1,$outcome); |
# |
|
# Set params for Placement Tests |
|
# |
|
if ($args->{'crstype'} eq 'Placement') { |
|
my %storecontent; |
|
my $prefix=$$crsudom.'_'.$$crsunum.'.0.'; |
|
my %defaults = ( |
|
buttonshide => { value => 'yes', |
|
type => 'string_yesno',}, |
|
type => { value => 'randomizetry', |
|
type => 'string_questiontype',}, |
|
maxtries => { value => 1, |
|
type => 'int_pos',}, |
|
problemstatus => { value => 'no', |
|
type => 'string_problemstatus',}, |
|
); |
|
foreach my $key (keys(%defaults)) { |
|
$storecontent{$prefix.$key} = $defaults{$key}{'value'}; |
|
$storecontent{$prefix.$key.'.type'} = $defaults{$key}{'type'}; |
|
} |
|
&Apache::lonnet::cput |
|
('resourcedata',\%storecontent,$$crsudom,$$crsunum); |
|
} |
|
|
|
return (1,$outcome,\@clonemsg); |
} |
} |
|
|
sub make_unique_code { |
sub make_unique_code { |
Line 14362 sub generate_code {
|
Line 16519 sub generate_code {
|
############################################################ |
############################################################ |
############################################################ |
############################################################ |
|
|
#SD |
# Community, Course and Placement Test |
# only Community and Course, or anything else? |
|
sub course_type { |
sub course_type { |
my ($cid) = @_; |
my ($cid) = @_; |
if (!defined($cid)) { |
if (!defined($cid)) { |
Line 14381 sub group_term {
|
Line 16537 sub group_term {
|
my %names = ( |
my %names = ( |
'Course' => 'group', |
'Course' => 'group', |
'Community' => 'group', |
'Community' => 'group', |
|
'Placement' => 'group', |
); |
); |
return $names{$crstype}; |
return $names{$crstype}; |
} |
} |
|
|
sub course_types { |
sub course_types { |
my @types = ('official','unofficial','community','textbook'); |
my @types = ('official','unofficial','community','textbook','placement','lti'); |
my %typename = ( |
my %typename = ( |
official => 'Official course', |
official => 'Official course', |
unofficial => 'Unofficial course', |
unofficial => 'Unofficial course', |
community => 'Community', |
community => 'Community', |
textbook => 'Textbook course', |
textbook => 'Textbook course', |
|
placement => 'Placement test', |
|
lti => 'LTI provider', |
); |
); |
return (\@types,\%typename); |
return (\@types,\%typename); |
} |
} |
Line 14452 sub escape_url {
|
Line 16611 sub escape_url {
|
my ($url) = @_; |
my ($url) = @_; |
my @urlslices = split(/\//, $url,-1); |
my @urlslices = split(/\//, $url,-1); |
my $lastitem = &escape(pop(@urlslices)); |
my $lastitem = &escape(pop(@urlslices)); |
return join('/',@urlslices).'/'.$lastitem; |
return &HTML::Entities::encode(join('/',@urlslices),"'").'/'.$lastitem; |
} |
} |
|
|
sub compare_arrays { |
sub compare_arrays { |
Line 14471 sub compare_arrays {
|
Line 16630 sub compare_arrays {
|
return @difference; |
return @difference; |
} |
} |
|
|
|
sub lon_status_items { |
|
my %defaults = ( |
|
E => 100, |
|
W => 4, |
|
N => 1, |
|
U => 5, |
|
threshold => 200, |
|
sysmail => 2500, |
|
); |
|
my %names = ( |
|
E => 'Errors', |
|
W => 'Warnings', |
|
N => 'Notices', |
|
U => 'Unsent', |
|
); |
|
return (\%defaults,\%names); |
|
} |
|
|
# -------------------------------------------------------- Initialize user login |
# -------------------------------------------------------- Initialize user login |
sub init_user_environment { |
sub init_user_environment { |
my ($r, $username, $domain, $authhost, $form, $args) = @_; |
my ($r, $username, $domain, $authhost, $form, $args) = @_; |
Line 14478 sub init_user_environment {
|
Line 16655 sub init_user_environment {
|
|
|
my $public=($username eq 'public' && $domain eq 'public'); |
my $public=($username eq 'public' && $domain eq 'public'); |
|
|
# See if old ID present, if so, remove |
|
|
|
my ($filename,$cookie,$userroles,$firstaccenv,$timerintenv); |
my ($filename,$cookie,$userroles,$firstaccenv,$timerintenv); |
my $now=time; |
my $now=time; |
|
|
Line 14501 sub init_user_environment {
|
Line 16676 sub init_user_environment {
|
} |
} |
if (!$cookie) { $cookie="publicuser_$oldest"; } |
if (!$cookie) { $cookie="publicuser_$oldest"; } |
} else { |
} else { |
# if this isn't a robot, kill any existing non-robot sessions |
# See if old ID present, if so, remove if this isn't a robot, |
|
# killing any existing non-robot sessions |
if (!$args->{'robot'}) { |
if (!$args->{'robot'}) { |
opendir(DIR,$lonids); |
opendir(DIR,$lonids); |
while ($filename=readdir(DIR)) { |
while ($filename=readdir(DIR)) { |
if ($filename=~/^$username\_\d+\_$domain\_$authhost\.id$/) { |
if ($filename=~/^$username\_\d+\_$domain\_$authhost\.id$/) { |
unlink($lonids.'/'.$filename); |
if (tie(my %oldenv,'GDBM_File',"$lonids/$filename", |
|
&GDBM_READER(),0640)) { |
|
my $linkedfile; |
|
if (exists($oldenv{'user.linkedenv'})) { |
|
$linkedfile = $oldenv{'user.linkedenv'}; |
|
} |
|
untie(%oldenv); |
|
if (unlink("$lonids/$filename")) { |
|
if ($linkedfile =~ /^[a-f0-9]+_linked$/) { |
|
if (-l "$lonids/$linkedfile.id") { |
|
unlink("$lonids/$linkedfile.id"); |
|
} |
|
} |
|
} |
|
} else { |
|
unlink($lonids.'/'.$filename); |
|
} |
} |
} |
} |
} |
closedir(DIR); |
closedir(DIR); |
|
# If there is a undeleted lockfile for the user's paste buffer remove it. |
|
my $namespace = 'nohist_courseeditor'; |
|
my $lockingkey = 'paste'."\0".'locked_num'; |
|
my %lockhash = &Apache::lonnet::get($namespace,[$lockingkey], |
|
$domain,$username); |
|
if (exists($lockhash{$lockingkey})) { |
|
my $delresult = &Apache::lonnet::del($namespace,[$lockingkey],$domain,$username); |
|
unless ($delresult eq 'ok') { |
|
&Apache::lonnet::logthis("Failed to delete paste buffer locking key in $namespace for ".$username.":".$domain." Result was: $delresult"); |
|
} |
|
} |
} |
} |
# Give them a new cookie |
# Give them a new cookie |
my $id = ($args->{'robot'} ? 'robot'.$args->{'robot'} |
my $id = ($args->{'robot'} ? 'robot'.$args->{'robot'} |
Line 14523 sub init_user_environment {
|
Line 16726 sub init_user_environment {
|
} |
} |
# ------------------------------------ Check browser type and MathML capability |
# ------------------------------------ Check browser type and MathML capability |
|
|
my ($httpbrowser,$clientbrowser,$clientversion,$clientmathml, |
my ($httpbrowser,$clientbrowser,$clientversion,$clientmathml,$clientunicode, |
$clientunicode,$clientos,$clientmobile,$clientinfo) = &decode_user_agent($r); |
$clientos,$clientmobile,$clientinfo,$clientosversion) = &decode_user_agent($r); |
|
|
# ------------------------------------------------------------- Get environment |
# ------------------------------------------------------------- Get environment |
|
|
my %userenv = &Apache::lonnet::dump('environment',$domain,$username); |
my %userenv = &Apache::lonnet::dump('environment',$domain,$username); |
my ($tmp) = keys(%userenv); |
my ($tmp) = keys(%userenv); |
if ($tmp !~ /^(con_lost|error|no_such_host)/i) { |
if ($tmp =~ /^(con_lost|error|no_such_host)/i) { |
} else { |
|
undef(%userenv); |
undef(%userenv); |
} |
} |
if (($userenv{'interface'}) && (!$form->{'interface'})) { |
if (($userenv{'interface'}) && (!$form->{'interface'})) { |
Line 14557 sub init_user_environment {
|
Line 16759 sub init_user_environment {
|
"browser.os" => $clientos, |
"browser.os" => $clientos, |
"browser.mobile" => $clientmobile, |
"browser.mobile" => $clientmobile, |
"browser.info" => $clientinfo, |
"browser.info" => $clientinfo, |
|
"browser.osversion" => $clientosversion, |
"server.domain" => $Apache::lonnet::perlvar{'lonDefDomain'}, |
"server.domain" => $Apache::lonnet::perlvar{'lonDefDomain'}, |
"request.course.fn" => '', |
"request.course.fn" => '', |
"request.course.uri" => '', |
"request.course.uri" => '', |
Line 14582 sub init_user_environment {
|
Line 16785 sub init_user_environment {
|
$env{'user.noloadbalance'} = $lonhost; |
$env{'user.noloadbalance'} = $lonhost; |
} |
} |
|
|
my %is_adv = ( is_adv => $env{'user.adv'} ); |
if ($form->{'noloadbalance'}) { |
my %domdef; |
my @hosts = &Apache::lonnet::current_machine_ids(); |
unless ($domain eq 'public') { |
my $hosthere = $form->{'noloadbalance'}; |
%domdef = &Apache::lonnet::get_domain_defaults($domain); |
if (grep(/^\Q$hosthere\E$/,@hosts)) { |
|
$initial_env{"user.noloadbalance"} = $hosthere; |
|
$env{'user.noloadbalance'} = $hosthere; |
|
} |
} |
} |
|
|
foreach my $tool ('aboutme','blog','webdav','portfolio') { |
unless ($domain eq 'public') { |
$userenv{'availabletools.'.$tool} = |
my %is_adv = ( is_adv => $env{'user.adv'} ); |
&Apache::lonnet::usertools_access($username,$domain,$tool,'reload', |
my %domdef = &Apache::lonnet::get_domain_defaults($domain); |
undef,\%userenv,\%domdef,\%is_adv); |
|
} |
|
|
|
foreach my $crstype ('official','unofficial','community','textbook') { |
foreach my $tool ('aboutme','blog','webdav','portfolio') { |
$userenv{'canrequest.'.$crstype} = |
$userenv{'availabletools.'.$tool} = |
&Apache::lonnet::usertools_access($username,$domain,$crstype, |
&Apache::lonnet::usertools_access($username,$domain,$tool,'reload', |
'reload','requestcourses', |
undef,\%userenv,\%domdef,\%is_adv); |
\%userenv,\%domdef,\%is_adv); |
} |
} |
|
|
|
$userenv{'canrequest.author'} = |
foreach my $crstype ('official','unofficial','community','textbook','placement','lti') { |
&Apache::lonnet::usertools_access($username,$domain,'requestauthor', |
$userenv{'canrequest.'.$crstype} = |
'reload','requestauthor', |
&Apache::lonnet::usertools_access($username,$domain,$crstype, |
\%userenv,\%domdef,\%is_adv); |
'reload','requestcourses', |
my %reqauthor = &Apache::lonnet::get('requestauthor',['author_status','author'], |
\%userenv,\%domdef,\%is_adv); |
$domain,$username); |
|
my $reqstatus = $reqauthor{'author_status'}; |
|
if ($reqstatus eq 'approval' || $reqstatus eq 'approved') { |
|
if (ref($reqauthor{'author'}) eq 'HASH') { |
|
$userenv{'requestauthorqueued'} = $reqstatus.':'. |
|
$reqauthor{'author'}{'timestamp'}; |
|
} |
} |
} |
|
|
|
|
$userenv{'canrequest.author'} = |
|
&Apache::lonnet::usertools_access($username,$domain,'requestauthor', |
|
'reload','requestauthor', |
|
\%userenv,\%domdef,\%is_adv); |
|
my %reqauthor = &Apache::lonnet::get('requestauthor',['author_status','author'], |
|
$domain,$username); |
|
my $reqstatus = $reqauthor{'author_status'}; |
|
if ($reqstatus eq 'approval' || $reqstatus eq 'approved') { |
|
if (ref($reqauthor{'author'}) eq 'HASH') { |
|
$userenv{'requestauthorqueued'} = $reqstatus.':'. |
|
$reqauthor{'author'}{'timestamp'}; |
|
} |
|
} |
|
my ($types,$typename) = &course_types(); |
|
if (ref($types) eq 'ARRAY') { |
|
my @options = ('approval','validate','autolimit'); |
|
my $optregex = join('|',@options); |
|
my (%willtrust,%trustchecked); |
|
foreach my $type (@{$types}) { |
|
my $dom_str = $env{'environment.reqcrsotherdom.'.$type}; |
|
if ($dom_str ne '') { |
|
my $updatedstr = ''; |
|
my @possdomains = split(',',$dom_str); |
|
foreach my $entry (@possdomains) { |
|
my ($extdom,$extopt) = split(':',$entry); |
|
unless ($trustchecked{$extdom}) { |
|
$willtrust{$extdom} = &Apache::lonnet::will_trust('reqcrs',$domain,$extdom); |
|
$trustchecked{$extdom} = 1; |
|
} |
|
if ($willtrust{$extdom}) { |
|
$updatedstr .= $entry.','; |
|
} |
|
} |
|
$updatedstr =~ s/,$//; |
|
if ($updatedstr) { |
|
$userenv{'reqcrsotherdom.'.$type} = $updatedstr; |
|
} else { |
|
delete($userenv{'reqcrsotherdom.'.$type}); |
|
} |
|
} |
|
} |
|
} |
|
} |
$env{'user.environment'} = "$lonids/$cookie.id"; |
$env{'user.environment'} = "$lonids/$cookie.id"; |
|
|
if (tie(my %disk_env,'GDBM_File',"$lonids/$cookie.id", |
if (tie(my %disk_env,'GDBM_File',"$lonids/$cookie.id", |
Line 14842 sub build_filters {
|
Line 17081 sub build_filters {
|
$createdfilterform = &timebased_select_form('createdfilter',$filter); |
$createdfilterform = &timebased_select_form('createdfilter',$filter); |
} |
} |
|
|
|
my $prefix = $crstype; |
|
if ($crstype eq 'Placement') { |
|
$prefix = 'Placement Test' |
|
} |
my %lt = &Apache::lonlocal::texthash( |
my %lt = &Apache::lonlocal::texthash( |
'cac' => "$crstype Activity", |
'cac' => "$prefix Activity", |
'ccr' => "$crstype Created", |
'ccr' => "$prefix Created", |
'cde' => "$crstype Title", |
'cde' => "$prefix Title", |
'cdo' => "$crstype Domain", |
'cdo' => "$prefix Domain", |
'ins' => 'Institutional Code', |
'ins' => 'Institutional Code', |
'inc' => 'Institutional Categorization', |
'inc' => 'Institutional Categorization', |
'cow' => "$crstype Owner/Co-owner", |
'cow' => "$prefix Owner/Co-owner", |
'cop' => "$crstype Personnel Includes", |
'cop' => "$prefix Personnel Includes", |
'cog' => 'Type', |
'cog' => 'Type', |
); |
); |
|
|
Line 14858 sub build_filters {
|
Line 17101 sub build_filters {
|
my $typeval = 'Course'; |
my $typeval = 'Course'; |
if ($crstype eq 'Community') { |
if ($crstype eq 'Community') { |
$typeval = 'Community'; |
$typeval = 'Community'; |
|
} elsif ($crstype eq 'Placement') { |
|
$typeval = 'Placement'; |
} |
} |
$typeselectform = '<input type="hidden" name="type" value="'.$typeval.'" />'; |
$typeselectform = '<input type="hidden" name="type" value="'.$typeval.'" />'; |
} else { |
} else { |
Line 14866 sub build_filters {
|
Line 17111 sub build_filters {
|
$typeselectform .= ' onchange="'.$onchange.'"'; |
$typeselectform .= ' onchange="'.$onchange.'"'; |
} |
} |
$typeselectform .= '>'."\n"; |
$typeselectform .= '>'."\n"; |
foreach my $posstype ('Course','Community') { |
foreach my $posstype ('Course','Community','Placement') { |
|
my $shown; |
|
if ($posstype eq 'Placement') { |
|
$shown = &mt('Placement Test'); |
|
} else { |
|
$shown = &mt($posstype); |
|
} |
$typeselectform.='<option value="'.$posstype.'"'. |
$typeselectform.='<option value="'.$posstype.'"'. |
($posstype eq $crstype ? ' selected="selected" ' : ''). ">".&mt($posstype)."</option>\n"; |
($posstype eq $crstype ? ' selected="selected" ' : ''). ">".$shown."</option>\n"; |
} |
} |
$typeselectform.="</select>"; |
$typeselectform.="</select>"; |
} |
} |
Line 14927 sub build_filters {
|
Line 17178 sub build_filters {
|
$output .= '<input type="hidden" name="phase" value="courselist" />'."\n". |
$output .= '<input type="hidden" name="phase" value="courselist" />'."\n". |
'<input type="hidden" name="prevphase" value="'. |
'<input type="hidden" name="prevphase" value="'. |
$prevphase.'" />'."\n"; |
$prevphase.'" />'."\n"; |
} elsif ($formname ne 'quotacheck') { |
} elsif ($formname eq 'quotacheck') { |
|
$output .= qq| |
|
<input type="hidden" name="sortby" value="" /> |
|
<input type="hidden" name="sortorder" value="" /> |
|
|; |
|
} else { |
my $name_input; |
my $name_input; |
if ($cnameelement ne '') { |
if ($cnameelement ne '') { |
$name_input = '<input type="hidden" name="cnameelement" value="'. |
$name_input = '<input type="hidden" name="cnameelement" value="'. |
Line 15120 cloneruname - optional username of new c
|
Line 17376 cloneruname - optional username of new c
|
|
|
clonerudom - optional domain of new course owner |
clonerudom - optional domain of new course owner |
|
|
domcloner - Optional "domcloner" flag; has value=1 if user has ccc priv in domain being filtered by, |
domcloner - optional "domcloner" flag; has value=1 if user has ccc priv in domain being filtered by, |
(used when DC is using course creation form) |
(used when DC is using course creation form) |
|
|
codetitles - reference to array of titles of components in institutional codes (official courses). |
codetitles - reference to array of titles of components in institutional codes (official courses). |
|
|
|
cc_clone - escaped comma separated list of courses for which course cloner has active CC role |
|
(and so can clone automatically) |
|
|
|
reqcrsdom - domain of new course, where search_courses is used to identify potential courses to clone |
|
|
|
reqinstcode - institutional code of new course, where search_courses is used to identify potential |
|
courses to clone |
|
|
Returns: %courses - hash of courses satisfying search criteria, keys = course IDs, values are corresponding colon-separated escaped description, institutional code, owner and type. |
Returns: %courses - hash of courses satisfying search criteria, keys = course IDs, values are corresponding colon-separated escaped description, institutional code, owner and type. |
|
|
Line 15135 Side Effects: None
|
Line 17398 Side Effects: None
|
|
|
|
|
sub search_courses { |
sub search_courses { |
my ($dom,$type,$filter,$numtitles,$cloneruname,$clonerudom,$domcloner,$codetitles) = @_; |
my ($dom,$type,$filter,$numtitles,$cloneruname,$clonerudom,$domcloner,$codetitles, |
|
$cc_clone,$reqcrsdom,$reqinstcode) = @_; |
my (%courses,%showcourses,$cloner); |
my (%courses,%showcourses,$cloner); |
if (($filter->{'ownerfilter'} ne '') || |
if (($filter->{'ownerfilter'} ne '') || |
($filter->{'ownerdomfilter'} ne '')) { |
($filter->{'ownerdomfilter'} ne '')) { |
Line 15183 sub search_courses {
|
Line 17447 sub search_courses {
|
$filter->{'combownerfilter'}, |
$filter->{'combownerfilter'}, |
$filter->{'coursefilter'}, |
$filter->{'coursefilter'}, |
undef,undef,$type,$regexpok,undef,undef, |
undef,undef,$type,$regexpok,undef,undef, |
undef,undef,$cloner,$env{'form.cc_clone'}, |
undef,undef,$cloner,$cc_clone, |
$filter->{'cloneableonly'}, |
$filter->{'cloneableonly'}, |
$createdbefore,$createdafter,undef, |
$createdbefore,$createdafter,undef, |
$domcloner); |
$domcloner,undef,$reqcrsdom,$reqinstcode); |
if (($filter->{'personfilter'} ne '') && ($filter->{'persondomfilter'} ne '')) { |
if (($filter->{'personfilter'} ne '') && ($filter->{'persondomfilter'} ne '')) { |
my $ccrole; |
my $ccrole; |
if ($type eq 'Community') { |
if ($type eq 'Community') { |
Line 15206 sub search_courses {
|
Line 17470 sub search_courses {
|
if (ref($courses{$cid}) eq 'HASH') { |
if (ref($courses{$cid}) eq 'HASH') { |
if (ref($courses{$cid}{roles}) eq 'ARRAY') { |
if (ref($courses{$cid}{roles}) eq 'ARRAY') { |
if (!grep(/^\Q$courserole\E$/,@{$courses{$cid}{roles}})) { |
if (!grep(/^\Q$courserole\E$/,@{$courses{$cid}{roles}})) { |
push (@{$courses{$cid}{roles}},$courserole); |
push(@{$courses{$cid}{roles}},$courserole); |
} |
} |
} else { |
} else { |
$courses{$cid}{roles} = [$courserole]; |
$courses{$cid}{roles} = [$courserole]; |
Line 15220 sub search_courses {
|
Line 17484 sub search_courses {
|
return %courses; |
return %courses; |
} |
} |
|
|
|
=pod |
|
|
|
=back |
|
|
|
=head1 Routines for version requirements for current course. |
|
|
|
=over 4 |
|
|
|
=item * &check_release_required() |
|
|
|
Compares required LON-CAPA version with version on server, and |
|
if required version is newer looks for a server with the required version. |
|
|
|
Looks first at servers in user's owen domain; if none suitable, looks at |
|
servers in course's domain are permitted to host sessions for user's domain. |
|
|
|
Inputs: |
|
|
|
$loncaparev - Version on current server (format: Major.Minor.Subrelease-datestamp) |
|
|
|
$courseid - Course ID of current course |
|
|
|
$rolecode - User's current role in course (for switchserver query string). |
|
|
|
$required - LON-CAPA version needed by course (format: Major.Minor). |
|
|
|
|
|
Returns: |
|
|
|
$switchserver - query string tp append to /adm/switchserver call (if |
|
current server's LON-CAPA version is too old. |
|
|
|
$warning - Message is displayed if no suitable server could be found. |
|
|
|
=cut |
|
|
|
sub check_release_required { |
|
my ($loncaparev,$courseid,$rolecode,$required) = @_; |
|
my ($switchserver,$warning); |
|
if ($required ne '') { |
|
my ($reqdmajor,$reqdminor) = ($required =~ /^(\d+)\.(\d+)$/); |
|
my ($major,$minor) = ($loncaparev =~ /^\'?(\d+)\.(\d+)\.[\w.\-]+\'?$/); |
|
if ($reqdmajor ne '' && $reqdminor ne '') { |
|
my $otherserver; |
|
if (($major eq '' && $minor eq '') || |
|
(($reqdmajor > $major) || (($reqdmajor == $major) && ($reqdminor > $minor)))) { |
|
my ($userdomserver) = &Apache::lonnet::choose_server($env{'user.domain'},undef,$required,1); |
|
my $switchlcrev = |
|
&Apache::lonnet::get_server_loncaparev($env{'user.domain'}, |
|
$userdomserver); |
|
my ($swmajor,$swminor) = ($switchlcrev =~ /^\'?(\d+)\.(\d+)\.[\w.\-]+\'?$/); |
|
if (($swmajor eq '' && $swminor eq '') || ($reqdmajor > $swmajor) || |
|
(($reqdmajor == $swmajor) && ($reqdminor > $swminor))) { |
|
my $cdom = $env{'course.'.$courseid.'.domain'}; |
|
if ($cdom ne $env{'user.domain'}) { |
|
my ($coursedomserver,$coursehostname) = &Apache::lonnet::choose_server($cdom,undef,$required,1); |
|
my $serverhomeID = &Apache::lonnet::get_server_homeID($coursehostname); |
|
my $serverhomedom = &Apache::lonnet::host_domain($serverhomeID); |
|
my %defdomdefaults = &Apache::lonnet::get_domain_defaults($serverhomedom); |
|
my %udomdefaults = &Apache::lonnet::get_domain_defaults($env{'user.domain'}); |
|
my $remoterev = &Apache::lonnet::get_server_loncaparev($serverhomedom,$coursedomserver); |
|
my $canhost = |
|
&Apache::lonnet::can_host_session($env{'user.domain'}, |
|
$coursedomserver, |
|
$remoterev, |
|
$udomdefaults{'remotesessions'}, |
|
$defdomdefaults{'hostedsessions'}); |
|
|
|
if ($canhost) { |
|
$otherserver = $coursedomserver; |
|
} else { |
|
$warning = &mt('Requires LON-CAPA version [_1].',$env{'course.'.$courseid.'.internal.releaserequired'}).'<br />'. &mt("No suitable server could be found amongst servers in either your own domain or in the course's domain."); |
|
} |
|
} else { |
|
$warning = &mt('Requires LON-CAPA version [_1].',$env{'course.'.$courseid.'.internal.releaserequired'}).'<br />'.&mt("No suitable server could be found amongst servers in your own domain (which is also the course's domain)."); |
|
} |
|
} else { |
|
$otherserver = $userdomserver; |
|
} |
|
} |
|
if ($otherserver ne '') { |
|
$switchserver = 'otherserver='.$otherserver.'&role='.$rolecode; |
|
} |
|
} |
|
} |
|
return ($switchserver,$warning); |
|
} |
|
|
|
=pod |
|
|
|
=item * &check_release_result() |
|
|
|
Inputs: |
|
|
|
$switchwarning - Warning message if no suitable server found to host session. |
|
|
|
$switchserver - query string to append to /adm/switchserver containing lonHostID |
|
and current role. |
|
|
|
Returns: HTML to display with information about requirement to switch server. |
|
Either displaying warning with link to Roles/Courses screen or |
|
display link to switchserver. |
|
|
|
=cut |
|
|
|
sub check_release_result { |
|
my ($switchwarning,$switchserver) = @_; |
|
my $output = &start_page('Selected course unavailable on this server'). |
|
'<p class="LC_warning">'; |
|
if ($switchwarning) { |
|
$output .= $switchwarning.'<br /><a href="/adm/roles">'; |
|
if (&show_course()) { |
|
$output .= &mt('Display courses'); |
|
} else { |
|
$output .= &mt('Display roles'); |
|
} |
|
$output .= '</a>'; |
|
} elsif ($switchserver) { |
|
$output .= &mt('This course requires a newer version of LON-CAPA than is installed on this server.'). |
|
'<br />'. |
|
'<a href="/adm/switchserver?'.$switchserver.'">'. |
|
&mt('Switch Server'). |
|
'</a>'; |
|
} |
|
$output .= '</p>'.&end_page(); |
|
return $output; |
|
} |
|
|
=pod |
=pod |
|
|
|
=item * &needs_coursereinit() |
|
|
|
Determine if course contents stored for user's session needs to be |
|
refreshed, because content has changed since "Big Hash" last tied. |
|
|
|
Check for change is made if time last checked is more than 10 minutes ago |
|
(by default). |
|
|
|
Inputs: |
|
|
|
$loncaparev - Version on current server (format: Major.Minor.Subrelease-datestamp) |
|
|
|
$interval (optional) - Time which may elapse (in s) between last check for content |
|
change in current course. (default: 600 s). |
|
|
|
Returns: an array; first element is: |
|
|
|
=over 4 |
|
|
|
'switch' - if content updates mean user's session |
|
needs to be switched to a server running a newer LON-CAPA version |
|
|
|
'update' - if course session needs to be refreshed (i.e., Big Hash needs to be reloaded) |
|
on current server hosting user's session |
|
|
|
'' - if no action required. |
|
|
|
=back |
|
|
|
If first item element is 'switch': |
|
|
|
second item is $switchwarning - Warning message if no suitable server found to host session. |
|
|
|
third item is $switchserver - query string to append to /adm/switchserver containing lonHostID |
|
and current role. |
|
|
|
otherwise: no other elements returned. |
|
|
=back |
=back |
|
|
=cut |
=cut |
|
|
|
sub needs_coursereinit { |
|
my ($loncaparev,$interval) = @_; |
|
return() unless ($env{'request.course.id'} && $env{'request.course.tied'}); |
|
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
my $now = time; |
|
if ($interval eq '') { |
|
$interval = 600; |
|
} |
|
if (($now-$env{'request.course.timechecked'})>$interval) { |
|
&Apache::lonnet::appenv({'request.course.timechecked'=>$now}); |
|
my $blocked = &blocking_status('reinit',$cnum,$cdom,undef,1); |
|
if ($blocked) { |
|
return (); |
|
} |
|
my $lastchange = &Apache::lonnet::get_coursechange($cdom,$cnum); |
|
if ($lastchange > $env{'request.course.tied'}) { |
|
my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired'); |
|
if ($curr_reqd_hash{'internal.releaserequired'} ne '') { |
|
my $required = $env{'course.'.$cdom.'_'.$cnum.'.internal.releaserequired'}; |
|
if ($curr_reqd_hash{'internal.releaserequired'} ne $required) { |
|
&Apache::lonnet::appenv({'course.'.$cdom.'_'.$cnum.'.internal.releaserequired' => |
|
$curr_reqd_hash{'internal.releaserequired'}}); |
|
my ($switchserver,$switchwarning) = |
|
&check_release_required($loncaparev,$cdom.'_'.$cnum,$env{'request.role'}, |
|
$curr_reqd_hash{'internal.releaserequired'}); |
|
if ($switchwarning ne '' || $switchserver ne '') { |
|
return ('switch',$switchwarning,$switchserver); |
|
} |
|
} |
|
} |
|
return ('update'); |
|
} |
|
} |
|
return (); |
|
} |
|
|
sub update_content_constraints { |
sub update_content_constraints { |
my ($cdom,$cnum,$chome,$cid) = @_; |
my ($cdom,$cnum,$chome,$cid,$keeporder) = @_; |
my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired'); |
my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired'); |
my ($reqdmajor,$reqdminor) = split(/\./,$curr_reqd_hash{'internal.releaserequired'}); |
my ($reqdmajor,$reqdminor) = split(/\./,$curr_reqd_hash{'internal.releaserequired'}); |
my %checkresponsetypes; |
my (%checkresponsetypes,%checkcrsrestypes); |
foreach my $key (keys(%Apache::lonnet::needsrelease)) { |
foreach my $key (keys(%Apache::lonnet::needsrelease)) { |
my ($item,$name,$value) = split(/:/,$key); |
my ($item,$name,$value) = split(/:/,$key); |
if ($item eq 'resourcetag') { |
if ($item eq 'resourcetag') { |
if ($name eq 'responsetype') { |
if ($name eq 'responsetype') { |
$checkresponsetypes{$value} = $Apache::lonnet::needsrelease{$key} |
$checkresponsetypes{$value} = $Apache::lonnet::needsrelease{$key} |
} |
} |
|
} elsif ($item eq 'course') { |
|
if ($name eq 'courserestype') { |
|
$checkcrsrestypes{$value} = $Apache::lonnet::needsrelease{$key}; |
|
} |
} |
} |
} |
} |
my $navmap = Apache::lonnavmaps::navmap->new(); |
my $navmap = Apache::lonnavmaps::navmap->new(); |
if (defined($navmap)) { |
if (defined($navmap)) { |
my %allresponses; |
my (%allresponses,%allcrsrestypes); |
foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_problem() },1,0)) { |
foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_problem() || $_[0]->is_tool() },1,0)) { |
|
if ($res->is_tool()) { |
|
if ($allcrsrestypes{'exttool'}) { |
|
$allcrsrestypes{'exttool'} ++; |
|
} else { |
|
$allcrsrestypes{'exttool'} = 1; |
|
} |
|
next; |
|
} |
my %responses = $res->responseTypes(); |
my %responses = $res->responseTypes(); |
foreach my $key (keys(%responses)) { |
foreach my $key (keys(%responses)) { |
next unless(exists($checkresponsetypes{$key})); |
next unless(exists($checkresponsetypes{$key})); |
Line 15257 sub update_content_constraints {
|
Line 17734 sub update_content_constraints {
|
($reqdmajor,$reqdminor) = ($major,$minor); |
($reqdmajor,$reqdminor) = ($major,$minor); |
} |
} |
} |
} |
|
foreach my $key (keys(%allcrsrestypes)) { |
|
my ($major,$minor) = split(/\./,$checkcrsrestypes{$key}); |
|
if (($major > $reqdmajor) || ($major == $reqdmajor && $minor > $reqdminor)) { |
|
($reqdmajor,$reqdminor) = ($major,$minor); |
|
} |
|
} |
undef($navmap); |
undef($navmap); |
} |
} |
|
my (@resources,@order,@resparms,@zombies); |
|
if ($keeporder) { |
|
use LONCAPA::map; |
|
@resources = @LONCAPA::map::resources; |
|
@order = @LONCAPA::map::order; |
|
@resparms = @LONCAPA::map::resparms; |
|
@zombies = @LONCAPA::map::zombies; |
|
} |
|
my $suppmap = 'supplemental.sequence'; |
|
my ($suppcount,$supptools,$errors) = (0,0,0); |
|
($suppcount,$supptools,$errors) = &recurse_supplemental($cnum,$cdom,$suppmap, |
|
$suppcount,$supptools,$errors); |
|
if ($keeporder) { |
|
@LONCAPA::map::resources = @resources; |
|
@LONCAPA::map::order = @order; |
|
@LONCAPA::map::resparms = @resparms; |
|
@LONCAPA::map::zombies = @zombies; |
|
} |
|
if ($supptools) { |
|
my ($major,$minor) = split(/\./,$checkcrsrestypes{'exttool'}); |
|
if (($major > $reqdmajor) || ($major == $reqdmajor && $minor > $reqdminor)) { |
|
($reqdmajor,$reqdminor) = ($major,$minor); |
|
} |
|
} |
unless (($reqdmajor eq '') && ($reqdminor eq '')) { |
unless (($reqdmajor eq '') && ($reqdminor eq '')) { |
&Apache::lonnet::update_released_required($reqdmajor.'.'.$reqdminor,$cdom,$cnum,$chome,$cid); |
&Apache::lonnet::update_released_required($reqdmajor.'.'.$reqdminor,$cdom,$cnum,$chome,$cid); |
} |
} |
Line 15279 sub allmaps_incourse {
|
Line 17786 sub allmaps_incourse {
|
if ($lastchange > $env{'request.course.tied'}) { |
if ($lastchange > $env{'request.course.tied'}) { |
my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum"); |
my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum"); |
unless ($ferr) { |
unless ($ferr) { |
&update_content_constraints($cdom,$cnum,$chome,$cid); |
&update_content_constraints($cdom,$cnum,$chome,$cid,1); |
} |
} |
} |
} |
my $navmap = Apache::lonnavmaps::navmap->new(); |
my $navmap = Apache::lonnavmaps::navmap->new(); |
Line 15315 sub parse_supplemental_title {
|
Line 17822 sub parse_supplemental_title {
|
} |
} |
|
|
sub recurse_supplemental { |
sub recurse_supplemental { |
my ($cnum,$cdom,$suppmap,$numfiles,$errors) = @_; |
my ($cnum,$cdom,$suppmap,$numfiles,$numexttools,$errors) = @_; |
if ($suppmap) { |
if ($suppmap) { |
my ($errtext,$fatal) = &LONCAPA::map::mapread('/uploaded/'.$cdom.'/'.$cnum.'/'.$suppmap); |
my ($errtext,$fatal) = &LONCAPA::map::mapread('/uploaded/'.$cdom.'/'.$cnum.'/'.$suppmap); |
if ($fatal) { |
if ($fatal) { |
Line 15326 sub recurse_supplemental {
|
Line 17833 sub recurse_supplemental {
|
my ($title,$src,$ext,$type,$status)=split(/\:/,$res); |
my ($title,$src,$ext,$type,$status)=split(/\:/,$res); |
if (($src ne '') && ($status eq 'res')) { |
if (($src ne '') && ($status eq 'res')) { |
if ($src =~ m{^\Q/uploaded/$cdom/$cnum/\E(supplemental_\d+\.sequence)$}) { |
if ($src =~ m{^\Q/uploaded/$cdom/$cnum/\E(supplemental_\d+\.sequence)$}) { |
($numfiles,$errors) = &recurse_supplemental($cnum,$cdom,$1,$numfiles,$errors); |
($numfiles,$numexttools,$errors) = &recurse_supplemental($cnum,$cdom,$1, |
|
$numfiles,$numexttools,$errors); |
} else { |
} else { |
|
if ($src =~ m{^/adm/$cdom/$cnum/\d+/ext\.tool$}) { |
|
$numexttools ++; |
|
} |
$numfiles ++; |
$numfiles ++; |
} |
} |
} |
} |
Line 15335 sub recurse_supplemental {
|
Line 17846 sub recurse_supplemental {
|
} |
} |
} |
} |
} |
} |
return ($numfiles,$errors); |
return ($numfiles,$numexttools,$errors); |
} |
} |
|
|
sub symb_to_docspath { |
sub symb_to_docspath { |
my ($symb) = @_; |
my ($symb,$navmapref) = @_; |
return unless ($symb); |
return unless ($symb && ref($navmapref)); |
my ($mapurl,$id,$resurl) = &Apache::lonnet::decode_symb($symb); |
my ($mapurl,$id,$resurl) = &Apache::lonnet::decode_symb($symb); |
if ($resurl=~/\.(sequence|page)$/) { |
if ($resurl=~/\.(sequence|page)$/) { |
$mapurl=$resurl; |
$mapurl=$resurl; |
Line 15348 sub symb_to_docspath {
|
Line 17859 sub symb_to_docspath {
|
$mapurl=$env{'course.'.$env{'request.course.id'}.'.url'}; |
$mapurl=$env{'course.'.$env{'request.course.id'}.'.url'}; |
} |
} |
my $mapresobj; |
my $mapresobj; |
my $navmap = Apache::lonnavmaps::navmap->new(); |
unless (ref($$navmapref)) { |
if (ref($navmap)) { |
$$navmapref = Apache::lonnavmaps::navmap->new(); |
$mapresobj = $navmap->getResourceByUrl($mapurl); |
} |
|
if (ref($$navmapref)) { |
|
$mapresobj = $$navmapref->getResourceByUrl($mapurl); |
} |
} |
$mapurl=~s{^.*/([^/]+)\.(\w+)$}{$1}; |
$mapurl=~s{^.*/([^/]+)\.(\w+)$}{$1}; |
my $type=$2; |
my $type=$2; |
Line 15360 sub symb_to_docspath {
|
Line 17873 sub symb_to_docspath {
|
if ($pcslist ne '') { |
if ($pcslist ne '') { |
foreach my $pc (split(/,/,$pcslist)) { |
foreach my $pc (split(/,/,$pcslist)) { |
next if ($pc <= 1); |
next if ($pc <= 1); |
my $res = $navmap->getByMapPc($pc); |
my $res = $$navmapref->getByMapPc($pc); |
if (ref($res)) { |
if (ref($res)) { |
my $thisurl = $res->src(); |
my $thisurl = $res->src(); |
$thisurl=~s{^.*/([^/]+)\.\w+$}{$1}; |
$thisurl=~s{^.*/([^/]+)\.\w+$}{$1}; |
Line 15407 sub symb_to_docspath {
|
Line 17920 sub symb_to_docspath {
|
} |
} |
|
|
sub captcha_display { |
sub captcha_display { |
my ($context,$lonhost) = @_; |
my ($context,$lonhost,$defdom) = @_; |
my ($output,$error); |
my ($output,$error); |
my ($captcha,$pubkey,$privkey) = &get_captcha_config($context,$lonhost); |
my ($captcha,$pubkey,$privkey,$version) = |
|
&get_captcha_config($context,$lonhost,$defdom); |
if ($captcha eq 'original') { |
if ($captcha eq 'original') { |
$output = &create_captcha(); |
$output = &create_captcha(); |
unless ($output) { |
unless ($output) { |
$error = 'captcha'; |
$error = 'captcha'; |
} |
} |
} elsif ($captcha eq 'recaptcha') { |
} elsif ($captcha eq 'recaptcha') { |
$output = &create_recaptcha($pubkey); |
$output = &create_recaptcha($pubkey,$version); |
unless ($output) { |
unless ($output) { |
$error = 'recaptcha'; |
$error = 'recaptcha'; |
} |
} |
} |
} |
return ($output,$error,$captcha); |
return ($output,$error,$captcha,$version); |
} |
} |
|
|
sub captcha_response { |
sub captcha_response { |
my ($context,$lonhost) = @_; |
my ($context,$lonhost,$defdom) = @_; |
my ($captcha_chk,$captcha_error); |
my ($captcha_chk,$captcha_error); |
my ($captcha,$pubkey,$privkey) = &get_captcha_config($context,$lonhost); |
my ($captcha,$pubkey,$privkey,$version) = &get_captcha_config($context,$lonhost,$defdom); |
if ($captcha eq 'original') { |
if ($captcha eq 'original') { |
($captcha_chk,$captcha_error) = &check_captcha(); |
($captcha_chk,$captcha_error) = &check_captcha(); |
} elsif ($captcha eq 'recaptcha') { |
} elsif ($captcha eq 'recaptcha') { |
$captcha_chk = &check_recaptcha($privkey); |
$captcha_chk = &check_recaptcha($privkey,$version); |
} else { |
} else { |
$captcha_chk = 1; |
$captcha_chk = 1; |
} |
} |
Line 15439 sub captcha_response {
|
Line 17953 sub captcha_response {
|
} |
} |
|
|
sub get_captcha_config { |
sub get_captcha_config { |
my ($context,$lonhost) = @_; |
my ($context,$lonhost,$dom_in_effect) = @_; |
my ($captcha,$pubkey,$privkey,$hashtocheck); |
my ($captcha,$pubkey,$privkey,$version,$hashtocheck); |
my $hostname = &Apache::lonnet::hostname($lonhost); |
my $hostname = &Apache::lonnet::hostname($lonhost); |
my $serverhomeID = &Apache::lonnet::get_server_homeID($hostname); |
my $serverhomeID = &Apache::lonnet::get_server_homeID($hostname); |
my $serverhomedom = &Apache::lonnet::host_domain($serverhomeID); |
my $serverhomedom = &Apache::lonnet::host_domain($serverhomeID); |
Line 15456 sub get_captcha_config {
|
Line 17970 sub get_captcha_config {
|
} |
} |
if ($privkey && $pubkey) { |
if ($privkey && $pubkey) { |
$captcha = 'recaptcha'; |
$captcha = 'recaptcha'; |
|
$version = $hashtocheck->{'recaptchaversion'}; |
|
if ($version ne '2') { |
|
$version = 1; |
|
} |
} else { |
} else { |
$captcha = 'original'; |
$captcha = 'original'; |
} |
} |
Line 15473 sub get_captcha_config {
|
Line 17991 sub get_captcha_config {
|
$privkey = $domconfhash{$serverhomedom.'.login.recaptchakeys_private'}; |
$privkey = $domconfhash{$serverhomedom.'.login.recaptchakeys_private'}; |
if ($privkey && $pubkey) { |
if ($privkey && $pubkey) { |
$captcha = 'recaptcha'; |
$captcha = 'recaptcha'; |
|
$version = $domconfhash{$serverhomedom.'.login.recaptchaversion'}; |
|
if ($version ne '2') { |
|
$version = 1; |
|
} |
} else { |
} else { |
$captcha = 'original'; |
$captcha = 'original'; |
} |
} |
} elsif ($domconfhash{$serverhomedom.'.login.captcha'} eq 'original') { |
} elsif ($domconfhash{$serverhomedom.'.login.captcha'} eq 'original') { |
$captcha = 'original'; |
$captcha = 'original'; |
} |
} |
} |
} elsif ($context eq 'passwords') { |
return ($captcha,$pubkey,$privkey); |
if ($dom_in_effect) { |
|
my %passwdconf = &Apache::lonnet::get_passwdconf($dom_in_effect); |
|
if ($passwdconf{'captcha'} eq 'recaptcha') { |
|
if (ref($passwdconf{'recaptchakeys'}) eq 'HASH') { |
|
$pubkey = $passwdconf{'recaptchakeys'}{'public'}; |
|
$privkey = $passwdconf{'recaptchakeys'}{'private'}; |
|
} |
|
if ($privkey && $pubkey) { |
|
$captcha = 'recaptcha'; |
|
$version = $passwdconf{'recaptchaversion'}; |
|
if ($version ne '2') { |
|
$version = 1; |
|
} |
|
} else { |
|
$captcha = 'original'; |
|
} |
|
} elsif ($passwdconf{'captcha'} ne 'notused') { |
|
$captcha = 'original'; |
|
} |
|
} |
|
} |
|
return ($captcha,$pubkey,$privkey,$version); |
} |
} |
|
|
sub create_captcha { |
sub create_captcha { |
Line 15503 sub create_captcha {
|
Line 18046 sub create_captcha {
|
last; |
last; |
} |
} |
} |
} |
|
if ($output eq '') { |
|
&Apache::lonnet::logthis("Failed to create Captcha code after $tries attempts."); |
|
} |
return $output; |
return $output; |
} |
} |
|
|
Line 15539 sub check_captcha {
|
Line 18085 sub check_captcha {
|
} |
} |
|
|
sub create_recaptcha { |
sub create_recaptcha { |
my ($pubkey) = @_; |
my ($pubkey,$version) = @_; |
my $use_ssl; |
if ($version >= 2) { |
if ($ENV{'SERVER_PORT'} == 443) { |
return '<div class="g-recaptcha" data-sitekey="'.$pubkey.'"></div>'; |
$use_ssl = 1; |
} else { |
} |
my $use_ssl; |
my $captcha = Captcha::reCAPTCHA->new; |
if ($ENV{'SERVER_PORT'} == 443) { |
return $captcha->get_options_setter({theme => 'white'})."\n". |
$use_ssl = 1; |
$captcha->get_html($pubkey,undef,$use_ssl). |
} |
&mt('If either word is hard to read, [_1] will replace them.', |
my $captcha = Captcha::reCAPTCHA->new; |
'<img src="/res/adm/pages/refresh.gif" alt="reCAPTCHA refresh" />'). |
return $captcha->get_options_setter({theme => 'white'})."\n". |
'<br /><br />'; |
$captcha->get_html($pubkey,undef,$use_ssl). |
|
&mt('If the text is hard to read, [_1] will replace them.', |
|
'<img src="/res/adm/pages/refresh.gif" alt="reCAPTCHA refresh" />'). |
|
'<br /><br />'; |
|
} |
} |
} |
|
|
sub check_recaptcha { |
sub check_recaptcha { |
my ($privkey) = @_; |
my ($privkey,$version) = @_; |
my $captcha_chk; |
my $captcha_chk; |
my $captcha = Captcha::reCAPTCHA->new; |
if ($version >= 2) { |
my $captcha_result = |
my %info = ( |
$captcha->check_answer( |
secret => $privkey, |
$privkey, |
response => $env{'form.g-recaptcha-response'}, |
$ENV{'REMOTE_ADDR'}, |
remoteip => $ENV{'REMOTE_ADDR'}, |
$env{'form.recaptcha_challenge_field'}, |
); |
$env{'form.recaptcha_response_field'}, |
my $request=new HTTP::Request('POST','https://www.google.com/recaptcha/api/siteverify'); |
); |
$request->content(join('&',map { |
if ($captcha_result->{is_valid}) { |
my $name = escape($_); |
$captcha_chk = 1; |
"$name=" . ( ref($info{$_}) eq 'ARRAY' |
|
? join("&$name=", map {escape($_) } @{$info{$_}}) |
|
: &escape($info{$_}) ); |
|
} keys(%info))); |
|
my $response = &LONCAPA::LWPReq::makerequest('',$request,'','',10,1); |
|
if ($response->is_success) { |
|
my $data = JSON::DWIW->from_json($response->decoded_content); |
|
if (ref($data) eq 'HASH') { |
|
if ($data->{'success'}) { |
|
$captcha_chk = 1; |
|
} |
|
} |
|
} |
|
} else { |
|
my $captcha = Captcha::reCAPTCHA->new; |
|
my $captcha_result = |
|
$captcha->check_answer( |
|
$privkey, |
|
$ENV{'REMOTE_ADDR'}, |
|
$env{'form.recaptcha_challenge_field'}, |
|
$env{'form.recaptcha_response_field'}, |
|
); |
|
if ($captcha_result->{is_valid}) { |
|
$captcha_chk = 1; |
|
} |
} |
} |
return $captcha_chk; |
return $captcha_chk; |
} |
} |
|
|
sub emailusername_info { |
sub emailusername_info { |
my @fields = ('firstname','lastname','institution','web','location','officialemail'); |
my @fields = ('firstname','lastname','institution','web','location','officialemail','id'); |
my %titles = &Apache::lonlocal::texthash ( |
my %titles = &Apache::lonlocal::texthash ( |
lastname => 'Last Name', |
lastname => 'Last Name', |
firstname => 'First Name', |
firstname => 'First Name', |
Line 15578 sub emailusername_info {
|
Line 18152 sub emailusername_info {
|
location => "School's city, state/province, country", |
location => "School's city, state/province, country", |
web => "School's web address", |
web => "School's web address", |
officialemail => 'E-mail address at institution (if different)', |
officialemail => 'E-mail address at institution (if different)', |
|
id => 'Student/Employee ID', |
); |
); |
return (\@fields,\%titles); |
return (\@fields,\%titles); |
} |
} |
Line 15606 sub cleanup_html {
|
Line 18181 sub cleanup_html {
|
|
|
# Checks for critical messages and returns a redirect url if one exists. |
# Checks for critical messages and returns a redirect url if one exists. |
# $interval indicates how often to check for messages. |
# $interval indicates how often to check for messages. |
|
# $context is the calling context -- roles, grades, contents, menu or flip. |
sub critical_redirect { |
sub critical_redirect { |
my ($interval) = @_; |
my ($interval,$context) = @_; |
if ((time-$env{'user.criticalcheck.time'})>$interval) { |
if ((time-$env{'user.criticalcheck.time'})>$interval) { |
|
if (($env{'request.course.id'}) && (($context eq 'flip') || ($context eq 'contents'))) { |
|
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
my $blocked = &blocking_status('alert',$cnum,$cdom,undef,1); |
|
if ($blocked) { |
|
my $checkrole = "cm./$cdom/$cnum"; |
|
if ($env{'request.course.sec'} ne '') { |
|
$checkrole .= "/$env{'request.course.sec'}"; |
|
} |
|
unless ((&Apache::lonnet::allowed('evb',undef,undef,$checkrole)) && |
|
($env{'request.role'} !~ m{^st\./$cdom/$cnum})) { |
|
return; |
|
} |
|
} |
|
} |
my @what=&Apache::lonnet::dump('critical', $env{'user.domain'}, |
my @what=&Apache::lonnet::dump('critical', $env{'user.domain'}, |
$env{'user.name'}); |
$env{'user.name'}); |
&Apache::lonnet::appenv({'user.criticalcheck.time'=>time}); |
&Apache::lonnet::appenv({'user.criticalcheck.time'=>time}); |
Line 15658 sub des_decrypt {
|
Line 18249 sub des_decrypt {
|
} else { |
} else { |
$cypher=new DES $keybin; |
$cypher=new DES $keybin; |
} |
} |
my $plaintext= |
my $plaintext=''; |
$cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,0,16)))); |
my $cypherlength = length($cyphertext); |
$plaintext.= |
my $numchunks = int($cypherlength/32); |
$cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,16,16)))); |
for (my $j=0; $j<$numchunks; $j++) { |
$plaintext=substr($plaintext,1,ord(substr($plaintext,0,1)) ); |
my $start = $j*32; |
|
my $cypherblock = substr($cyphertext,$start,32); |
|
my $chunk = |
|
$cypher->decrypt(unpack("a8",pack("H16",substr($cypherblock,0,16)))); |
|
$chunk .= |
|
$cypher->decrypt(unpack("a8",pack("H16",substr($cypherblock,16,16)))); |
|
$chunk=substr($chunk,1,ord(substr($chunk,0,1)) ); |
|
$plaintext .= $chunk; |
|
} |
return $plaintext; |
return $plaintext; |
} |
} |
|
|
|
sub get_requested_shorturls { |
|
my ($cdom,$cnum,$navmap) = @_; |
|
return unless (ref($navmap)); |
|
my ($numnew,$errors); |
|
my @toshorten = &Apache::loncommon::get_env_multiple('form.addtiny'); |
|
if (@toshorten) { |
|
my (%maps,%resources,%titles); |
|
&Apache::loncourserespicker::enumerate_course_contents($navmap,\%maps,\%resources,\%titles, |
|
'shorturls',$cdom,$cnum); |
|
if (keys(%resources)) { |
|
my %tocreate; |
|
foreach my $item (sort {$a <=> $b} (@toshorten)) { |
|
my $symb = $resources{$item}; |
|
if ($symb) { |
|
$tocreate{$cnum.'&'.$symb} = 1; |
|
} |
|
} |
|
if (keys(%tocreate)) { |
|
($numnew,$errors) = &make_short_symbs($cdom,$cnum, |
|
\%tocreate); |
|
} |
|
} |
|
} |
|
return ($numnew,$errors); |
|
} |
|
|
|
sub make_short_symbs { |
|
my ($cdom,$cnum,$tocreateref,$lockuser) = @_; |
|
my ($numnew,@errors); |
|
if (ref($tocreateref) eq 'HASH') { |
|
my %tocreate = %{$tocreateref}; |
|
if (keys(%tocreate)) { |
|
my %coursetiny = &Apache::lonnet::dump('tiny',$cdom,$cnum); |
|
my $su = Short::URL->new(no_vowels => 1); |
|
my $init = ''; |
|
my (%newunique,%addcourse,%courseonly,%failed); |
|
# get lock on tiny db |
|
my $now = time; |
|
if ($lockuser eq '') { |
|
$lockuser = $env{'user.name'}.':'.$env{'user.domain'}; |
|
} |
|
my $lockhash = { |
|
"lock\0$now" => $lockuser, |
|
}; |
|
my $tries = 0; |
|
my $gotlock = &Apache::lonnet::newput_dom('tiny',$lockhash,$cdom); |
|
my ($code,$error); |
|
while (($gotlock ne 'ok') && ($tries<3)) { |
|
$tries ++; |
|
sleep 1; |
|
$gotlock = &Apache::lonnet::newput_dom('tiny',$lockhash,$cdom); |
|
} |
|
if ($gotlock eq 'ok') { |
|
$init = &shorten_symbs($cdom,$init,$su,\%coursetiny,\%tocreate,\%newunique, |
|
\%addcourse,\%courseonly,\%failed); |
|
if (keys(%failed)) { |
|
my $numfailed = scalar(keys(%failed)); |
|
push(@errors,&mt('error: could not obtain unique six character URL for [quant,_1,resource]',$numfailed)); |
|
} |
|
if (keys(%newunique)) { |
|
my $putres = &Apache::lonnet::newput_dom('tiny',\%newunique,$cdom); |
|
if ($putres eq 'ok') { |
|
$numnew = scalar(keys(%newunique)); |
|
my $newputres = &Apache::lonnet::newput('tiny',\%addcourse,$cdom,$cnum); |
|
unless ($newputres eq 'ok') { |
|
push(@errors,&mt('error: could not store course look-up of short URLs')); |
|
} |
|
} else { |
|
push(@errors,&mt('error: could not store unique six character URLs')); |
|
} |
|
} |
|
my $dellockres = &Apache::lonnet::del_dom('tiny',["lock\0$now"],$cdom); |
|
unless ($dellockres eq 'ok') { |
|
push(@errors,&mt('error: could not release lockfile')); |
|
} |
|
} else { |
|
push(@errors,&mt('error: could not obtain lockfile')); |
|
} |
|
if (keys(%courseonly)) { |
|
my $result = &Apache::lonnet::newput('tiny',\%courseonly,$cdom,$cnum); |
|
if ($result ne 'ok') { |
|
push(@errors,&mt('error: could not update course look-up of short URLs')); |
|
} |
|
} |
|
} |
|
} |
|
return ($numnew,\@errors); |
|
} |
|
|
|
sub shorten_symbs { |
|
my ($cdom,$init,$su,$coursetiny,$tocreate,$newunique,$addcourse,$courseonly,$failed) = @_; |
|
return unless ((ref($su)) && (ref($coursetiny) eq 'HASH') && (ref($tocreate) eq 'HASH') && |
|
(ref($newunique) eq 'HASH') && (ref($addcourse) eq 'HASH') && |
|
(ref($courseonly) eq 'HASH') && (ref($failed) eq 'HASH')); |
|
my (%possibles,%collisions); |
|
foreach my $key (keys(%{$tocreate})) { |
|
my $num = String::CRC32::crc32($key); |
|
my $tiny = $su->encode($num,$init); |
|
if ($tiny) { |
|
$possibles{$tiny} = $key; |
|
} |
|
} |
|
if (!$init) { |
|
$init = 1; |
|
} else { |
|
$init ++; |
|
} |
|
if (keys(%possibles)) { |
|
my @posstiny = keys(%possibles); |
|
my $configuname = &Apache::lonnet::get_domainconfiguser($cdom); |
|
my %currtiny = &Apache::lonnet::get('tiny',\@posstiny,$cdom,$configuname); |
|
if (keys(%currtiny)) { |
|
foreach my $key (keys(%currtiny)) { |
|
next if ($currtiny{$key} eq ''); |
|
if ($currtiny{$key} eq $possibles{$key}) { |
|
my ($tcnum,$tsymb) = split(/\&/,$currtiny{$key}); |
|
unless (($coursetiny->{$tsymb} eq $key) || ($addcourse->{$tsymb} eq $key) || ($courseonly->{$tsymb} eq $key)) { |
|
$courseonly->{$tsymb} = $key; |
|
} |
|
} else { |
|
$collisions{$possibles{$key}} = 1; |
|
} |
|
delete($possibles{$key}); |
|
} |
|
} |
|
foreach my $key (keys(%possibles)) { |
|
$newunique->{$key} = $possibles{$key}; |
|
my ($tcnum,$tsymb) = split(/\&/,$possibles{$key}); |
|
unless (($coursetiny->{$tsymb} eq $key) || ($addcourse->{$tsymb} eq $key) || ($courseonly->{$tsymb} eq $key)) { |
|
$addcourse->{$tsymb} = $key; |
|
} |
|
} |
|
} |
|
if (keys(%collisions)) { |
|
if ($init <5) { |
|
if (!$init) { |
|
$init = 1; |
|
} else { |
|
$init ++; |
|
} |
|
$init = &shorten_symbs($cdom,$init,$su,$coursetiny,\%collisions, |
|
$newunique,$addcourse,$courseonly,$failed); |
|
} else { |
|
foreach my $key (keys(%collisions)) { |
|
$failed->{$key} = 1; |
|
} |
|
} |
|
} |
|
return $init; |
|
} |
|
|
|
sub is_nonframeable { |
|
my ($url,$absolute,$hostname,$ip,$nocache) = @_; |
|
my ($remprotocol,$remhost) = ($url =~ m{^(https?)\://(([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,})}i); |
|
return if (($remprotocol eq '') || ($remhost eq '')); |
|
|
|
$remprotocol = lc($remprotocol); |
|
$remhost = lc($remhost); |
|
my $remport = 80; |
|
if ($remprotocol eq 'https') { |
|
$remport = 443; |
|
} |
|
my ($result,$cached) = &Apache::lonnet::is_cached_new('noiframe',$remhost.':'.$remport); |
|
if ($cached) { |
|
unless ($nocache) { |
|
if ($result) { |
|
return 1; |
|
} else { |
|
return 0; |
|
} |
|
} |
|
} |
|
my $uselink; |
|
my $request = new HTTP::Request('HEAD',$url); |
|
my $response = &LONCAPA::LWPReq::makerequest('',$request,'','',5); |
|
if ($response->is_success()) { |
|
my $secpolicy = lc($response->header('content-security-policy')); |
|
my $xframeop = lc($response->header('x-frame-options')); |
|
$secpolicy =~ s/^\s+|\s+$//g; |
|
$xframeop =~ s/^\s+|\s+$//g; |
|
if (($secpolicy ne '') || ($xframeop ne '')) { |
|
my $remotehost = $remprotocol.'://'.$remhost; |
|
my ($origin,$protocol,$port); |
|
if ($ENV{'SERVER_PORT'} =~/^\d+$/) { |
|
$port = $ENV{'SERVER_PORT'}; |
|
} else { |
|
$port = 80; |
|
} |
|
if ($absolute eq '') { |
|
$protocol = 'http:'; |
|
if ($port == 443) { |
|
$protocol = 'https:'; |
|
} |
|
$origin = $protocol.'//'.lc($hostname); |
|
} else { |
|
$origin = lc($absolute); |
|
($protocol,$hostname) = ($absolute =~ m{^(https?:)//([^/]+)$}); |
|
} |
|
if (($secpolicy) && ($secpolicy =~ /\Qframe-ancestors\E([^;]*)(;|$)/)) { |
|
my $framepolicy = $1; |
|
$framepolicy =~ s/^\s+|\s+$//g; |
|
my @policies = split(/\s+/,$framepolicy); |
|
if (@policies) { |
|
if (grep(/^\Q'none'\E$/,@policies)) { |
|
$uselink = 1; |
|
} else { |
|
$uselink = 1; |
|
if ((grep(/^\Q*\E$/,@policies)) || (grep(/^\Q$protocol\E$/,@policies)) || |
|
(($origin ne '') && (grep(/^\Q$origin\E$/,@policies))) || |
|
(($ip ne '') && (grep(/^\Q$ip\E$/,@policies)))) { |
|
undef($uselink); |
|
} |
|
if ($uselink) { |
|
if (grep(/^\Q'self'\E$/,@policies)) { |
|
if (($origin ne '') && ($remotehost eq $origin)) { |
|
undef($uselink); |
|
} |
|
} |
|
} |
|
if ($uselink) { |
|
my @possok; |
|
if ($ip ne '') { |
|
push(@possok,$ip); |
|
} |
|
my $hoststr = ''; |
|
foreach my $part (reverse(split(/\./,$hostname))) { |
|
if ($hoststr eq '') { |
|
$hoststr = $part; |
|
} else { |
|
$hoststr = "$part.$hoststr"; |
|
} |
|
if ($hoststr eq $hostname) { |
|
push(@possok,$hostname); |
|
} else { |
|
push(@possok,"*.$hoststr"); |
|
} |
|
} |
|
if (@possok) { |
|
foreach my $poss (@possok) { |
|
last if (!$uselink); |
|
foreach my $policy (@policies) { |
|
if ($policy =~ m{^(\Q$protocol\E//|)\Q$poss\E(\Q:$port\E|)$}) { |
|
undef($uselink); |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} elsif ($xframeop ne '') { |
|
$uselink = 1; |
|
my @policies = split(/\s*,\s*/,$xframeop); |
|
if (@policies) { |
|
unless (grep(/^deny$/,@policies)) { |
|
if ($origin ne '') { |
|
if (grep(/^sameorigin$/,@policies)) { |
|
if ($remotehost eq $origin) { |
|
undef($uselink); |
|
} |
|
} |
|
if ($uselink) { |
|
foreach my $policy (@policies) { |
|
if ($policy =~ /^allow-from\s*(.+)$/) { |
|
my $allowfrom = $1; |
|
if (($allowfrom ne '') && ($allowfrom eq $origin)) { |
|
undef($uselink); |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if ($nocache) { |
|
if ($cached) { |
|
my $devalidate; |
|
if ($uselink && !$result) { |
|
$devalidate = 1; |
|
} elsif (!$uselink && $result) { |
|
$devalidate = 1; |
|
} |
|
if ($devalidate) { |
|
&Apache::lonnet::devalidate_cache_new('noiframe',$remhost.':'.$remport); |
|
} |
|
} |
|
} else { |
|
if ($uselink) { |
|
$result = 1; |
|
} else { |
|
$result = 0; |
|
} |
|
&Apache::lonnet::do_cache_new('noiframe',$remhost.':'.$remport,$result,3600); |
|
} |
|
return $uselink; |
|
} |
|
|
1; |
1; |
__END__; |
__END__; |
|
|