version 1.978, 2010/08/18 17:59:28
|
version 1.1118, 2013/03/20 01:26:15
|
Line 67 use Apache::lonhtmlcommon();
|
Line 67 use Apache::lonhtmlcommon();
|
use Apache::loncoursedata(); |
use Apache::loncoursedata(); |
use Apache::lontexconvert(); |
use Apache::lontexconvert(); |
use Apache::lonclonecourse(); |
use Apache::lonclonecourse(); |
|
use Apache::lonuserutils(); |
|
use Apache::lonuserstate(); |
use LONCAPA qw(:DEFAULT :match); |
use LONCAPA qw(:DEFAULT :match); |
use DateTime::TimeZone; |
use DateTime::TimeZone; |
use DateTime::Locale::Catalog; |
use DateTime::Locale::Catalog; |
|
use Text::Aspell; |
|
use Authen::Captcha; |
|
use Captcha::reCAPTCHA; |
|
|
# ---------------------------------------------- Designs |
# ---------------------------------------------- Designs |
use vars qw(%defaultdesign); |
use vars qw(%defaultdesign); |
Line 154 sub ssi_with_retries {
|
Line 159 sub ssi_with_retries {
|
# ----------------------------------------------- Filetypes/Languages/Copyright |
# ----------------------------------------------- Filetypes/Languages/Copyright |
my %language; |
my %language; |
my %supported_language; |
my %supported_language; |
|
my %supported_codes; |
|
my %latex_language; # For choosing hyphenation in <transl..> |
|
my %latex_language_bykey; # for choosing hyphenation from metadata |
my %cprtag; |
my %cprtag; |
my %scprtag; |
my %scprtag; |
my %fe; my %fd; my %fm; |
my %fe; my %fd; my %fm; |
Line 186 BEGIN {
|
Line 194 BEGIN {
|
while (my $line = <$fh>) { |
while (my $line = <$fh>) { |
next if ($line=~/^\#/); |
next if ($line=~/^\#/); |
chomp($line); |
chomp($line); |
my ($key,$two,$country,$three,$enc,$val,$sup)=(split(/\t/,$line)); |
my ($key,$code,$country,$three,$enc,$val,$sup,$latex)=(split(/\t/,$line)); |
$language{$key}=$val.' - '.$enc; |
$language{$key}=$val.' - '.$enc; |
if ($sup) { |
if ($sup) { |
$supported_language{$key}=$sup; |
$supported_language{$key}=$sup; |
|
$supported_codes{$key} = $code; |
} |
} |
|
if ($latex) { |
|
$latex_language_bykey{$key} = $latex; |
|
$latex_language{$code} = $latex; |
|
} |
} |
} |
close($fh); |
close($fh); |
} |
} |
Line 409 sub studentbrowser_javascript {
|
Line 422 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,roleflag,ignorefilter,courseadvonly) { |
function openstdbrowser(formname,uname,udom,clicker,roleflag,ignorefilter,courseadvonly) { |
var url = '/adm/pickstudent?'; |
var url = '/adm/pickstudent?'; |
var filter; |
var filter; |
if (!ignorefilter) { |
if (!ignorefilter) { |
Line 421 sub studentbrowser_javascript {
|
Line 434 sub studentbrowser_javascript {
|
} |
} |
} |
} |
url += 'form=' + formname + '&unameelement='+uname+ |
url += 'form=' + formname + '&unameelement='+uname+ |
'&udomelement='+udom; |
'&udomelement='+udom+ |
|
'&clicker='+clicker; |
if (roleflag) { url+="&roles=1"; } |
if (roleflag) { url+="&roles=1"; } |
if (courseadvonly) { url+="&courseadvonly=1"; } |
if (courseadvonly) { url+="&courseadvonly=1"; } |
var title = 'Student_Browser'; |
var title = 'Student_Browser'; |
Line 435 sub studentbrowser_javascript {
|
Line 449 sub studentbrowser_javascript {
|
ENDSTDBRW |
ENDSTDBRW |
} |
} |
|
|
|
sub resourcebrowser_javascript { |
|
unless ($env{'request.course.id'}) { return ''; } |
|
return (<<'ENDRESBRW'); |
|
<script type="text/javascript" language="Javascript"> |
|
// <![CDATA[ |
|
var reseditbrowser; |
|
function openresbrowser(formname,reslink) { |
|
var url = '/adm/pickresource?form='+formname+'&reslink='+reslink; |
|
var title = 'Resource_Browser'; |
|
var options = 'scrollbars=1,resizable=1,menubar=0'; |
|
options += ',width=700,height=500'; |
|
reseditbrowser = open(url,title,options,'1'); |
|
reseditbrowser.focus(); |
|
} |
|
// ]]> |
|
</script> |
|
ENDRESBRW |
|
} |
|
|
sub selectstudent_link { |
sub selectstudent_link { |
my ($form,$unameele,$udomele,$courseadvonly)=@_; |
my ($form,$unameele,$udomele,$courseadvonly,$clickerid)=@_; |
my $callargs = "'".$form."','".$unameele."','".$udomele."'"; |
my $callargs = "'".&Apache::lonhtmlcommon::entity_encode($form)."','". |
|
&Apache::lonhtmlcommon::entity_encode($unameele)."','". |
|
&Apache::lonhtmlcommon::entity_encode($udomele)."'"; |
if ($env{'request.course.id'}) { |
if ($env{'request.course.id'}) { |
if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'}) |
if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'}) |
&& !&Apache::lonnet::allowed('srm',$env{'request.course.id'}. |
&& !&Apache::lonnet::allowed('srm',$env{'request.course.id'}. |
'/'.$env{'request.course.sec'})) { |
'/'.$env{'request.course.sec'})) { |
return ''; |
return ''; |
} |
} |
|
$callargs.=",'".&Apache::lonhtmlcommon::entity_encode($clickerid)."'"; |
if ($courseadvonly) { |
if ($courseadvonly) { |
$callargs .= ",'',1,1"; |
$callargs .= ",'',1,1"; |
} |
} |
Line 452 sub selectstudent_link {
|
Line 488 sub selectstudent_link {
|
&mt('Select User').'</a></span>'; |
&mt('Select User').'</a></span>'; |
} |
} |
if ($env{'request.role'}=~/^(au|dc|su)/) { |
if ($env{'request.role'}=~/^(au|dc|su)/) { |
$callargs .= ",1"; |
$callargs .= ",'',1"; |
return '<span class="LC_nobreak">'. |
return '<span class="LC_nobreak">'. |
'<a href="javascript:openstdbrowser('.$callargs.');">'. |
'<a href="javascript:openstdbrowser('.$callargs.');">'. |
&mt('Select User').'</a></span>'; |
&mt('Select User').'</a></span>'; |
Line 460 sub selectstudent_link {
|
Line 496 sub selectstudent_link {
|
return ''; |
return ''; |
} |
} |
|
|
|
sub selectresource_link { |
|
my ($form,$reslink,$arg)=@_; |
|
|
|
my $callargs = "'".&Apache::lonhtmlcommon::entity_encode($form)."','". |
|
&Apache::lonhtmlcommon::entity_encode($reslink)."'"; |
|
unless ($env{'request.course.id'}) { return $arg; } |
|
return '<span class="LC_nobreak">'. |
|
'<a href="javascript:openresbrowser('.$callargs.');">'. |
|
$arg.'</a></span>'; |
|
} |
|
|
|
|
|
|
sub authorbrowser_javascript { |
sub authorbrowser_javascript { |
return <<"ENDAUTHORBRW"; |
return <<"ENDAUTHORBRW"; |
<script type="text/javascript" language="JavaScript"> |
<script type="text/javascript" language="JavaScript"> |
Line 482 ENDAUTHORBRW
|
Line 531 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) = @_; |
my $wintitle = 'Course_Browser'; |
my $wintitle = 'Course_Browser'; |
if ($crstype eq 'Community') { |
if ($crstype eq 'Community') { |
$wintitle = 'Community_Browser'; |
$wintitle = 'Community_Browser'; |
Line 545 sub coursebrowser_javascript {
|
Line 595 sub coursebrowser_javascript {
|
} |
} |
$id_functions |
$id_functions |
ENDSTDBRW |
ENDSTDBRW |
if (($sec_element ne '') || ($role_element ne '')) { |
if (($sec_element ne '') || ($role_element ne '') || ($credits_element ne '')) { |
$output .= &setsec_javascript($sec_element,$formname,$role_element); |
$output .= &setsec_javascript($sec_element,$formname,$role_element, |
|
$credits_element); |
} |
} |
$output .= ' |
$output .= ' |
// ]]> |
// ]]> |
Line 596 ENDJS
|
Line 647 ENDJS
|
|
|
} |
} |
|
|
|
sub javascript_array_indexof { |
|
return <<ENDJS; |
|
<script type="text/javascript" language="JavaScript"> |
|
// <![CDATA[ |
|
|
|
if (!Array.prototype.indexOf) { |
|
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) { |
|
"use strict"; |
|
if (this === void 0 || this === null) { |
|
throw new TypeError(); |
|
} |
|
var t = Object(this); |
|
var len = t.length >>> 0; |
|
if (len === 0) { |
|
return -1; |
|
} |
|
var n = 0; |
|
if (arguments.length > 0) { |
|
n = Number(arguments[1]); |
|
if (n !== n) { // shortcut for verifying if it is NaN |
|
n = 0; |
|
} else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) { |
|
n = (n > 0 || -1) * Math.floor(Math.abs(n)); |
|
} |
|
} |
|
if (n >= len) { |
|
return -1; |
|
} |
|
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); |
|
for (; k < len; k++) { |
|
if (k in t && t[k] === searchElement) { |
|
return k; |
|
} |
|
} |
|
return -1; |
|
} |
|
} |
|
|
|
// ]]> |
|
</script> |
|
|
|
ENDJS |
|
|
|
} |
|
|
sub userbrowser_javascript { |
sub userbrowser_javascript { |
my $id_functions = &javascript_index_functions(); |
my $id_functions = &javascript_index_functions(); |
return <<"ENDUSERBRW"; |
return <<"ENDUSERBRW"; |
Line 658 ENDUSERBRW
|
Line 754 ENDUSERBRW
|
} |
} |
|
|
sub setsec_javascript { |
sub setsec_javascript { |
my ($sec_element,$formname,$role_element) = @_; |
my ($sec_element,$formname,$role_element,$credits_element) = @_; |
my (@courserolenames,@communityrolenames,$rolestr,$courserolestr, |
my (@courserolenames,@communityrolenames,$rolestr,$courserolestr, |
$communityrolestr); |
$communityrolestr); |
if ($role_element ne '') { |
if ($role_element ne '') { |
Line 753 function setRole(crstype) {
|
Line 849 function setRole(crstype) {
|
} |
} |
|; |
|; |
} |
} |
|
if ($credits_element) { |
|
$setsections .= qq| |
|
function setCredits(defaultcredits) { |
|
document.$formname.$credits_element.value = defaultcredits; |
|
return; |
|
} |
|
|; |
|
} |
return $setsections; |
return $setsections; |
} |
} |
|
|
Line 766 sub selectcourse_link {
|
Line 870 sub selectcourse_link {
|
} elsif ($selecttype eq 'Course/Community') { |
} elsif ($selecttype eq 'Course/Community') { |
$linktext = &mt('Select Course/Community'); |
$linktext = &mt('Select Course/Community'); |
$type = ''; |
$type = ''; |
|
} elsif ($selecttype eq 'Select') { |
|
$linktext = &mt('Select'); |
|
$type = ''; |
} |
} |
return '<span class="LC_nobreak">' |
return '<span class="LC_nobreak">' |
."<a href='" |
."<a href='" |
Line 795 sub check_uncheck_jscript {
|
Line 902 sub check_uncheck_jscript {
|
function checkAll(field) { |
function checkAll(field) { |
if (field.length > 0) { |
if (field.length > 0) { |
for (i = 0; i < field.length; i++) { |
for (i = 0; i < field.length; i++) { |
field[i].checked = true ; |
if (!field[i].disabled) { |
|
field[i].checked = true; |
|
} |
} |
} |
} else { |
} else { |
field.checked = true |
if (!field.disabled) { |
|
field.checked = true; |
|
} |
} |
} |
} |
} |
|
|
Line 900 sub select_language {
|
Line 1011 sub select_language {
|
$langchoices{$code} = &plainlanguagedescription($id); |
$langchoices{$code} = &plainlanguagedescription($id); |
} |
} |
} |
} |
|
%langchoices = &Apache::lonlocal::texthash(%langchoices); |
return &select_form($selected,$name,\%langchoices); |
return &select_form($selected,$name,\%langchoices); |
} |
} |
|
|
=pod |
=pod |
|
|
|
|
|
=item * &list_languages() |
|
|
|
Returns an array reference that is suitable for use in language prompters. |
|
Each array element is itself a two element array. The first element |
|
is the language code. The second element a descsriptiuon of the |
|
language itself. This is suitable for use in e.g. |
|
&Apache::edit::select_arg (once dereferenced that is). |
|
|
|
=cut |
|
|
|
sub list_languages { |
|
my @lang_choices; |
|
|
|
foreach my $id (&languageids()) { |
|
my $code = &supportedlanguagecode($id); |
|
if ($code) { |
|
my $selector = $supported_codes{$id}; |
|
my $description = &plainlanguagedescription($id); |
|
push (@lang_choices, [$selector, $description]); |
|
} |
|
} |
|
return \@lang_choices; |
|
} |
|
|
|
=pod |
|
|
=item * &linked_select_forms(...) |
=item * &linked_select_forms(...) |
|
|
linked_select_forms returns a string containing a <script></script> block |
linked_select_forms returns a string containing a <script></script> block |
Line 931 linked_select_forms takes the following
|
Line 1070 linked_select_forms takes the following
|
|
|
=item * $menuorder, the order of values in the first menu |
=item * $menuorder, the order of values in the first menu |
|
|
|
=item * $onchangefirst, additional javascript call to execute for an onchange |
|
event for the first <select> tag |
|
|
|
=item * $onchangesecond, additional javascript call to execute for an onchange |
|
event for the second <select> tag |
|
|
=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 984 sub linked_select_forms {
|
Line 1129 sub linked_select_forms {
|
$secondselectname, |
$secondselectname, |
$hashref, |
$hashref, |
$menuorder, |
$menuorder, |
|
$onchangefirst, |
|
$onchangesecond |
) = @_; |
) = @_; |
my $second = "document.$formname.$secondselectname"; |
my $second = "document.$formname.$secondselectname"; |
my $first = "document.$formname.$firstselectname"; |
my $first = "document.$formname.$firstselectname"; |
Line 1040 function select1_changed() {
|
Line 1187 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()\">\n"; |
$result .= "<select size=\"1\" name=\"$firstselectname\" onchange=\"select1_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 1053 END
|
Line 1200 END
|
$result .= "</select>\n"; |
$result .= "</select>\n"; |
my %select2 = %{$hashref->{$firstdefault}->{'select2'}}; |
my %select2 = %{$hashref->{$firstdefault}->{'select2'}}; |
$result .= $middletext; |
$result .= $middletext; |
$result .= "<select size=\"1\" name=\"$secondselectname\">\n"; |
$result .= "<select size=\"1\" name=\"$secondselectname\""; |
|
if ($onchangesecond) { |
|
$result .= ' onchange="'.$onchangesecond.'"'; |
|
} |
|
$result .= ">\n"; |
my $seconddefault = $hashref->{$firstdefault}->{'default'}; |
my $seconddefault = $hashref->{$firstdefault}->{'default'}; |
|
|
my @secondorder = sort(keys(%select2)); |
my @secondorder = sort(keys(%select2)); |
Line 1102 sub help_open_topic {
|
Line 1253 sub help_open_topic {
|
my ($topic, $text, $stayOnPage, $width, $height, $imgid) = @_; |
my ($topic, $text, $stayOnPage, $width, $height, $imgid) = @_; |
$text = "" if (not defined $text); |
$text = "" if (not defined $text); |
$stayOnPage = 0 if (not defined $stayOnPage); |
$stayOnPage = 0 if (not defined $stayOnPage); |
$width = 350 if (not defined $width); |
$width = 500 if (not defined $width); |
$height = 400 if (not defined $height); |
$height = 400 if (not defined $height); |
my $filename = $topic; |
my $filename = $topic; |
$filename =~ s/ /_/g; |
$filename =~ s/ /_/g; |
Line 1113 sub help_open_topic {
|
Line 1264 sub help_open_topic {
|
$topic=~s/\W/\_/g; |
$topic=~s/\W/\_/g; |
|
|
if (!$stayOnPage) { |
if (!$stayOnPage) { |
$link = "javascript:void(open('/adm/help/${filename}.hlp', 'Help_for_$topic', 'menubar=0,toolbar=1,scrollbars=1,width=$width,height=$height,resizable=yes'))"; |
$link = "javascript:openMyModal('/adm/help/${filename}.hlp',$width,$height,'yes');"; |
|
} elsif ($stayOnPage eq 'popup') { |
|
$link = "javascript:void(open('/adm/help/${filename}.hlp', 'Help_for_$topic', 'menubar=0,toolbar=1,scrollbars=1,width=$width,height=$height,resizable=yes'))"; |
} else { |
} else { |
$link = "/adm/help/${filename}.hlp"; |
$link = "/adm/help/${filename}.hlp"; |
} |
} |
Line 1146 sub help_open_topic {
|
Line 1299 sub help_open_topic {
|
# This is a quicky function for Latex cheatsheet editing, since it |
# This is a quicky function for Latex cheatsheet editing, since it |
# appears in at least four places |
# appears in at least four places |
sub helpLatexCheatsheet { |
sub helpLatexCheatsheet { |
my ($topic,$text,$not_author) = @_; |
my ($topic,$text,$not_author,$stayOnPage) = @_; |
my $out; |
my $out; |
my $addOther = ''; |
my $addOther = ''; |
if ($topic) { |
if ($topic) { |
$addOther = '<span>'.&Apache::loncommon::help_open_topic($topic,&mt($text), |
$addOther = '<span>'.&help_open_topic($topic,&mt($text),$stayOnPage, undef, 600).'</span> '; |
undef, undef, 600). |
|
'</span> '; |
|
} |
} |
$out = '<span>' # Start cheatsheet |
$out = '<span>' # Start cheatsheet |
.$addOther |
.$addOther |
.'<span>' |
.'<span>' |
.&Apache::loncommon::help_open_topic('Greek_Symbols',&mt('Greek Symbols'), |
.&help_open_topic('Greek_Symbols',&mt('Greek Symbols'),$stayOnPage,undef,600) |
undef,undef,600) |
|
.'</span> <span>' |
.'</span> <span>' |
.&Apache::loncommon::help_open_topic('Other_Symbols',&mt('Other Symbols'), |
.&help_open_topic('Other_Symbols',&mt('Other Symbols'),$stayOnPage,undef,600) |
undef,undef,600) |
|
.'</span>'; |
.'</span>'; |
unless ($not_author) { |
unless ($not_author) { |
$out .= ' <span>' |
$out .= ' <span>' |
.&Apache::loncommon::help_open_topic('Authoring_Output_Tags',&mt('Output Tags'), |
.&help_open_topic('Authoring_Output_Tags',&mt('Output Tags'),$stayOnPage,undef,600) |
undef,undef,600) |
|
.'</span>'; |
.'</span>'; |
} |
} |
$out .= '</span>'; # End cheatsheet |
$out .= '</span>'; # End cheatsheet |
Line 1287 function helpMenu(target) {
|
Line 1435 function helpMenu(target) {
|
return; |
return; |
} |
} |
function writeHelp(caller) { |
function writeHelp(caller) { |
caller.document.writeln('$start_page<frame name="bannerframe" src="'+banner_link+'" /><frame name="bodyframe" src="$details_link" /> $end_page') |
caller.document.writeln('$start_page\\n<frame name="bannerframe" src="'+banner_link+'" />\\n<frame name="bodyframe" src="$details_link" />\\n$end_page') |
caller.document.close() |
caller.document.close() |
caller.focus() |
caller.focus() |
} |
} |
Line 1661 Inputs: $workbook
|
Line 1809 Inputs: $workbook
|
|
|
Returns: $format, a hash reference. |
Returns: $format, a hash reference. |
|
|
|
|
=cut |
=cut |
|
|
############################################################### |
############################################################### |
Line 1722 sub create_workbook {
|
Line 1871 sub create_workbook {
|
return (undef); |
return (undef); |
} |
} |
# |
# |
$workbook->set_tempdir('/home/httpd/perl/tmp'); |
$workbook->set_tempdir(LONCAPA::tempdir()); |
# |
# |
my $format = &Apache::loncommon::define_excel_formats($workbook); |
my $format = &Apache::loncommon::define_excel_formats($workbook); |
return ($workbook,$filename,$format); |
return ($workbook,$filename,$format); |
Line 1893 sub select_form {
|
Line 2042 sub select_form {
|
# For display filters |
# For display filters |
|
|
sub display_filter { |
sub display_filter { |
|
my ($context) = @_; |
if (!$env{'form.show'}) { $env{'form.show'}=10; } |
if (!$env{'form.show'}) { $env{'form.show'}=10; } |
if (!$env{'form.displayfilter'}) { $env{'form.displayfilter'}='currentfolder'; } |
if (!$env{'form.displayfilter'}) { $env{'form.displayfilter'}='currentfolder'; } |
return '<span class="LC_nobreak"><label>'.&mt('Records [_1]', |
my $phraseinput = 'hidden'; |
|
my $includeinput = 'hidden'; |
|
my ($checked,$includetypestext); |
|
if ($env{'form.displayfilter'} eq 'containing') { |
|
$phraseinput = 'text'; |
|
if ($context eq 'parmslog') { |
|
$includeinput = 'checkbox'; |
|
if ($env{'form.includetypes'}) { |
|
$checked = ' checked="checked"'; |
|
} |
|
$includetypestext = &mt('Include parameter types'); |
|
} |
|
} else { |
|
$includetypestext = ' '; |
|
} |
|
my ($additional,$secondid,$thirdid); |
|
if ($context eq 'parmslog') { |
|
$additional = |
|
'<label><input type="'.$includeinput.'" name="includetypes"'. |
|
$checked.' name="includetypes" value="1" id="includetypes" />'. |
|
' <span id="includetypestext">'.$includetypestext.'</span>'. |
|
'</label>'; |
|
$secondid = 'includetypes'; |
|
$thirdid = 'includetypestext'; |
|
} |
|
my $onchange = "javascript:toggleHistoryOptions(this,'containingphrase','$context', |
|
'$secondid','$thirdid')"; |
|
return '<span class="LC_nobreak"><label>'.&mt('Records: [_1]', |
&Apache::lonmeta::selectbox('show',$env{'form.show'},undef, |
&Apache::lonmeta::selectbox('show',$env{'form.show'},undef, |
(&mt('all'),10,20,50,100,1000,10000))). |
(&mt('all'),10,20,50,100,1000,10000))). |
'</label></span> <span class="LC_nobreak">'. |
'</label></span> <span class="LC_nobreak">'. |
&mt('Filter [_1]', |
&mt('Filter: [_1]', |
&select_form($env{'form.displayfilter'}, |
&select_form($env{'form.displayfilter'}, |
'displayfilter', |
'displayfilter', |
{'currentfolder' => 'Current folder/page', |
{'currentfolder' => 'Current folder/page', |
'containing' => 'Containing phrase', |
'containing' => 'Containing phrase', |
'none' => 'None'})). |
'none' => 'None'},$onchange)).' '. |
'<input type="text" name="containingphrase" size="30" value="'.&HTML::Entities::encode($env{'form.containingphrase'}).'" /></span>'; |
'<input type="'.$phraseinput.'" name="containingphrase" id="containingphrase" size="30" value="'. |
|
&HTML::Entities::encode($env{'form.containingphrase'}). |
|
'" />'.$additional; |
|
} |
|
|
|
sub display_filter_js { |
|
my $includetext = &mt('Include parameter types'); |
|
return <<"ENDJS"; |
|
|
|
function toggleHistoryOptions(setter,firstid,context,secondid,thirdid) { |
|
var firstType = 'hidden'; |
|
if (setter.options[setter.selectedIndex].value == 'containing') { |
|
firstType = 'text'; |
|
} |
|
firstObject = document.getElementById(firstid); |
|
if (typeof(firstObject) == 'object') { |
|
if (firstObject.type != firstType) { |
|
changeInputType(firstObject,firstType); |
|
} |
|
} |
|
if (context == 'parmslog') { |
|
var secondType = 'hidden'; |
|
if (firstType == 'text') { |
|
secondType = 'checkbox'; |
|
} |
|
secondObject = document.getElementById(secondid); |
|
if (typeof(secondObject) == 'object') { |
|
if (secondObject.type != secondType) { |
|
changeInputType(secondObject,secondType); |
|
} |
|
} |
|
var textItem = document.getElementById(thirdid); |
|
var currtext = textItem.innerHTML; |
|
var newtext; |
|
if (firstType == 'text') { |
|
newtext = '$includetext'; |
|
} else { |
|
newtext = ' '; |
|
} |
|
if (currtext != newtext) { |
|
textItem.innerHTML = newtext; |
|
} |
|
} |
|
return; |
|
} |
|
|
|
function changeInputType(oldObject,newType) { |
|
var newObject = document.createElement('input'); |
|
newObject.type = newType; |
|
if (oldObject.size) { |
|
newObject.size = oldObject.size; |
|
} |
|
if (oldObject.value) { |
|
newObject.value = oldObject.value; |
|
} |
|
if (oldObject.name) { |
|
newObject.name = oldObject.name; |
|
} |
|
if (oldObject.id) { |
|
newObject.id = oldObject.id; |
|
} |
|
oldObject.parentNode.replaceChild(newObject,oldObject); |
|
return; |
|
} |
|
|
|
ENDJS |
} |
} |
|
|
sub gradeleveldescription { |
sub gradeleveldescription { |
Line 2274 function changed_text(choice,currentform
|
Line 2516 function changed_text(choice,currentform
|
} |
} |
|
|
function set_auth_radio_buttons(newvalue,currentform) { |
function set_auth_radio_buttons(newvalue,currentform) { |
|
var numauthchoices = currentform.login.length; |
|
if (typeof numauthchoices == "undefined") { |
|
return; |
|
} |
var i=0; |
var i=0; |
while (i < currentform.login.length) { |
while (i < numauthchoices) { |
if (currentform.login[i].value == newvalue) { break; } |
if (currentform.login[i].value == newvalue) { break; } |
i++; |
i++; |
} |
} |
if (i == currentform.login.length) { |
if (i == numauthchoices) { |
return; |
return; |
} |
} |
current.radiovalue = newvalue; |
current.radiovalue = newvalue; |
Line 2290 END
|
Line 2536 END
|
return $result; |
return $result; |
} |
} |
|
|
sub authform_authorwarning{ |
sub authform_authorwarning { |
my $result=''; |
my $result=''; |
$result='<i>'. |
$result='<i>'. |
&mt('As a general rule, only authors or co-authors should be '. |
&mt('As a general rule, only authors or co-authors should be '. |
Line 2299 sub authform_authorwarning{
|
Line 2545 sub authform_authorwarning{
|
return $result; |
return $result; |
} |
} |
|
|
sub authform_nochange{ |
sub authform_nochange { |
my %in = ( |
my %in = ( |
formname => 'document.cu', |
formname => 'document.cu', |
kerb_def_dom => 'MSU.EDU', |
kerb_def_dom => 'MSU.EDU', |
@_, |
@_, |
); |
); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
my $result; |
my $result; |
if (keys(%can_assign) == 0) { |
if (!$authnum) { |
$result = &mt('Under you current role you are not permitted to change login settings for this user'); |
$result = &mt('Under your current role you are not permitted to change login settings for this user'); |
} else { |
} else { |
$result = '<label>'.&mt('[_1] Do not change login data', |
$result = '<label>'.&mt('[_1] Do not change login data', |
'<input type="radio" name="login" value="nochange" '. |
'<input type="radio" name="login" value="nochange" '. |
Line 2328 sub authform_kerberos {
|
Line 2574 sub authform_kerberos {
|
); |
); |
my ($check4,$check5,$krbcheck,$krbarg,$krbver,$result,$authtype, |
my ($check4,$check5,$krbcheck,$krbarg,$krbver,$result,$authtype, |
$autharg,$jscall); |
$autharg,$jscall); |
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 { |
Line 2378 sub authform_kerberos {
|
Line 2624 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="hidden" name="login" value="krb" />'; |
$authtype = '<input type="radio" name="login" value="krb" />'; |
} |
} |
} |
} |
} |
} |
Line 2390 sub authform_kerberos {
|
Line 2636 sub authform_kerberos {
|
$krbcheck.' />'; |
$krbcheck.' />'; |
} |
} |
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'} && |
$in{'curr_authtype'} eq 'krb5') || |
$in{'curr_authtype'} eq 'krb5') || |
(!$can_assign{'krb4'} && $can_assign{'krb5'} && |
(!$can_assign{'krb4'} && $can_assign{'krb5'} && |
$in{'curr_authtype'} eq 'krb4')) { |
$in{'curr_authtype'} eq 'krb4')) { |
$result .= &mt |
$result .= &mt |
('[_1] Kerberos authenticated with domain [_2] '. |
('[_1] Kerberos authenticated with domain [_2] '. |
Line 2428 sub authform_kerberos {
|
Line 2674 sub authform_kerberos {
|
return $result; |
return $result; |
} |
} |
|
|
sub authform_internal{ |
sub authform_internal { |
my %in = ( |
my %in = ( |
formname => 'document.cu', |
formname => 'document.cu', |
kerb_def_dom => 'MSU.EDU', |
kerb_def_dom => 'MSU.EDU', |
@_, |
@_, |
); |
); |
my ($intcheck,$intarg,$result,$authtype,$autharg,$jscall); |
my ($intcheck,$intarg,$result,$authtype,$autharg,$jscall); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
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 2464 sub authform_internal{
|
Line 2710 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="hidden" name="login" value="int" />'; |
$authtype = '<input type="radio" name="login" value="int" />'; |
} |
} |
} |
} |
} |
} |
Line 2483 sub authform_internal{
|
Line 2729 sub authform_internal{
|
return $result; |
return $result; |
} |
} |
|
|
sub authform_local{ |
sub authform_local { |
my %in = ( |
my %in = ( |
formname => 'document.cu', |
formname => 'document.cu', |
kerb_def_dom => 'MSU.EDU', |
kerb_def_dom => 'MSU.EDU', |
@_, |
@_, |
); |
); |
my ($loccheck,$locarg,$result,$authtype,$autharg,$jscall); |
my ($loccheck,$locarg,$result,$authtype,$autharg,$jscall); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
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 2519 sub authform_local{
|
Line 2765 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="hidden" name="login" value="loc" />'; |
$authtype = '<input type="radio" name="login" value="loc" />'; |
} |
} |
} |
} |
} |
} |
Line 2537 sub authform_local{
|
Line 2783 sub authform_local{
|
return $result; |
return $result; |
} |
} |
|
|
sub authform_filesystem{ |
sub authform_filesystem { |
my %in = ( |
my %in = ( |
formname => 'document.cu', |
formname => 'document.cu', |
kerb_def_dom => 'MSU.EDU', |
kerb_def_dom => 'MSU.EDU', |
@_, |
@_, |
); |
); |
my ($fsyscheck,$result,$authtype,$autharg,$jscall); |
my ($fsyscheck,$result,$authtype,$autharg,$jscall); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'}); |
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 2570 sub authform_filesystem{
|
Line 2816 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="hidden" name="login" value="fsys" />'; |
$authtype = '<input type="radio" name="login" value="fsys" />'; |
} |
} |
} |
} |
} |
} |
Line 2765 database which holds them.
|
Line 3011 database which holds them.
|
|
|
Uses global $thesaurus_db_file. |
Uses global $thesaurus_db_file. |
|
|
|
|
=cut |
=cut |
|
|
############################################################### |
############################################################### |
Line 2800 sub get_related_words {
|
Line 3047 sub get_related_words {
|
untie %thesaurus_db; |
untie %thesaurus_db; |
return @Words; |
return @Words; |
} |
} |
|
############################################################### |
|
# |
|
# Spell checking |
|
# |
|
|
=pod |
=pod |
|
|
|
=head1 Spell checking |
|
|
|
=over 4 |
|
|
|
=item * &check_spelling($wordlist $language) |
|
|
|
Takes a string containing words and feeds it to an external |
|
spellcheck program via a pipeline. Returns a string containing |
|
them mis-spelled words. |
|
|
|
Parameters: |
|
|
|
=over 4 |
|
|
|
=item - $wordlist |
|
|
|
String that will be fed into the spellcheck program. |
|
|
|
=item - $language |
|
|
|
Language string that specifies the language for which the spell |
|
check will be performed. |
|
|
=back |
=back |
|
|
|
=back |
|
|
|
Note: This sub assumes that aspell is installed. |
|
|
|
|
=cut |
=cut |
|
|
|
|
|
=pod |
|
|
|
=back |
|
|
|
=cut |
|
|
|
sub check_spelling { |
|
my ($wordlist, $language) = @_; |
|
my @misspellings; |
|
|
|
# Generate the speller and set the langauge. |
|
# if explicitly selected: |
|
|
|
my $speller = Text::Aspell->new; |
|
if ($language) { |
|
$speller->set_option('lang', $language); |
|
} |
|
|
|
# Turn the word list into an array of words by splittingon whitespace |
|
|
|
my @words = split(/\s+/, $wordlist); |
|
|
|
foreach my $word (@words) { |
|
if(! $speller->check($word)) { |
|
push(@misspellings, $word); |
|
} |
|
} |
|
return join(' ', @misspellings); |
|
|
|
} |
|
|
# -------------------------------------------------------------- Plaintext name |
# -------------------------------------------------------------- Plaintext name |
=pod |
=pod |
|
|
Line 3036 sub noteswrapper {
|
Line 3347 sub noteswrapper {
|
# ------------------------------------------------------------- Aboutme Wrapper |
# ------------------------------------------------------------- Aboutme Wrapper |
|
|
sub aboutmewrapper { |
sub aboutmewrapper { |
my ($link,$username,$domain,$target)=@_; |
my ($link,$username,$domain,$target,$class)=@_; |
if (!defined($username) && !defined($domain)) { |
if (!defined($username) && !defined($domain)) { |
return; |
return; |
} |
} |
return '<a href="/adm/'.$domain.'/'.$username.'/aboutme?forcestudent=1"'. |
return '<a href="/adm/'.$domain.'/'.$username.'/aboutme"'. |
($target?' target="$target"':'').' title="'.&mt("View this user's personal information page").'">'.$link.'</a>'; |
($target?' target="'.$target.'"':'').($class?' class="'.$class.'"':'').' title="'.&mt("View this user's personal information page").'">'.$link.'</a>'; |
} |
} |
|
|
# ------------------------------------------------------------ Syllabus Wrapper |
# ------------------------------------------------------------ Syllabus Wrapper |
Line 3142 sub languagedescription {
|
Line 3453 sub languagedescription {
|
($supported_language{$code}?' ('.&mt('interface available').')':''); |
($supported_language{$code}?' ('.&mt('interface available').')':''); |
} |
} |
|
|
|
=pod |
|
|
|
=item * &plainlanguagedescription |
|
|
|
Returns both the plain language description (e.g. 'Creoles and Pidgins, English-based (Other)') |
|
and the language character encoding (e.g. ISO) separated by a ' - ' string. |
|
|
|
=cut |
|
|
sub plainlanguagedescription { |
sub plainlanguagedescription { |
my $code=shift; |
my $code=shift; |
return $language{$code}; |
return $language{$code}; |
} |
} |
|
|
|
=pod |
|
|
|
=item * &supportedlanguagecode |
|
|
|
Returns the supported language code (e.g. sptutf maps to pt) given a language |
|
code. |
|
|
|
=cut |
|
|
sub supportedlanguagecode { |
sub supportedlanguagecode { |
my $code=shift; |
my $code=shift; |
return $supported_language{$code}; |
return $supported_language{$code}; |
Line 3154 sub supportedlanguagecode {
|
Line 3483 sub supportedlanguagecode {
|
|
|
=pod |
=pod |
|
|
|
=item * &latexlanguage() |
|
|
|
Given a language key code returns the correspondnig language to use |
|
to select the correct hyphenation on LaTeX printouts. This is undef if there |
|
is no supported hyphenation for the language code. |
|
|
|
=cut |
|
|
|
sub latexlanguage { |
|
my $code = shift; |
|
return $latex_language{$code}; |
|
} |
|
|
|
=pod |
|
|
|
=item * &latexhyphenation() |
|
|
|
Same as above but what's supplied is the language as it might be stored |
|
in the metadata. |
|
|
|
=cut |
|
|
|
sub latexhyphenation { |
|
my $key = shift; |
|
return $latex_language_bykey{$key}; |
|
} |
|
|
|
=pod |
|
|
=item * ©rightids() |
=item * ©rightids() |
|
|
returns list of all copyrights |
returns list of all copyrights |
Line 3417 sub get_previous_attempt {
|
Line 3775 sub get_previous_attempt {
|
my ($ign,@parts) = split(/\./,$key); |
my ($ign,@parts) = split(/\./,$key); |
if ($#parts > 0) { |
if ($#parts > 0) { |
my $data=$parts[-1]; |
my $data=$parts[-1]; |
|
next if ($data eq 'foilorder'); |
pop(@parts); |
pop(@parts); |
|
$prevattempts.='<th>'.&mt('Part ').join('.',@parts).'<br />'.$data.' </th>'; |
if ($data eq 'type') { |
if ($data eq 'type') { |
unless ($showsurv) { |
unless ($showsurv) { |
my $id = join(',',@parts); |
my $id = join(',',@parts); |
Line 3426 sub get_previous_attempt {
|
Line 3786 sub get_previous_attempt {
|
$lasthidden{$ign.'.'.$id} = 1; |
$lasthidden{$ign.'.'.$id} = 1; |
} |
} |
} |
} |
delete($lasthash{$key}); |
} |
} else { |
|
$prevattempts.='<th>'.&mt('Part ').join('.',@parts).'<br />'.$data.' </th>'; |
|
} |
|
} else { |
} else { |
if ($#parts == 0) { |
if ($#parts == 0) { |
$prevattempts.='<th>'.$parts[0].'</th>'; |
$prevattempts.='<th>'.$parts[0].'</th>'; |
Line 3453 sub get_previous_attempt {
|
Line 3810 sub get_previous_attempt {
|
'<td>'.&mt('Transaction [_1]',$version).'</td>'; |
'<td>'.&mt('Transaction [_1]',$version).'</td>'; |
if (@hidden) { |
if (@hidden) { |
foreach my $key (sort(keys(%lasthash))) { |
foreach my $key (sort(keys(%lasthash))) { |
|
next if ($key =~ /\.foilorder$/); |
my $hide; |
my $hide; |
foreach my $id (@hidden) { |
foreach my $id (@hidden) { |
if ($key =~ /^\Q$id\E/) { |
if ($key =~ /^\Q$id\E/) { |
Line 3481 sub get_previous_attempt {
|
Line 3839 sub get_previous_attempt {
|
} |
} |
} else { |
} else { |
foreach my $key (sort(keys(%lasthash))) { |
foreach my $key (sort(keys(%lasthash))) { |
|
next if ($key =~ /\.foilorder$/); |
my $value = &format_previous_attempt_value($key, |
my $value = &format_previous_attempt_value($key, |
$returnhash{$version.':'.$key}); |
$returnhash{$version.':'.$key}); |
$prevattempts.='<td>'.$value.' </td>'; |
$prevattempts.='<td>'.$value.' </td>'; |
Line 3492 sub get_previous_attempt {
|
Line 3851 sub get_previous_attempt {
|
my @currhidden = keys(%lasthidden); |
my @currhidden = keys(%lasthidden); |
$prevattempts.=&start_data_table_row().'<td>'.&mt('Current').'</td>'; |
$prevattempts.=&start_data_table_row().'<td>'.&mt('Current').'</td>'; |
foreach my $key (sort(keys(%lasthash))) { |
foreach my $key (sort(keys(%lasthash))) { |
|
next if ($key =~ /\.foilorder$/); |
if (%typeparts) { |
if (%typeparts) { |
my $hidden; |
my $hidden; |
foreach my $id (@currhidden) { |
foreach my $id (@currhidden) { |
Line 3543 sub get_previous_attempt {
|
Line 3903 sub get_previous_attempt {
|
|
|
sub format_previous_attempt_value { |
sub format_previous_attempt_value { |
my ($key,$value) = @_; |
my ($key,$value) = @_; |
if ($key =~ /timestamp/) { |
if (($key =~ /timestamp/) || ($key=~/duedate/)) { |
$value = &Apache::lonlocal::locallocaltime($value); |
$value = &Apache::lonlocal::locallocaltime($value); |
} elsif (ref($value) eq 'ARRAY') { |
} elsif (ref($value) eq 'ARRAY') { |
$value = '('.join(', ', @{ $value }).')'; |
$value = '('.join(', ', @{ $value }).')'; |
|
} elsif ($key =~ /answerstring$/) { |
|
my %answers = &Apache::lonnet::str2hash($value); |
|
my @anskeys = sort(keys(%answers)); |
|
if (@anskeys == 1) { |
|
my $answer = $answers{$anskeys[0]}; |
|
if ($answer =~ m{\0}) { |
|
$answer =~ s{\0}{,}g; |
|
} |
|
my $tag_internal_answer_name = 'INTERNAL'; |
|
if ($anskeys[0] eq $tag_internal_answer_name) { |
|
$value = $answer; |
|
} else { |
|
$value = $anskeys[0].'='.$answer; |
|
} |
|
} else { |
|
foreach my $ans (@anskeys) { |
|
my $answer = $answers{$ans}; |
|
if ($answer =~ m{\0}) { |
|
$answer =~ s{\0}{,}g; |
|
} |
|
$value .= $ans.'='.$answer.'<br />';; |
|
} |
|
} |
} else { |
} else { |
$value = &unescape($value); |
$value = &unescape($value); |
} |
} |
Line 3850 sub findallcourses {
|
Line 4233 sub findallcourses {
|
if ($tstart) { |
if ($tstart) { |
next if ($tstart > $now); |
next if ($tstart > $now); |
} |
} |
my ($cdom,$cnum,$sec,$cnumpart,$secpart,$role,$realsec); |
my ($cdom,$cnum,$sec,$cnumpart,$secpart,$role); |
(undef,$cdom,$cnumpart,$secpart) = split(/\//,$entry); |
(undef,$cdom,$cnumpart,$secpart) = split(/\//,$entry); |
|
my $value = $trole.'/'.$cdom.'/'; |
if ($secpart eq '') { |
if ($secpart eq '') { |
($cnum,$role) = split(/_/,$cnumpart); |
($cnum,$role) = split(/_/,$cnumpart); |
$sec = 'none'; |
$sec = 'none'; |
$realsec = ''; |
$value .= $cnum.'/'; |
} else { |
} else { |
$cnum = $cnumpart; |
$cnum = $cnumpart; |
($sec,$role) = split(/_/,$secpart); |
($sec,$role) = split(/_/,$secpart); |
$realsec = $sec; |
$value .= $cnum.'/'.$sec; |
|
} |
|
if (ref($courses{$cdom.'_'.$cnum}{$sec}) eq 'ARRAY') { |
|
unless (grep(/^\Q$value\E$/,@{$courses{$cdom.'_'.$cnum}{$sec}})) { |
|
push(@{$courses{$cdom.'_'.$cnum}{$sec}},$value); |
|
} |
|
} else { |
|
@{$courses{$cdom.'_'.$cnum}{$sec}} = ($value); |
} |
} |
$courses{$cdom.'_'.$cnum}{$sec} = $trole.'/'.$cdom.'/'.$cnum.'/'.$realsec; |
|
} |
} |
} else { |
} else { |
foreach my $key (keys(%env)) { |
foreach my $key (keys(%env)) { |
Line 3879 sub findallcourses {
|
Line 4269 sub findallcourses {
|
if ($now>$endtime) { $active=0; } |
if ($now>$endtime) { $active=0; } |
} |
} |
if ($active) { |
if ($active) { |
|
my $value = $role.'/'.$cdom.'/'.$cnum.'/'; |
if ($sec eq '') { |
if ($sec eq '') { |
$sec = 'none'; |
$sec = 'none'; |
|
} else { |
|
$value .= $sec; |
|
} |
|
if (ref($courses{$cdom.'_'.$cnum}{$sec}) eq 'ARRAY') { |
|
unless (grep(/^\Q$value\E$/,@{$courses{$cdom.'_'.$cnum}{$sec}})) { |
|
push(@{$courses{$cdom.'_'.$cnum}{$sec}},$value); |
|
} |
|
} else { |
|
@{$courses{$cdom.'_'.$cnum}{$sec}} = ($value); |
} |
} |
$courses{$cdom.'_'.$cnum}{$sec} = |
|
$role.'/'.$cdom.'/'.$cnum.'/'.$sec; |
|
} |
} |
} |
} |
} |
} |
Line 3894 sub findallcourses {
|
Line 4292 sub findallcourses {
|
############################################### |
############################################### |
|
|
sub blockcheck { |
sub blockcheck { |
my ($setters,$activity,$uname,$udom) = @_; |
my ($setters,$activity,$uname,$udom,$url) = @_; |
|
|
if (!defined($udom)) { |
if (!defined($udom)) { |
$udom = $env{'user.domain'}; |
$udom = $env{'user.domain'}; |
Line 3906 sub blockcheck {
|
Line 4304 sub blockcheck {
|
# 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 (&Apache::lonnet::is_course($udom,$uname)) { |
if (&Apache::lonnet::is_course($udom,$uname)) { |
my %records = &Apache::lonnet::dump('comm_block',$udom,$uname); |
my ($startblock,$endblock,$triggerblock) = |
my ($startblock,$endblock)=&get_blocks($setters,$activity,$udom,$uname); |
&get_blocks($setters,$activity,$udom,$uname,$url); |
return ($startblock,$endblock); |
return ($startblock,$endblock,$triggerblock); |
} |
} |
|
|
my $startblock = 0; |
my $startblock = 0; |
my $endblock = 0; |
my $endblock = 0; |
|
my $triggerblock = ''; |
my %live_courses = &findallcourses(undef,$uname,$udom); |
my %live_courses = &findallcourses(undef,$uname,$udom); |
|
|
# If uname is for a user, and activity is course-specific, i.e., |
# If uname is for a user, and activity is course-specific, i.e., |
Line 3976 sub blockcheck {
|
Line 4375 sub blockcheck {
|
if ($otheruser) { |
if ($otheruser) { |
# Resource belongs to user other than current user. |
# Resource belongs to user other than current user. |
# Assemble privs for that user, and check for 'evb' priv. |
# Assemble privs for that user, and check for 'evb' priv. |
my ($trole,$tdom,$tnum,$tsec); |
my (%allroles,%userroles); |
my $entry = $live_courses{$course}{$sec}; |
if (ref($live_courses{$course}{$sec}) eq 'ARRAY') { |
if ($entry =~ /^cr/) { |
foreach my $entry (@{$live_courses{$course}{$sec}}) { |
($trole,$tdom,$tnum,$tsec) = |
my ($trole,$tdom,$tnum,$tsec); |
($entry =~ m|^(cr/$match_domain/$match_username/\w+)\./($match_domain)/($match_username)/?(\w*)$|); |
if ($entry =~ /^cr/) { |
} else { |
($trole,$tdom,$tnum,$tsec) = |
($trole,$tdom,$tnum,$tsec) = split(/\//,$entry); |
($entry =~ m|^(cr/$match_domain/$match_username/\w+)\./($match_domain)/($match_username)/?(\w*)$|); |
} |
} else { |
my ($spec,$area,$trest,%allroles,%userroles); |
($trole,$tdom,$tnum,$tsec) = split(/\//,$entry); |
$area = '/'.$tdom.'/'.$tnum; |
} |
$trest = $tnum; |
my ($spec,$area,$trest); |
if ($tsec ne '') { |
$area = '/'.$tdom.'/'.$tnum; |
$area .= '/'.$tsec; |
$trest = $tnum; |
$trest .= '/'.$tsec; |
if ($tsec ne '') { |
} |
$area .= '/'.$tsec; |
$spec = $trole.'.'.$area; |
$trest .= '/'.$tsec; |
if ($trole =~ /^cr/) { |
} |
&Apache::lonnet::custom_roleprivs(\%allroles,$trole, |
$spec = $trole.'.'.$area; |
$tdom,$spec,$trest,$area); |
if ($trole =~ /^cr/) { |
} else { |
&Apache::lonnet::custom_roleprivs(\%allroles,$trole, |
&Apache::lonnet::standard_roleprivs(\%allroles,$trole, |
$tdom,$spec,$trest,$area); |
$tdom,$spec,$trest,$area); |
} else { |
} |
&Apache::lonnet::standard_roleprivs(\%allroles,$trole, |
my ($author,$adv) = &Apache::lonnet::set_userprivs(\%userroles,\%allroles); |
$tdom,$spec,$trest,$area); |
if ($userroles{'user.priv.'.$checkrole} =~ /evb\&([^\:]*)/) { |
} |
if ($1) { |
} |
$no_userblock = 1; |
my ($author,$adv) = &Apache::lonnet::set_userprivs(\%userroles,\%allroles); |
last; |
if ($userroles{'user.priv.'.$checkrole} =~ /evb\&([^\:]*)/) { |
|
if ($1) { |
|
$no_userblock = 1; |
|
last; |
|
} |
} |
} |
} |
} |
} else { |
} else { |
Line 4023 sub blockcheck {
|
Line 4426 sub blockcheck {
|
# Retrieve blocking times and identity of locker for course |
# Retrieve blocking times and identity of locker for course |
# of specified user, unless user has 'evb' privilege. |
# of specified user, unless user has 'evb' privilege. |
|
|
my ($start,$end)=&get_blocks($setters,$activity,$cdom,$cnum); |
my ($start,$end,$trigger) = |
|
&get_blocks($setters,$activity,$cdom,$cnum,$url); |
if (($start != 0) && |
if (($start != 0) && |
(($startblock == 0) || ($startblock > $start))) { |
(($startblock == 0) || ($startblock > $start))) { |
$startblock = $start; |
$startblock = $start; |
|
if ($trigger ne '') { |
|
$triggerblock = $trigger; |
|
} |
} |
} |
if (($end != 0) && |
if (($end != 0) && |
(($endblock == 0) || ($endblock < $end))) { |
(($endblock == 0) || ($endblock < $end))) { |
$endblock = $end; |
$endblock = $end; |
|
if ($trigger ne '') { |
|
$triggerblock = $trigger; |
|
} |
} |
} |
} |
} |
return ($startblock,$endblock); |
return ($startblock,$endblock,$triggerblock); |
} |
} |
|
|
sub get_blocks { |
sub get_blocks { |
my ($setters,$activity,$cdom,$cnum) = @_; |
my ($setters,$activity,$cdom,$cnum,$url) = @_; |
my $startblock = 0; |
my $startblock = 0; |
my $endblock = 0; |
my $endblock = 0; |
|
my $triggerblock = ''; |
my $course = $cdom.'_'.$cnum; |
my $course = $cdom.'_'.$cnum; |
$setters->{$course} = {}; |
$setters->{$course} = {}; |
$setters->{$course}{'staff'} = []; |
$setters->{$course}{'staff'} = []; |
$setters->{$course}{'times'} = []; |
$setters->{$course}{'times'} = []; |
my %records = &Apache::lonnet::dump('comm_block',$cdom,$cnum); |
$setters->{$course}{'triggers'} = []; |
foreach my $record (keys(%records)) { |
my (@blockers,%triggered); |
my ($start,$end) = ($record =~ m/^(\d+)____(\d+)$/); |
my $now = time; |
if ($start <= time && $end >= time) { |
my %commblocks = &Apache::lonnet::get_comm_blocks($cdom,$cnum); |
my ($staff_name,$staff_dom,$title,$blocks) = |
if ($activity eq 'docs') { |
&parse_block_record($records{$record}); |
@blockers = &Apache::lonnet::has_comm_blocking('bre',undef,$url,\%commblocks); |
if ($blocks->{$activity} eq 'on') { |
foreach my $block (@blockers) { |
push(@{$$setters{$course}{'staff'}},[$staff_name,$staff_dom]); |
if ($block =~ /^firstaccess____(.+)$/) { |
push(@{$$setters{$course}{'times'}}, [$start,$end]); |
my $item = $1; |
if ( ($startblock == 0) || ($startblock > $start) ) { |
my $type = 'map'; |
$startblock = $start; |
my $timersymb = $item; |
|
if ($item eq 'course') { |
|
$type = 'course'; |
|
} elsif ($item =~ /___\d+___/) { |
|
$type = 'resource'; |
|
} else { |
|
$timersymb = &Apache::lonnet::symbread($item); |
|
} |
|
my $start = $env{'course.'.$cdom.'_'.$cnum.'.firstaccess.'.$timersymb}; |
|
my $end = $start + $env{'course.'.$cdom.'_'.$cnum.'.timerinterval.'.$timersymb}; |
|
$triggered{$block} = { |
|
start => $start, |
|
end => $end, |
|
type => $type, |
|
}; |
|
} |
|
} |
|
} else { |
|
foreach my $block (keys(%commblocks)) { |
|
if ($block =~ m/^(\d+)____(\d+)$/) { |
|
my ($start,$end) = ($1,$2); |
|
if ($start <= time && $end >= time) { |
|
if (ref($commblocks{$block}) eq 'HASH') { |
|
if (ref($commblocks{$block}{'blocks'}) eq 'HASH') { |
|
if ($commblocks{$block}{'blocks'}{$activity} eq 'on') { |
|
unless(grep(/^\Q$block\E$/,@blockers)) { |
|
push(@blockers,$block); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} elsif ($block =~ /^firstaccess____(.+)$/) { |
|
my $item = $1; |
|
my $timersymb = $item; |
|
my $type = 'map'; |
|
if ($item eq 'course') { |
|
$type = 'course'; |
|
} elsif ($item =~ /___\d+___/) { |
|
$type = 'resource'; |
|
} else { |
|
$timersymb = &Apache::lonnet::symbread($item); |
|
} |
|
my $start = $env{'course.'.$cdom.'_'.$cnum.'.firstaccess.'.$timersymb}; |
|
my $end = $start + $env{'course.'.$cdom.'_'.$cnum.'.timerinterval.'.$timersymb}; |
|
if ($start && $end) { |
|
if (($start <= time) && ($end >= time)) { |
|
unless (grep(/^\Q$block\E$/,@blockers)) { |
|
push(@blockers,$block); |
|
$triggered{$block} = { |
|
start => $start, |
|
end => $end, |
|
type => $type, |
|
}; |
|
} |
|
} |
} |
} |
if ( ($endblock == 0) || ($endblock < $end) ) { |
} |
$endblock = $end; |
} |
|
} |
|
foreach my $blocker (@blockers) { |
|
my ($staff_name,$staff_dom,$title,$blocks) = |
|
&parse_block_record($commblocks{$blocker}); |
|
push(@{$$setters{$course}{'staff'}},[$staff_name,$staff_dom]); |
|
my ($start,$end,$triggertype); |
|
if ($blocker =~ m/^(\d+)____(\d+)$/) { |
|
($start,$end) = ($1,$2); |
|
} elsif (ref($triggered{$blocker}) eq 'HASH') { |
|
$start = $triggered{$blocker}{'start'}; |
|
$end = $triggered{$blocker}{'end'}; |
|
$triggertype = $triggered{$blocker}{'type'}; |
|
} |
|
if ($start) { |
|
push(@{$$setters{$course}{'times'}}, [$start,$end]); |
|
if ($triggertype) { |
|
push(@{$$setters{$course}{'triggers'}},$triggertype); |
|
} else { |
|
push(@{$$setters{$course}{'triggers'}},0); |
|
} |
|
if ( ($startblock == 0) || ($startblock > $start) ) { |
|
$startblock = $start; |
|
if ($triggertype) { |
|
$triggerblock = $blocker; |
} |
} |
} |
} |
|
if ( ($endblock == 0) || ($endblock < $end) ) { |
|
$endblock = $end; |
|
if ($triggertype) { |
|
$triggerblock = $blocker; |
|
} |
|
} |
} |
} |
} |
} |
return ($startblock,$endblock); |
return ($startblock,$endblock,$triggerblock); |
} |
} |
|
|
sub parse_block_record { |
sub parse_block_record { |
Line 4086 sub parse_block_record {
|
Line 4582 sub parse_block_record {
|
} |
} |
|
|
sub blocking_status { |
sub blocking_status { |
my ($activity,$uname,$udom) = @_; |
my ($activity,$uname,$udom,$url) = @_; |
my %setters; |
my %setters; |
|
|
# check for active blocking |
|
my ($startblock,$endblock)=&blockcheck(\%setters,$activity,$uname,$udom); |
|
|
|
my $blocked = $startblock && $endblock ? 1 : 0; |
# check for active blocking |
|
my ($startblock,$endblock,$triggerblock) = |
# caller just wants to know whether a block is active |
&blockcheck(\%setters,$activity,$uname,$udom,$url); |
if (!wantarray) { return $blocked; } |
my $blocked = 0; |
|
if ($startblock && $endblock) { |
# build a link to a popup window containing the details |
$blocked = 1; |
my $querystring = "?activity=$activity"; |
} |
# $uname and $udom decide whose portfolio the user is trying to look at |
|
$querystring .= "&udom=$udom" if $udom; |
# caller just wants to know whether a block is active |
$querystring .= "&uname=$uname" if $uname; |
if (!wantarray) { return $blocked; } |
|
|
my $output .= <<'END_MYBLOCK'; |
# build a link to a popup window containing the details |
function openWindow(url, wdwName, w, h, toolbar,scrollbar) { |
my $querystring = "?activity=$activity"; |
var options = "width=" + w + ",height=" + h + ","; |
# $uname and $udom decide whose portfolio the user is trying to look at |
options += "resizable=yes,scrollbars="+scrollbar+",status=no,"; |
if ($activity eq 'port') { |
options += "menubar=no,toolbar="+toolbar+",location=no,directories=no"; |
$querystring .= "&udom=$udom" if $udom; |
var newWin = window.open(url, wdwName, options); |
$querystring .= "&uname=$uname" if $uname; |
newWin.focus(); |
} elsif ($activity eq 'docs') { |
} |
$querystring .= '&url='.&HTML::Entities::encode($url,'&"'); |
|
} |
|
|
|
my $output .= <<'END_MYBLOCK'; |
|
function openWindow(url, wdwName, w, h, toolbar,scrollbar) { |
|
var options = "width=" + w + ",height=" + h + ","; |
|
options += "resizable=yes,scrollbars="+scrollbar+",status=no,"; |
|
options += "menubar=no,toolbar="+toolbar+",location=no,directories=no"; |
|
var newWin = window.open(url, wdwName, options); |
|
newWin.focus(); |
|
} |
END_MYBLOCK |
END_MYBLOCK |
|
|
$output = Apache::lonhtmlcommon::scripttag($output); |
$output = Apache::lonhtmlcommon::scripttag($output); |
|
|
my $popupUrl = "/adm/blockingstatus/$querystring"; |
my $popupUrl = "/adm/blockingstatus/$querystring"; |
my $text = mt('Communication Blocked'); |
my $text = &mt('Communication Blocked'); |
|
if ($activity eq 'docs') { |
$output .= <<"END_BLOCK"; |
$text = &mt('Content Access Blocked'); |
|
} elsif ($activity eq 'printout') { |
|
$text = &mt('Printing Blocked'); |
|
} |
|
$output .= <<"END_BLOCK"; |
<div class='LC_comblock'> |
<div class='LC_comblock'> |
<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'> |
Line 4129 END_MYBLOCK
|
Line 4636 END_MYBLOCK
|
|
|
END_BLOCK |
END_BLOCK |
|
|
return ($blocked, $output); |
return ($blocked, $output); |
} |
} |
|
|
############################################### |
############################################### |
Line 4239 sub get_domainconf {
|
Line 4746 sub get_domainconf {
|
if (ref($domconfig{'login'}{$key}) eq 'HASH') { |
if (ref($domconfig{'login'}{$key}) eq 'HASH') { |
if ($key eq 'loginvia') { |
if ($key eq 'loginvia') { |
if (ref($domconfig{'login'}{'loginvia'}) eq 'HASH') { |
if (ref($domconfig{'login'}{'loginvia'}) eq 'HASH') { |
my @ids = &Apache::lonnet::current_machine_ids(); |
foreach my $hostname (keys(%{$domconfig{'login'}{'loginvia'}})) { |
foreach my $hostname (@ids) { |
|
if (ref($domconfig{'login'}{'loginvia'}{$hostname}) eq 'HASH') { |
if (ref($domconfig{'login'}{'loginvia'}{$hostname}) eq 'HASH') { |
if ($domconfig{'login'}{'loginvia'}{$hostname}{'server'}) { |
if ($domconfig{'login'}{'loginvia'}{$hostname}{'server'}) { |
my $server = $domconfig{'login'}{'loginvia'}{$hostname}{'server'}; |
my $server = $domconfig{'login'}{'loginvia'}{$hostname}{'server'}; |
Line 4249 sub get_domainconf {
|
Line 4755 sub get_domainconf {
|
|
|
$designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'custompath'}; |
$designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'custompath'}; |
} else { |
} else { |
$designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'}; |
$designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'}; |
} |
} |
if ($domconfig{'login'}{'loginvia'}{$hostname}{'exempt'}) { |
if ($domconfig{'login'}{'loginvia'}{$hostname}{'exempt'}) { |
$designhash{$udom.'.login.loginvia_exempt_'.$hostname} = $domconfig{'login'}{'loginvia'}{$hostname}{'exempt'}; |
$designhash{$udom.'.login.loginvia_exempt_'.$hostname} = $domconfig{'login'}{'loginvia'}{$hostname}{'exempt'}; |
Line 4332 sub get_legacy_domconf {
|
Line 4838 sub get_legacy_domconf {
|
close($fh); |
close($fh); |
} |
} |
} |
} |
if (-e '/home/httpd/html/adm/lonDomLogos/'.$udom.'.gif') { |
if (-e $Apache::lonnet::perlvar{'lonDocRoot'}.'/adm/lonDomLogos/'.$udom.'.gif') { |
$legacyhash{$udom.'.login.domlogo'} = "/adm/lonDomLogos/$udom.gif"; |
$legacyhash{$udom.'.login.domlogo'} = "/adm/lonDomLogos/$udom.gif"; |
} |
} |
return %legacyhash; |
return %legacyhash; |
Line 4390 sub designparm {
|
Line 4896 sub designparm {
|
return $env{'environment.color.'.$which}; |
return $env{'environment.color.'.$which}; |
} |
} |
$domain=&determinedomain($domain); |
$domain=&determinedomain($domain); |
my %domdesign = &get_domainconf($domain); |
my %domdesign; |
|
unless ($domain eq 'public') { |
|
%domdesign = &get_domainconf($domain); |
|
} |
my $output; |
my $output; |
if ($domdesign{$domain.'.'.$which} ne '') { |
if ($domdesign{$domain.'.'.$which} ne '') { |
$output = $domdesign{$domain.'.'.$which}; |
$output = $domdesign{$domain.'.'.$which}; |
Line 4415 sub designparm {
|
Line 4924 sub designparm {
|
|
|
=item * &authorspace() |
=item * &authorspace() |
|
|
Inputs: ./. |
Inputs: $url (usually will be undef). |
|
|
Returns: Path to the Construction Space of the current user's |
Returns: Path to Construction Space containing the resource or |
accessed author space |
directory being viewed (or for which action is being taken). |
The author space will be that of the current user |
If $url is provided, and begins /priv/<domain>/<uname> |
when accessing the own author space |
the path will be that portion of the $context argument. |
and that of the co-author/assistent co-author |
Otherwise the path will be for the author space of the current |
when accessing the co-author's/assistent co-author's |
user when the current role is author, or for that of the |
space |
co-author/assistant co-author space when the current role |
|
is co-author or assistant co-author. |
|
|
=cut |
=cut |
|
|
sub authorspace { |
sub authorspace { |
|
my ($url) = @_; |
|
if ($url ne '') { |
|
if ($url =~ m{^(/priv/$match_domain/$match_username/)}) { |
|
return $1; |
|
} |
|
} |
my $caname = ''; |
my $caname = ''; |
if ($env{'request.role'} =~ /^ca|^aa/) { |
my $cadom = ''; |
(undef,$caname) = |
if ($env{'request.role'} =~ /^(?:ca|aa)/) { |
|
($cadom,$caname) = |
($env{'request.role'}=~/($match_domain)\/($match_username)$/); |
($env{'request.role'}=~/($match_domain)\/($match_username)$/); |
} else { |
} elsif ($env{'request.role'} =~ m{^au\./($match_domain)/}) { |
$caname = $env{'user.name'}; |
$caname = $env{'user.name'}; |
|
$cadom = $env{'user.domain'}; |
} |
} |
return '/priv/'.$caname.'/'; |
if (($caname ne '') && ($cadom ne '')) { |
|
return "/priv/$cadom/$caname/"; |
|
} |
|
return; |
} |
} |
|
|
############################################## |
############################################## |
Line 4453 Returns: HTML div with $content
|
Line 4974 Returns: HTML div with $content
|
sub head_subbox { |
sub head_subbox { |
my ($content)=@_; |
my ($content)=@_; |
my $output = |
my $output = |
'<div id="LC_head_subbox">' |
'<div class="LC_head_subbox">' |
.$content |
.$content |
.'</div>' |
.'</div>' |
} |
} |
Line 4463 sub head_subbox {
|
Line 4984 sub head_subbox {
|
|
|
=item * &CSTR_pageheader() |
=item * &CSTR_pageheader() |
|
|
Inputs: ./. |
Input: (optional) filename from which breadcrumb trail is built. |
|
In most cases no input as needed, as $env{'request.filename'} |
|
is appropriate for use in building the breadcrumb trail. |
|
|
Returns: HTML div with CSTR path and recent box |
Returns: HTML div with CSTR path and recent box |
To be included on Construction Space pages |
To be included on Construction Space pages |
Line 4471 Returns: HTML div with CSTR path and rec
|
Line 4994 Returns: HTML div with CSTR path and rec
|
=cut |
=cut |
|
|
sub CSTR_pageheader { |
sub CSTR_pageheader { |
# this is for resources; directories have customtitle, and crumbs |
my ($trailfile) = @_; |
# and select recent are created in lonpubdir.pm |
if ($trailfile eq '') { |
my ($uname,$thisdisfn)= |
$trailfile = $env{'request.filename'}; |
($env{'request.filename'} =~ m|^/home/([^/]+)/public_html/(.*)|); |
} |
my $formaction='/priv/'.$uname.'/'.$thisdisfn; |
|
$formaction=~s/\/+/\//g; |
# this is for resources; directories have customtitle, and crumbs |
|
# and select recent are created in lonpubdir.pm |
|
|
|
my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'}; |
|
my ($udom,$uname,$thisdisfn)= |
|
($trailfile =~ m{^\Q$londocroot\E/priv/([^/]+)/([^/]+)(?:|/(.*))$}); |
|
my $formaction = "/priv/$udom/$uname/$thisdisfn"; |
|
$formaction =~ s{/+}{/}g; |
|
|
my $parentpath = ''; |
my $parentpath = ''; |
my $lastitem = ''; |
my $lastitem = ''; |
Line 4493 sub CSTR_pageheader {
|
Line 5023 sub CSTR_pageheader {
|
.'<b>'.&mt('Construction Space:').'</b> ' |
.'<b>'.&mt('Construction Space:').'</b> ' |
.'<form name="dirs" method="post" action="'.$formaction |
.'<form name="dirs" method="post" action="'.$formaction |
.'" target="_top">' #FIXME lonpubdir: target="_parent" |
.'" target="_top">' #FIXME lonpubdir: target="_parent" |
.&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,'_top','/priv',undef,undef); |
.&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,'_top','/priv/'.$udom,undef,undef); |
|
|
if ($lastitem) { |
if ($lastitem) { |
$output .= |
$output .= |
Line 4555 Inputs:
|
Line 5085 Inputs:
|
should it have jsmath forced on by the |
should it have jsmath forced on by the |
current page |
current page |
|
|
|
=item * $advtoolsref, optional argument, ref to an array containing |
|
inlineremote items to be added in "Functions" menu below |
|
breadcrumbs. |
|
|
=back |
=back |
|
|
Returns: A uniform header for LON-CAPA web pages. |
Returns: A uniform header for LON-CAPA web pages. |
Line 4566 other decorations will be returned.
|
Line 5100 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)=@_; |
$no_nav_bar,$bgcolor,$args,$advtoolsref)=@_; |
|
|
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 4623 sub bodytag {
|
Line 5157 sub bodytag {
|
if ($public) { |
if ($public) { |
undef($role); |
undef($role); |
} else { |
} else { |
$name = &aboutmewrapper($name,$env{'user.name'},$env{'user.domain'}); |
$name = &aboutmewrapper($name,$env{'user.name'},$env{'user.domain'}, |
|
undef,'LC_menubuttons_link'); |
} |
} |
|
|
my $titleinfo = '<h1>'.$title.'</h1>'; |
my $titleinfo = '<h1>'.$title.'</h1>'; |
Line 4684 sub bodytag {
|
Line 5219 sub bodytag {
|
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'}); |
} elsif ($forcereg) { |
} elsif ($forcereg) { |
$bodytag .= &Apache::lonmenu::innerregister($forcereg); |
$bodytag .= &Apache::lonmenu::innerregister($forcereg,undef, |
|
$args->{'group'}); |
|
} else { |
|
$bodytag .= |
|
&Apache::lonmenu::prepare_functions($env{'request.noversionuri'}, |
|
$forcereg,$args->{'group'}, |
|
$args->{'bread_crumbs'}, |
|
$advtoolsref); |
} |
} |
}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 4699 sub bodytag {
|
Line 5241 sub bodytag {
|
|
|
sub dc_courseid_toggle { |
sub dc_courseid_toggle { |
my ($dc_info) = @_; |
my ($dc_info) = @_; |
return ' <span id="dccidtext" class="LC_cusr_subheading">'. |
return ' <span id="dccidtext" class="LC_cusr_subheading LC_nobreak">'. |
'<a href="javascript:showCourseID();">'. |
'<a href="javascript:showCourseID();" class="LC_menubuttons_link">'. |
&mt('(More ...)').'</a></span>'. |
&mt('(More ...)').'</a></span>'. |
'<div id="dccid" class="LC_dccid">'.$dc_info.'</div>'; |
'<div id="dccid" class="LC_dccid">'.$dc_info.'</div>'; |
} |
} |
Line 4757 i.e., $env{'internal.head.redirect'} exi
|
Line 5299 i.e., $env{'internal.head.redirect'} exi
|
|
|
sub endbodytag { |
sub endbodytag { |
my ($args) = @_; |
my ($args) = @_; |
my $endbodytag='</body>'; |
my $endbodytag; |
|
unless ((ref($args) eq 'HASH') && ($args->{'notbody'})) { |
|
$endbodytag='</body>'; |
|
} |
$endbodytag=&Apache::lontexconvert::jsMath_process()."\n".$endbodytag; |
$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'})) { |
Line 4805 sub standard_css {
|
Line 5350 sub standard_css {
|
my $mono = 'monospace'; |
my $mono = 'monospace'; |
my $data_table_head = $sidebg; |
my $data_table_head = $sidebg; |
my $data_table_light = '#FAFAFA'; |
my $data_table_light = '#FAFAFA'; |
my $data_table_dark = '#F0F0F0'; |
my $data_table_dark = '#E0E0E0'; |
my $data_table_darker = '#CCCCCC'; |
my $data_table_darker = '#CCCCCC'; |
my $data_table_highlight = '#FFFF00'; |
my $data_table_highlight = '#FFFF00'; |
my $mail_new = '#FFBB77'; |
my $mail_new = '#FFBB77'; |
Line 4845 body {
|
Line 5390 body {
|
a:focus, |
a:focus, |
a:focus img { |
a:focus img { |
color: red; |
color: red; |
background: yellow; |
|
} |
} |
|
|
form, .inline { |
form, .inline { |
Line 4892 form, .inline {
|
Line 5436 form, .inline {
|
text-decoration:none; |
text-decoration:none; |
} |
} |
|
|
|
.LC_setting { |
|
text-decoration:underline; |
|
} |
|
|
.LC_error { |
.LC_error { |
color: red; |
color: red; |
font-size: larger; |
|
} |
} |
|
|
.LC_warning, |
.LC_warning { |
|
color: darkorange; |
|
} |
|
|
.LC_diff_removed { |
.LC_diff_removed { |
color: red; |
color: red; |
} |
} |
Line 4936 div.LC_confirm_box .LC_success img {
|
Line 5486 div.LC_confirm_box .LC_success img {
|
} |
} |
|
|
.LC_discussion { |
.LC_discussion { |
background: $tabbg; |
background: $data_table_dark; |
border: 1px solid black; |
border: 1px solid black; |
margin: 2px; |
margin: 2px; |
} |
} |
|
|
.LC_disc_action_links_bar { |
|
background: $tabbg; |
|
border: none; |
|
margin: 4px; |
|
} |
|
|
|
.LC_disc_action_left { |
.LC_disc_action_left { |
|
background: $sidebg; |
text-align: left; |
text-align: left; |
|
padding: 4px; |
|
margin: 2px; |
} |
} |
|
|
.LC_disc_action_right { |
.LC_disc_action_right { |
|
background: $sidebg; |
text-align: right; |
text-align: right; |
|
padding: 4px; |
|
margin: 2px; |
} |
} |
|
|
.LC_disc_new_item { |
.LC_disc_new_item { |
background: white; |
background: white; |
border: 2px solid red; |
border: 2px solid red; |
margin: 2px; |
margin: 4px; |
|
padding: 4px; |
} |
} |
|
|
.LC_disc_old_item { |
.LC_disc_old_item { |
background: white; |
background: white; |
border: 1px solid black; |
margin: 4px; |
margin: 2px; |
padding: 4px; |
} |
} |
|
|
table.LC_pastsubmission { |
table.LC_pastsubmission { |
Line 5056 td.LC_table_cell_checkbox {
|
Line 5607 td.LC_table_cell_checkbox {
|
overflow: hidden; |
overflow: hidden; |
margin: 0; |
margin: 0; |
padding: 0; |
padding: 0; |
|
text-align: left; |
} |
} |
|
|
#LC_head_subbox { |
.LC_head_subbox, .LC_actionbox { |
clear:both; |
clear:both; |
background: #F8F8F8; /* $sidebg; */ |
background: #F8F8F8; /* $sidebg; */ |
border: 1px solid $sidebg; |
border: 1px solid $sidebg; |
margin: 0 0 10px 0; |
margin: 0 0 10px 0; |
padding: 3px; |
padding: 3px; |
|
text-align: left; |
} |
} |
|
|
.LC_fontsize_medium { |
.LC_fontsize_medium { |
Line 5084 td.LC_table_cell_checkbox {
|
Line 5637 td.LC_table_cell_checkbox {
|
vertical-align: middle; |
vertical-align: middle; |
} |
} |
|
|
li.LC_menubuttons_inline_text img,a { |
li.LC_menubuttons_inline_text img { |
cursor:pointer; |
cursor:pointer; |
|
text-decoration: none; |
} |
} |
|
|
.LC_menubuttons_link { |
.LC_menubuttons_link { |
Line 5133 table.LC_nested {
|
Line 5687 table.LC_nested {
|
width: 100%; |
width: 100%; |
} |
} |
|
|
.ui-accordion, |
|
.ui-accordion table.LC_data_table, |
|
.ui-accordion table.LC_nested_outer{ |
|
border: 0px; |
|
border-spacing: 0px; |
|
margin: 3px; |
|
} |
|
|
|
table.LC_data_table tr th, |
table.LC_data_table tr th, |
table.LC_calendar tr th, |
table.LC_calendar tr th, |
table.LC_prior_tries tr th, |
table.LC_prior_tries tr th, |
Line 5201 table.LC_nested tr.LC_empty_row td {
|
Line 5747 table.LC_nested tr.LC_empty_row td {
|
padding: 8px; |
padding: 8px; |
} |
} |
|
|
table.LC_data_table tr.LC_empty_row td { |
table.LC_data_table tr.LC_empty_row td, |
|
table.LC_data_table tr.LC_footer_row td { |
background-color: $sidebg; |
background-color: $sidebg; |
} |
} |
|
|
Line 5256 table.LC_nested tr td.LC_right_item {
|
Line 5803 table.LC_nested tr td.LC_right_item {
|
text-align: right; |
text-align: right; |
} |
} |
|
|
.ui-accordion table.LC_nested tr.LC_odd_row td.LC_left_item, |
|
.ui-accordion table.LC_nested tr.LC_even_row td.LC_left_item { |
|
text-align: right; |
|
width: 40%; |
|
padding-right:10px; |
|
vertical-align: top; |
|
padding: 5px; |
|
} |
|
|
|
.ui-accordion table.LC_nested tr.LC_odd_row td.LC_right_item, |
|
.ui-accordion table.LC_nested tr.LC_even_row td.LC_right_item { |
|
text-align: left; |
|
width: 60%; |
|
padding: 2px 4px; |
|
} |
|
|
|
table.LC_nested tr.LC_odd_row td { |
table.LC_nested tr.LC_odd_row td { |
background-color: #EEEEEE; |
background-color: #EEEEEE; |
} |
} |
Line 5403 span.LC_current_location {
|
Line 5934 span.LC_current_location {
|
background: $pgbg; |
background: $pgbg; |
} |
} |
|
|
|
span.LC_current_nav_location { |
|
font-weight:bold; |
|
background: $sidebg; |
|
} |
|
|
span.LC_parm_menu_item { |
span.LC_parm_menu_item { |
font-size: larger; |
font-size: larger; |
} |
} |
Line 5774 div.LC_docs_entry_move {
|
Line 6310 div.LC_docs_entry_move {
|
|
|
table.LC_data_table tr > td.LC_docs_entry_commands, |
table.LC_data_table tr > td.LC_docs_entry_commands, |
table.LC_data_table tr > td.LC_docs_entry_parameter { |
table.LC_data_table tr > td.LC_docs_entry_parameter { |
background: #DDDDDD; |
|
font-size: x-small; |
font-size: x-small; |
} |
} |
|
|
Line 5904 div.LC_edit_problem_footer {
|
Line 6439 div.LC_edit_problem_footer {
|
font-weight: normal; |
font-weight: normal; |
font-size: medium; |
font-size: medium; |
margin: 2px; |
margin: 2px; |
|
background-color: $sidebg; |
} |
} |
|
|
div.LC_edit_problem_header, |
div.LC_edit_problem_header, |
Line 5920 div.LC_edit_problem_header_title {
|
Line 6456 div.LC_edit_problem_header_title {
|
font-size: larger; |
font-size: larger; |
background: $tabbg; |
background: $tabbg; |
padding: 3px; |
padding: 3px; |
|
margin: 0 0 5px 0; |
} |
} |
|
|
table.LC_edit_problem_header_title { |
table.LC_edit_problem_header_title { |
Line 5957 div.LC_createcourse {
|
Line 6494 div.LC_createcourse {
|
display:none; |
display:none; |
} |
} |
|
|
a:hover, |
|
ol.LC_primary_menu a:hover, |
ol.LC_primary_menu a:hover, |
ol#LC_MenuBreadcrumbs a:hover, |
ol#LC_MenuBreadcrumbs a:hover, |
ol#LC_PathBreadcrumbs a:hover, |
ol#LC_PathBreadcrumbs a:hover, |
Line 6031 fieldset > legend {
|
Line 6567 fieldset > legend {
|
|
|
#LC_nav_bar { |
#LC_nav_bar { |
float: left; |
float: left; |
|
background-color: $pgbg_or_bgcolor; |
margin: 0 0 2px 0; |
margin: 0 0 2px 0; |
} |
} |
|
|
Line 6039 fieldset > legend {
|
Line 6576 fieldset > legend {
|
padding: 0; |
padding: 0; |
font-weight: bold; |
font-weight: bold; |
text-align: center; |
text-align: center; |
|
background-color: $pgbg_or_bgcolor; |
} |
} |
|
|
#LC_nav_bar em { |
#LC_nav_bar em { |
Line 6046 fieldset > legend {
|
Line 6584 fieldset > legend {
|
font-style: normal; |
font-style: normal; |
} |
} |
|
|
/* Preliminary fix to hide nav_bar inside bookmarks window */ |
|
#LC_bookmarks #LC_nav_bar { |
|
display:none; |
|
} |
|
|
|
ol.LC_primary_menu { |
ol.LC_primary_menu { |
float: right; |
float: right; |
margin: 0; |
margin: 0; |
|
padding: 0; |
|
background-color: $pgbg_or_bgcolor; |
} |
} |
|
|
ol#LC_PathBreadcrumbs { |
ol#LC_PathBreadcrumbs { |
Line 6061 ol#LC_PathBreadcrumbs {
|
Line 6596 ol#LC_PathBreadcrumbs {
|
} |
} |
|
|
ol.LC_primary_menu li { |
ol.LC_primary_menu li { |
display: inline; |
color: RGB(80, 80, 80); |
padding: 5px 5px 0 10px; |
vertical-align: middle; |
|
text-align: left; |
|
list-style: none; |
|
float: left; |
|
} |
|
|
|
ol.LC_primary_menu li a { |
|
display: block; |
|
margin: 0; |
|
padding: 0 5px 0 10px; |
|
text-decoration: none; |
|
} |
|
|
|
ol.LC_primary_menu li ul { |
|
display: none; |
|
width: 10em; |
|
background-color: $data_table_light; |
|
} |
|
|
|
ol.LC_primary_menu li:hover ul, ol.LC_primary_menu li.hover ul { |
|
display: block; |
|
position: absolute; |
|
margin: 0; |
|
padding: 0; |
|
z-index: 2; |
|
} |
|
|
|
ol.LC_primary_menu li:hover li, ol.LC_primary_menu li.hover li { |
|
font-size: 90%; |
vertical-align: top; |
vertical-align: top; |
|
float: none; |
|
border-left: 1px solid black; |
|
border-right: 1px solid black; |
|
} |
|
|
|
ol.LC_primary_menu li:hover li a, ol.LC_primary_menu li.hover li a { |
|
background-color:$data_table_light; |
|
} |
|
|
|
ol.LC_primary_menu li li a:hover { |
|
color:$button_hover; |
|
background-color:$data_table_dark; |
} |
} |
|
|
ol.LC_primary_menu li img { |
ol.LC_primary_menu li img { |
vertical-align: bottom; |
vertical-align: bottom; |
height: 1.1em; |
height: 1.1em; |
|
margin: 0.2em 0 0 0; |
} |
} |
|
|
ol.LC_primary_menu a { |
ol.LC_primary_menu a { |
Line 6106 ol.LC_docs_parameters li.LC_docs_paramet
|
Line 6682 ol.LC_docs_parameters li.LC_docs_paramet
|
} |
} |
|
|
ul#LC_secondary_menu { |
ul#LC_secondary_menu { |
clear: both; |
clear: right; |
color: $fontmenu; |
color: $fontmenu; |
background: $tabbg; |
background: $tabbg; |
list-style: none; |
list-style: none; |
padding: 0; |
padding: 0; |
margin: 0; |
margin: 0; |
width: 100%; |
width: 100%; |
|
text-align: left; |
|
float: left; |
} |
} |
|
|
ul#LC_secondary_menu li { |
ul#LC_secondary_menu li { |
font-weight: bold; |
font-weight: bold; |
line-height: 1.8em; |
line-height: 1.8em; |
|
border-right: 1px solid black; |
|
float: left; |
|
} |
|
|
|
ul#LC_secondary_menu li.LC_hoverable:hover, ul#LC_secondary_menu li.hover { |
|
background-color: $data_table_light; |
|
} |
|
|
|
ul#LC_secondary_menu li a { |
padding: 0 0.8em; |
padding: 0 0.8em; |
|
} |
|
|
|
ul#LC_secondary_menu li ul { |
|
display: none; |
|
} |
|
|
|
ul#LC_secondary_menu li:hover ul, ul#LC_secondary_menu li.hover ul { |
|
display: block; |
|
position: absolute; |
|
margin: 0; |
|
padding: 0; |
|
list-style:none; |
|
float: none; |
|
background-color: $data_table_light; |
|
z-index: 2; |
|
margin-left: -1px; |
|
} |
|
|
|
ul#LC_secondary_menu li ul li { |
|
font-size: 90%; |
|
vertical-align: top; |
|
border-left: 1px solid black; |
border-right: 1px solid black; |
border-right: 1px solid black; |
display: inline; |
background-color: $data_table_light |
vertical-align: middle; |
list-style:none; |
|
float: none; |
|
} |
|
|
|
ul#LC_secondary_menu li ul li:hover, ul#LC_secondary_menu li ul li.hover { |
|
background-color: $data_table_dark; |
} |
} |
|
|
ul.LC_TabContent { |
ul.LC_TabContent { |
Line 6129 ul.LC_TabContent {
|
Line 6743 ul.LC_TabContent {
|
background: $sidebg; |
background: $sidebg; |
border-bottom: solid 1px $lg_border_color; |
border-bottom: solid 1px $lg_border_color; |
list-style:none; |
list-style:none; |
margin: 0 -10px; |
margin: -1px -10px 0 -10px; |
padding: 0; |
padding: 0; |
} |
} |
|
|
Line 6152 ul.LC_TabContent li {
|
Line 6766 ul.LC_TabContent li {
|
padding: 0 16px 0 10px; |
padding: 0 16px 0 10px; |
background-color:$tabbg; |
background-color:$tabbg; |
border-bottom:solid 1px $lg_border_color; |
border-bottom:solid 1px $lg_border_color; |
border-right: solid 1px $font; |
border-left: solid 1px $font; |
} |
} |
|
|
ul.LC_TabContent .right { |
ul.LC_TabContent .right { |
Line 6192 ul.LC_TabContent li.active a {
|
Line 6806 ul.LC_TabContent li.active a {
|
background:#FFFFFF; |
background:#FFFFFF; |
outline: none; |
outline: none; |
} |
} |
|
|
|
ul.LC_TabContent li.goback { |
|
float: left; |
|
border-left: none; |
|
} |
|
|
#maincoursedoc { |
#maincoursedoc { |
clear:both; |
clear:both; |
} |
} |
Line 6246 ul.LC_TabContentBigger li.active b {
|
Line 6866 ul.LC_TabContentBigger li.active b {
|
background:url('/adm/lonIcons/tabbgright.gif') right top no-repeat; |
background:url('/adm/lonIcons/tabbgright.gif') right top no-repeat; |
color:$font; |
color:$font; |
border: 0; |
border: 0; |
cursor:default; |
|
} |
} |
|
|
|
|
ul.LC_CourseBreadcrumbs { |
ul.LC_CourseBreadcrumbs { |
background: $sidebg; |
background: $sidebg; |
line-height: 32px; |
height: 2em; |
padding-left: 10px; |
padding-left: 10px; |
margin: 0 0 10px 0; |
margin: 0; |
list-style-position: inside; |
list-style-position: inside; |
|
|
} |
} |
|
|
ol#LC_MenuBreadcrumbs, |
ol#LC_MenuBreadcrumbs, |
Line 6298 ol#LC_PathBreadcrumbs li a {
|
Line 6916 ol#LC_PathBreadcrumbs li a {
|
padding: 0 10px 10px 10px; |
padding: 0 10px 10px 10px; |
} |
} |
|
|
|
.LC_DocsBox { |
|
border: solid 1px $lg_border_color; |
|
padding: 0 0 10px 10px; |
|
} |
|
|
.LC_AboutMe_Image { |
.LC_AboutMe_Image { |
float:left; |
float:left; |
margin-right:10px; |
margin-right:10px; |
Line 6438 a#LC_content_toolbar_changefolder_toggle
|
Line 7061 a#LC_content_toolbar_changefolder_toggle
|
background-image:url(/res/adm/pages/open-all-folders.gif); |
background-image:url(/res/adm/pages/open-all-folders.gif); |
} |
} |
|
|
|
a#LC_content_toolbar_edittoplevel { |
|
background-image:url(/res/adm/pages/edittoplevel.gif); |
|
} |
|
|
ul#LC_toolbar li a:hover { |
ul#LC_toolbar li a:hover { |
background-position: bottom center; |
background-position: bottom center; |
} |
} |
Line 6448 ul#LC_toolbar {
|
Line 7075 ul#LC_toolbar {
|
list-style:none; |
list-style:none; |
position:relative; |
position:relative; |
background-color:white; |
background-color:white; |
|
overflow: auto; |
} |
} |
|
|
ul#LC_toolbar li { |
ul#LC_toolbar li { |
Line 6457 ul#LC_toolbar li {
|
Line 7085 ul#LC_toolbar li {
|
float: left; |
float: left; |
display:inline; |
display:inline; |
vertical-align:middle; |
vertical-align:middle; |
|
white-space: nowrap; |
} |
} |
|
|
|
|
Line 6502 ul.LC_funclist li {
|
Line 7131 ul.LC_funclist li {
|
line-height: 150%; |
line-height: 150%; |
} |
} |
|
|
.ui-accordion .LC_advanced_toggle { |
|
float: right; |
|
font-size: 90%; |
|
padding: 0px 4px |
|
} |
|
|
|
.LC_hidden { |
.LC_hidden { |
display: none; |
display: none; |
} |
} |
|
|
|
.LCmodal-overlay { |
|
position:fixed; |
|
top:0; |
|
right:0; |
|
bottom:0; |
|
left:0; |
|
height:100%; |
|
width:100%; |
|
margin:0; |
|
padding:0; |
|
background:#999; |
|
opacity:.75; |
|
filter: alpha(opacity=75); |
|
-moz-opacity: 0.75; |
|
z-index:101; |
|
} |
|
|
|
* html .LCmodal-overlay { |
|
position: absolute; |
|
height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'); |
|
} |
|
|
|
.LCmodal-window { |
|
position:fixed; |
|
top:50%; |
|
left:50%; |
|
margin:0; |
|
padding:0; |
|
z-index:102; |
|
} |
|
|
|
* html .LCmodal-window { |
|
position:absolute; |
|
} |
|
|
|
.LCclose-window { |
|
position:absolute; |
|
width:32px; |
|
height:32px; |
|
right:8px; |
|
top:8px; |
|
background:transparent url('/res/adm/pages/process-stop.png') no-repeat scroll right top; |
|
text-indent:-99999px; |
|
overflow:hidden; |
|
cursor:pointer; |
|
} |
|
|
|
/* |
|
styles used by TTH when "Default set of options to pass to tth/m |
|
when converting TeX" in course settings has been set |
|
|
|
option passed: -t |
|
|
|
*/ |
|
|
|
td div.comp { margin-top: -0.6ex; margin-bottom: -1ex;} |
|
td div.comb { margin-top: -0.6ex; margin-bottom: -.6ex;} |
|
td div.hrcomp { line-height: 0.9; margin-top: -0.8ex; margin-bottom: -1ex;} |
|
td div.norm {line-height:normal;} |
|
|
|
/* |
|
option passed -y3 |
|
*/ |
|
|
|
span.roman {font-family: serif; font-style: normal; font-weight: normal;} |
|
span.overacc2 {position: relative; left: .8em; top: -1.2ex;} |
|
span.overacc1 {position: relative; left: .6em; top: -1.2ex;} |
|
|
END |
END |
} |
} |
|
|
Line 6560 sub headtag {
|
Line 7251 sub headtag {
|
'<head>'. |
'<head>'. |
&font_settings(); |
&font_settings(); |
|
|
|
my $inhibitprint = &print_suppression(); |
|
|
if (!$args->{'frameset'}) { |
if (!$args->{'frameset'}) { |
$result .= &Apache::lonhtmlcommon::htmlareaheaders(); |
$result .= &Apache::lonhtmlcommon::htmlareaheaders(); |
} |
} |
Line 6570 sub headtag {
|
Line 7263 sub headtag {
|
&& !$args->{'only_body'} |
&& !$args->{'only_body'} |
&& !$args->{'frameset'}) { |
&& !$args->{'frameset'}) { |
$result .= &help_menu_js(); |
$result .= &help_menu_js(); |
|
$result.=&modal_window(); |
|
$result.=&togglebox_script(); |
|
$result.=&wishlist_window(); |
|
$result.=&LCprogressbarUpdate_script(); |
|
} else { |
|
if ($args->{'add_modal'}) { |
|
$result.=&modal_window(); |
|
} |
|
if ($args->{'add_wishlist'}) { |
|
$result.=&wishlist_window(); |
|
} |
|
if ($args->{'add_togglebox'}) { |
|
$result.=&togglebox_script(); |
|
} |
|
if ($args->{'add_progressbar'}) { |
|
$result.=&LCprogressbarUpdate_script(); |
|
} |
} |
} |
|
|
if (ref($args->{'redirect'})) { |
if (ref($args->{'redirect'})) { |
my ($time,$url,$inhibit_continue) = @{$args->{'redirect'}}; |
my ($time,$url,$inhibit_continue) = @{$args->{'redirect'}}; |
$url = &Apache::lonenc::check_encrypt($url); |
$url = &Apache::lonenc::check_encrypt($url); |
Line 6589 ADDMETA
|
Line 7298 ADDMETA
|
if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); } |
if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); } |
$result .= '<title> LON-CAPA '.$title.'</title>' |
$result .= '<title> LON-CAPA '.$title.'</title>' |
.'<link rel="stylesheet" type="text/css" href="'.$url.'" />' |
.'<link rel="stylesheet" type="text/css" href="'.$url.'" />' |
|
.$inhibitprint |
.$head_extra; |
.$head_extra; |
return $result.'</head>'; |
return $result.'</head>'; |
} |
} |
Line 6614 sub font_settings {
|
Line 7324 sub font_settings {
|
|
|
=pod |
=pod |
|
|
|
=item * &print_suppression() |
|
|
|
In course context returns css which causes the body to be blank when media="print", |
|
if printout generation is unavailable for the current resource. |
|
|
|
This could be because: |
|
|
|
(a) printstartdate is in the future |
|
|
|
(b) printenddate is in the past |
|
|
|
(c) there is an active exam block with "printout" |
|
functionality blocked |
|
|
|
Users with pav, pfo or evb privileges are exempt. |
|
|
|
Inputs: none |
|
|
|
=cut |
|
|
|
|
|
sub print_suppression { |
|
my $noprint; |
|
if ($env{'request.course.id'}) { |
|
my $scope = $env{'request.course.id'}; |
|
if ((&Apache::lonnet::allowed('pav',$scope)) || |
|
(&Apache::lonnet::allowed('pfo',$scope))) { |
|
return; |
|
} |
|
if ($env{'request.course.sec'} ne '') { |
|
$scope .= "/$env{'request.course.sec'}"; |
|
if ((&Apache::lonnet::allowed('pav',$scope)) || |
|
(&Apache::lonnet::allowed('pfo',$scope))) { |
|
return; |
|
} |
|
} |
|
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
my $blocked = &blocking_status('printout',$cnum,$cdom); |
|
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})) { |
|
$noprint = 1; |
|
} |
|
} |
|
unless ($noprint) { |
|
my $symb = &Apache::lonnet::symbread(); |
|
if ($symb ne '') { |
|
my $navmap = Apache::lonnavmaps::navmap->new(); |
|
if (ref($navmap)) { |
|
my $res = $navmap->getBySymb($symb); |
|
if (ref($res)) { |
|
if (!$res->resprintable()) { |
|
$noprint = 1; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if ($noprint) { |
|
return <<"ENDSTYLE"; |
|
<style type="text/css" media="print"> |
|
body { display:none } |
|
</style> |
|
ENDSTYLE |
|
} |
|
} |
|
return; |
|
} |
|
|
|
=pod |
|
|
=item * &xml_begin() |
=item * &xml_begin() |
|
|
Returns the needed doctype and <html> |
Returns the needed doctype and <html> |
Line 6685 $args - additional optional args support
|
Line 7471 $args - additional optional args support
|
should it have jsmath forced on by the |
should it have jsmath forced on by the |
current page |
current page |
bread_crumbs -> Array containing breadcrumbs |
bread_crumbs -> Array containing breadcrumbs |
bread_crumbs_components -> if exists show it as headline else show only the breadcrumbs |
bread_crumbs_component -> if exists show it as headline else show only the breadcrumbs |
|
group -> includes the current group, if page is for a |
|
specific group |
|
|
=back |
=back |
|
|
Line 6696 $args - additional optional args support
|
Line 7484 $args - additional optional args support
|
sub start_page { |
sub start_page { |
my ($title,$head_extra,$args) = @_; |
my ($title,$head_extra,$args) = @_; |
#&Apache::lonnet::logthis("start_page ".join(':',caller(0))); |
#&Apache::lonnet::logthis("start_page ".join(':',caller(0))); |
#SD |
|
#I don't see why we copy certain elements of %$args to %head_args |
|
#head args is passed to headtag() and this routine only reads those |
|
#keys that are needed. There doesn't happen any writes or any processing |
|
#of other keys. |
|
#proposal: just pass $args to headtag instead of \%head_args and delete |
|
#marked lines |
|
#<- MARK |
|
my %head_args; |
|
foreach my $arg ('redirect','force_register','domain','function', |
|
'bgcolor','frameset','no_nav_bar','only_body', |
|
'no_auto_mt_title') { |
|
if (defined($args->{$arg})) { |
|
$head_args{$arg} = $args->{$arg}; |
|
} |
|
} |
|
#MARK -> |
|
|
|
$env{'internal.start_page'}++; |
$env{'internal.start_page'}++; |
my $result; |
my ($result,@advtools); |
|
|
if (! exists($args->{'skip_phases'}{'head'}) ) { |
if (! exists($args->{'skip_phases'}{'head'}) ) { |
$result .= |
$result .= &xml_begin() . &headtag($title, $head_extra, $args); |
&xml_begin() . &headtag($title,$head_extra,\%head_args); |
|
#replace prev line by |
|
# &xml_begin() . &headtag($title, $head_extra, $args); |
|
} |
} |
|
|
if (! exists($args->{'skip_phases'}{'body'}) ) { |
if (! exists($args->{'skip_phases'}{'body'}) ) { |
Line 6735 sub start_page {
|
Line 7503 sub start_page {
|
$args->{'function'}, $args->{'add_entries'}, |
$args->{'function'}, $args->{'add_entries'}, |
$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); |
} |
} |
} |
} |
|
|
Line 6764 sub start_page {
|
Line 7533 sub start_page {
|
&Apache::lonhtmlcommon::add_breadcrumb($crumb); |
&Apache::lonhtmlcommon::add_breadcrumb($crumb); |
} |
} |
} |
} |
|
# if @advtools array contains items add then to the breadcrumbs |
|
if (@advtools > 0) { |
|
&Apache::lonmenu::advtools_crumbs(@advtools); |
|
} |
|
|
#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'})){ |
Line 6787 sub end_page {
|
Line 7560 sub end_page {
|
} |
} |
$result .= &Apache::lonxml::xmlend($target,$parser); |
$result .= &Apache::lonxml::xmlend($target,$parser); |
} |
} |
|
|
if ($args->{'frameset'}) { |
if ($args->{'frameset'}) { |
$result .= '</frameset>'; |
$result .= '</frameset>'; |
} else { |
} else { |
$result .= &endbodytag($args); |
$result .= &endbodytag($args); |
} |
} |
$result .= "\n</html>"; |
unless ($args->{'notbody'}) { |
|
$result .= "\n</html>"; |
|
} |
|
|
if ($args->{'js_ready'}) { |
if ($args->{'js_ready'}) { |
$result = &js_ready($result); |
$result = &js_ready($result); |
Line 6806 sub end_page {
|
Line 7580 sub end_page {
|
return $result; |
return $result; |
} |
} |
|
|
|
sub wishlist_window { |
|
return(<<'ENDWISHLIST'); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
// <!-- BEGIN LON-CAPA Internal |
|
function set_wishlistlink(title, path) { |
|
if (!title) { |
|
title = document.title; |
|
title = title.replace(/^LON-CAPA /,''); |
|
} |
|
if (!path) { |
|
path = location.pathname; |
|
} |
|
Win = window.open('/adm/wishlist?mode=newLink&setTitle='+title+'&setPath='+path, |
|
'wishlistNewLink','width=560,height=350,scrollbars=0'); |
|
} |
|
// END LON-CAPA Internal --> |
|
// ]]> |
|
</script> |
|
ENDWISHLIST |
|
} |
|
|
|
sub modal_window { |
|
return(<<'ENDMODAL'); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
// <!-- BEGIN LON-CAPA Internal |
|
var modalWindow = { |
|
parent:"body", |
|
windowId:null, |
|
content:null, |
|
width:null, |
|
height:null, |
|
close:function() |
|
{ |
|
$(".LCmodal-window").remove(); |
|
$(".LCmodal-overlay").remove(); |
|
}, |
|
open:function() |
|
{ |
|
var modal = ""; |
|
modal += "<div class=\"LCmodal-overlay\"></div>"; |
|
modal += "<div id=\"" + this.windowId + "\" class=\"LCmodal-window\" style=\"width:" + this.width + "px; height:" + this.height + "px; margin-top:-" + (this.height / 2) + "px; margin-left:-" + (this.width / 2) + "px;\">"; |
|
modal += this.content; |
|
modal += "</div>"; |
|
|
|
$(this.parent).append(modal); |
|
|
|
$(".LCmodal-window").append("<a class=\"LCclose-window\"></a>"); |
|
$(".LCclose-window").click(function(){modalWindow.close();}); |
|
$(".LCmodal-overlay").click(function(){modalWindow.close();}); |
|
} |
|
}; |
|
var openMyModal = function(source,width,height,scrolling) |
|
{ |
|
modalWindow.windowId = "myModal"; |
|
modalWindow.width = width; |
|
modalWindow.height = height; |
|
modalWindow.content = "<iframe width='"+width+"' height='"+height+"' frameborder='0' scrolling='"+scrolling+"' allowtransparency='true' src='" + source + "'></iframe>"; |
|
modalWindow.open(); |
|
}; |
|
// END LON-CAPA Internal --> |
|
// ]]> |
|
</script> |
|
ENDMODAL |
|
} |
|
|
|
sub modal_link { |
|
my ($link,$linktext,$width,$height,$target,$scrolling,$title)=@_; |
|
unless ($width) { $width=480; } |
|
unless ($height) { $height=400; } |
|
unless ($scrolling) { $scrolling='yes'; } |
|
my $target_attr; |
|
if (defined($target)) { |
|
$target_attr = 'target="'.$target.'"'; |
|
} |
|
return <<"ENDLINK"; |
|
<a href="$link" $target_attr title="$title" onclick="javascript:openMyModal('$link',$width,$height,'$scrolling'); return false;"> |
|
$linktext</a> |
|
ENDLINK |
|
} |
|
|
|
sub modal_adhoc_script { |
|
my ($funcname,$width,$height,$content)=@_; |
|
return (<<ENDADHOC); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
var $funcname = function() |
|
{ |
|
modalWindow.windowId = "myModal"; |
|
modalWindow.width = $width; |
|
modalWindow.height = $height; |
|
modalWindow.content = '$content'; |
|
modalWindow.open(); |
|
}; |
|
// ]]> |
|
</script> |
|
ENDADHOC |
|
} |
|
|
|
sub modal_adhoc_inner { |
|
my ($funcname,$width,$height,$content)=@_; |
|
my $innerwidth=$width-20; |
|
$content=&js_ready( |
|
&start_page('Dialog',undef,{'only_body'=>1,'bgcolor'=>'#FFFFFF'}). |
|
&start_scrollbox($width.'px',$innerwidth.'px',$height.'px'). |
|
$content. |
|
&end_scrollbox(). |
|
&end_page() |
|
); |
|
return &modal_adhoc_script($funcname,$width,$height,$content); |
|
} |
|
|
|
sub modal_adhoc_window { |
|
my ($funcname,$width,$height,$content,$linktext)=@_; |
|
return &modal_adhoc_inner($funcname,$width,$height,$content). |
|
"<a href=\"javascript:$funcname();void(0);\">".$linktext."</a>"; |
|
} |
|
|
|
sub modal_adhoc_launch { |
|
my ($funcname,$width,$height,$content)=@_; |
|
return &modal_adhoc_inner($funcname,$width,$height,$content).(<<ENDLAUNCH); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
$funcname(); |
|
// ]]> |
|
</script> |
|
ENDLAUNCH |
|
} |
|
|
|
sub modal_adhoc_close { |
|
return (<<ENDCLOSE); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
modalWindow.close(); |
|
// ]]> |
|
</script> |
|
ENDCLOSE |
|
} |
|
|
|
sub togglebox_script { |
|
return(<<ENDTOGGLE); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
function LCtoggleDisplay(id,hidetext,showtext) { |
|
link = document.getElementById(id + "link").childNodes[0]; |
|
with (document.getElementById(id).style) { |
|
if (display == "none" ) { |
|
display = "inline"; |
|
link.nodeValue = hidetext; |
|
} else { |
|
display = "none"; |
|
link.nodeValue = showtext; |
|
} |
|
} |
|
} |
|
// ]]> |
|
</script> |
|
ENDTOGGLE |
|
} |
|
|
|
sub start_togglebox { |
|
my ($id,$heading,$headerbg,$hidetext,$showtext)=@_; |
|
unless ($heading) { $heading=''; } else { $heading.=' '; } |
|
unless ($showtext) { $showtext=&mt('show'); } |
|
unless ($hidetext) { $hidetext=&mt('hide'); } |
|
unless ($headerbg) { $headerbg='#FFFFFF'; } |
|
return &start_data_table(). |
|
&start_data_table_header_row(). |
|
'<td bgcolor="'.$headerbg.'">'.$heading. |
|
'[<a id="'.$id.'link" href="javascript:LCtoggleDisplay(\''.$id.'\',\''.$hidetext.'\',\''. |
|
$showtext.'\')">'.$showtext.'</a>]</td>'. |
|
&end_data_table_header_row(). |
|
'<tr id="'.$id.'" style="display:none""><td>'; |
|
} |
|
|
|
sub end_togglebox { |
|
return '</td></tr>'.&end_data_table(); |
|
} |
|
|
|
sub LCprogressbar_script { |
|
my ($id)=@_; |
|
return(<<ENDPROGRESS); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
\$('#progressbar$id').progressbar({ |
|
value: 0, |
|
change: function(event, ui) { |
|
var newVal = \$(this).progressbar('option', 'value'); |
|
\$('.pblabel', this).text(LCprogressTxt); |
|
} |
|
}); |
|
// ]]> |
|
</script> |
|
ENDPROGRESS |
|
} |
|
|
|
sub LCprogressbarUpdate_script { |
|
return(<<ENDPROGRESSUPDATE); |
|
<style type="text/css"> |
|
.ui-progressbar { position:relative; } |
|
.pblabel { position: absolute; width: 100%; text-align: center; line-height: 1.9em; } |
|
</style> |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
var LCprogressTxt='---'; |
|
|
|
function LCupdateProgress(percent,progresstext,id) { |
|
LCprogressTxt=progresstext; |
|
\$('#progressbar'+id).progressbar('value',percent); |
|
} |
|
// ]]> |
|
</script> |
|
ENDPROGRESSUPDATE |
|
} |
|
|
|
my $LClastpercent; |
|
my $LCidcnt; |
|
my $LCcurrentid; |
|
|
|
sub LCprogressbar { |
|
my ($r)=(@_); |
|
$LClastpercent=0; |
|
$LCidcnt++; |
|
$LCcurrentid=$$.'_'.$LCidcnt; |
|
my $starting=&mt('Starting'); |
|
my $content=(<<ENDPROGBAR); |
|
<p> |
|
<div id="progressbar$LCcurrentid"> |
|
<span class="pblabel">$starting</span> |
|
</div> |
|
</p> |
|
ENDPROGBAR |
|
&r_print($r,$content.&LCprogressbar_script($LCcurrentid)); |
|
} |
|
|
|
sub LCprogressbarUpdate { |
|
my ($r,$val,$text)=@_; |
|
unless ($val) { |
|
if ($LClastpercent) { |
|
$val=$LClastpercent; |
|
} else { |
|
$val=0; |
|
} |
|
} |
|
if ($val<0) { $val=0; } |
|
if ($val>100) { $val=0; } |
|
$LClastpercent=$val; |
|
unless ($text) { $text=$val.'%'; } |
|
$text=&js_ready($text); |
|
&r_print($r,<<ENDUPDATE); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
LCupdateProgress($val,'$text','$LCcurrentid'); |
|
// ]]> |
|
</script> |
|
ENDUPDATE |
|
} |
|
|
|
sub LCprogressbarClose { |
|
my ($r)=@_; |
|
$LClastpercent=0; |
|
&r_print($r,<<ENDCLOSE); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
\$("#progressbar$LCcurrentid").hide('slow'); |
|
// ]]> |
|
</script> |
|
ENDCLOSE |
|
} |
|
|
|
sub r_print { |
|
my ($r,$to_print)=@_; |
|
if ($r) { |
|
$r->print($to_print); |
|
$r->rflush(); |
|
} else { |
|
print($to_print); |
|
} |
|
} |
|
|
sub html_encode { |
sub html_encode { |
my ($result) = @_; |
my ($result) = @_; |
|
|
Line 6813 sub html_encode {
|
Line 7868 sub html_encode {
|
|
|
return $result; |
return $result; |
} |
} |
|
|
sub js_ready { |
sub js_ready { |
my ($result) = @_; |
my ($result) = @_; |
|
|
Line 6849 sub validate_page {
|
Line 7905 sub validate_page {
|
} |
} |
} |
} |
|
|
|
|
|
sub start_scrollbox { |
|
my ($outerwidth,$width,$height,$id,$bgcolor)=@_; |
|
unless ($outerwidth) { $outerwidth='520px'; } |
|
unless ($width) { $width='500px'; } |
|
unless ($height) { $height='200px'; } |
|
my ($table_id,$div_id,$tdcol); |
|
if ($id ne '') { |
|
$table_id = " id='table_$id'"; |
|
$div_id = " id='div_$id'"; |
|
} |
|
if ($bgcolor ne '') { |
|
$tdcol = "background-color: $bgcolor;"; |
|
} |
|
return <<"END"; |
|
<table style="width: $outerwidth; border: 1px solid none;"$table_id><tr><td style="width: $width;$tdcol"><div style="overflow:auto; width:$width; height: $height;"$div_id> |
|
END |
|
} |
|
|
|
sub end_scrollbox { |
|
return '</div></td></tr></table>'; |
|
} |
|
|
sub simple_error_page { |
sub simple_error_page { |
my ($r,$title,$msg) = @_; |
my ($r,$title,$msg) = @_; |
my $page = |
my $page = |
&Apache::loncommon::start_page($title). |
&Apache::loncommon::start_page($title). |
&mt($msg). |
'<p class="LC_error">'.&mt($msg).'</p>'. |
&Apache::loncommon::end_page(); |
&Apache::loncommon::end_page(); |
if (ref($r)) { |
if (ref($r)) { |
$r->print($page); |
$r->print($page); |
Line 6876 sub simple_error_page {
|
Line 7955 sub simple_error_page {
|
} |
} |
|
|
sub start_data_table { |
sub start_data_table { |
my ($add_class) = @_; |
my ($add_class,$id) = @_; |
my $css_class = (join(' ','LC_data_table',$add_class)); |
my $css_class = (join(' ','LC_data_table',$add_class)); |
|
my $table_id; |
|
if (defined($id)) { |
|
$table_id = ' id="'.$id.'"'; |
|
} |
&start_data_table_count(); |
&start_data_table_count(); |
return '<table class="'.$css_class.'">'."\n"; |
return '<table class="'.$css_class.'"'.$table_id.'>'."\n"; |
} |
} |
|
|
sub end_data_table { |
sub end_data_table { |
Line 7006 sub get_users_function {
|
Line 8089 sub get_users_function {
|
$function='admin'; |
$function='admin'; |
} |
} |
if (($env{'request.role'}=~/^(au|ca|aa)/) || |
if (($env{'request.role'}=~/^(au|ca|aa)/) || |
($ENV{'REQUEST_URI'}=~/^(\/priv|\~)/)) { |
($ENV{'REQUEST_URI'}=~ m{/^(/priv)})) { |
$function='author'; |
$function='author'; |
} |
} |
return $function; |
return $function; |
Line 7142 sub get_sections {
|
Line 8225 sub get_sections {
|
my %sectioncount; |
my %sectioncount; |
my $now = time; |
my $now = time; |
|
|
if (!defined($possible_roles) || (grep(/^st$/,@$possible_roles))) { |
my $check_students = 1; |
|
my $only_students = 0; |
|
if (ref($possible_roles) eq 'ARRAY') { |
|
if (grep(/^st$/,@{$possible_roles})) { |
|
if (@{$possible_roles} == 1) { |
|
$only_students = 1; |
|
} |
|
} else { |
|
$check_students = 0; |
|
} |
|
} |
|
|
|
if ($check_students) { |
my ($classlist) = &Apache::loncoursedata::get_classlist($cdom,$cnum); |
my ($classlist) = &Apache::loncoursedata::get_classlist($cdom,$cnum); |
my $sec_index = &Apache::loncoursedata::CL_SECTION(); |
my $sec_index = &Apache::loncoursedata::CL_SECTION(); |
my $status_index = &Apache::loncoursedata::CL_STATUS(); |
my $status_index = &Apache::loncoursedata::CL_STATUS(); |
Line 7169 sub get_sections {
|
Line 8264 sub get_sections {
|
} |
} |
} |
} |
} |
} |
|
if ($only_students) { |
|
return %sectioncount; |
|
} |
my %courseroles = &Apache::lonnet::dump('nohist_userroles',$cdom,$cnum); |
my %courseroles = &Apache::lonnet::dump('nohist_userroles',$cdom,$cnum); |
foreach my $user (sort(keys(%courseroles))) { |
foreach my $user (sort(keys(%courseroles))) { |
if ($user !~ /^(\w{2})/) { next; } |
if ($user !~ /^(\w{2})/) { next; } |
Line 7647 sub get_secgrprole_info {
|
Line 8745 sub get_secgrprole_info {
|
} |
} |
|
|
sub user_picker { |
sub user_picker { |
my ($dom,$srch,$forcenewuser,$caller,$cancreate,$usertype) = @_; |
my ($dom,$srch,$forcenewuser,$caller,$cancreate,$usertype,$context) = @_; |
my $currdom = $dom; |
my $currdom = $dom; |
my %curr_selected = ( |
my %curr_selected = ( |
srchin => 'dom', |
srchin => 'dom', |
Line 7738 sub user_picker {
|
Line 8836 sub user_picker {
|
$srchtypesel .= "\n </select>\n"; |
$srchtypesel .= "\n </select>\n"; |
|
|
my ($newuserscript,$new_user_create); |
my ($newuserscript,$new_user_create); |
|
my $context_dom = $env{'request.role.domain'}; |
|
if ($context eq 'requestcrs') { |
|
if ($env{'form.coursedom'} ne '') { |
|
$context_dom = $env{'form.coursedom'}; |
|
} |
|
} |
if ($forcenewuser) { |
if ($forcenewuser) { |
if (ref($srch) eq 'HASH') { |
if (ref($srch) eq 'HASH') { |
if ($srch->{'srchby'} eq 'uname' && $srch->{'srchtype'} eq 'exact' && $srch->{'srchin'} eq 'dom' && $srch->{'srchdomain'} eq $env{'request.role.domain'}) { |
if ($srch->{'srchby'} eq 'uname' && $srch->{'srchtype'} eq 'exact' && $srch->{'srchin'} eq 'dom' && $srch->{'srchdomain'} eq $context_dom) { |
if ($cancreate) { |
if ($cancreate) { |
$new_user_create = '<p> <input type="submit" name="forcenew" value="'.&HTML::Entities::encode(&mt('Make new user "[_1]"',$srchterm),'<>&"').'" onclick="javascript:setSearch(\'1\','.$caller.');" /> </p>'; |
$new_user_create = '<p> <input type="submit" name="forcenew" value="'.&HTML::Entities::encode(&mt('Make new user "[_1]"',$srchterm),'<>&"').'" onclick="javascript:setSearch(\'1\','.$caller.');" /> </p>'; |
} else { |
} else { |
Line 7780 function setSearch(createnew,callingForm
|
Line 8883 function setSearch(createnew,callingForm
|
} |
} |
} |
} |
for (var i=0; i<callingForm.srchdomain.length; i++) { |
for (var i=0; i<callingForm.srchdomain.length; i++) { |
if (callingForm.srchdomain.options[i].value == '$env{'request.role.domain'}') { |
if (callingForm.srchdomain.options[i].value == '$context_dom') { |
callingForm.srchdomain.selectedIndex = i; |
callingForm.srchdomain.selectedIndex = i; |
} |
} |
} |
} |
Line 7961 sub user_rule_formats {
|
Line 9064 sub user_rule_formats {
|
my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($domain,$check); |
my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($domain,$check); |
if ((ref($rules) eq 'HASH') && (ref($ruleorder) eq 'ARRAY')) { |
if ((ref($rules) eq 'HASH') && (ref($ruleorder) eq 'ARRAY')) { |
if (@{$ruleorder} > 0) { |
if (@{$ruleorder} > 0) { |
$output = '<br />'.&mt("$text{$check} with the following format(s) may <span class=\"LC_cusr_emph\">only</span> be used for verified users at [_1]:",$domdesc).' <ul>'; |
$output = '<br />'. |
|
&mt($text{$check}.' with the following format(s) may [_1]only[_2] be used for verified users at [_3]:', |
|
'<span class="LC_cusr_emph">','</span>',$domdesc). |
|
' <ul>'; |
foreach my $rule (@{$ruleorder}) { |
foreach my $rule (@{$ruleorder}) { |
if (ref($curr_rules) eq 'ARRAY') { |
if (ref($curr_rules) eq 'ARRAY') { |
if (grep(/^\Q$rule\E$/,@{$curr_rules})) { |
if (grep(/^\Q$rule\E$/,@{$curr_rules})) { |
Line 8115 sub get_standard_codeitems {
|
Line 9221 sub get_standard_codeitems {
|
|
|
=item * sorted_slots() |
=item * sorted_slots() |
|
|
Sorts an array of slot names in order of slot start time (earliest first). |
Sorts an array of slot names in order of an optional sort key, |
|
default sort is by slot start time (earliest first). |
|
|
Inputs: |
Inputs: |
|
|
Line 8125 slotsarr - Reference to array of unsort
|
Line 9232 slotsarr - Reference to array of unsort
|
|
|
slots - Reference to hash of hash, where outer hash keys are slot names. |
slots - Reference to hash of hash, where outer hash keys are slot names. |
|
|
|
sortkey - Name of key in inner hash to be sorted on (e.g., starttime). |
|
|
=back |
=back |
|
|
Returns: |
Returns: |
|
|
=over 4 |
=over 4 |
|
|
sorted - An array of slot names sorted by the start time of the slot. |
sorted - An array of slot names sorted by a specified sort key |
|
(default sort key is start time of the slot). |
=back |
|
|
|
=back |
=back |
|
|
Line 8141 sorted - An array of slot names sorted
|
Line 9249 sorted - An array of slot names sorted
|
|
|
|
|
sub sorted_slots { |
sub sorted_slots { |
my ($slotsarr,$slots) = @_; |
my ($slotsarr,$slots,$sortkey) = @_; |
|
if ($sortkey eq '') { |
|
$sortkey = 'starttime'; |
|
} |
my @sorted; |
my @sorted; |
if ((ref($slotsarr) eq 'ARRAY') && (ref($slots) eq 'HASH')) { |
if ((ref($slotsarr) eq 'ARRAY') && (ref($slots) eq 'HASH')) { |
@sorted = |
@sorted = |
sort { |
sort { |
if (ref($slots->{$a}) && ref($slots->{$b})) { |
if (ref($slots->{$a}) && ref($slots->{$b})) { |
return $slots->{$a}{'starttime'} <=> $slots->{$b}{'starttime'} |
return $slots->{$a}{$sortkey} <=> $slots->{$b}{$sortkey} |
} |
} |
if (ref($slots->{$a})) { return -1;} |
if (ref($slots->{$a})) { return -1;} |
if (ref($slots->{$b})) { return 1;} |
if (ref($slots->{$b})) { return 1;} |
Line 8157 sub sorted_slots {
|
Line 9268 sub sorted_slots {
|
return @sorted; |
return @sorted; |
} |
} |
|
|
|
=pod |
|
|
|
=item * get_future_slots() |
|
|
|
Inputs: |
|
|
|
=over 4 |
|
|
|
cnum - course number |
|
|
|
cdom - course domain |
|
|
|
now - current UNIX time |
|
|
|
symb - optional symb |
|
|
|
=back |
|
|
|
Returns: |
|
|
|
=over 4 |
|
|
|
sorted_reservable - ref to array of student_schedulable slots currently |
|
reservable, ordered by end date of reservation period. |
|
|
|
reservable_now - ref to hash of student_schedulable slots currently |
|
reservable. |
|
|
|
Keys in inner hash are: |
|
(a) symb: either blank or symb to which slot use is restricted. |
|
(b) endreserve: end date of reservation period. |
|
|
|
sorted_future - ref to array of student_schedulable slots reservable in |
|
the future, ordered by start date of reservation period. |
|
|
|
future_reservable - ref to hash of student_schedulable slots reservable |
|
in the future. |
|
|
|
Keys in inner hash are: |
|
(a) symb: either blank or symb to which slot use is restricted. |
|
(b) startreserve: start date of reservation period. |
|
|
|
=back |
|
|
|
=cut |
|
|
|
sub get_future_slots { |
|
my ($cnum,$cdom,$now,$symb) = @_; |
|
my (%reservable_now,%future_reservable,@sorted_reservable,@sorted_future); |
|
my %slots = &Apache::lonnet::get_course_slots($cnum,$cdom); |
|
foreach my $slot (keys(%slots)) { |
|
next unless($slots{$slot}->{'type'} eq 'schedulable_student'); |
|
if ($symb) { |
|
next if (($slots{$slot}->{'symb'} ne '') && |
|
($slots{$slot}->{'symb'} ne $symb)); |
|
} |
|
if (($slots{$slot}->{'starttime'} > $now) && |
|
($slots{$slot}->{'endtime'} > $now)) { |
|
if (($slots{$slot}->{'allowedsections'}) || ($slots{$slot}->{'allowedusers'})) { |
|
my $userallowed = 0; |
|
if ($slots{$slot}->{'allowedsections'}) { |
|
my @allowed_sec = split(',',$slots{$slot}->{'allowedsections'}); |
|
if (!defined($env{'request.role.sec'}) |
|
&& grep(/^No section assigned$/,@allowed_sec)) { |
|
$userallowed=1; |
|
} else { |
|
if (grep(/^\Q$env{'request.role.sec'}\E$/,@allowed_sec)) { |
|
$userallowed=1; |
|
} |
|
} |
|
unless ($userallowed) { |
|
if (defined($env{'request.course.groups'})) { |
|
my @groups = split(/:/,$env{'request.course.groups'}); |
|
foreach my $group (@groups) { |
|
if (grep(/^\Q$group\E$/,@allowed_sec)) { |
|
$userallowed=1; |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if ($slots{$slot}->{'allowedusers'}) { |
|
my @allowed_users = split(',',$slots{$slot}->{'allowedusers'}); |
|
my $user = $env{'user.name'}.':'.$env{'user.domain'}; |
|
if (grep(/^\Q$user\E$/,@allowed_users)) { |
|
$userallowed = 1; |
|
} |
|
} |
|
next unless($userallowed); |
|
} |
|
my $startreserve = $slots{$slot}->{'startreserve'}; |
|
my $endreserve = $slots{$slot}->{'endreserve'}; |
|
my $symb = $slots{$slot}->{'symb'}; |
|
if (($startreserve < $now) && |
|
(!$endreserve || $endreserve > $now)) { |
|
my $lastres = $endreserve; |
|
if (!$lastres) { |
|
$lastres = $slots{$slot}->{'starttime'}; |
|
} |
|
$reservable_now{$slot} = { |
|
symb => $symb, |
|
endreserve => $lastres |
|
}; |
|
} elsif (($startreserve > $now) && |
|
(!$endreserve || $endreserve > $startreserve)) { |
|
$future_reservable{$slot} = { |
|
symb => $symb, |
|
startreserve => $startreserve |
|
}; |
|
} |
|
} |
|
} |
|
my @unsorted_reservable = keys(%reservable_now); |
|
if (@unsorted_reservable > 0) { |
|
@sorted_reservable = |
|
&sorted_slots(\@unsorted_reservable,\%reservable_now,'endreserve'); |
|
} |
|
my @unsorted_future = keys(%future_reservable); |
|
if (@unsorted_future > 0) { |
|
@sorted_future = |
|
&sorted_slots(\@unsorted_future,\%future_reservable,'startreserve'); |
|
} |
|
return (\@sorted_reservable,\%reservable_now,\@sorted_future,\%future_reservable); |
|
} |
|
|
=pod |
=pod |
|
|
|
=back |
|
|
=head1 HTTP Helpers |
=head1 HTTP Helpers |
|
|
=over 4 |
=over 4 |
Line 8298 sub get_env_multiple {
|
Line 9536 sub get_env_multiple {
|
|
|
sub ask_for_embedded_content { |
sub ask_for_embedded_content { |
my ($actionurl,$state,$allfiles,$codebase,$args)=@_; |
my ($actionurl,$state,$allfiles,$codebase,$args)=@_; |
my $upload_output = ' |
my (%subdependencies,%dependencies,%mapping,%existing,%newfiles,%pathchanges, |
<form name="upload_embedded" action="'.$actionurl.'" |
%currsubfile,%unused,$rem); |
method="post" enctype="multipart/form-data">'; |
my $counter = 0; |
$upload_output .= $state; |
my $numnew = 0; |
$upload_output .= '<b>Upload embedded files</b>:<br />'.&start_data_table(); |
my $numremref = 0; |
|
my $numinvalid = 0; |
|
my $numpathchg = 0; |
|
my $numexisting = 0; |
|
my $numunused = 0; |
|
my ($output,$upload_output,$toplevel,$url,$udom,$uname,$getpropath,$cdom,$cnum, |
|
$fileloc,$filename,$delete_output,$modify_output,$title,$symb,$path); |
|
my $heading = &mt('Upload embedded files'); |
|
my $buttontext = &mt('Upload'); |
|
|
my $num = 0; |
my $navmap; |
foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%{$allfiles})) { |
if ($env{'request.course.id'}) { |
|
$navmap = Apache::lonnavmaps::navmap->new(); |
|
} |
|
if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) { |
|
my $current_path='/'; |
|
if ($env{'form.currentpath'}) { |
|
$current_path = $env{'form.currentpath'}; |
|
} |
|
if ($actionurl eq '/adm/coursegrp_portfolio') { |
|
$udom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
$uname = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
$url = '/userfiles/groups/'.$env{'form.group'}.'/portfolio'; |
|
} else { |
|
$udom = $env{'user.domain'}; |
|
$uname = $env{'user.name'}; |
|
$url = '/userfiles/portfolio'; |
|
} |
|
$toplevel = $url.'/'; |
|
$url .= $current_path; |
|
$getpropath = 1; |
|
} elsif (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank') || |
|
($actionurl eq '/adm/imsimport')) { |
|
my ($udom,$uname,$rest) = ($args->{'current_path'} =~ m{/priv/($match_domain)/($match_username)/?(.*)$}); |
|
$url = $Apache::lonnet::perlvar{'lonDocRoot'}."/priv/$udom/$uname/"; |
|
$toplevel = $url; |
|
if ($rest ne '') { |
|
$url .= $rest; |
|
} |
|
} elsif ($actionurl eq '/adm/coursedocs') { |
|
if (ref($args) eq 'HASH') { |
|
$url = $args->{'docs_url'}; |
|
$toplevel = $url; |
|
if ($args->{'context'} eq 'paste') { |
|
($cdom,$cnum) = ($url =~ m{^\Q/uploaded/\E($match_domain)/($match_courseid)/}); |
|
($path) = |
|
($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/\E(?:docs|supplemental)/(?:default|\d+)/\d+)/}); |
|
$fileloc = &Apache::lonnet::filelocation('',$toplevel); |
|
$fileloc =~ s{^/}{}; |
|
} |
|
} |
|
} elsif ($actionurl eq '/adm/dependencies') { |
|
if ($env{'request.course.id'} ne '') { |
|
$cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
$cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
if (ref($args) eq 'HASH') { |
|
$url = $args->{'docs_url'}; |
|
$title = $args->{'docs_title'}; |
|
$toplevel = "/$url"; |
|
($rem) = ($toplevel =~ m{^(.+/)[^/]+$}); |
|
($path) = |
|
($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/\E(?:docs|supplemental)/(?:default|\d+)/\d+)/}); |
|
$fileloc = &Apache::lonnet::filelocation('',$toplevel); |
|
$fileloc =~ s{^/}{}; |
|
($filename) = ($fileloc =~ m{.+/([^/]+)$}); |
|
$heading = &mt('Status of dependencies in [_1]',"$title ($filename)"); |
|
} |
|
} |
|
} |
|
my $now = time(); |
|
foreach my $embed_file (keys(%{$allfiles})) { |
|
my $absolutepath; |
|
if ($embed_file =~ m{^\w+://}) { |
|
$newfiles{$embed_file} = 1; |
|
$mapping{$embed_file} = $embed_file; |
|
} else { |
|
if ($embed_file =~ m{^/}) { |
|
$absolutepath = $embed_file; |
|
$embed_file =~ s{^(/+)}{}; |
|
} |
|
if ($embed_file =~ m{/}) { |
|
my ($path,$fname) = ($embed_file =~ m{^(.+)/([^/]*)$}); |
|
$path = &check_for_traversal($path,$url,$toplevel); |
|
my $item = $fname; |
|
if ($path ne '') { |
|
$item = $path.'/'.$fname; |
|
$subdependencies{$path}{$fname} = 1; |
|
} else { |
|
$dependencies{$item} = 1; |
|
} |
|
if ($absolutepath) { |
|
$mapping{$item} = $absolutepath; |
|
} else { |
|
$mapping{$item} = $embed_file; |
|
} |
|
} else { |
|
$dependencies{$embed_file} = 1; |
|
if ($absolutepath) { |
|
$mapping{$embed_file} = $absolutepath; |
|
} else { |
|
$mapping{$embed_file} = $embed_file; |
|
} |
|
} |
|
} |
|
} |
|
my $dirptr = 16384; |
|
foreach my $path (keys(%subdependencies)) { |
|
$currsubfile{$path} = {}; |
|
if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) { |
|
my ($sublistref,$listerror) = |
|
&Apache::lonnet::dirlist($url.$path,$udom,$uname,$getpropath); |
|
if (ref($sublistref) eq 'ARRAY') { |
|
foreach my $line (@{$sublistref}) { |
|
my ($file_name,$rest) = split(/\&/,$line,2); |
|
$currsubfile{$path}{$file_name} = 1; |
|
} |
|
} |
|
} elsif (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank')) { |
|
if (opendir(my $dir,$url.'/'.$path)) { |
|
my @subdir_list = grep(!/^\./,readdir($dir)); |
|
map {$currsubfile{$path}{$_} = 1;} @subdir_list; |
|
} |
|
} elsif (($actionurl eq '/adm/dependencies') || |
|
(($actionurl eq '/adm/coursedocs') && (ref($args) eq 'HASH') && |
|
($args->{'context'} eq 'paste'))) { |
|
if ($env{'request.course.id'} ne '') { |
|
my ($dir) = ($fileloc =~ m{^(.+/)[^/]+$}); |
|
if ($dir ne '') { |
|
my ($sublistref,$listerror) = |
|
&Apache::lonnet::dirlist($dir.$path,$cdom,$cnum,$getpropath,undef,'/'); |
|
if (ref($sublistref) eq 'ARRAY') { |
|
foreach my $line (@{$sublistref}) { |
|
my ($file_name,$dom,undef,$testdir,undef,undef,undef,undef,$size, |
|
undef,$mtime)=split(/\&/,$line,12); |
|
unless (($testdir&$dirptr) || |
|
($file_name =~ /^\.\.?$/)) { |
|
$currsubfile{$path}{$file_name} = [$size,$mtime]; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
foreach my $file (keys(%{$subdependencies{$path}})) { |
|
if (exists($currsubfile{$path}{$file})) { |
|
my $item = $path.'/'.$file; |
|
unless ($mapping{$item} eq $item) { |
|
$pathchanges{$item} = 1; |
|
} |
|
$existing{$item} = 1; |
|
$numexisting ++; |
|
} else { |
|
$newfiles{$path.'/'.$file} = 1; |
|
} |
|
} |
|
if ($actionurl eq '/adm/dependencies') { |
|
foreach my $path (keys(%currsubfile)) { |
|
if (ref($currsubfile{$path}) eq 'HASH') { |
|
foreach my $file (keys(%{$currsubfile{$path}})) { |
|
unless ($subdependencies{$path}{$file}) { |
|
next if (($rem ne '') && |
|
(($env{"httpref.$rem"."$path/$file"} ne '') || |
|
(ref($navmap) && |
|
(($navmap->getResourceByUrl($rem."$path/$file") ne '') || |
|
(($file =~ /^(.*\.s?html?)\.bak$/i) && |
|
($navmap->getResourceByUrl($rem."$path/$1"))))))); |
|
$unused{$path.'/'.$file} = 1; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
my %currfile; |
|
if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) { |
|
my ($dirlistref,$listerror) = |
|
&Apache::lonnet::dirlist($url,$udom,$uname,$getpropath); |
|
if (ref($dirlistref) eq 'ARRAY') { |
|
foreach my $line (@{$dirlistref}) { |
|
my ($file_name,$rest) = split(/\&/,$line,2); |
|
$currfile{$file_name} = 1; |
|
} |
|
} |
|
} elsif (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank')) { |
|
if (opendir(my $dir,$url)) { |
|
my @dir_list = grep(!/^\./,readdir($dir)); |
|
map {$currfile{$_} = 1;} @dir_list; |
|
} |
|
} elsif (($actionurl eq '/adm/dependencies') || |
|
(($actionurl eq '/adm/coursedocs') && (ref($args) eq 'HASH') && |
|
($args->{'context'} eq 'paste'))) { |
|
if ($env{'request.course.id'} ne '') { |
|
my ($dir) = ($fileloc =~ m{^(.+/)[^/]+$}); |
|
if ($dir ne '') { |
|
my ($dirlistref,$listerror) = |
|
&Apache::lonnet::dirlist($dir,$cdom,$cnum,$getpropath,undef,'/'); |
|
if (ref($dirlistref) eq 'ARRAY') { |
|
foreach my $line (@{$dirlistref}) { |
|
my ($file_name,$dom,undef,$testdir,undef,undef,undef,undef, |
|
$size,undef,$mtime)=split(/\&/,$line,12); |
|
unless (($testdir&$dirptr) || |
|
($file_name =~ /^\.\.?$/)) { |
|
$currfile{$file_name} = [$size,$mtime]; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
foreach my $file (keys(%dependencies)) { |
|
if (exists($currfile{$file})) { |
|
unless ($mapping{$file} eq $file) { |
|
$pathchanges{$file} = 1; |
|
} |
|
$existing{$file} = 1; |
|
$numexisting ++; |
|
} else { |
|
$newfiles{$file} = 1; |
|
} |
|
} |
|
foreach my $file (keys(%currfile)) { |
|
unless (($file eq $filename) || |
|
($file eq $filename.'.bak') || |
|
($dependencies{$file})) { |
|
if ($actionurl eq '/adm/dependencies') { |
|
next if (($rem ne '') && |
|
(($env{"httpref.$rem".$file} ne '') || |
|
(ref($navmap) && |
|
(($navmap->getResourceByUrl($rem.$file) ne '') || |
|
(($file =~ /^(.*\.s?html?)\.bak$/i) && |
|
($navmap->getResourceByUrl($rem.$1))))))); |
|
} |
|
$unused{$file} = 1; |
|
} |
|
} |
|
if (($actionurl eq '/adm/coursedocs') && (ref($args) eq 'HASH') && |
|
($args->{'context'} eq 'paste')) { |
|
$counter = scalar(keys(%existing)); |
|
$numpathchg = scalar(keys(%pathchanges)); |
|
return ($output,$counter,$numpathchg,\%existing); |
|
} |
|
foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%newfiles)) { |
|
if ($actionurl eq '/adm/dependencies') { |
|
next if ($embed_file =~ m{^\w+://}); |
|
} |
$upload_output .= &start_data_table_row(). |
$upload_output .= &start_data_table_row(). |
'<td>'.$embed_file.'</td><td>'; |
'<td><img src="'.&icon($embed_file).'" /> '. |
if ($args->{'ignore_remote_references'} |
'<span class="LC_filename">'.$embed_file.'</span>'; |
&& $embed_file =~ m{^\w+://}) { |
unless ($mapping{$embed_file} eq $embed_file) { |
|
$upload_output .= '<br /><span class="LC_info" style="font-size:smaller;">'.&mt('changed from: [_1]',$mapping{$embed_file}).'</span>'; |
|
} |
|
$upload_output .= '</td><td>'; |
|
if ($args->{'ignore_remote_references'} && $embed_file =~ m{^\w+://}) { |
$upload_output.='<span class="LC_warning">'.&mt("URL points to other server.").'</span>'; |
$upload_output.='<span class="LC_warning">'.&mt("URL points to other server.").'</span>'; |
|
$numremref++; |
} elsif ($args->{'error_on_invalid_names'} |
} elsif ($args->{'error_on_invalid_names'} |
&& $embed_file ne &Apache::lonnet::clean_filename($embed_file,{'keep_path' => 1,})) { |
&& $embed_file ne &Apache::lonnet::clean_filename($embed_file,{'keep_path' => 1,})) { |
|
$upload_output.='<span class="LC_warning">'.&mt('Invalid characters').'</span>'; |
|
$numinvalid++; |
|
} else { |
|
$upload_output .= &embedded_file_element('upload_embedded',$counter, |
|
$embed_file,\%mapping, |
|
$allfiles,$codebase,'upload'); |
|
$counter ++; |
|
$numnew ++; |
|
} |
|
$upload_output .= '</td>'.&Apache::loncommon::end_data_table_row()."\n"; |
|
} |
|
foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%existing)) { |
|
if ($actionurl eq '/adm/dependencies') { |
|
my ($size,$mtime) = &get_dependency_details(\%currfile,\%currsubfile,$embed_file); |
|
$modify_output .= &start_data_table_row(). |
|
'<td><a href="'.$path.'/'.$embed_file.'" style="text-decoration:none;">'. |
|
'<img src="'.&icon($embed_file).'" border="0" />'. |
|
' <span class="LC_filename">'.$embed_file.'</span></a></td>'. |
|
'<td>'.$size.'</td>'. |
|
'<td>'.$mtime.'</td>'. |
|
'<td><label><input type="checkbox" name="mod_upload_dep" '. |
|
'onclick="toggleBrowse('."'$counter'".')" id="mod_upload_dep_'. |
|
$counter.'" value="'.$counter.'" />'.&mt('Yes').'</label>'. |
|
'<div id="moduploaddep_'.$counter.'" style="display:none;">'. |
|
&embedded_file_element('upload_embedded',$counter, |
|
$embed_file,\%mapping, |
|
$allfiles,$codebase,'modify'). |
|
'</div></td>'. |
|
&end_data_table_row()."\n"; |
|
$counter ++; |
|
} else { |
|
$upload_output .= &start_data_table_row(). |
|
'<td><span class="LC_filename">'.$embed_file.'</span></td>'; |
|
'<td><span class="LC_warning">'.&mt('Already exists').'</span></td>'. |
|
&Apache::loncommon::end_data_table_row()."\n"; |
|
} |
|
} |
|
my $delidx = $counter; |
|
foreach my $oldfile (sort {lc($a) cmp lc($b)} keys(%unused)) { |
|
my ($size,$mtime) = &get_dependency_details(\%currfile,\%currsubfile,$oldfile); |
|
$delete_output .= &start_data_table_row(). |
|
'<td><img src="'.&icon($oldfile).'" />'. |
|
' <span class="LC_filename">'.$oldfile.'</span></td>'. |
|
'<td>'.$size.'</td>'. |
|
'<td>'.$mtime.'</td>'. |
|
'<td><label><input type="checkbox" name="del_upload_dep" '. |
|
' value="'.$delidx.'" />'.&mt('Yes').'</label>'. |
|
&embedded_file_element('upload_embedded',$delidx, |
|
$oldfile,\%mapping,$allfiles, |
|
$codebase,'delete').'</td>'. |
|
&end_data_table_row()."\n"; |
|
$numunused ++; |
|
$delidx ++; |
|
} |
|
if ($upload_output) { |
|
$upload_output = &start_data_table(). |
|
$upload_output. |
|
&end_data_table()."\n"; |
|
} |
|
if ($modify_output) { |
|
$modify_output = &start_data_table(). |
|
&start_data_table_header_row(). |
|
'<th>'.&mt('File').'</th>'. |
|
'<th>'.&mt('Size (KB)').'</th>'. |
|
'<th>'.&mt('Modified').'</th>'. |
|
'<th>'.&mt('Upload replacement?').'</th>'. |
|
&end_data_table_header_row(). |
|
$modify_output. |
|
&end_data_table()."\n"; |
|
} |
|
if ($delete_output) { |
|
$delete_output = &start_data_table(). |
|
&start_data_table_header_row(). |
|
'<th>'.&mt('File').'</th>'. |
|
'<th>'.&mt('Size (KB)').'</th>'. |
|
'<th>'.&mt('Modified').'</th>'. |
|
'<th>'.&mt('Delete?').'</th>'. |
|
&end_data_table_header_row(). |
|
$delete_output. |
|
&end_data_table()."\n"; |
|
} |
|
my $applies = 0; |
|
if ($numremref) { |
|
$applies ++; |
|
} |
|
if ($numinvalid) { |
|
$applies ++; |
|
} |
|
if ($numexisting) { |
|
$applies ++; |
|
} |
|
if ($counter || $numunused) { |
|
$output = '<form name="upload_embedded" action="'.$actionurl.'"'. |
|
' method="post" enctype="multipart/form-data">'."\n". |
|
$state.'<h3>'.$heading.'</h3>'; |
|
if ($actionurl eq '/adm/dependencies') { |
|
if ($numnew) { |
|
$output .= '<h4>'.&mt('Missing dependencies').'</h4>'. |
|
'<p>'.&mt('The following files need to be uploaded.').'</p>'."\n". |
|
$upload_output.'<br />'."\n"; |
|
} |
|
if ($numexisting) { |
|
$output .= '<h4>'.&mt('Uploaded dependencies (in use)').'</h4>'. |
|
'<p>'.&mt('Upload a new file to replace the one currently in use.').'</p>'."\n". |
|
$modify_output.'<br />'."\n"; |
|
$buttontext = &mt('Save changes'); |
|
} |
|
if ($numunused) { |
|
$output .= '<h4>'.&mt('Unused files').'</h4>'. |
|
'<p>'.&mt('The following uploaded files are no longer used.').'</p>'."\n". |
|
$delete_output.'<br />'."\n"; |
|
$buttontext = &mt('Save changes'); |
|
} |
|
} else { |
|
$output .= $upload_output.'<br />'."\n"; |
|
} |
|
$output .= '<input type ="hidden" name="number_embedded_items" value="'. |
|
$counter.'" />'."\n"; |
|
if ($actionurl eq '/adm/dependencies') { |
|
$output .= '<input type ="hidden" name="number_newemb_items" value="'. |
|
$numnew.'" />'."\n"; |
|
} elsif ($actionurl eq '') { |
|
$output .= '<input type="hidden" name="phase" value="three" />'; |
|
} |
|
} elsif ($applies) { |
|
$output = '<b>'.&mt('Referenced files').'</b>:<br />'; |
|
if ($applies > 1) { |
|
$output .= |
|
&mt('No files need to be uploaded, as one of the following applies to each reference:').'<ul>'; |
|
if ($numremref) { |
|
$output .= '<li>'.&mt('reference is to a URL which points to another server').'</li>'."\n"; |
|
} |
|
if ($numinvalid) { |
|
$output .= '<li>'.&mt('reference is to file with a name containing invalid characters').'</li>'."\n"; |
|
} |
|
if ($numexisting) { |
|
$output .= '<li>'.&mt('reference is to an existing file at the specified location').'</li>'."\n"; |
|
} |
|
$output .= '</ul><br />'; |
|
} elsif ($numremref) { |
|
$output .= '<p>'.&mt('None to upload, as all references are to URLs pointing to another server.').'</p>'; |
|
} elsif ($numinvalid) { |
|
$output .= '<p>'.&mt('None to upload, as all references are to files with names containing invalid characters.').'</p>'; |
|
} elsif ($numexisting) { |
|
$output .= '<p>'.&mt('None to upload, as all references are to existing files.').'</p>'; |
|
} |
|
$output .= $upload_output.'<br />'; |
|
} |
|
my ($pathchange_output,$chgcount); |
|
$chgcount = $counter; |
|
if (keys(%pathchanges) > 0) { |
|
foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%pathchanges)) { |
|
if ($counter) { |
|
$output .= &embedded_file_element('pathchange',$chgcount, |
|
$embed_file,\%mapping, |
|
$allfiles,$codebase,'change'); |
|
} else { |
|
$pathchange_output .= |
|
&start_data_table_row(). |
|
'<td><input type ="checkbox" name="namechange" value="'. |
|
$chgcount.'" checked="checked" /></td>'. |
|
'<td>'.$mapping{$embed_file}.'</td>'. |
|
'<td>'.$embed_file. |
|
&embedded_file_element('pathchange',$numpathchg,$embed_file, |
|
\%mapping,$allfiles,$codebase,'change'). |
|
'</td>'.&end_data_table_row(); |
|
} |
|
$numpathchg ++; |
|
$chgcount ++; |
|
} |
|
} |
|
if ($counter) { |
|
if ($numpathchg) { |
|
$output .= '<input type ="hidden" name="number_pathchange_items" value="'. |
|
$numpathchg.'" />'."\n"; |
|
} |
|
if (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank') || |
|
($actionurl eq '/adm/imsimport')) { |
|
$output .= '<input type="hidden" name="phase" value="three" />'."\n"; |
|
} elsif ($actionurl eq '/adm/portfolio' || $actionurl eq '/adm/coursegrp_portfolio') { |
|
$output .= '<input type="hidden" name="action" value="upload_embedded" />'; |
|
} elsif ($actionurl eq '/adm/dependencies') { |
|
$output .= '<input type="hidden" name="action" value="process_changes" />'; |
|
} |
|
$output .= '<input type ="submit" value="'.$buttontext.'" />'."\n".'</form>'."\n"; |
|
} elsif ($numpathchg) { |
|
my %pathchange = (); |
|
$output .= &modify_html_form('pathchange',$actionurl,$state,\%pathchange,$pathchange_output); |
|
if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) { |
|
$output .= '<p>'.&mt('or').'</p>'; |
|
} |
|
} |
|
return ($output,$counter,$numpathchg); |
|
} |
|
|
$upload_output.='<span class="LC_warning">'.&mt("Invalid characters").'</span>'; |
sub embedded_file_element { |
|
my ($context,$num,$embed_file,$mapping,$allfiles,$codebase,$type) = @_; |
|
return unless ((ref($mapping) eq 'HASH') && (ref($allfiles) eq 'HASH') && |
|
(ref($codebase) eq 'HASH')); |
|
my $output; |
|
if (($context eq 'upload_embedded') && ($type ne 'delete')) { |
|
$output = '<input name="embedded_item_'.$num.'" type="file" value="" />'."\n"; |
|
} |
|
$output .= '<input name="embedded_orig_'.$num.'" type="hidden" value="'. |
|
&escape($embed_file).'" />'; |
|
unless (($context eq 'upload_embedded') && |
|
($mapping->{$embed_file} eq $embed_file)) { |
|
$output .=' |
|
<input name="embedded_ref_'.$num.'" type="hidden" value="'.&escape($mapping->{$embed_file}).'" />'; |
|
} |
|
my $attrib; |
|
if (ref($allfiles->{$mapping->{$embed_file}}) eq 'ARRAY') { |
|
$attrib = &escape(join(':',@{$allfiles->{$mapping->{$embed_file}}})); |
|
} |
|
$output .= |
|
"\n\t\t". |
|
'<input name="embedded_attrib_'.$num.'" type="hidden" value="'. |
|
$attrib.'" />'; |
|
if (exists($codebase->{$mapping->{$embed_file}})) { |
|
$output .= |
|
"\n\t\t". |
|
'<input name="codebase_'.$num.'" type="hidden" value="'. |
|
&escape($codebase->{$mapping->{$embed_file}}).'" />'; |
|
} |
|
return $output; |
|
} |
|
|
|
sub get_dependency_details { |
|
my ($currfile,$currsubfile,$embed_file) = @_; |
|
my ($size,$mtime,$showsize,$showmtime); |
|
if ((ref($currfile) eq 'HASH') && (ref($currsubfile))) { |
|
if ($embed_file =~ m{/}) { |
|
my ($path,$fname) = split(/\//,$embed_file); |
|
if (ref($currsubfile->{$path}{$fname}) eq 'ARRAY') { |
|
($size,$mtime) = @{$currsubfile->{$path}{$fname}}; |
|
} |
} else { |
} else { |
$upload_output .=' |
if (ref($currfile->{$embed_file}) eq 'ARRAY') { |
<input name="embedded_item_'.$num.'" type="file" value="" /> |
($size,$mtime) = @{$currfile->{$embed_file}}; |
<input name="embedded_orig_'.$num.'" type="hidden" value="'.&escape($embed_file).'" />'; |
} |
my $attrib = join(':',@{$$allfiles{$embed_file}}); |
} |
$upload_output .= |
$showsize = $size/1024.0; |
"\n\t\t". |
$showsize = sprintf("%.1f",$showsize); |
'<input name="embedded_attrib_'.$num.'" type="hidden" value="'. |
if ($mtime > 0) { |
$attrib.'" />'; |
$showmtime = &Apache::lonlocal::locallocaltime($mtime); |
if (exists($$codebase{$embed_file})) { |
} |
$upload_output .= |
} |
"\n\t\t". |
return ($showsize,$showmtime); |
'<input name="codebase_'.$num.'" type="hidden" value="'. |
} |
&escape($$codebase{$embed_file}).'" />'; |
|
} |
sub ask_embedded_js { |
} |
return <<"END"; |
$upload_output .= '</td>'.&Apache::loncommon::end_data_table_row(); |
<script type="text/javascript""> |
$num++; |
// <![CDATA[ |
} |
function toggleBrowse(counter) { |
$upload_output .= &Apache::loncommon::end_data_table().'<br /> |
var chkboxid = document.getElementById('mod_upload_dep_'+counter); |
<input type ="hidden" name="number_embedded_items" value="'.$num.'" /> |
var fileid = document.getElementById('embedded_item_'+counter); |
<input type ="submit" value="'.&mt('Upload Listed Files').'" /> |
var uploaddivid = document.getElementById('moduploaddep_'+counter); |
'.&mt('(only files for which a location has been provided will be uploaded)').' |
if (chkboxid.checked == true) { |
</form>'; |
uploaddivid.style.display='block'; |
return $upload_output; |
} else { |
|
uploaddivid.style.display='none'; |
|
fileid.value = ''; |
|
} |
|
} |
|
// ]]> |
|
</script> |
|
|
|
END |
} |
} |
|
|
sub upload_embedded { |
sub upload_embedded { |
my ($context,$dirpath,$uname,$udom,$dir_root,$url_root,$group,$disk_quota, |
my ($context,$dirpath,$uname,$udom,$dir_root,$url_root,$group,$disk_quota, |
$current_disk_usage) = @_; |
$current_disk_usage,$hiddenstate,$actionurl) = @_; |
my $output; |
my (%pathchange,$output,$modifyform,$footer,$returnflag); |
for (my $i=0; $i<$env{'form.number_embedded_items'}; $i++) { |
for (my $i=0; $i<$env{'form.number_embedded_items'}; $i++) { |
next if (!exists($env{'form.embedded_item_'.$i.'.filename'})); |
next if (!exists($env{'form.embedded_item_'.$i.'.filename'})); |
my $orig_uploaded_filename = |
my $orig_uploaded_filename = |
$env{'form.embedded_item_'.$i.'.filename'}; |
$env{'form.embedded_item_'.$i.'.filename'}; |
|
foreach my $type ('orig','ref','attrib','codebase') { |
$env{'form.embedded_orig_'.$i} = |
if ($env{'form.embedded_'.$type.'_'.$i} ne '') { |
&unescape($env{'form.embedded_orig_'.$i}); |
$env{'form.embedded_'.$type.'_'.$i} = |
|
&unescape($env{'form.embedded_'.$type.'_'.$i}); |
|
} |
|
} |
my ($path,$fname) = |
my ($path,$fname) = |
($env{'form.embedded_orig_'.$i} =~ m{(.*/)([^/]*)}); |
($env{'form.embedded_orig_'.$i} =~ m{(.*/)([^/]*)}); |
# no path, whole string is fname |
# no path, whole string is fname |
if (!$fname) { $fname = $env{'form.embedded_orig_'.$i} }; |
if (!$fname) { $fname = $env{'form.embedded_orig_'.$i} }; |
|
|
$path = $env{'form.currentpath'}.$path; |
|
$fname = &Apache::lonnet::clean_filename($fname); |
$fname = &Apache::lonnet::clean_filename($fname); |
# See if there is anything left |
# See if there is anything left |
next if ($fname eq ''); |
next if ($fname eq ''); |
Line 8371 sub upload_embedded {
|
Line 10097 sub upload_embedded {
|
if ($group ne '') { |
if ($group ne '') { |
$port_path = "groups/$group/$port_path"; |
$port_path = "groups/$group/$port_path"; |
} |
} |
($state,$msg) = &check_for_upload($path,$fname,$group,'embedded_item_'.$i, |
($state,$msg) = &check_for_upload($env{'form.currentpath'}.$path, |
|
$fname,$group,'embedded_item_'.$i, |
$dir_root,$port_path,$disk_quota, |
$dir_root,$port_path,$disk_quota, |
$current_disk_usage,$uname,$udom); |
$current_disk_usage,$uname,$udom); |
if ($state eq 'will_exceed_quota' |
if ($state eq 'will_exceed_quota' |
|| $state eq 'file_locked' |
|| $state eq 'file_locked') { |
|| $state eq 'file_exists' ) { |
|
$output .= $msg; |
$output .= $msg; |
next; |
next; |
} |
} |
Line 8390 sub upload_embedded {
|
Line 10116 sub upload_embedded {
|
# Check if extension is valid |
# Check if extension is valid |
if (($fname =~ /\.(\w+)$/) && |
if (($fname =~ /\.(\w+)$/) && |
(&Apache::loncommon::fileembstyle($1) eq 'hdn')) { |
(&Apache::loncommon::fileembstyle($1) eq 'hdn')) { |
$output .= &mt('Invalid file extension ([_1]) - reserved for LONCAPA use - rename the file with a different extension and re-upload. ',$1); |
$output .= &mt('Invalid file extension ([_1]) - reserved for LONCAPA use - rename the file with a different extension and re-upload. ',$1).'<br />'; |
next; |
next; |
} elsif (($fname =~ /\.(\w+)$/) && |
} elsif (($fname =~ /\.(\w+)$/) && |
(!defined(&Apache::loncommon::fileembstyle($1)))) { |
(!defined(&Apache::loncommon::fileembstyle($1)))) { |
$output .= &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1); |
$output .= &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1).'<br />'; |
next; |
next; |
} elsif ($fname=~/\.(\d+)\.(\w+)$/) { |
} elsif ($fname=~/\.(\d+)\.(\w+)$/) { |
$output .= &mt('File name not allowed - rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2); |
$output .= &mt('File name not allowed - rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2).'<br />'; |
next; |
next; |
} |
} |
|
|
$env{'form.embedded_item_'.$i.'.filename'}=$fname; |
$env{'form.embedded_item_'.$i.'.filename'}=$fname; |
if ($context eq 'portfolio') { |
if ($context eq 'portfolio') { |
my $result= |
my $result; |
&Apache::lonnet::userfileupload('embedded_item_'.$i,'', |
if ($state eq 'existingfile') { |
$dirpath.$path); |
$result= |
|
&Apache::lonnet::userfileupload('embedded_item_'.$i,'existingfile', |
|
$dirpath.$env{'form.currentpath'}.$path); |
|
} else { |
|
$result= |
|
&Apache::lonnet::userfileupload('embedded_item_'.$i,'', |
|
$dirpath. |
|
$env{'form.currentpath'}.$path); |
|
if ($result !~ m|^/uploaded/|) { |
|
$output .= '<span class="LC_error">' |
|
.&mt('An error occurred ([_1]) while trying to upload [_2] for embedded element [_3].' |
|
,$result,$orig_uploaded_filename,$env{'form.embedded_orig_'.$i}) |
|
.'</span><br />'; |
|
next; |
|
} else { |
|
$output .= &mt('Uploaded [_1]','<span class="LC_filename">'. |
|
$path.$fname.'</span>').'<br />'; |
|
} |
|
} |
|
} elsif ($context eq 'coursedoc') { |
|
my $result = |
|
&Apache::lonnet::userfileupload('embedded_item_'.$i,'coursedoc', |
|
$dirpath.'/'.$path); |
if ($result !~ m|^/uploaded/|) { |
if ($result !~ m|^/uploaded/|) { |
$output .= '<span class="LC_error">' |
$output .= '<span class="LC_error">' |
.&mt('An error occurred ([_1]) while trying to upload [_2] for embedded element [_3].' |
.&mt('An error occurred ([_1]) while trying to upload [_2] for embedded element [_3].' |
,$result,$orig_uploaded_filename,$env{'form.embedded_orig_'.$i}) |
,$result,$orig_uploaded_filename,$env{'form.embedded_orig_'.$i}) |
.'</span><br />'; |
.'</span><br />'; |
next; |
next; |
} else { |
} else { |
$output .= '<p>'.&mt('Uploaded [_1]','<span class="LC_filename">'. |
$output .= &mt('Uploaded [_1]','<span class="LC_filename">'. |
$path.$fname.'</span>').'</p>'; |
$path.$fname.'</span>').'<br />'; |
} |
} |
} else { |
} else { |
# Save the file |
# Save the file |
Line 8422 sub upload_embedded {
|
Line 10169 sub upload_embedded {
|
my $fullpath = $dir_root.$dirpath.'/'.$path; |
my $fullpath = $dir_root.$dirpath.'/'.$path; |
my $dest = $fullpath.$fname; |
my $dest = $fullpath.$fname; |
my $url = $url_root.$dirpath.'/'.$path.$fname; |
my $url = $url_root.$dirpath.'/'.$path.$fname; |
my @parts=split(/\//,$fullpath); |
my @parts=split(/\//,"$dirpath/$path"); |
my $count; |
my $count; |
my $filepath = $dir_root; |
my $filepath = $dir_root; |
for ($count=4;$count<=$#parts;$count++) { |
foreach my $subdir (@parts) { |
$filepath .= "/$parts[$count]"; |
$filepath .= "/$subdir"; |
if ((-e $filepath)!=1) { |
if (!-e $filepath) { |
mkdir($filepath,0770); |
mkdir($filepath,0770); |
} |
} |
} |
} |
Line 8435 sub upload_embedded {
|
Line 10182 sub upload_embedded {
|
if (!open($fh,'>'.$dest)) { |
if (!open($fh,'>'.$dest)) { |
&Apache::lonnet::logthis('Failed to create '.$dest); |
&Apache::lonnet::logthis('Failed to create '.$dest); |
$output .= '<span class="LC_error">'. |
$output .= '<span class="LC_error">'. |
&mt('An error occurred while trying to upload [_1] for embedded element [_2].',$orig_uploaded_filename,$env{'form.embedded_orig_'.$i}). |
&mt('An error occurred while trying to upload [_1] for embedded element [_2].', |
|
$orig_uploaded_filename,$env{'form.embedded_orig_'.$i}). |
'</span><br />'; |
'</span><br />'; |
} else { |
} else { |
if (!print $fh $env{'form.embedded_item_'.$i}) { |
if (!print $fh $env{'form.embedded_item_'.$i}) { |
&Apache::lonnet::logthis('Failed to write to '.$dest); |
&Apache::lonnet::logthis('Failed to write to '.$dest); |
$output .= '<span class="LC_error">'. |
$output .= '<span class="LC_error">'. |
&mt('An error occurred while writing the file [_1] for embedded element [_2].',$orig_uploaded_filename,$env{'form.embedded_orig_'.$i}). |
&mt('An error occurred while writing the file [_1] for embedded element [_2].', |
|
$orig_uploaded_filename,$env{'form.embedded_orig_'.$i}). |
'</span><br />'; |
'</span><br />'; |
} else { |
} else { |
if ($context eq 'testbank') { |
$output .= &mt('Uploaded [_1]','<span class="LC_filename">'. |
$output .= &mt('Embedded file uploaded successfully:'). |
$url.'</span>').'<br />'; |
' <a href="'.$url.'">'. |
unless ($context eq 'testbank') { |
$orig_uploaded_filename.'</a><br />'; |
$footer .= &mt('View embedded file: [_1]', |
} else { |
'<a href="'.$url.'">'.$fname.'</a>').'<br />'; |
$output .= '<span class=\"LC_fontsize_large\">'. |
|
&mt('View embedded file: [_1]','<a href="'.$url.'">'. |
|
$orig_uploaded_filename.'</a>').'</span><br />'; |
|
} |
} |
} |
} |
close($fh); |
close($fh); |
} |
} |
} |
} |
|
if ($env{'form.embedded_ref_'.$i}) { |
|
$pathchange{$i} = 1; |
|
} |
|
} |
|
if ($output) { |
|
$output = '<p>'.$output.'</p>'; |
|
} |
|
$output .= &modify_html_form('upload_embedded',$actionurl,$hiddenstate,\%pathchange); |
|
$returnflag = 'ok'; |
|
my $numpathchgs = scalar(keys(%pathchange)); |
|
if ($numpathchgs > 0) { |
|
if ($context eq 'portfolio') { |
|
$output .= '<p>'.&mt('or').'</p>'; |
|
} elsif ($context eq 'testbank') { |
|
$output .= '<p>'.&mt('Or [_1]continue[_2] the testbank import without modifying the reference(s).', |
|
'<a href="javascript:document.testbankForm.submit();">','</a>').'</p>'; |
|
$returnflag = 'modify_orightml'; |
|
} |
|
} |
|
return ($output.$footer,$returnflag,$numpathchgs); |
|
} |
|
|
|
sub modify_html_form { |
|
my ($context,$actionurl,$hiddenstate,$pathchange,$pathchgtable) = @_; |
|
my $end = 0; |
|
my $modifyform; |
|
if ($context eq 'upload_embedded') { |
|
return unless (ref($pathchange) eq 'HASH'); |
|
if ($env{'form.number_embedded_items'}) { |
|
$end += $env{'form.number_embedded_items'}; |
|
} |
|
if ($env{'form.number_pathchange_items'}) { |
|
$end += $env{'form.number_pathchange_items'}; |
|
} |
|
if ($end) { |
|
for (my $i=0; $i<$end; $i++) { |
|
if ($i < $env{'form.number_embedded_items'}) { |
|
next unless($pathchange->{$i}); |
|
} |
|
$modifyform .= |
|
&start_data_table_row(). |
|
'<td><input type ="checkbox" name="namechange" value="'.$i.'" '. |
|
'checked="checked" /></td>'. |
|
'<td>'.$env{'form.embedded_ref_'.$i}. |
|
'<input type="hidden" name="embedded_ref_'.$i.'" value="'. |
|
&escape($env{'form.embedded_ref_'.$i}).'" />'. |
|
'<input type="hidden" name="embedded_codebase_'.$i.'" value="'. |
|
&escape($env{'form.embedded_codebase_'.$i}).'" />'. |
|
'<input type="hidden" name="embedded_attrib_'.$i.'" value="'. |
|
&escape($env{'form.embedded_attrib_'.$i}).'" /></td>'. |
|
'<td>'.$env{'form.embedded_orig_'.$i}. |
|
'<input type="hidden" name="embedded_orig_'.$i.'" value="'. |
|
&escape($env{'form.embedded_orig_'.$i}).'" /></td>'. |
|
&end_data_table_row(); |
|
} |
|
} |
|
} else { |
|
$modifyform = $pathchgtable; |
|
if (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank')) { |
|
$hiddenstate .= '<input type="hidden" name="phase" value="four" />'; |
|
} elsif (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) { |
|
$hiddenstate .= '<input type="hidden" name="action" value="modify_orightml" />'; |
|
} |
|
} |
|
if ($modifyform) { |
|
if ($actionurl eq '/adm/dependencies') { |
|
$hiddenstate .= '<input type="hidden" name="action" value="modifyhrefs" />'; |
|
} |
|
return '<h3>'.&mt('Changes in content of HTML file required').'</h3>'."\n". |
|
'<p>'.&mt('Changes need to be made to the reference(s) used for one or more of the dependencies, if your HTML file is to work correctly:').'<ol>'."\n". |
|
'<li>'.&mt('For consistency between the reference(s) and the location of the corresponding stored file within LON-CAPA.').'</li>'."\n". |
|
'<li>'.&mt('To change absolute paths to relative paths, or replace directory traversal via "../" within the original reference.').'</li>'."\n". |
|
'</ol></p>'."\n".'<p>'. |
|
&mt('LON-CAPA can make the required changes to your HTML file.').'</p>'."\n". |
|
'<form method="post" name="refchanger" action="'.$actionurl.'">'. |
|
&start_data_table()."\n". |
|
&start_data_table_header_row(). |
|
'<th>'.&mt('Change?').'</th>'. |
|
'<th>'.&mt('Current reference').'</th>'. |
|
'<th>'.&mt('Required reference').'</th>'. |
|
&end_data_table_header_row()."\n". |
|
$modifyform. |
|
&end_data_table().'<br />'."\n".$hiddenstate. |
|
'<input type="submit" name="pathchanges" value="'.&mt('Modify HTML file').'" />'. |
|
'</form>'."\n"; |
|
} |
|
return; |
|
} |
|
|
|
sub modify_html_refs { |
|
my ($context,$dirpath,$uname,$udom,$dir_root) = @_; |
|
my $container; |
|
if ($context eq 'portfolio') { |
|
$container = $env{'form.container'}; |
|
} elsif ($context eq 'coursedoc') { |
|
$container = $env{'form.primaryurl'}; |
|
} elsif ($context eq 'manage_dependencies') { |
|
(undef,undef,$container) = &Apache::lonnet::decode_symb($env{'form.symb'}); |
|
$container = "/$container"; |
|
} else { |
|
$container = $Apache::lonnet::perlvar{'lonDocRoot'}.$env{'form.filename'}; |
|
} |
|
my (%allfiles,%codebase,$output,$content); |
|
my @changes = &get_env_multiple('form.namechange'); |
|
unless (@changes > 0) { |
|
if (wantarray) { |
|
return ('',0,0); |
|
} else { |
|
return; |
|
} |
|
} |
|
if (($context eq 'portfolio') || ($context eq 'coursedoc') || |
|
($context eq 'manage_dependencies')) { |
|
unless ($container =~ m{^/uploaded/\Q$udom\E/\Q$uname\E/}) { |
|
if (wantarray) { |
|
return ('',0,0); |
|
} else { |
|
return; |
|
} |
|
} |
|
$content = &Apache::lonnet::getfile($container); |
|
if ($content eq '-1') { |
|
if (wantarray) { |
|
return ('',0,0); |
|
} else { |
|
return; |
|
} |
|
} |
|
} else { |
|
unless ($container =~ /^\Q$dir_root\E/) { |
|
if (wantarray) { |
|
return ('',0,0); |
|
} else { |
|
return; |
|
} |
|
} |
|
if (open(my $fh,"<$container")) { |
|
$content = join('', <$fh>); |
|
close($fh); |
|
} else { |
|
if (wantarray) { |
|
return ('',0,0); |
|
} else { |
|
return; |
|
} |
|
} |
|
} |
|
my ($count,$codebasecount) = (0,0); |
|
my $mm = new File::MMagic; |
|
my $mime_type = $mm->checktype_contents($content); |
|
if ($mime_type eq 'text/html') { |
|
my $parse_result = |
|
&Apache::lonnet::extract_embedded_items($container,\%allfiles, |
|
\%codebase,\$content); |
|
if ($parse_result eq 'ok') { |
|
foreach my $i (@changes) { |
|
my $orig = &unescape($env{'form.embedded_orig_'.$i}); |
|
my $ref = &unescape($env{'form.embedded_ref_'.$i}); |
|
if ($allfiles{$ref}) { |
|
my $newname = $orig; |
|
my ($attrib_regexp,$codebase); |
|
$attrib_regexp = &unescape($env{'form.embedded_attrib_'.$i}); |
|
if ($attrib_regexp =~ /:/) { |
|
$attrib_regexp =~ s/\:/|/g; |
|
} |
|
if ($content =~ m{($attrib_regexp\s*=\s*['"]?)\Q$ref\E(['"]?)}) { |
|
my $numchg = ($content =~ s{($attrib_regexp\s*=\s*['"]?)\Q$ref\E(['"]?)}{$1$newname$2}gi); |
|
$count += $numchg; |
|
} |
|
if ($env{'form.embedded_codebase_'.$i} ne '') { |
|
$codebase = &unescape($env{'form.embedded_codebase_'.$i}); |
|
my $numchg = ($content =~ s/(codebase\s*=\s*["']?)\Q$codebase\E(["']?)/$1.$2/i); #' stupid emacs |
|
$codebasecount ++; |
|
} |
|
} |
|
} |
|
if ($count || $codebasecount) { |
|
my $saveresult; |
|
if (($context eq 'portfolio') || ($context eq 'coursedoc') || |
|
($context eq 'manage_dependencies')) { |
|
my $url = &Apache::lonnet::store_edited_file($container,$content,$udom,$uname,\$saveresult); |
|
if ($url eq $container) { |
|
my ($fname) = ($container =~ m{/([^/]+)$}); |
|
$output = '<p>'.&mt('Updated [quant,_1,reference] in [_2].', |
|
$count,'<span class="LC_filename">'. |
|
$fname.'</span>').'</p>'; |
|
} else { |
|
$output = '<p class="LC_error">'. |
|
&mt('Error: update failed for: [_1].', |
|
'<span class="LC_filename">'. |
|
$container.'</span>').'</p>'; |
|
} |
|
} else { |
|
if (open(my $fh,">$container")) { |
|
print $fh $content; |
|
close($fh); |
|
$output = '<p>'.&mt('Updated [quant,_1,reference] in [_2].', |
|
$count,'<span class="LC_filename">'. |
|
$container.'</span>').'</p>'; |
|
} else { |
|
$output = '<p class="LC_error">'. |
|
&mt('Error: could not update [_1].', |
|
'<span class="LC_filename">'. |
|
$container.'</span>').'</p>'; |
|
} |
|
} |
|
} |
|
} else { |
|
&logthis('Failed to parse '.$container. |
|
' to modify references: '.$parse_result); |
|
} |
|
} |
|
if (wantarray) { |
|
return ($output,$count,$codebasecount); |
|
} else { |
|
return $output; |
} |
} |
return $output; |
|
} |
} |
|
|
sub check_for_existing { |
sub check_for_existing { |
Line 8480 sub check_for_existing {
|
Line 10441 sub check_for_existing {
|
sub check_for_upload { |
sub check_for_upload { |
my ($path,$fname,$group,$element,$portfolio_root,$port_path, |
my ($path,$fname,$group,$element,$portfolio_root,$port_path, |
$disk_quota,$current_disk_usage,$uname,$udom) = @_; |
$disk_quota,$current_disk_usage,$uname,$udom) = @_; |
my $filesize = (length($env{'form.'.$element})) / 1000; #express in k (1024?) |
my $filesize = length($env{'form.'.$element}); |
|
if (!$filesize) { |
|
my $msg = '<span class="LC_error">'. |
|
&mt('Unable to upload [_1]. (size = [_2] bytes)', |
|
'<span class="LC_filename">'.$fname.'</span>', |
|
$filesize).'<br />'. |
|
&mt('Either the file you attempted to upload was empty, or your web browser was unable to read its contents.').'<br />'. |
|
'</span>'; |
|
return ('zero_bytes',$msg); |
|
} |
|
$filesize = $filesize/1000; #express in k (1024?) |
my $getpropath = 1; |
my $getpropath = 1; |
my @dir_list = &Apache::lonnet::dirlist($portfolio_root.$path,$udom,$uname, |
my ($dirlistref,$listerror) = |
$getpropath); |
&Apache::lonnet::dirlist($portfolio_root.$path,$udom,$uname,$getpropath); |
my $found_file = 0; |
my $found_file = 0; |
my $locked_file = 0; |
my $locked_file = 0; |
foreach my $line (@dir_list) { |
my @lockers; |
my ($file_name)=split(/\&/,$line,2); |
my $navmap; |
if ($file_name eq $fname){ |
if ($env{'request.course.id'}) { |
$file_name = $path.$file_name; |
$navmap = Apache::lonnavmaps::navmap->new(); |
if ($group ne '') { |
} |
$file_name = $group.$file_name; |
if (ref($dirlistref) eq 'ARRAY') { |
} |
foreach my $line (@{$dirlistref}) { |
$found_file = 1; |
my ($file_name,$rest)=split(/\&/,$line,2); |
if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') { |
if ($file_name eq $fname){ |
$locked_file = 1; |
$file_name = $path.$file_name; |
|
if ($group ne '') { |
|
$file_name = $group.$file_name; |
|
} |
|
$found_file = 1; |
|
if (&Apache::lonnet::is_locked($file_name,$udom,$uname,\@lockers) eq 'true') { |
|
foreach my $lock (@lockers) { |
|
if (ref($lock) eq 'ARRAY') { |
|
my ($symb,$crsid) = @{$lock}; |
|
if ($crsid eq $env{'request.course.id'}) { |
|
if (ref($navmap)) { |
|
my $res = $navmap->getBySymb($symb); |
|
foreach my $part (@{$res->parts()}) { |
|
my ($slot_status,$slot_time,$slot_name)=$res->check_for_slot($part); |
|
unless (($slot_status == $res->RESERVED) || |
|
($slot_status == $res->RESERVED_LOCATION)) { |
|
$locked_file = 1; |
|
} |
|
} |
|
} else { |
|
$locked_file = 1; |
|
} |
|
} else { |
|
$locked_file = 1; |
|
} |
|
} |
|
} |
|
} else { |
|
my @info = split(/\&/,$rest); |
|
my $currsize = $info[6]/1000; |
|
if ($currsize < $filesize) { |
|
my $extra = $filesize - $currsize; |
|
if (($current_disk_usage + $extra) > $disk_quota) { |
|
my $msg = '<span class="LC_error">'. |
|
&mt('Unable to upload [_1]. (size = [_2] kilobytes). Disk quota will be exceeded if existing (smaller) file with same name (size = [_3] kilobytes) is replaced.', |
|
'<span class="LC_filename">'.$fname.'</span>',$filesize,$currsize).'</span>'. |
|
'<br />'.&mt('Disk quota is [_1] kilobytes. Your current disk usage is [_2] kilobytes.', |
|
$disk_quota,$current_disk_usage); |
|
return ('will_exceed_quota',$msg); |
|
} |
|
} |
|
} |
} |
} |
} |
} |
} |
} |
Line 8513 sub check_for_upload {
|
Line 10525 sub check_for_upload {
|
return ('file_locked',$msg); |
return ('file_locked',$msg); |
} else { |
} else { |
my $msg = '<span class="LC_error">'; |
my $msg = '<span class="LC_error">'; |
$msg .= &mt('Unable to upload [_1]. A file by that name was found in [_2].','<span class="LC_filename">'.$fname.'</span>',$port_path.$env{'form.currentpath'}); |
$msg .= &mt(' A file by that name: [_1] was found in [_2].','<span class="LC_filename">'.$fname.'</span>',$port_path.$env{'form.currentpath'}); |
$msg .= '</span>'; |
$msg .= '</span>'; |
$msg .= '<br />'; |
return ('existingfile',$msg); |
$msg .= &mt('To upload, rename or delete existing [_1] in [_2].','<span class="LC_filename">'.$fname.'</span>', $port_path.$env{'form.currentpath'}); |
} |
return ('file_exists',$msg); |
} |
|
} |
|
|
|
sub check_for_traversal { |
|
my ($path,$url,$toplevel) = @_; |
|
my @parts=split(/\//,$path); |
|
my $cleanpath; |
|
my $fullpath = $url; |
|
for (my $i=0;$i<@parts;$i++) { |
|
next if ($parts[$i] eq '.'); |
|
if ($parts[$i] eq '..') { |
|
$fullpath =~ s{([^/]+/)$}{}; |
|
} else { |
|
$fullpath .= $parts[$i].'/'; |
|
} |
|
} |
|
if ($fullpath =~ /^\Q$url\E(.*)$/) { |
|
$cleanpath = $1; |
|
} elsif ($fullpath =~ /^\Q$toplevel\E(.*)$/) { |
|
my $curr_toprel = $1; |
|
my @parts = split(/\//,$curr_toprel); |
|
my ($url_toprel) = ($url =~ /^\Q$toplevel\E(.*)$/); |
|
my @urlparts = split(/\//,$url_toprel); |
|
my $doubledots; |
|
my $startdiff = -1; |
|
for (my $i=0; $i<@urlparts; $i++) { |
|
if ($startdiff == -1) { |
|
unless ($urlparts[$i] eq $parts[$i]) { |
|
$startdiff = $i; |
|
$doubledots .= '../'; |
|
} |
|
} else { |
|
$doubledots .= '../'; |
|
} |
|
} |
|
if ($startdiff > -1) { |
|
$cleanpath = $doubledots; |
|
for (my $i=$startdiff; $i<@parts; $i++) { |
|
$cleanpath .= $parts[$i].'/'; |
|
} |
|
} |
|
} |
|
$cleanpath =~ s{(/)$}{}; |
|
return $cleanpath; |
|
} |
|
|
|
sub is_archive_file { |
|
my ($mimetype) = @_; |
|
if (($mimetype eq 'application/octet-stream') || |
|
($mimetype eq 'application/x-stuffit') || |
|
($mimetype =~ m{^application/(x\-)?(compressed|tar|zip|tgz|gz|gtar|gzip|gunzip|bz|bz2|bzip2)})) { |
|
return 1; |
|
} |
|
return; |
|
} |
|
|
|
sub decompress_form { |
|
my ($mimetype,$archiveurl,$action,$noextract,$hiddenelements,$dirlist) = @_; |
|
my %lt = &Apache::lonlocal::texthash ( |
|
this => 'This file is an archive file.', |
|
camt => 'This file is a Camtasia archive file.', |
|
itsc => 'Its contents are as follows:', |
|
youm => 'You may wish to extract its contents.', |
|
extr => 'Extract contents', |
|
auto => 'LON-CAPA can process the files automatically, or you can decide how each should be handled.', |
|
proa => 'Process automatically?', |
|
yes => 'Yes', |
|
no => 'No', |
|
fold => 'Title for folder containing movie', |
|
movi => 'Title for page containing embedded movie', |
|
); |
|
my $fileloc = &Apache::lonnet::filelocation(undef,$archiveurl); |
|
my ($is_camtasia,$topdir,%toplevel,@paths); |
|
my $info = &list_archive_contents($fileloc,\@paths); |
|
if (@paths) { |
|
foreach my $path (@paths) { |
|
$path =~ s{^/}{}; |
|
if ($path =~ m{^([^/]+)/$}) { |
|
$topdir = $1; |
|
} |
|
if ($path =~ m{^([^/]+)/}) { |
|
$toplevel{$1} = $path; |
|
} else { |
|
$toplevel{$path} = $path; |
|
} |
} |
} |
} |
} |
|
if ($mimetype =~ m{^application/(x\-)?(compressed|zip)}) { |
|
my @camtasia = ("$topdir/","$topdir/index.html", |
|
"$topdir/media/", |
|
"$topdir/media/$topdir.mp4", |
|
"$topdir/media/FirstFrame.png", |
|
"$topdir/media/player.swf", |
|
"$topdir/media/swfobject.js", |
|
"$topdir/media/expressInstall.swf"); |
|
my @diffs = &compare_arrays(\@paths,\@camtasia); |
|
if (@diffs == 0) { |
|
$is_camtasia = 1; |
|
} |
|
} |
|
my $output; |
|
if ($is_camtasia) { |
|
$output = <<"ENDCAM"; |
|
<script type="text/javascript" language="Javascript"> |
|
// <![CDATA[ |
|
|
|
function camtasiaToggle() { |
|
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].value == 1) { |
|
|
|
document.getElementById('camtasia_titles').style.display='block'; |
|
} else { |
|
document.getElementById('camtasia_titles').style.display='none'; |
|
} |
|
} |
|
} |
|
return; |
} |
} |
|
|
|
// ]]> |
|
</script> |
|
<p>$lt{'camt'}</p> |
|
ENDCAM |
|
} else { |
|
$output = '<p>'.$lt{'this'}; |
|
if ($info eq '') { |
|
$output .= ' '.$lt{'youm'}.'</p>'."\n"; |
|
} else { |
|
$output .= ' '.$lt{'itsc'}.'</p>'."\n". |
|
'<div><pre>'.$info.'</pre></div>'; |
|
} |
|
} |
|
$output .= '<form name="uploaded_decompress" action="'.$action.'" method="post">'."\n"; |
|
my $duplicates; |
|
my $num = 0; |
|
if (ref($dirlist) eq 'ARRAY') { |
|
foreach my $item (@{$dirlist}) { |
|
if (ref($item) eq 'ARRAY') { |
|
if (exists($toplevel{$item->[0]})) { |
|
$duplicates .= |
|
&start_data_table_row(). |
|
'<td><label><input type="radio" name="archive_overwrite_'.$num.'" '. |
|
'value="0" checked="checked" />'.&mt('No').'</label>'. |
|
' <label><input type="radio" name="archive_overwrite_'.$num.'" '. |
|
'value="1" />'.&mt('Yes').'</label>'. |
|
'<input type="hidden" name="archive_overwrite_name_'.$num.'" value="'.$item->[0].'" /></td>'."\n". |
|
'<td>'.$item->[0].'</td>'; |
|
if ($item->[2]) { |
|
$duplicates .= '<td>'.&mt('Directory').'</td>'; |
|
} else { |
|
$duplicates .= '<td>'.&mt('File').'</td>'; |
|
} |
|
$duplicates .= '<td>'.$item->[3].'</td>'. |
|
'<td>'. |
|
&Apache::lonlocal::locallocaltime($item->[4]). |
|
'</td>'. |
|
&end_data_table_row(); |
|
$num ++; |
|
} |
|
} |
|
} |
|
} |
|
my $itemcount; |
|
if (@paths > 0) { |
|
$itemcount = scalar(@paths); |
|
} else { |
|
$itemcount = 1; |
|
} |
|
if ($is_camtasia) { |
|
$output .= $lt{'auto'}.'<br />'. |
|
'<span class="LC_nobreak">'.$lt{'proa'}.'<label>'. |
|
'<input type="radio" name="autoextract_camtasia" value="1" onclick="javascript:camtasiaToggle();" checked="checked" />'. |
|
$lt{'yes'}.'</label> <label>'. |
|
'<input type="radio" name="autoextract_camtasia" value="0" onclick="javascript:camtasiaToggle();" />'. |
|
$lt{'no'}.'</label></span><br />'. |
|
'<div id="camtasia_titles" style="display:block">'. |
|
&Apache::lonhtmlcommon::start_pick_box(). |
|
&Apache::lonhtmlcommon::row_title($lt{'fold'}). |
|
'<input type="textbox" name="camtasia_foldername" value="'.$env{'form.comment'}.'" />'."\n". |
|
&Apache::lonhtmlcommon::row_closure(). |
|
&Apache::lonhtmlcommon::row_title($lt{'movi'}). |
|
'<input type="textbox" name="camtasia_moviename" value="" />'."\n". |
|
&Apache::lonhtmlcommon::row_closure(1). |
|
&Apache::lonhtmlcommon::end_pick_box(). |
|
'</div>'; |
|
} |
|
$output .= |
|
'<input type="hidden" name="archive_overwrite_total" value="'.$num.'" />'. |
|
'<input type="hidden" name="archive_itemcount" value="'.$itemcount.'" />'. |
|
"\n"; |
|
if ($duplicates ne '') { |
|
$output .= '<p><span class="LC_warning">'. |
|
&mt('Warning: decompression of the archive will overwrite the following items which already exist:').'</span><br />'. |
|
&start_data_table(). |
|
&start_data_table_header_row(). |
|
'<th>'.&mt('Overwrite?').'</th>'. |
|
'<th>'.&mt('Name').'</th>'. |
|
'<th>'.&mt('Type').'</th>'. |
|
'<th>'.&mt('Size').'</th>'. |
|
'<th>'.&mt('Last modified').'</th>'. |
|
&end_data_table_header_row(). |
|
$duplicates. |
|
&end_data_table(). |
|
'</p>'; |
|
} |
|
$output .= '<input type="hidden" name="archiveurl" value="'.$archiveurl.'" />'."\n"; |
|
if (ref($hiddenelements) eq 'HASH') { |
|
foreach my $hidden (sort(keys(%{$hiddenelements}))) { |
|
$output .= '<input type="hidden" name="'.$hidden.'" value="'.$hiddenelements->{$hidden}.'" />'."\n"; |
|
} |
|
} |
|
$output .= <<"END"; |
|
<br /> |
|
<input type="submit" name="decompress" value="$lt{'extr'}" /> |
|
</form> |
|
$noextract |
|
END |
|
return $output; |
|
} |
|
|
|
sub decompression_utility { |
|
my ($program) = @_; |
|
my @utilities = ('tar','gunzip','bunzip2','unzip'); |
|
my $location; |
|
if (grep(/^\Q$program\E$/,@utilities)) { |
|
foreach my $dir ('/bin/','/usr/bin/','/usr/local/bin/','/sbin/', |
|
'/usr/sbin/') { |
|
if (-x $dir.$program) { |
|
$location = $dir.$program; |
|
last; |
|
} |
|
} |
|
} |
|
return $location; |
|
} |
|
|
|
sub list_archive_contents { |
|
my ($file,$pathsref) = @_; |
|
my (@cmd,$output); |
|
my $needsregexp; |
|
if ($file =~ /\.zip$/) { |
|
@cmd = (&decompression_utility('unzip'),"-l"); |
|
$needsregexp = 1; |
|
} elsif (($file =~ m/\.tar\.gz$/) || |
|
($file =~ /\.tgz$/)) { |
|
@cmd = (&decompression_utility('tar'),"-ztf"); |
|
} elsif ($file =~ /\.tar\.bz2$/) { |
|
@cmd = (&decompression_utility('tar'),"-jtf"); |
|
} elsif ($file =~ m|\.tar$|) { |
|
@cmd = (&decompression_utility('tar'),"-tf"); |
|
} |
|
if (@cmd) { |
|
undef($!); |
|
undef($@); |
|
if (open(my $fh,"-|", @cmd, $file)) { |
|
while (my $line = <$fh>) { |
|
$output .= $line; |
|
chomp($line); |
|
my $item; |
|
if ($needsregexp) { |
|
($item) = ($line =~ /^\s*\d+\s+[\d\-]+\s+[\d:]+\s*(.+)$/); |
|
} else { |
|
$item = $line; |
|
} |
|
if ($item ne '') { |
|
unless (grep(/^\Q$item\E$/,@{$pathsref})) { |
|
push(@{$pathsref},$item); |
|
} |
|
} |
|
} |
|
close($fh); |
|
} |
|
} |
|
return $output; |
|
} |
|
|
|
sub decompress_uploaded_file { |
|
my ($file,$dir) = @_; |
|
&Apache::lonnet::appenv({'cgi.file' => $file}); |
|
&Apache::lonnet::appenv({'cgi.dir' => $dir}); |
|
my $result = &Apache::lonnet::ssi_body('/cgi-bin/decompress.pl'); |
|
my ($handle) = ($env{'user.environment'} =~m{/([^/]+)\.id$}); |
|
my $lonidsdir = $Apache::lonnet::perlvar{'lonIDsDir'}; |
|
&Apache::lonnet::transfer_profile_to_env($lonidsdir,$handle,1); |
|
my $decompressed = $env{'cgi.decompressed'}; |
|
&Apache::lonnet::delenv('cgi.file'); |
|
&Apache::lonnet::delenv('cgi.dir'); |
|
&Apache::lonnet::delenv('cgi.decompressed'); |
|
return ($decompressed,$result); |
|
} |
|
|
|
sub process_decompression { |
|
my ($docudom,$docuname,$file,$destination,$dir_root,$hiddenelem) = @_; |
|
my ($dir,$error,$warning,$output); |
|
if ($file !~ /\.(zip|tar|bz2|gz|tar.gz|tar.bz2|tgz)$/) { |
|
$error = &mt('File name not a supported archive file type.'). |
|
'<br />'.&mt('File name should end with one of: [_1].', |
|
'.zip, .tar, .bz2, .gz, .tar.gz, .tar.bz2, .tgz'); |
|
} else { |
|
my $docuhome = &Apache::lonnet::homeserver($docuname,$docudom); |
|
if ($docuhome eq 'no_host') { |
|
$error = &mt('Could not determine home server for course.'); |
|
} else { |
|
my @ids=&Apache::lonnet::current_machine_ids(); |
|
my $currdir = "$dir_root/$destination"; |
|
if (grep(/^\Q$docuhome\E$/,@ids)) { |
|
$dir = &LONCAPA::propath($docudom,$docuname). |
|
"$dir_root/$destination"; |
|
} else { |
|
$dir = $Apache::lonnet::perlvar{'lonDocRoot'}. |
|
"$dir_root/$docudom/$docuname/$destination"; |
|
unless (&Apache::lonnet::repcopy_userfile("$dir/$file") eq 'ok') { |
|
$error = &mt('Archive file not found.'); |
|
} |
|
} |
|
my (@to_overwrite,@to_skip); |
|
if ($env{'form.archive_overwrite_total'} > 0) { |
|
my $total = $env{'form.archive_overwrite_total'}; |
|
for (my $i=0; $i<$total; $i++) { |
|
if ($env{'form.archive_overwrite_'.$i} == 1) { |
|
push(@to_overwrite,$env{'form.archive_overwrite_name_'.$i}); |
|
} elsif ($env{'form.archive_overwrite_'.$i} == 0) { |
|
push(@to_skip,$env{'form.archive_overwrite_name_'.$i}); |
|
} |
|
} |
|
} |
|
my $numskip = scalar(@to_skip); |
|
if (($numskip > 0) && |
|
($numskip == $env{'form.archive_itemcount'})) { |
|
$warning = &mt('All items in the archive file already exist, and no overwriting of existing files has been requested.'); |
|
} elsif ($dir eq '') { |
|
$error = &mt('Directory containing archive file unavailable.'); |
|
} elsif (!$error) { |
|
my ($decompressed,$display); |
|
if ($numskip > 0) { |
|
my $tempdir = time.'_'.$$.int(rand(10000)); |
|
mkdir("$dir/$tempdir",0755); |
|
system("mv $dir/$file $dir/$tempdir/$file"); |
|
($decompressed,$display) = |
|
&decompress_uploaded_file($file,"$dir/$tempdir"); |
|
foreach my $item (@to_skip) { |
|
if (($item ne '') && ($item !~ /\.\./)) { |
|
if (-f "$dir/$tempdir/$item") { |
|
unlink("$dir/$tempdir/$item"); |
|
} elsif (-d "$dir/$tempdir/$item") { |
|
system("rm -rf $dir/$tempdir/$item"); |
|
} |
|
} |
|
} |
|
system("mv $dir/$tempdir/* $dir"); |
|
rmdir("$dir/$tempdir"); |
|
} else { |
|
($decompressed,$display) = |
|
&decompress_uploaded_file($file,$dir); |
|
} |
|
if ($decompressed eq 'ok') { |
|
$output = '<p class="LC_info">'. |
|
&mt('Files extracted successfully from archive.'). |
|
'</p>'."\n"; |
|
my ($warning,$result,@contents); |
|
my ($newdirlistref,$newlisterror) = |
|
&Apache::lonnet::dirlist($currdir,$docudom, |
|
$docuname,1); |
|
my (%is_dir,%changes,@newitems); |
|
my $dirptr = 16384; |
|
if (ref($newdirlistref) eq 'ARRAY') { |
|
foreach my $dir_line (@{$newdirlistref}) { |
|
my ($item,undef,undef,$testdir)=split(/\&/,$dir_line,5); |
|
unless (($item =~ /^\.+$/) || ($item eq $file) || |
|
((@to_skip > 0) && (grep(/^\Q$item\E$/,@to_skip)))) { |
|
push(@newitems,$item); |
|
if ($dirptr&$testdir) { |
|
$is_dir{$item} = 1; |
|
} |
|
$changes{$item} = 1; |
|
} |
|
} |
|
} |
|
if (keys(%changes) > 0) { |
|
foreach my $item (sort(@newitems)) { |
|
if ($changes{$item}) { |
|
push(@contents,$item); |
|
} |
|
} |
|
} |
|
if (@contents > 0) { |
|
my $wantform; |
|
unless ($env{'form.autoextract_camtasia'}) { |
|
$wantform = 1; |
|
} |
|
my (%children,%parent,%dirorder,%titles); |
|
my ($count,$datatable) = &get_extracted($docudom,$docuname, |
|
$currdir,\%is_dir, |
|
\%children,\%parent, |
|
\@contents,\%dirorder, |
|
\%titles,$wantform); |
|
if ($datatable ne '') { |
|
$output .= &archive_options_form('decompressed',$datatable, |
|
$count,$hiddenelem); |
|
my $startcount = 6; |
|
$output .= &archive_javascript($startcount,$count, |
|
\%titles,\%children); |
|
} |
|
if ($env{'form.autoextract_camtasia'}) { |
|
my %displayed; |
|
my $total = 1; |
|
$env{'form.archive_directory'} = []; |
|
foreach my $i (sort { $a <=> $b } keys(%dirorder)) { |
|
my $path = join('/',map { $titles{$_}; } @{$dirorder{$i}}); |
|
$path =~ s{/$}{}; |
|
my $item; |
|
if ($path ne '') { |
|
$item = "$path/$titles{$i}"; |
|
} else { |
|
$item = $titles{$i}; |
|
} |
|
$env{'form.archive_content_'.$i} = "$dir_root/$destination/$item"; |
|
if ($item eq $contents[0]) { |
|
push(@{$env{'form.archive_directory'}},$i); |
|
$env{'form.archive_'.$i} = 'display'; |
|
$env{'form.archive_title_'.$i} = $env{'form.camtasia_foldername'}; |
|
$displayed{'folder'} = $i; |
|
} elsif ($item eq "$contents[0]/index.html") { |
|
$env{'form.archive_'.$i} = 'display'; |
|
$env{'form.archive_title_'.$i} = $env{'form.camtasia_moviename'}; |
|
$displayed{'web'} = $i; |
|
} else { |
|
if ($item eq "$contents[0]/media") { |
|
push(@{$env{'form.archive_directory'}},$i); |
|
} |
|
$env{'form.archive_'.$i} = 'dependency'; |
|
} |
|
$total ++; |
|
} |
|
for (my $i=1; $i<$total; $i++) { |
|
next if ($i == $displayed{'web'}); |
|
next if ($i == $displayed{'folder'}); |
|
$env{'form.archive_dependent_on_'.$i} = $displayed{'web'}; |
|
} |
|
$env{'form.phase'} = 'decompress_cleanup'; |
|
$env{'form.archivedelete'} = 1; |
|
$env{'form.archive_count'} = $total-1; |
|
$output .= |
|
&process_extracted_files('coursedocs',$docudom, |
|
$docuname,$destination, |
|
$dir_root,$hiddenelem); |
|
} |
|
} else { |
|
$warning = &mt('No new items extracted from archive file.'); |
|
} |
|
} else { |
|
$output = $display; |
|
$error = &mt('An error occurred during extraction from the archive file.'); |
|
} |
|
} |
|
} |
|
} |
|
if ($error) { |
|
$output .= '<p class="LC_error">'.&mt('Not extracted.').'<br />'. |
|
$error.'</p>'."\n"; |
|
} |
|
if ($warning) { |
|
$output .= '<p class="LC_warning">'.$warning.'</p>'."\n"; |
|
} |
|
return $output; |
|
} |
|
|
|
sub get_extracted { |
|
my ($docudom,$docuname,$currdir,$is_dir,$children,$parent,$contents,$dirorder, |
|
$titles,$wantform) = @_; |
|
my $count = 0; |
|
my $depth = 0; |
|
my $datatable; |
|
my @hierarchy; |
|
return unless ((ref($is_dir) eq 'HASH') && (ref($children) eq 'HASH') && |
|
(ref($parent) eq 'HASH') && (ref($contents) eq 'ARRAY') && |
|
(ref($dirorder) eq 'HASH') && (ref($titles) eq 'HASH')); |
|
foreach my $item (@{$contents}) { |
|
$count ++; |
|
@{$dirorder->{$count}} = @hierarchy; |
|
$titles->{$count} = $item; |
|
&archive_hierarchy($depth,$count,$parent,$children); |
|
if ($wantform) { |
|
$datatable .= &archive_row($is_dir->{$item},$item, |
|
$currdir,$depth,$count); |
|
} |
|
if ($is_dir->{$item}) { |
|
$depth ++; |
|
push(@hierarchy,$count); |
|
$parent->{$depth} = $count; |
|
$datatable .= |
|
&recurse_extracted_archive("$currdir/$item",$docudom,$docuname, |
|
\$depth,\$count,\@hierarchy,$dirorder, |
|
$children,$parent,$titles,$wantform); |
|
$depth --; |
|
pop(@hierarchy); |
|
} |
|
} |
|
return ($count,$datatable); |
|
} |
|
|
|
sub recurse_extracted_archive { |
|
my ($currdir,$docudom,$docuname,$depth,$count,$hierarchy,$dirorder, |
|
$children,$parent,$titles,$wantform) = @_; |
|
my $result=''; |
|
unless ((ref($depth)) && (ref($count)) && (ref($hierarchy) eq 'ARRAY') && |
|
(ref($children) eq 'HASH') && (ref($parent) eq 'HASH') && |
|
(ref($dirorder) eq 'HASH')) { |
|
return $result; |
|
} |
|
my $dirptr = 16384; |
|
my ($newdirlistref,$newlisterror) = |
|
&Apache::lonnet::dirlist($currdir,$docudom,$docuname,1); |
|
if (ref($newdirlistref) eq 'ARRAY') { |
|
foreach my $dir_line (@{$newdirlistref}) { |
|
my ($item,undef,undef,$testdir)=split(/\&/,$dir_line,5); |
|
unless ($item =~ /^\.+$/) { |
|
$$count ++; |
|
@{$dirorder->{$$count}} = @{$hierarchy}; |
|
$titles->{$$count} = $item; |
|
&archive_hierarchy($$depth,$$count,$parent,$children); |
|
|
|
my $is_dir; |
|
if ($dirptr&$testdir) { |
|
$is_dir = 1; |
|
} |
|
if ($wantform) { |
|
$result .= &archive_row($is_dir,$item,$currdir,$$depth,$$count); |
|
} |
|
if ($is_dir) { |
|
$$depth ++; |
|
push(@{$hierarchy},$$count); |
|
$parent->{$$depth} = $$count; |
|
$result .= |
|
&recurse_extracted_archive("$currdir/$item",$docudom, |
|
$docuname,$depth,$count, |
|
$hierarchy,$dirorder,$children, |
|
$parent,$titles,$wantform); |
|
$$depth --; |
|
pop(@{$hierarchy}); |
|
} |
|
} |
|
} |
|
} |
|
return $result; |
|
} |
|
|
|
sub archive_hierarchy { |
|
my ($depth,$count,$parent,$children) =@_; |
|
if ((ref($parent) eq 'HASH') && (ref($children) eq 'HASH')) { |
|
if (exists($parent->{$depth})) { |
|
$children->{$parent->{$depth}} .= $count.':'; |
|
} |
|
} |
|
return; |
|
} |
|
|
|
sub archive_row { |
|
my ($is_dir,$item,$currdir,$depth,$count) = @_; |
|
my ($name) = ($item =~ m{([^/]+)$}); |
|
my %choices = &Apache::lonlocal::texthash ( |
|
'display' => 'Add as file', |
|
'dependency' => 'Include as dependency', |
|
'discard' => 'Discard', |
|
); |
|
if ($is_dir) { |
|
$choices{'display'} = &mt('Add as folder'); |
|
} |
|
my $output = &start_data_table_row().'<td align="right">'.$count.'</td>'."\n"; |
|
my $offset = 0; |
|
foreach my $action ('display','dependency','discard') { |
|
$offset ++; |
|
if ($action ne 'display') { |
|
$offset ++; |
|
} |
|
$output .= '<td><span class="LC_nobreak">'. |
|
'<label><input type="radio" name="archive_'.$count. |
|
'" id="archive_'.$action.'_'.$count.'" value="'.$action.'"'; |
|
my $text = $choices{$action}; |
|
if ($is_dir) { |
|
$output .= ' onclick="javascript:propagateCheck(this.form,'."'$count'".');"'; |
|
if ($action eq 'display') { |
|
$text = &mt('Add as folder'); |
|
} |
|
} else { |
|
$output .= ' onclick="javascript:dependencyCheck(this.form,'."$count,$offset".');"'; |
|
|
|
} |
|
$output .= ' /> '.$choices{$action}.'</label></span>'; |
|
if ($action eq 'dependency') { |
|
$output .= '<div id="arc_depon_'.$count.'" style="display:none;">'."\n". |
|
&mt('Used by:').' <select name="archive_dependent_on_'.$count.'" '. |
|
'onchange="propagateSelect(this.form,'."$count,$offset".')">'."\n". |
|
'<option value=""></option>'."\n". |
|
'</select>'."\n". |
|
'</div>'; |
|
} elsif ($action eq 'display') { |
|
$output .= '<div id="arc_title_'.$count.'" style="display:none;">'."\n". |
|
&mt('Title:').' <input type="text" name="archive_title_'.$count.'" id="archive_title_'.$count.'" />'."\n". |
|
'</div>'; |
|
} |
|
$output .= '</td>'; |
|
} |
|
$output .= '<td><input type="hidden" name="archive_content_'.$count.'" value="'. |
|
&HTML::Entities::encode("$currdir/$item",'"<>&').'" />'.(' ' x 2); |
|
for (my $i=0; $i<$depth; $i++) { |
|
$output .= ('<img src="/adm/lonIcons/whitespace1.gif" class="LC_docs_spacer" alt="" />' x2)."\n"; |
|
} |
|
if ($is_dir) { |
|
$output .= '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" /> '."\n". |
|
'<input type="hidden" name="archive_directory" value="'.$count.'" />'."\n"; |
|
} else { |
|
$output .= '<input type="hidden" name="archive_file" value="'.$count.'" />'."\n"; |
|
} |
|
$output .= ' '.$name.'</td>'."\n". |
|
&end_data_table_row(); |
|
return $output; |
|
} |
|
|
|
sub archive_options_form { |
|
my ($form,$display,$count,$hiddenelem) = @_; |
|
my %lt = &Apache::lonlocal::texthash( |
|
perm => 'Permanently remove archive file?', |
|
hows => 'How should each extracted item be incorporated in the course?', |
|
cont => 'Content actions for all', |
|
addf => 'Add as folder/file', |
|
incd => 'Include as dependency for a displayed file', |
|
disc => 'Discard', |
|
no => 'No', |
|
yes => 'Yes', |
|
save => 'Save', |
|
); |
|
my $output = <<"END"; |
|
<form name="$form" method="post" action=""> |
|
<p><span class="LC_nobreak">$lt{'perm'} |
|
<label> |
|
<input type="radio" name="archivedelete" value="0" checked="checked" />$lt{'no'} |
|
</label> |
|
|
|
<label> |
|
<input type="radio" name="archivedelete" value="1" />$lt{'yes'}</label> |
|
</span> |
|
</p> |
|
<input type="hidden" name="phase" value="decompress_cleanup" /> |
|
<br />$lt{'hows'} |
|
<div class="LC_columnSection"> |
|
<fieldset> |
|
<legend>$lt{'cont'}</legend> |
|
<input type="button" value="$lt{'addf'}" onclick="javascript:checkAll(document.$form,'display');" /> |
|
<input type="button" value="$lt{'incd'}" onclick="javascript:checkAll(document.$form,'dependency');" /> |
|
<input type="button" value="$lt{'disc'}" onclick="javascript:checkAll(document.$form,'discard');" /> |
|
</fieldset> |
|
</div> |
|
END |
|
return $output. |
|
&start_data_table()."\n". |
|
$display."\n". |
|
&end_data_table()."\n". |
|
'<input type="hidden" name="archive_count" value="'.$count.'" />'. |
|
$hiddenelem. |
|
'<br /><input type="submit" name="archive_submit" value="'.$lt{'save'}.'" />'. |
|
'</form>'; |
|
} |
|
|
|
sub archive_javascript { |
|
my ($startcount,$numitems,$titles,$children) = @_; |
|
return unless ((ref($titles) eq 'HASH') && (ref($children) eq 'HASH')); |
|
my $maintitle = $env{'form.comment'}; |
|
my $scripttag = <<START; |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
|
|
function checkAll(form,prefix) { |
|
var idstr = new RegExp("^archive_"+prefix+"_\\\\d+\$"); |
|
for (var i=0; i < form.elements.length; i++) { |
|
var id = form.elements[i].id; |
|
if ((id != '') && (id != undefined)) { |
|
if (idstr.test(id)) { |
|
if (form.elements[i].type == 'radio') { |
|
form.elements[i].checked = true; |
|
var nostart = i-$startcount; |
|
var offset = nostart%7; |
|
var count = (nostart-offset)/7; |
|
dependencyCheck(form,count,offset); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
function propagateCheck(form,count) { |
|
if (count > 0) { |
|
var startelement = $startcount + ((count-1) * 7); |
|
for (var j=1; j<6; j++) { |
|
if ((j != 2) && (j != 4)) { |
|
var item = startelement + j; |
|
if (form.elements[item].type == 'radio') { |
|
if (form.elements[item].checked) { |
|
containerCheck(form,count,j); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
numitems = $numitems |
|
var titles = new Array(numitems); |
|
var parents = new Array(numitems); |
|
for (var i=0; i<numitems; i++) { |
|
parents[i] = new Array; |
|
} |
|
var maintitle = '$maintitle'; |
|
|
|
START |
|
|
|
foreach my $container (sort { $a <=> $b } (keys(%{$children}))) { |
|
my @contents = split(/:/,$children->{$container}); |
|
for (my $i=0; $i<@contents; $i ++) { |
|
$scripttag .= 'parents['.$container.']['.$i.'] = '.$contents[$i]."\n"; |
|
} |
|
} |
|
|
|
foreach my $key (sort { $a <=> $b } (keys(%{$titles}))) { |
|
$scripttag .= "titles[$key] = '".$titles->{$key}."';\n"; |
|
} |
|
|
|
$scripttag .= <<END; |
|
|
|
function containerCheck(form,count,offset) { |
|
if (count > 0) { |
|
dependencyCheck(form,count,offset); |
|
var item = (offset+$startcount)+7*(count-1); |
|
form.elements[item].checked = true; |
|
if(Object.prototype.toString.call(parents[count]) === '[object Array]') { |
|
if (parents[count].length > 0) { |
|
for (var j=0; j<parents[count].length; j++) { |
|
containerCheck(form,parents[count][j],offset); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
function dependencyCheck(form,count,offset) { |
|
if (count > 0) { |
|
var chosen = (offset+$startcount)+7*(count-1); |
|
var depitem = $startcount + ((count-1) * 7) + 4; |
|
var currtype = form.elements[depitem].type; |
|
if (form.elements[chosen].value == 'dependency') { |
|
document.getElementById('arc_depon_'+count).style.display='block'; |
|
form.elements[depitem].options.length = 0; |
|
form.elements[depitem].options[0] = new Option('Select','',true,true); |
|
for (var i=1; i<=numitems; i++) { |
|
if (i == count) { |
|
continue; |
|
} |
|
var startelement = $startcount + (i-1) * 7; |
|
for (var j=1; j<6; j++) { |
|
if ((j != 2) && (j!= 4)) { |
|
var item = startelement + j; |
|
if (form.elements[item].type == 'radio') { |
|
if (form.elements[item].checked) { |
|
if (form.elements[item].value == 'display') { |
|
var n = form.elements[depitem].options.length; |
|
form.elements[depitem].options[n] = new Option(titles[i],i,false,false); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} else { |
|
document.getElementById('arc_depon_'+count).style.display='none'; |
|
form.elements[depitem].options.length = 0; |
|
form.elements[depitem].options[0] = new Option('Select','',true,true); |
|
} |
|
titleCheck(form,count,offset); |
|
} |
|
} |
|
|
|
function propagateSelect(form,count,offset) { |
|
if (count > 0) { |
|
var item = (1+offset+$startcount)+7*(count-1); |
|
var picked = form.elements[item].options[form.elements[item].selectedIndex].value; |
|
if (Object.prototype.toString.call(parents[count]) === '[object Array]') { |
|
if (parents[count].length > 0) { |
|
for (var j=0; j<parents[count].length; j++) { |
|
containerSelect(form,parents[count][j],offset,picked); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
function containerSelect(form,count,offset,picked) { |
|
if (count > 0) { |
|
var item = (offset+$startcount)+7*(count-1); |
|
if (form.elements[item].type == 'radio') { |
|
if (form.elements[item].value == 'dependency') { |
|
if (form.elements[item+1].type == 'select-one') { |
|
for (var i=0; i<form.elements[item+1].options.length; i++) { |
|
if (form.elements[item+1].options[i].value == picked) { |
|
form.elements[item+1].selectedIndex = i; |
|
break; |
|
} |
|
} |
|
} |
|
if (Object.prototype.toString.call(parents[count]) === '[object Array]') { |
|
if (parents[count].length > 0) { |
|
for (var j=0; j<parents[count].length; j++) { |
|
containerSelect(form,parents[count][j],offset,picked); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
function titleCheck(form,count,offset) { |
|
if (count > 0) { |
|
var chosen = (offset+$startcount)+7*(count-1); |
|
var depitem = $startcount + ((count-1) * 7) + 2; |
|
var currtype = form.elements[depitem].type; |
|
if (form.elements[chosen].value == 'display') { |
|
document.getElementById('arc_title_'+count).style.display='block'; |
|
if ((count==1) && ((parents[count].length > 0) || (numitems == 1))) { |
|
document.getElementById('archive_title_'+count).value=maintitle; |
|
} |
|
} else { |
|
document.getElementById('arc_title_'+count).style.display='none'; |
|
if (currtype == 'text') { |
|
document.getElementById('archive_title_'+count).value=''; |
|
} |
|
} |
|
} |
|
return; |
|
} |
|
|
|
// ]]> |
|
</script> |
|
END |
|
return $scripttag; |
|
} |
|
|
|
sub process_extracted_files { |
|
my ($context,$docudom,$docuname,$destination,$dir_root,$hiddenelem) = @_; |
|
my $numitems = $env{'form.archive_count'}; |
|
return unless ($numitems); |
|
my @ids=&Apache::lonnet::current_machine_ids(); |
|
my ($prefix,$pathtocheck,$dir,$ishome,$error,$warning,%toplevelitems,%is_dir, |
|
%folders,%containers,%mapinner,%prompttofetch); |
|
my $docuhome = &Apache::lonnet::homeserver($docuname,$docudom); |
|
if (grep(/^\Q$docuhome\E$/,@ids)) { |
|
$prefix = &LONCAPA::propath($docudom,$docuname); |
|
$pathtocheck = "$dir_root/$destination"; |
|
$dir = $dir_root; |
|
$ishome = 1; |
|
} else { |
|
$prefix = $Apache::lonnet::perlvar{'lonDocRoot'}; |
|
$pathtocheck = "$dir_root/$docudom/$docuname/$destination"; |
|
$dir = "$dir_root/$docudom/$docuname"; |
|
} |
|
my $currdir = "$dir_root/$destination"; |
|
(my $docstype,$mapinner{'0'}) = ($destination =~ m{^(docs|supplemental)/(\w+)/}); |
|
if ($env{'form.folderpath'}) { |
|
my @items = split('&',$env{'form.folderpath'}); |
|
$folders{'0'} = $items[-2]; |
|
if ($env{'form.folderpath'} =~ /\:1$/) { |
|
$containers{'0'}='page'; |
|
} else { |
|
$containers{'0'}='sequence'; |
|
} |
|
} |
|
my @archdirs = &get_env_multiple('form.archive_directory'); |
|
if ($numitems) { |
|
for (my $i=1; $i<=$numitems; $i++) { |
|
my $path = $env{'form.archive_content_'.$i}; |
|
if ($path =~ m{^\Q$pathtocheck\E/([^/]+)$}) { |
|
my $item = $1; |
|
$toplevelitems{$item} = $i; |
|
if (grep(/^\Q$i\E$/,@archdirs)) { |
|
$is_dir{$item} = 1; |
|
} |
|
} |
|
} |
|
} |
|
my ($output,%children,%parent,%titles,%dirorder,$result); |
|
if (keys(%toplevelitems) > 0) { |
|
my @contents = sort(keys(%toplevelitems)); |
|
(my $count,undef) = &get_extracted($docudom,$docuname,$currdir,\%is_dir,\%children, |
|
\%parent,\@contents,\%dirorder,\%titles); |
|
} |
|
my (%referrer,%orphaned,%todelete,%todeletedir,%newdest,%newseqid); |
|
if ($numitems) { |
|
for (my $i=1; $i<=$numitems; $i++) { |
|
next if ($env{'form.archive_'.$i} eq 'dependency'); |
|
my $path = $env{'form.archive_content_'.$i}; |
|
if ($path =~ /^\Q$pathtocheck\E/) { |
|
if ($env{'form.archive_'.$i} eq 'discard') { |
|
if ($prefix ne '' && $path ne '') { |
|
if (-e $prefix.$path) { |
|
if ((@archdirs > 0) && |
|
(grep(/^\Q$i\E$/,@archdirs))) { |
|
$todeletedir{$prefix.$path} = 1; |
|
} else { |
|
$todelete{$prefix.$path} = 1; |
|
} |
|
} |
|
} |
|
} elsif ($env{'form.archive_'.$i} eq 'display') { |
|
my ($docstitle,$title,$url,$outer); |
|
($title) = ($path =~ m{/([^/]+)$}); |
|
$docstitle = $env{'form.archive_title_'.$i}; |
|
if ($docstitle eq '') { |
|
$docstitle = $title; |
|
} |
|
$outer = 0; |
|
if (ref($dirorder{$i}) eq 'ARRAY') { |
|
if (@{$dirorder{$i}} > 0) { |
|
foreach my $item (reverse(@{$dirorder{$i}})) { |
|
if ($env{'form.archive_'.$item} eq 'display') { |
|
$outer = $item; |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
my ($errtext,$fatal) = |
|
&LONCAPA::map::mapread('/uploaded/'.$docudom.'/'.$docuname. |
|
'/'.$folders{$outer}.'.'. |
|
$containers{$outer}); |
|
next if ($fatal); |
|
if ((@archdirs > 0) && (grep(/^\Q$i\E$/,@archdirs))) { |
|
if ($context eq 'coursedocs') { |
|
$mapinner{$i} = time; |
|
$folders{$i} = 'default_'.$mapinner{$i}; |
|
$containers{$i} = 'sequence'; |
|
my $url = '/uploaded/'.$docudom.'/'.$docuname.'/'. |
|
$folders{$i}.'.'.$containers{$i}; |
|
my $newidx = &LONCAPA::map::getresidx(); |
|
$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); |
|
$newseqid{$i} = $newidx; |
|
unless ($errtext) { |
|
$result .= '<li>'.&mt('Folder: [_1] added to course',$docstitle).'</li>'."\n"; |
|
} |
|
} |
|
} else { |
|
if ($context eq 'coursedocs') { |
|
my $newidx=&LONCAPA::map::getresidx(); |
|
my $url = '/uploaded/'.$docudom.'/'.$docuname.'/'. |
|
$docstype.'/'.$mapinner{$outer}.'/'.$newidx.'/'. |
|
$title; |
|
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; |
|
} |
|
} |
|
$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',$docstitle).'</li>'."\n"; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} else { |
|
$warning .= &mt('Item extracted from archive: [_1] has unexpected path.',$path).'<br />'; |
|
} |
|
} |
|
for (my $i=1; $i<=$numitems; $i++) { |
|
next unless ($env{'form.archive_'.$i} eq 'dependency'); |
|
my $path = $env{'form.archive_content_'.$i}; |
|
if ($path =~ /^\Q$pathtocheck\E/) { |
|
my ($title) = ($path =~ m{/([^/]+)$}); |
|
$referrer{$i} = $env{'form.archive_dependent_on_'.$i}; |
|
if ($env{'form.archive_'.$referrer{$i}} eq 'display') { |
|
if (ref($dirorder{$i}) eq 'ARRAY') { |
|
my ($itemidx,$fullpath,$relpath); |
|
if (ref($dirorder{$referrer{$i}}) eq 'ARRAY') { |
|
my $container = $dirorder{$referrer{$i}}->[-1]; |
|
for (my $j=0; $j<@{$dirorder{$i}}; $j++) { |
|
if ($dirorder{$i}->[$j] eq $container) { |
|
$itemidx = $j; |
|
} |
|
} |
|
} |
|
if ($itemidx eq '') { |
|
$itemidx = 0; |
|
} |
|
if (grep(/^\Q$referrer{$i}\E$/,@archdirs)) { |
|
if ($mapinner{$referrer{$i}}) { |
|
$fullpath = "$prefix$dir/$docstype/$mapinner{$referrer{$i}}"; |
|
for (my $j=$itemidx; $j<@{$dirorder{$i}}; $j++) { |
|
if (grep(/^\Q$dirorder{$i}->[$j]\E$/,@archdirs)) { |
|
unless (defined($newseqid{$dirorder{$i}->[$j]})) { |
|
$fullpath .= '/'.$titles{$dirorder{$i}->[$j]}; |
|
$relpath .= '/'.$titles{$dirorder{$i}->[$j]}; |
|
if (!-e $fullpath) { |
|
mkdir($fullpath,0755); |
|
} |
|
} |
|
} else { |
|
last; |
|
} |
|
} |
|
} |
|
} elsif ($newdest{$referrer{$i}}) { |
|
$fullpath = $newdest{$referrer{$i}}; |
|
for (my $j=$itemidx; $j<@{$dirorder{$i}}; $j++) { |
|
if ($env{'form.archive_'.$dirorder{$i}->[$j]} eq 'discard') { |
|
$orphaned{$i} = $env{'form.archive_'.$dirorder{$i}->[$j]}; |
|
last; |
|
} elsif (grep(/^\Q$dirorder{$i}->[$j]\E$/,@archdirs)) { |
|
unless (defined($newseqid{$dirorder{$i}->[$j]})) { |
|
$fullpath .= '/'.$titles{$dirorder{$i}->[$j]}; |
|
$relpath .= '/'.$titles{$dirorder{$i}->[$j]}; |
|
if (!-e $fullpath) { |
|
mkdir($fullpath,0755); |
|
} |
|
} |
|
} else { |
|
last; |
|
} |
|
} |
|
} |
|
if ($fullpath ne '') { |
|
if (-e "$prefix$path") { |
|
system("mv $prefix$path $fullpath/$title"); |
|
} |
|
if (-e "$fullpath/$title") { |
|
my $showpath; |
|
if ($relpath ne '') { |
|
$showpath = "$relpath/$title"; |
|
} else { |
|
$showpath = "/$title"; |
|
} |
|
$result .= '<li>'.&mt('[_1] included as a dependency',$showpath).'</li>'."\n"; |
|
} |
|
unless ($ishome) { |
|
my $fetch = "$fullpath/$title"; |
|
$fetch =~ s/^\Q$prefix$dir\E//; |
|
$prompttofetch{$fetch} = 1; |
|
} |
|
} |
|
} |
|
} elsif ($env{'form.archive_'.$referrer{$i}} eq 'discard') { |
|
$warning .= &mt('[_1] is a dependency of [_2], which was discarded.', |
|
$path,$env{'form.archive_content_'.$referrer{$i}}).'<br />'; |
|
} |
|
} else { |
|
$warning .= &mt('Item extracted from archive: [_1] has unexpected path.',$path).'<br />'; |
|
} |
|
} |
|
if (keys(%todelete)) { |
|
foreach my $key (keys(%todelete)) { |
|
unlink($key); |
|
} |
|
} |
|
if (keys(%todeletedir)) { |
|
foreach my $key (keys(%todeletedir)) { |
|
rmdir($key); |
|
} |
|
} |
|
foreach my $dir (sort(keys(%is_dir))) { |
|
if (($pathtocheck ne '') && ($dir ne '')) { |
|
&cleanup_empty_dirs($prefix."$pathtocheck/$dir"); |
|
} |
|
} |
|
if ($result ne '') { |
|
$output .= '<ul>'."\n". |
|
$result."\n". |
|
'</ul>'; |
|
} |
|
unless ($ishome) { |
|
my $replicationfail; |
|
foreach my $item (keys(%prompttofetch)) { |
|
my $fetchresult= &Apache::lonnet::reply('fetchuserfile:'.$item,$docuhome); |
|
unless ($fetchresult eq 'ok') { |
|
$replicationfail .= '<li>'.$item.'</li>'."\n"; |
|
} |
|
} |
|
if ($replicationfail) { |
|
$output .= '<p class="LC_error">'. |
|
&mt('Course home server failed to retrieve:').'<ul>'. |
|
$replicationfail. |
|
'</ul></p>'; |
|
} |
|
} |
|
} else { |
|
$warning = &mt('No items found in archive.'); |
|
} |
|
if ($error) { |
|
$output .= '<p class="LC_error">'.&mt('Not extracted.').'<br />'. |
|
$error.'</p>'."\n"; |
|
} |
|
if ($warning) { |
|
$output .= '<p class="LC_warning">'.$warning.'</p>'."\n"; |
|
} |
|
return $output; |
|
} |
|
|
|
sub cleanup_empty_dirs { |
|
my ($path) = @_; |
|
if (($path ne '') && (-d $path)) { |
|
if (opendir(my $dirh,$path)) { |
|
my @dircontents = grep(!/^\./,readdir($dirh)); |
|
my $numitems = 0; |
|
foreach my $item (@dircontents) { |
|
if (-d "$path/$item") { |
|
&cleanup_empty_dirs("$path/$item"); |
|
if (-e "$path/$item") { |
|
$numitems ++; |
|
} |
|
} else { |
|
$numitems ++; |
|
} |
|
} |
|
if ($numitems == 0) { |
|
rmdir($path); |
|
} |
|
closedir($dirh); |
|
} |
|
} |
|
return; |
|
} |
|
|
|
=pod |
|
|
|
=item &get_folder_hierarchy() |
|
|
|
Provides hierarchy of names of folders/sub-folders containing the current |
|
item, |
|
|
|
Inputs: 3 |
|
- $navmap - navmaps object |
|
|
|
- $map - url for map (either the trigger itself, or map containing |
|
the resource, which is the trigger). |
|
|
|
- $showitem - 1 => show title for map itself; 0 => do not show. |
|
|
|
Outputs: 1 @pathitems - array of folder/subfolder names. |
|
|
|
=cut |
|
|
|
sub get_folder_hierarchy { |
|
my ($navmap,$map,$showitem) = @_; |
|
my @pathitems; |
|
if (ref($navmap)) { |
|
my $mapres = $navmap->getResourceByUrl($map); |
|
if (ref($mapres)) { |
|
my $pcslist = $mapres->map_hierarchy(); |
|
if ($pcslist ne '') { |
|
my @pcs = split(/,/,$pcslist); |
|
foreach my $pc (@pcs) { |
|
if ($pc == 1) { |
|
push(@pathitems,&mt('Main Course Documents')); |
|
} else { |
|
my $res = $navmap->getByMapPc($pc); |
|
if (ref($res)) { |
|
my $title = $res->compTitle(); |
|
$title =~ s/\W+/_/g; |
|
if ($title ne '') { |
|
push(@pathitems,$title); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if ($showitem) { |
|
if ($mapres->{ID} eq '0.0') { |
|
push(@pathitems,&mt('Main Course Documents')); |
|
} else { |
|
my $maptitle = $mapres->compTitle(); |
|
$maptitle =~ s/\W+/_/g; |
|
if ($maptitle ne '') { |
|
push(@pathitems,$maptitle); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
return @pathitems; |
|
} |
|
|
|
=pod |
|
|
|
=item * &get_turnedin_filepath() |
|
|
|
Determines path in a user's portfolio file for storage of files uploaded |
|
to a specific essayresponse or dropbox item. |
|
|
|
Inputs: 3 required + 1 optional. |
|
$symb is symb for resource, $uname and $udom are for current user (required). |
|
$caller is optional (can be "submission", if routine is called when storing |
|
an upoaded file when "Submit Answer" button was pressed). |
|
|
|
Returns array containing $path and $multiresp. |
|
$path is path in portfolio. $multiresp is 1 if this resource contains more |
|
than one file upload item. Callers of routine should append partid as a |
|
subdirectory to $path in cases where $multiresp is 1. |
|
|
|
Called by: homework/essayresponse.pm and homework/structuretags.pm |
|
|
|
=cut |
|
|
|
sub get_turnedin_filepath { |
|
my ($symb,$uname,$udom,$caller) = @_; |
|
my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb); |
|
my $turnindir; |
|
my %userhash = &Apache::lonnet::userenvironment($udom,$uname,'turnindir'); |
|
$turnindir = $userhash{'turnindir'}; |
|
my ($path,$multiresp); |
|
if ($turnindir eq '') { |
|
if ($caller eq 'submission') { |
|
$turnindir = &mt('turned in'); |
|
$turnindir =~ s/\W+/_/g; |
|
my %newhash = ( |
|
'turnindir' => $turnindir, |
|
); |
|
&Apache::lonnet::put('environment',\%newhash,$udom,$uname); |
|
} |
|
} |
|
if ($turnindir ne '') { |
|
$path = '/'.$turnindir.'/'; |
|
my ($multipart,$turnin,@pathitems); |
|
my $navmap = Apache::lonnavmaps::navmap->new(); |
|
if (defined($navmap)) { |
|
my $mapres = $navmap->getResourceByUrl($map); |
|
if (ref($mapres)) { |
|
my $pcslist = $mapres->map_hierarchy(); |
|
if ($pcslist ne '') { |
|
foreach my $pc (split(/,/,$pcslist)) { |
|
my $res = $navmap->getByMapPc($pc); |
|
if (ref($res)) { |
|
my $title = $res->compTitle(); |
|
$title =~ s/\W+/_/g; |
|
if ($title ne '') { |
|
push(@pathitems,$title); |
|
} |
|
} |
|
} |
|
} |
|
my $maptitle = $mapres->compTitle(); |
|
$maptitle =~ s/\W+/_/g; |
|
if ($maptitle ne '') { |
|
push(@pathitems,$maptitle); |
|
} |
|
unless ($env{'request.state'} eq 'construct') { |
|
my $res = $navmap->getBySymb($symb); |
|
if (ref($res)) { |
|
my $partlist = $res->parts(); |
|
my $totaluploads = 0; |
|
if (ref($partlist) eq 'ARRAY') { |
|
foreach my $part (@{$partlist}) { |
|
my @types = $res->responseType($part); |
|
my @ids = $res->responseIds($part); |
|
for (my $i=0; $i < scalar(@ids); $i++) { |
|
if ($types[$i] eq 'essay') { |
|
my $partid = $part.'_'.$ids[$i]; |
|
if (&Apache::lonnet::EXT("resource.$partid.uploadedfiletypes") ne '') { |
|
$totaluploads ++; |
|
} |
|
} |
|
} |
|
} |
|
if ($totaluploads > 1) { |
|
$multiresp = 1; |
|
} |
|
} |
|
} |
|
} |
|
} else { |
|
return; |
|
} |
|
} else { |
|
return; |
|
} |
|
my $restitle=&Apache::lonnet::gettitle($symb); |
|
$restitle =~ s/\W+/_/g; |
|
if ($restitle eq '') { |
|
$restitle = ($resurl =~ m{/[^/]+$}); |
|
if ($restitle eq '') { |
|
$restitle = time; |
|
} |
|
} |
|
push(@pathitems,$restitle); |
|
$path .= join('/',@pathitems); |
|
} |
|
return ($path,$multiresp); |
|
} |
|
|
=pod |
=pod |
|
|
Line 9889 sub commit_customrole {
|
Line 13214 sub commit_customrole {
|
} |
} |
|
|
sub commit_standardrole { |
sub commit_standardrole { |
my ($udom,$uname,$url,$three,$start,$end,$one,$two,$sec,$context) = @_; |
my ($udom,$uname,$url,$three,$start,$end,$one,$two,$sec,$context,$credits) = @_; |
my ($output,$logmsg,$linefeed); |
my ($output,$logmsg,$linefeed); |
if ($context eq 'auto') { |
if ($context eq 'auto') { |
$linefeed = "\n"; |
$linefeed = "\n"; |
Line 9898 sub commit_standardrole {
|
Line 13223 sub commit_standardrole {
|
} |
} |
if ($three eq 'st') { |
if ($three eq 'st') { |
my $result = &commit_studentrole(\$logmsg,$udom,$uname,$url,$three,$start,$end, |
my $result = &commit_studentrole(\$logmsg,$udom,$uname,$url,$three,$start,$end, |
$one,$two,$sec,$context); |
$one,$two,$sec,$context,$credits); |
if (($result =~ /^error/) || ($result eq 'not_in_class') || |
if (($result =~ /^error/) || ($result eq 'not_in_class') || |
($result eq 'unknown_course') || ($result eq 'refused')) { |
($result eq 'unknown_course') || ($result eq 'refused')) { |
$output = $logmsg.' '.&mt('Error: ').$result."\n"; |
$output = $logmsg.' '.&mt('Error: ').$result."\n"; |
Line 9929 sub commit_standardrole {
|
Line 13254 sub commit_standardrole {
|
} |
} |
|
|
sub commit_studentrole { |
sub commit_studentrole { |
my ($logmsg,$udom,$uname,$url,$three,$start,$end,$one,$two,$sec,$context) = @_; |
my ($logmsg,$udom,$uname,$url,$three,$start,$end,$one,$two,$sec,$context, |
|
$credits) = @_; |
my ($result,$linefeed,$oldsecurl,$newsecurl); |
my ($result,$linefeed,$oldsecurl,$newsecurl); |
if ($context eq 'auto') { |
if ($context eq 'auto') { |
$linefeed = "\n"; |
$linefeed = "\n"; |
Line 9976 sub commit_studentrole {
|
Line 13302 sub commit_studentrole {
|
} |
} |
} |
} |
if (($expire_role_result eq 'ok') || ($secchange == 0)) { |
if (($expire_role_result eq 'ok') || ($secchange == 0)) { |
$modify_section_result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,'','',$cid,'',$context); |
$modify_section_result = |
|
&Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef, |
|
undef,undef,undef,$sec, |
|
$end,$start,'','',$cid, |
|
'',$context,$credits); |
if ($modify_section_result =~ /^ok/) { |
if ($modify_section_result =~ /^ok/) { |
if ($secchange == 1) { |
if ($secchange == 1) { |
if ($sec eq '') { |
if ($sec eq '') { |
Line 9998 sub commit_studentrole {
|
Line 13328 sub commit_studentrole {
|
} |
} |
} |
} |
} else { |
} else { |
if ($secchange) { |
if ($secchange) { |
$$logmsg .= &mt('Error when attempting section change for [_1] from old section "[_2]" to new section: "[_3]" in course [_4] -error:',$uname,$oldsec,$sec,$cid).' '.$modify_section_result.$linefeed; |
$$logmsg .= &mt('Error when attempting section change for [_1] from old section "[_2]" to new section: "[_3]" in course [_4] -error:',$uname,$oldsec,$sec,$cid).' '.$modify_section_result.$linefeed; |
} else { |
} else { |
$$logmsg .= &mt('Error when attempting to modify role for [_1] for section: "[_2]" in course [_3] -error:',$uname,$sec,$cid).' '.$modify_section_result.$linefeed; |
$$logmsg .= &mt('Error when attempting to modify role for [_1] for section: "[_2]" in course [_3] -error:',$uname,$sec,$cid).' '.$modify_section_result.$linefeed; |
Line 10007 sub commit_studentrole {
|
Line 13337 sub commit_studentrole {
|
$result = $modify_section_result; |
$result = $modify_section_result; |
} elsif ($secchange == 1) { |
} elsif ($secchange == 1) { |
if ($oldsec eq '') { |
if ($oldsec eq '') { |
$$logmsg .= &mt('Error when attempting to expire existing role without a section for [_1] in course [_3] -error: ',$uname,$cid).' '.$expire_role_result.$linefeed; |
$$logmsg .= &mt('Error when attempting to expire existing role without a section for [_1] in course [_2] -error: ',$uname,$cid).' '.$expire_role_result.$linefeed; |
} else { |
} else { |
$$logmsg .= &mt('Error when attempting to expire existing role for [_1] in section [_2] in course [_3] -error: ',$uname,$oldsec,$cid).' '.$expire_role_result.$linefeed; |
$$logmsg .= &mt('Error when attempting to expire existing role for [_1] in section [_2] in course [_3] -error: ',$uname,$oldsec,$cid).' '.$expire_role_result.$linefeed; |
} |
} |
Line 10033 sub commit_studentrole {
|
Line 13363 sub commit_studentrole {
|
return $result; |
return $result; |
} |
} |
|
|
|
sub show_role_extent { |
|
my ($scope,$context,$role) = @_; |
|
$scope =~ s{^/}{}; |
|
my @courseroles = &Apache::lonuserutils::roles_by_context('course',1); |
|
push(@courseroles,'co'); |
|
my @authorroles = &Apache::lonuserutils::roles_by_context('author'); |
|
if (($context eq 'course') || (grep(/^\Q$role\E/,@courseroles))) { |
|
$scope =~ s{/}{_}; |
|
return '<span class="LC_cusr_emph">'.$env{'course.'.$scope.'.description'}.'</span>'; |
|
} elsif (($context eq 'author') || (grep(/^\Q$role\E/,@authorroles))) { |
|
my ($audom,$auname) = split(/\//,$scope); |
|
return &mt('[_1] Author Space','<span class="LC_cusr_emph">'. |
|
&Apache::loncommon::plainname($auname,$audom).'</span>'); |
|
} else { |
|
$scope =~ s{/$}{}; |
|
return &mt('Domain: [_1]','<span class="LC_cusr_emph">'. |
|
&Apache::lonnet::domain($scope,'description').'</span>'); |
|
} |
|
} |
|
|
############################################################ |
############################################################ |
############################################################ |
############################################################ |
|
|
Line 10225 sub construct_course {
|
Line 13575 sub construct_course {
|
} else { |
} else { |
$cenv{'internal.courseowner'} = $args->{'curruser'}; |
$cenv{'internal.courseowner'} = $args->{'curruser'}; |
} |
} |
|
if ($args->{'defaultcredits'}) { |
|
$cenv{'internal.defaultcredits'} = $args->{'defaultcredits'}; |
|
} |
my @badclasses = (); # Used to accumulate sections/crosslistings that did not pass classlist access check for course owner. |
my @badclasses = (); # Used to accumulate sections/crosslistings that did not pass classlist access check for course owner. |
if ($args->{'crssections'}) { |
if ($args->{'crssections'}) { |
$cenv{'internal.sectionnums'} = ''; |
$cenv{'internal.sectionnums'} = ''; |
Line 10561 sub init_user_environment {
|
Line 13914 sub init_user_environment {
|
|
|
# See if old ID present, if so, remove |
# See if old ID present, if so, remove |
|
|
my ($filename,$cookie,$userroles); |
my ($filename,$cookie,$userroles,$firstaccenv,$timerintenv); |
my $now=time; |
my $now=time; |
|
|
if ($public) { |
if ($public) { |
Line 10599 sub init_user_environment {
|
Line 13952 sub init_user_environment {
|
|
|
# Initialize roles |
# Initialize roles |
|
|
$userroles=&Apache::lonnet::rolesinit($domain,$username,$authhost); |
($userroles,$firstaccenv,$timerintenv) = |
|
&Apache::lonnet::rolesinit($domain,$username,$authhost); |
} |
} |
# ------------------------------------ Check browser type and MathML capability |
# ------------------------------------ Check browser type and MathML capability |
|
|
Line 10654 sub init_user_environment {
|
Line 14008 sub init_user_environment {
|
$env{'browser.interface'}=$form->{'interface'}; |
$env{'browser.interface'}=$form->{'interface'}; |
} |
} |
|
|
foreach my $tool ('aboutme','blog','portfolio') { |
my %is_adv = ( is_adv => $env{'user.adv'} ); |
|
my %domdef; |
|
unless ($domain eq 'public') { |
|
%domdef = &Apache::lonnet::get_domain_defaults($domain); |
|
} |
|
|
|
foreach my $tool ('aboutme','blog','webdav','portfolio') { |
$userenv{'availabletools.'.$tool} = |
$userenv{'availabletools.'.$tool} = |
&Apache::lonnet::usertools_access($username,$domain,$tool,'reload'); |
&Apache::lonnet::usertools_access($username,$domain,$tool,'reload', |
|
undef,\%userenv,\%domdef,\%is_adv); |
} |
} |
|
|
foreach my $crstype ('official','unofficial','community') { |
foreach my $crstype ('official','unofficial','community') { |
$userenv{'canrequest.'.$crstype} = |
$userenv{'canrequest.'.$crstype} = |
&Apache::lonnet::usertools_access($username,$domain,$crstype, |
&Apache::lonnet::usertools_access($username,$domain,$crstype, |
'reload','requestcourses'); |
'reload','requestcourses', |
|
\%userenv,\%domdef,\%is_adv); |
|
} |
|
|
|
$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'}; |
|
} |
} |
} |
|
|
$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", |
&GDBM_WRCREAT(),0640)) { |
&GDBM_WRCREAT(),0640)) { |
&_add_to_env(\%disk_env,\%initial_env); |
&_add_to_env(\%disk_env,\%initial_env); |
&_add_to_env(\%disk_env,\%userenv,'environment.'); |
&_add_to_env(\%disk_env,\%userenv,'environment.'); |
&_add_to_env(\%disk_env,$userroles); |
&_add_to_env(\%disk_env,$userroles); |
|
if (ref($firstaccenv) eq 'HASH') { |
|
&_add_to_env(\%disk_env,$firstaccenv); |
|
} |
|
if (ref($timerintenv) eq 'HASH') { |
|
&_add_to_env(\%disk_env,$timerintenv); |
|
} |
if (ref($args->{'extra_env'})) { |
if (ref($args->{'extra_env'})) { |
&_add_to_env(\%disk_env,$args->{'extra_env'}); |
&_add_to_env(\%disk_env,$args->{'extra_env'}); |
} |
} |
Line 10707 sub get_symb {
|
Line 14089 sub get_symb {
|
my $symb=($env{'form.symb'} ne '' ? $env{'form.symb'} : (&Apache::lonnet::symbread($url))); |
my $symb=($env{'form.symb'} ne '' ? $env{'form.symb'} : (&Apache::lonnet::symbread($url))); |
if ($symb eq '') { |
if ($symb eq '') { |
if (!$silent) { |
if (!$silent) { |
$request->print("Unable to handle ambiguous references:$url:."); |
if (ref($request)) { |
|
$request->print("Unable to handle ambiguous references:$url:."); |
|
} |
return (); |
return (); |
} |
} |
} |
} |
Line 10741 sub clean_symb {
|
Line 14125 sub clean_symb {
|
return ($symb,$enc); |
return ($symb,$enc); |
} |
} |
|
|
|
sub build_release_hashes { |
|
my ($checkparms,$checkresponsetypes,$checkcrstypes,$anonsurvey,$randomizetry) = @_; |
|
return unless((ref($checkparms) eq 'HASH') && (ref($checkresponsetypes) eq 'HASH') && |
|
(ref($checkcrstypes) eq 'HASH') && (ref($anonsurvey) eq 'HASH') && |
|
(ref($randomizetry) eq 'HASH')); |
|
foreach my $key (keys(%Apache::lonnet::needsrelease)) { |
|
my ($item,$name,$value) = split(/:/,$key); |
|
if ($item eq 'parameter') { |
|
if (ref($checkparms->{$name}) eq 'ARRAY') { |
|
unless(grep(/^\Q$name\E$/,@{$checkparms->{$name}})) { |
|
push(@{$checkparms->{$name}},$value); |
|
} |
|
} else { |
|
push(@{$checkparms->{$name}},$value); |
|
} |
|
} elsif ($item eq 'resourcetag') { |
|
if ($name eq 'responsetype') { |
|
$checkresponsetypes->{$value} = $Apache::lonnet::needsrelease{$key} |
|
} |
|
} elsif ($item eq 'course') { |
|
if ($name eq 'crstype') { |
|
$checkcrstypes->{$value} = $Apache::lonnet::needsrelease{$key}; |
|
} |
|
} |
|
} |
|
($anonsurvey->{major},$anonsurvey->{minor}) = split(/\./,$Apache::lonnet::needsrelease{'parameter:type:anonsurvey'}); |
|
($randomizetry->{major},$randomizetry->{minor}) = split(/\./,$Apache::lonnet::needsrelease{'parameter:type:randomizetry'}); |
|
return; |
|
} |
|
|
|
sub update_content_constraints { |
|
my ($cdom,$cnum,$chome,$cid) = @_; |
|
my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired'); |
|
my ($reqdmajor,$reqdminor) = split(/\./,$curr_reqd_hash{'internal.releaserequired'}); |
|
my %checkresponsetypes; |
|
foreach my $key (keys(%Apache::lonnet::needsrelease)) { |
|
my ($item,$name,$value) = split(/:/,$key); |
|
if ($item eq 'resourcetag') { |
|
if ($name eq 'responsetype') { |
|
$checkresponsetypes{$value} = $Apache::lonnet::needsrelease{$key} |
|
} |
|
} |
|
} |
|
my $navmap = Apache::lonnavmaps::navmap->new(); |
|
if (defined($navmap)) { |
|
my %allresponses; |
|
foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_problem() },1,0)) { |
|
my %responses = $res->responseTypes(); |
|
foreach my $key (keys(%responses)) { |
|
next unless(exists($checkresponsetypes{$key})); |
|
$allresponses{$key} += $responses{$key}; |
|
} |
|
} |
|
foreach my $key (keys(%allresponses)) { |
|
my ($major,$minor) = split(/\./,$checkresponsetypes{$key}); |
|
if (($major > $reqdmajor) || ($major == $reqdmajor && $minor > $reqdminor)) { |
|
($reqdmajor,$reqdminor) = ($major,$minor); |
|
} |
|
} |
|
undef($navmap); |
|
} |
|
unless (($reqdmajor eq '') && ($reqdminor eq '')) { |
|
&Apache::lonnet::update_released_required($reqdmajor.'.'.$reqdminor,$cdom,$cnum,$chome,$cid); |
|
} |
|
return; |
|
} |
|
|
|
sub allmaps_incourse { |
|
my ($cdom,$cnum,$chome,$cid) = @_; |
|
if ($cdom eq '' || $cnum eq '' || $chome eq '' || $cid eq '') { |
|
$cid = $env{'request.course.id'}; |
|
$cdom = $env{'course.'.$cid.'.domain'}; |
|
$cnum = $env{'course.'.$cid.'.num'}; |
|
$chome = $env{'course.'.$cid.'.home'}; |
|
} |
|
my %allmaps = (); |
|
my $lastchange = |
|
&Apache::lonnet::get_coursechange($cdom,$cnum); |
|
if ($lastchange > $env{'request.course.tied'}) { |
|
my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum"); |
|
unless ($ferr) { |
|
&update_content_constraints($cdom,$cnum,$chome,$cid); |
|
} |
|
} |
|
my $navmap = Apache::lonnavmaps::navmap->new(); |
|
if (defined($navmap)) { |
|
foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_map() },1,0,1)) { |
|
$allmaps{$res->src()} = 1; |
|
} |
|
} |
|
return \%allmaps; |
|
} |
|
|
|
sub parse_supplemental_title { |
|
my ($title) = @_; |
|
|
|
my ($foldertitle,$renametitle); |
|
if ($title =~ /&&&/) { |
|
$title = &HTML::Entites::decode($title); |
|
} |
|
if ($title =~ m/^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/) { |
|
$renametitle=$4; |
|
my ($time,$uname,$udom) = ($1,$2,$3); |
|
$foldertitle=&Apache::lontexconvert::msgtexconverted($4); |
|
my $name = &plainname($uname,$udom); |
|
$name = &HTML::Entities::encode($name,'"<>&\''); |
|
$renametitle = &HTML::Entities::encode($renametitle,'"<>&\''); |
|
$title='<i>'.&Apache::lonlocal::locallocaltime($time).'</i> '. |
|
$name.': <br />'.$foldertitle; |
|
} |
|
if (wantarray) { |
|
return ($title,$foldertitle,$renametitle); |
|
} |
|
return $title; |
|
} |
|
|
|
sub symb_to_docspath { |
|
my ($symb) = @_; |
|
return unless ($symb); |
|
my ($mapurl,$id,$resurl) = &Apache::lonnet::decode_symb($symb); |
|
if ($resurl=~/\.(sequence|page)$/) { |
|
$mapurl=$resurl; |
|
} elsif ($resurl eq 'adm/navmaps') { |
|
$mapurl=$env{'course.'.$env{'request.course.id'}.'.url'}; |
|
} |
|
my $mapresobj; |
|
my $navmap = Apache::lonnavmaps::navmap->new(); |
|
if (ref($navmap)) { |
|
$mapresobj = $navmap->getResourceByUrl($mapurl); |
|
} |
|
$mapurl=~s{^.*/([^/]+)\.(\w+)$}{$1}; |
|
my $type=$2; |
|
my $path; |
|
if (ref($mapresobj)) { |
|
my $pcslist = $mapresobj->map_hierarchy(); |
|
if ($pcslist ne '') { |
|
foreach my $pc (split(/,/,$pcslist)) { |
|
next if ($pc <= 1); |
|
my $res = $navmap->getByMapPc($pc); |
|
if (ref($res)) { |
|
my $thisurl = $res->src(); |
|
$thisurl=~s{^.*/([^/]+)\.\w+$}{$1}; |
|
my $thistitle = $res->title(); |
|
$path .= '&'. |
|
&Apache::lonhtmlcommon::entity_encode($thisurl).'&'. |
|
&Apache::lonhtmlcommon::entity_encode($thistitle). |
|
':'.$res->randompick(). |
|
':'.$res->randomout(). |
|
':'.$res->encrypted(). |
|
':'.$res->randomorder(). |
|
':'.$res->is_page(); |
|
} |
|
} |
|
} |
|
$path =~ s/^\&//; |
|
my $maptitle = $mapresobj->title(); |
|
if ($mapurl eq 'default') { |
|
$maptitle = 'Main Course Documents'; |
|
} |
|
$path .= (($path ne '')? '&' : ''). |
|
&Apache::lonhtmlcommon::entity_encode($mapurl).'&'. |
|
&Apache::lonhtmlcommon::entity_encode($maptitle). |
|
':'.$mapresobj->randompick(). |
|
':'.$mapresobj->randomout(). |
|
':'.$mapresobj->encrypted(). |
|
':'.$mapresobj->randomorder(). |
|
':'.$mapresobj->is_page(); |
|
} else { |
|
my $maptitle = &Apache::lonnet::gettitle($mapurl); |
|
my $ispage = (($type eq 'page')? 1 : ''); |
|
if ($mapurl eq 'default') { |
|
$maptitle = 'Main Course Documents'; |
|
} |
|
$path = &Apache::lonhtmlcommon::entity_encode($mapurl).'&'. |
|
&Apache::lonhtmlcommon::entity_encode($maptitle).':::::'.$ispage; |
|
} |
|
unless ($mapurl eq 'default') { |
|
$path = 'default&'. |
|
&Apache::lonhtmlcommon::entity_encode('Main Course Documents'). |
|
':::::&'.$path; |
|
} |
|
return $path; |
|
} |
|
|
|
sub captcha_display { |
|
my ($context,$lonhost) = @_; |
|
my ($output,$error); |
|
my ($captcha,$pubkey,$privkey) = &get_captcha_config($context,$lonhost); |
|
if ($captcha eq 'original') { |
|
$output = &create_captcha(); |
|
unless ($output) { |
|
$error = 'captcha'; |
|
} |
|
} elsif ($captcha eq 'recaptcha') { |
|
$output = &create_recaptcha($pubkey); |
|
unless ($output) { |
|
$error = 'recaptcha'; |
|
} |
|
} |
|
return ($output,$error); |
|
} |
|
|
|
sub captcha_response { |
|
my ($context,$lonhost) = @_; |
|
my ($captcha_chk,$captcha_error); |
|
my ($captcha,$pubkey,$privkey) = &get_captcha_config($context,$lonhost); |
|
if ($captcha eq 'original') { |
|
($captcha_chk,$captcha_error) = &check_captcha(); |
|
} elsif ($captcha eq 'recaptcha') { |
|
$captcha_chk = &check_recaptcha($privkey); |
|
} else { |
|
$captcha_chk = 1; |
|
} |
|
return ($captcha_chk,$captcha_error); |
|
} |
|
|
|
sub get_captcha_config { |
|
my ($context,$lonhost) = @_; |
|
my ($captcha,$pubkey,$privkey,$hashtocheck); |
|
my $hostname = &Apache::lonnet::hostname($lonhost); |
|
my $serverhomeID = &Apache::lonnet::get_server_homeID($hostname); |
|
my $serverhomedom = &Apache::lonnet::host_domain($serverhomeID); |
|
if ($context eq 'usercreation') { |
|
my %domconfig = &Apache::lonnet::get_dom('configuration',[$context],$serverhomedom); |
|
if (ref($domconfig{$context}) eq 'HASH') { |
|
$hashtocheck = $domconfig{$context}{'cancreate'}; |
|
if (ref($hashtocheck) eq 'HASH') { |
|
if ($hashtocheck->{'captcha'} eq 'recaptcha') { |
|
if (ref($hashtocheck->{'recaptchakeys'}) eq 'HASH') { |
|
$pubkey = $hashtocheck->{'recaptchakeys'}{'public'}; |
|
$privkey = $hashtocheck->{'recaptchakeys'}{'private'}; |
|
} |
|
if ($privkey && $pubkey) { |
|
$captcha = 'recaptcha'; |
|
} else { |
|
$captcha = 'original'; |
|
} |
|
} elsif ($hashtocheck->{'captcha'} ne 'notused') { |
|
$captcha = 'original'; |
|
} |
|
} |
|
} else { |
|
$captcha = 'captcha'; |
|
} |
|
} elsif ($context eq 'login') { |
|
my %domconfhash = &Apache::loncommon::get_domainconf($serverhomedom); |
|
if ($domconfhash{$serverhomedom.'.login.captcha'} eq 'recaptcha') { |
|
$pubkey = $domconfhash{$serverhomedom.'.login.recaptchakeys_public'}; |
|
$privkey = $domconfhash{$serverhomedom.'.login.recaptchakeys_private'}; |
|
if ($privkey && $pubkey) { |
|
$captcha = 'recaptcha'; |
|
} else { |
|
$captcha = 'original'; |
|
} |
|
} elsif ($domconfhash{$serverhomedom.'.login.captcha'} eq 'original') { |
|
$captcha = 'original'; |
|
} |
|
} |
|
return ($captcha,$pubkey,$privkey); |
|
} |
|
|
|
sub create_captcha { |
|
my %captcha_params = &captcha_settings(); |
|
my ($output,$maxtries,$tries) = ('',10,0); |
|
while ($tries < $maxtries) { |
|
$tries ++; |
|
my $captcha = Authen::Captcha->new ( |
|
output_folder => $captcha_params{'output_dir'}, |
|
data_folder => $captcha_params{'db_dir'}, |
|
); |
|
my $md5sum = $captcha->generate_code($captcha_params{'numchars'}); |
|
|
|
if (-e $Apache::lonnet::perlvar{'lonCaptchaDir'}.'/'.$md5sum.'.png') { |
|
$output = '<input type="hidden" name="crypt" value="'.$md5sum.'" />'."\n". |
|
&mt('Type in the letters/numbers shown below').' '. |
|
'<input type="text" size="5" name="code" value="" /><br />'. |
|
'<img src="'.$captcha_params{'www_output_dir'}.'/'.$md5sum.'.png" />'; |
|
last; |
|
} |
|
} |
|
return $output; |
|
} |
|
|
|
sub captcha_settings { |
|
my %captcha_params = ( |
|
output_dir => $Apache::lonnet::perlvar{'lonCaptchaDir'}, |
|
www_output_dir => "/captchaspool", |
|
db_dir => $Apache::lonnet::perlvar{'lonCaptchaDb'}, |
|
numchars => '5', |
|
); |
|
return %captcha_params; |
|
} |
|
|
|
sub check_captcha { |
|
my ($captcha_chk,$captcha_error); |
|
my $code = $env{'form.code'}; |
|
my $md5sum = $env{'form.crypt'}; |
|
my %captcha_params = &captcha_settings(); |
|
my $captcha = Authen::Captcha->new( |
|
output_folder => $captcha_params{'output_dir'}, |
|
data_folder => $captcha_params{'db_dir'}, |
|
); |
|
$captcha_chk = $captcha->check_code($code,$md5sum); |
|
my %captcha_hash = ( |
|
0 => 'Code not checked (file error)', |
|
-1 => 'Failed: code expired', |
|
-2 => 'Failed: invalid code (not in database)', |
|
-3 => 'Failed: invalid code (code does not match crypt)', |
|
); |
|
if ($captcha_chk != 1) { |
|
$captcha_error = $captcha_hash{$captcha_chk} |
|
} |
|
return ($captcha_chk,$captcha_error); |
|
} |
|
|
|
sub create_recaptcha { |
|
my ($pubkey) = @_; |
|
my $captcha = Captcha::reCAPTCHA->new; |
|
return $captcha->get_options_setter({theme => 'white'})."\n". |
|
$captcha->get_html($pubkey). |
|
&mt('If either word is hard to read, [_1] will replace them.', |
|
'<image src="/res/adm/pages/refresh.gif" alt="reCAPTCHA refresh" />'). |
|
'<br /><br />'; |
|
} |
|
|
|
sub check_recaptcha { |
|
my ($privkey) = @_; |
|
my $captcha_chk; |
|
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; |
|
} |
|
|
=pod |
=pod |
|
|
=back |
=back |