version 1.1351, 2021/01/02 21:07:36
|
version 1.1405, 2023/05/22 21:10:55
|
Line 61 use POSIX qw(strftime mktime);
|
Line 61 use POSIX qw(strftime mktime);
|
use Apache::lonmenu(); |
use Apache::lonmenu(); |
use Apache::lonenc(); |
use Apache::lonenc(); |
use Apache::lonlocal; |
use Apache::lonlocal; |
use Apache::lonnet(); |
use Apache::lonnavmaps(); |
use HTML::Entities; |
use HTML::Entities; |
use Apache::lonhtmlcommon(); |
use Apache::lonhtmlcommon(); |
use Apache::loncoursedata(); |
use Apache::loncoursedata(); |
Line 72 use Apache::lonuserstate();
|
Line 72 use Apache::lonuserstate();
|
use Apache::courseclassifier(); |
use Apache::courseclassifier(); |
use LONCAPA qw(:DEFAULT :match); |
use LONCAPA qw(:DEFAULT :match); |
use LONCAPA::LWPReq; |
use LONCAPA::LWPReq; |
|
use LONCAPA::map(); |
use HTTP::Request; |
use HTTP::Request; |
use DateTime::TimeZone; |
use DateTime::TimeZone; |
use DateTime::Locale; |
use DateTime::Locale; |
Line 957 ENDSCRT
|
Line 958 ENDSCRT
|
} |
} |
|
|
sub select_timezone { |
sub select_timezone { |
my ($name,$selected,$onchange,$includeempty,$disabled)=@_; |
my ($name,$selected,$onchange,$includeempty,$id,$disabled)=@_; |
my $output='<select name="'.$name.'" '.$onchange.$disabled.'>'."\n"; |
my $output='<select name="'.$name.'" '.$id.$onchange.$disabled.'>'."\n"; |
if ($includeempty) { |
if ($includeempty) { |
$output .= '<option value=""'; |
$output .= '<option value=""'; |
if (($selected eq '') || ($selected eq 'local')) { |
if (($selected eq '') || ($selected eq 'local')) { |
Line 1232 END
|
Line 1233 END
|
$result.=">".&mt($hashref->{$value}->{'text'})."</option>\n"; |
$result.=">".&mt($hashref->{$value}->{'text'})."</option>\n"; |
} |
} |
$result .= "</select>\n"; |
$result .= "</select>\n"; |
my %select2 = %{$hashref->{$firstdefault}->{'select2'}}; |
my %select2; |
|
if (ref($hashref->{$firstdefault}) eq 'HASH') { |
|
if (ref($hashref->{$firstdefault}->{'select2'}) eq 'HASH') { |
|
%select2 = %{$hashref->{$firstdefault}->{'select2'}}; |
|
} |
|
} |
$result .= $middletext; |
$result .= $middletext; |
$result .= "<select size=\"1\" name=\"$secondselectname\""; |
$result .= "<select size=\"1\" name=\"$secondselectname\""; |
if ($onchangesecond) { |
if ($onchangesecond) { |
Line 1257 END
|
Line 1263 END
|
|
|
=pod |
=pod |
|
|
=item * &help_open_topic($topic,$text,$stayOnPage,$width,$height,$imgid) |
=item * &help_open_topic($topic,$text,$stayOnPage,$width,$height,$imgid,$links_target) |
|
|
Returns a string corresponding to an HTML link to the given help |
Returns a string corresponding to an HTML link to the given help |
$topic, where $topic corresponds to the name of a .tex file in |
$topic, where $topic corresponds to the name of a .tex file in |
Line 1281 $imgid is the id of the img tag used for
|
Line 1287 $imgid is the id of the img tag used for
|
used in a javascript call to switch the image src. See |
used in a javascript call to switch the image src. See |
lonhtmlcommon::htmlareaselectactive() for an example. |
lonhtmlcommon::htmlareaselectactive() for an example. |
|
|
|
$links_target will optionally be set to a target (_top, _parent or _self). |
|
|
=cut |
=cut |
|
|
sub help_open_topic { |
sub help_open_topic { |
my ($topic, $text, $stayOnPage, $width, $height, $imgid) = @_; |
my ($topic, $text, $stayOnPage, $width, $height, $imgid, $links_target) = @_; |
$text = "" if (not defined $text); |
$text = "" if (not defined $text); |
$stayOnPage = 0 if (not defined $stayOnPage); |
$stayOnPage = 0 if (not defined $stayOnPage); |
$width = 500 if (not defined $width); |
$width = 500 if (not defined $width); |
Line 1307 sub help_open_topic {
|
Line 1315 sub help_open_topic {
|
|
|
# Add the text |
# Add the text |
my $target = ' target="_top"'; |
my $target = ' target="_top"'; |
if (($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) { |
if ($links_target) { |
|
$target = ' target="'.$links_target.'"'; |
|
} elsif ((($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) || |
|
(($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'} eq '_self'))) { |
$target = ''; |
$target = ''; |
} |
} |
if ($text ne "") { |
if ($text ne "") { |
$template.='<span class="LC_help_open_topic">' |
$template.='<span class="LC_help_open_topic">' |
.'<a'.$target.' href="'.$link.'">' |
.'<a'.$target.' href="'.$link.'">' |
.$text.'</a>'; |
.$text.'</a>'; |
Line 1395 ENDOUTPUT
|
Line 1406 ENDOUTPUT
|
|
|
# now just updates the help link and generates a blue icon |
# now just updates the help link and generates a blue icon |
sub help_open_menu { |
sub help_open_menu { |
my ($topic,$component_help,$faq,$bug,$stayOnPage,$width,$height,$text) |
my ($topic,$component_help,$faq,$bug,$stayOnPage,$width,$height,$text,$links_target) |
= @_; |
= @_; |
$stayOnPage = 1; |
$stayOnPage = 1; |
my $output; |
my $output; |
if ($component_help) { |
if ($component_help) { |
if (!$text) { |
if (!$text) { |
$output=&help_open_topic($component_help,undef,$stayOnPage, |
$output=&help_open_topic($component_help,undef,$stayOnPage, |
$width,$height); |
$width,$height,'',$links_target); |
} else { |
} else { |
my $help_text; |
my $help_text; |
$help_text=&unescape($topic); |
$help_text=&unescape($topic); |
$output='<table><tr><td>'. |
$output='<table><tr><td>'. |
&help_open_topic($component_help,$help_text,$stayOnPage, |
&help_open_topic($component_help,$help_text,$stayOnPage, |
$width,$height).'</td></tr></table>'; |
$width,$height,'',$links_target).'</td></tr></table>'; |
} |
} |
} |
} |
my $banner_link = &update_help_link($topic,$component_help,$faq,$bug,$stayOnPage); |
my $banner_link = &update_help_link($topic,$component_help,$faq,$bug,$stayOnPage); |
Line 1416 sub help_open_menu {
|
Line 1427 sub help_open_menu {
|
} |
} |
|
|
sub top_nav_help { |
sub top_nav_help { |
my ($text) = @_; |
my ($text,$linkattr) = @_; |
$text = &mt($text); |
$text = &mt($text); |
my $stay_on_page = 1; |
my $stay_on_page = 1; |
|
|
Line 1430 sub top_nav_help {
|
Line 1441 sub top_nav_help {
|
if ($link) { |
if ($link) { |
return <<"END"; |
return <<"END"; |
$banner_link |
$banner_link |
<a href="$link" title="$title">$text</a> |
<a href="$link" title="$title" $linkattr>$text</a> |
END |
END |
} else { |
} else { |
return ' '.$text.' '; |
return ' '.$text.' '; |
Line 1516 sub help_open_bug {
|
Line 1527 sub help_open_bug {
|
$link = $url; |
$link = $url; |
} |
} |
|
|
my $target = ' target="_top"'; |
my $target = '_top'; |
if (($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) { |
if ((($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) || |
$target = ''; |
(($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'} eq '_self'))) { |
|
$target = '_blank'; |
} |
} |
|
|
# Add the text |
# Add the text |
if ($text ne "") |
if ($text ne "") |
{ |
{ |
$template .= |
$template .= |
"<table bgcolor='#AA3333' cellspacing='1' cellpadding='1' border='0'><tr>". |
"<table bgcolor='#AA3333' cellspacing='1' cellpadding='1' border='0'><tr>". |
"<td bgcolor='#FF5555'><a".$target." href=\"$link\"><span style=\"color:#FFFFFF;font-size:10pt;\">$text</span></a>"; |
"<td bgcolor='#FF5555'><a target=\"$target\" href=\"$link\"><span style=\"color:#FFFFFF;font-size:10pt;\">$text</span></a>"; |
} |
} |
|
|
# Add the graphic |
# Add the graphic |
my $title = &mt('Report a Bug'); |
my $title = &mt('Report a Bug'); |
my $bugicon=&lonhttpdurl("/adm/lonMisc/smallBug.gif"); |
my $bugicon=&lonhttpdurl("/adm/lonMisc/smallBug.gif"); |
$template .= <<"ENDTEMPLATE"; |
$template .= <<"ENDTEMPLATE"; |
<a$target href="$link" title="$title"><img src="$bugicon" border="0" alt="(Bug: $topic)" /></a> |
<a target="$target" href="$link" title="$title"><img src="$bugicon" border="0" alt="(Bug: $topic)" /></a> |
ENDTEMPLATE |
ENDTEMPLATE |
if ($text ne '') { $template.='</td></tr></table>' }; |
if ($text ne '') { $template.='</td></tr></table>' }; |
return $template; |
return $template; |
Line 1808 sub colorfuleditor_js {
|
Line 1821 sub colorfuleditor_js {
|
save => 'Save page to make this permanent', |
save => 'Save page to make this permanent', |
); |
); |
&js_escape(\%js_lt); |
&js_escape(\%js_lt); |
|
my $showfile_js = &show_crsfiles_js(); |
$browse_or_search = <<"END"; |
$browse_or_search = <<"END"; |
|
|
|
$showfile_js |
|
|
function toggleChooser(form,element,titleid,only,search) { |
function toggleChooser(form,element,titleid,only,search) { |
var disp = 'none'; |
var disp = 'none'; |
if (document.getElementById('chooser_'+element)) { |
if (document.getElementById('chooser_'+element)) { |
Line 1824 sub colorfuleditor_js {
|
Line 1840 sub colorfuleditor_js {
|
toggleResImport(form,element); |
toggleResImport(form,element); |
} |
} |
document.getElementById('chooser_'+element).style.display = disp; |
document.getElementById('chooser_'+element).style.display = disp; |
|
var dirsel = ''; |
|
var filesel = ''; |
|
if (document.getElementById('chooser_'+element+'_crsres')) { |
|
var currcrsres = document.getElementById('chooser_'+element+'_crsres').style.display; |
|
if (currcrsres == 'none') { |
|
dirsel = 'coursepath_'+element; |
|
var filesel = 'coursefile_'+element; |
|
var include; |
|
if (document.getElementById('crsres_include_'+element)) { |
|
include = document.getElementById('crsres_include_'+element).value; |
|
} |
|
populateCrsSelects(form,dirsel,filesel,1,include,1,0,1,1,0); |
|
} |
|
} |
|
if (document.getElementById('chooser_'+element+'_upload')) { |
|
var currcrsupload = document.getElementById('chooser_'+element+'_upload').style.display; |
|
if (currcrsupload == 'none') { |
|
dirsel = 'crsauthorpath_'+element; |
|
filesel = ''; |
|
populateCrsSelects(form,dirsel,filesel,0,'',1,0,1,0,1); |
|
} |
|
} |
} |
} |
} |
} |
|
|
function toggleCrsFile(form,element,numdirs) { |
function toggleCrsFile(form,element) { |
if (document.getElementById('chooser_'+element+'_crsres')) { |
if (document.getElementById('chooser_'+element+'_crsres')) { |
var curr = document.getElementById('chooser_'+element+'_crsres').style.display; |
var curr = document.getElementById('chooser_'+element+'_crsres').style.display; |
if (curr == 'none') { |
if (curr == 'none') { |
if (numdirs) { |
if (document.getElementById('coursepath_'+element)) { |
|
var numdirs; |
|
if (document.getElementById('coursepath_'+element).length) { |
|
numdirs = document.getElementById('coursepath_'+element).length; |
|
} |
|
if ((document.getElementById('hascrsres_'+element)) && |
|
(document.getElementById('nocrsres_'+element))) { |
|
if (numdirs) { |
|
document.getElementById('hascrsres_'+element).style.display='inline-block'; |
|
document.getElementById('nocrsres_'+element).style.display='none'; |
|
} else { |
|
document.getElementById('hascrsres_'+element).style.display='none'; |
|
document.getElementById('nocrsres_'+element).style.display='inline-block'; |
|
} |
|
} |
form.elements['coursepath_'+element].selectedIndex = 0; |
form.elements['coursepath_'+element].selectedIndex = 0; |
if (numdirs > 1) { |
if (numdirs > 1) { |
window['select1'+element+'_changed'](); |
var selelem = form.elements['coursefile_'+element]; |
|
var i, len = selelem.options.length -1; |
|
if (len >=0) { |
|
for (i = len; i >= 0; i--) { |
|
selelem.remove(i); |
|
} |
|
selelem.options[0] = new Option('',''); |
|
} |
} |
} |
} |
} |
} |
} |
document.getElementById('chooser_'+element+'_crsres').style.display = 'block'; |
document.getElementById('chooser_'+element+'_crsres').style.display = 'block'; |
|
|
} |
} |
if (document.getElementById('chooser_'+element+'_upload')) { |
if (document.getElementById('chooser_'+element+'_upload')) { |
document.getElementById('chooser_'+element+'_upload').style.display = 'none'; |
document.getElementById('chooser_'+element+'_upload').style.display = 'none'; |
Line 1850 sub colorfuleditor_js {
|
Line 1908 sub colorfuleditor_js {
|
return; |
return; |
} |
} |
|
|
function toggleCrsUpload(form,element,numcrsdirs) { |
function toggleCrsUpload(form,element) { |
if (document.getElementById('chooser_'+element+'_crsres')) { |
if (document.getElementById('chooser_'+element+'_crsres')) { |
document.getElementById('chooser_'+element+'_crsres').style.display = 'none'; |
document.getElementById('chooser_'+element+'_crsres').style.display = 'none'; |
} |
} |
if (document.getElementById('chooser_'+element+'_upload')) { |
if (document.getElementById('chooser_'+element+'_upload')) { |
var curr = document.getElementById('chooser_'+element+'_upload').style.display; |
var curr = document.getElementById('chooser_'+element+'_upload').style.display; |
if (curr == 'none') { |
if (curr == 'none') { |
if (numcrsdirs) { |
form.elements['newsubdir_'+element][0].checked = true; |
form.elements['crsauthorpath_'+element].selectedIndex = 0; |
toggleNewsubdir(form,element); |
form.elements['newsubdir_'+element][0].checked = true; |
document.getElementById('chooser_'+element+'_upload').style.display = 'block'; |
toggleNewsubdir(form,element); |
if (document.getElementById('uploadcrsres_'+element)) { |
|
document.getElementById('uploadcrsres_'+element).value = ''; |
} |
} |
} |
} |
document.getElementById('chooser_'+element+'_upload').style.display = 'block'; |
|
} |
} |
return; |
return; |
} |
} |
Line 1907 sub colorfuleditor_js {
|
Line 1965 sub colorfuleditor_js {
|
var filename = form.elements['coursefile_'+element]; |
var filename = form.elements['coursefile_'+element]; |
var path = directory.options[directory.selectedIndex].value; |
var path = directory.options[directory.selectedIndex].value; |
var file = filename.options[filename.selectedIndex].value; |
var file = filename.options[filename.selectedIndex].value; |
form.elements[element].value = '$respath'; |
if (file != '') { |
if (path == '/') { |
form.elements[element].value = '$respath'; |
form.elements[element].value += file; |
if (path == '/') { |
} else { |
form.elements[element].value += file; |
form.elements[element].value += path+'/'+file; |
} else { |
} |
form.elements[element].value += path+'/'+file; |
unClean(); |
} |
if (document.getElementById('previewimg_'+element)) { |
unClean(); |
document.getElementById('previewimg_'+element).src = form.elements[element].value; |
if (document.getElementById('previewimg_'+element)) { |
var newsrc = document.getElementById('previewimg_'+element).src; |
document.getElementById('previewimg_'+element).src = form.elements[element].value; |
} |
var newsrc = document.getElementById('previewimg_'+element).src; |
if (document.getElementById('showimg_'+element)) { |
} |
document.getElementById('showimg_'+element).innerHTML = '($js_lt{save})'; |
if (document.getElementById('showimg_'+element)) { |
|
document.getElementById('showimg_'+element).innerHTML = '($js_lt{save})'; |
|
} |
} |
} |
toggleChooser(form,element); |
toggleChooser(form,element); |
return; |
return; |
Line 2208 sub crsauthor_url {
|
Line 2268 sub crsauthor_url {
|
} |
} |
|
|
sub import_crsauthor_form { |
sub import_crsauthor_form { |
my ($form,$firstselectname,$secondselectname,$onchangefirst,$only,$suffix,$disabled) = @_; |
my ($firstselectname,$secondselectname,$onchangefirst,$only,$suffix,$disabled) = @_; |
return (0) unless ($env{'request.course.id'}); |
return (0) unless ($env{'request.course.id'}); |
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
my $crshome = $env{'course.'.$env{'request.course.id'}.'.home'}; |
my $crshome = $env{'course.'.$env{'request.course.id'}.'.home'}; |
return (0) unless (($cnum ne '') && ($cdom ne '')); |
return (0) unless (($cnum ne '') && ($cdom ne '')); |
my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'}; |
|
my @ids=&Apache::lonnet::current_machine_ids(); |
my @ids=&Apache::lonnet::current_machine_ids(); |
my ($output,$is_home,$relpath,%subdirs,%files,%selimport_menus); |
my ($output,$is_home,$toppath,%subdirs,%files,%selimport_menus,$include,$exclude); |
|
|
if (grep(/^\Q$crshome\E$/,@ids)) { |
if (grep(/^\Q$crshome\E$/,@ids)) { |
$is_home = 1; |
$is_home = 1; |
} |
} |
$relpath = "/priv/$cdom/$cnum"; |
$toppath = "/priv/$cdom/$cnum"; |
&Apache::lonnet::recursedirs($is_home,'priv',$londocroot,$relpath,'',\%subdirs,\%files); |
my $nonemptydir = 1; |
|
my $js_only; |
|
if ($only) { |
|
map { $include->{$_} = 1; } split(/\s*,\s*/,$only); |
|
$js_only = join(',',map { &js_escape($_); } sort(keys(%{$include}))); |
|
} |
|
$exclude = &Apache::lonnet::priv_exclude(); |
|
&Apache::lonnet::recursedirs($is_home,1,$include,$exclude,1,0,$toppath,'',\%subdirs,\%files); |
|
my $numdirs = scalar(keys(%files)); |
my %lt = &Apache::lonlocal::texthash ( |
my %lt = &Apache::lonlocal::texthash ( |
fnam => 'Filename', |
fnam => 'Filename', |
dire => 'Directory', |
dire => 'Directory', |
|
se => 'Select', |
); |
); |
my $numdirs = scalar(keys(%files)); |
$output = $lt{'dire'}.': '. |
my (%possexts,$singledir,@singledirfiles); |
'<select id="'.$firstselectname.'" name="'.$firstselectname.'" '. |
if ($only) { |
'onchange="populateCrsSelects(this.form,'."'$firstselectname','$secondselectname',1,'$js_only',0,1,0,0,0".');">'. |
map { $possexts{$_} = 1; } split(/\s*,\s*/,$only); |
'<option value="" selected="selected">'.$lt{'se'}.'</option>'; |
} |
if ($files{'/'}) { |
my (%nonemptydirs,$possdirs); |
$output .= '<option value="/">/</option>'."\n"; |
if ($numdirs > 1) { |
} |
my @order; |
foreach my $key (sort { lc($a) cmp lc($b) } (keys(%files))) { |
foreach my $key (sort { lc($a) cmp lc($b) } (keys(%files))) { |
next if ($key eq '/'); |
if (ref($files{$key}) eq 'HASH') { |
$output .= '<option value="'.$key.'">'.$key.'</option>'."\n"; |
my $shown = $key; |
} |
if ($key eq '') { |
$output .= '</select><br />'."\n". |
$shown = '/'; |
$lt{'fnam'}.': <select id="'.$secondselectname.'" name="'.$secondselectname.'">'."\n". |
} |
'<option value="" selected="selected"></option>'."\n". |
my @ordered = (); |
'</select>'."\n". |
foreach my $file (sort { lc($a) cmp lc($b) } (keys(%{$files{$key}}))) { |
'<input type="hidden" id="crsres_include_'.$suffix.'" value="'.$only.'" />'; |
next if ($file =~ /\.rights$/); |
return ($numdirs,$output); |
if ($only) { |
} |
my ($ext) = ($file =~ /\.([^.]+)$/); |
|
unless ($possexts{lc($ext)}) { |
sub show_crsfiles_js { |
next; |
my $excluderef = &Apache::lonnet::priv_exclude(); |
} |
my $se = &js_escape(&mt('Select')); |
|
my $exclude; |
|
if (ref($excluderef) eq 'HASH') { |
|
$exclude = join(',', map { &js_escape($_); } sort(keys(%{$excluderef}))); |
|
} |
|
my $js = <<"END"; |
|
|
|
|
|
function populateCrsSelects (form,dirsel,filesel,exc,include,setdir,setfile,recurse,nonemptydir,addtopdir) { |
|
var relpath = ''; |
|
if ((setfile) && (dirsel != null) && (dirsel != 'undefined') && (dirsel != '')) { |
|
var currdir = form.elements[dirsel].options[form.elements[dirsel].selectedIndex].value; |
|
if (currdir == '') { |
|
if ((filesel != null) && (filesel != 'undefined') && (filesel != '')) { |
|
selelem = form.elements[filesel]; |
|
var j, numfiles = selelem.options.length -1; |
|
if (numfiles >=0) { |
|
for (j = numfiles; j >= 0; j--) { |
|
selelem.remove(j); |
|
} |
|
} |
|
if (selelem.options.length == 0) { |
|
selelem.options[selelem.options.length] = new Option('',''); |
|
selelem.selectedIndex = 0; |
} |
} |
$selimport_menus{$key}->{'select2'}->{$file} = $file; |
|
push(@ordered,$file); |
|
} |
|
if (@ordered) { |
|
push(@order,$key); |
|
$nonemptydirs{$key} = 1; |
|
$selimport_menus{$key}->{'text'} = $shown; |
|
$selimport_menus{$key}->{'default'} = ''; |
|
$selimport_menus{$key}->{'select2'}->{''} = ''; |
|
$selimport_menus{$key}->{'order'} = \@ordered; |
|
} |
} |
|
return; |
|
} else { |
|
relpath = encodeURIComponent(form.elements[dirsel].options[form.elements[dirsel].selectedIndex].value); |
} |
} |
} |
} |
$possdirs = scalar(keys(%nonemptydirs)); |
var http = new XMLHttpRequest(); |
if ($possdirs > 1) { |
var url = "/adm/courseauthor"; |
my @order = sort { lc($a) cmp lc($b) } (keys(%nonemptydirs)); |
var crsrole = "$env{'request.role'}"; |
$output = $lt{'dire'}. |
var exclude = ''; |
&linked_select_forms($form,'<br />'. |
if (exc) { |
$lt{'fnam'},'', |
exclude = '$exclude'; |
$firstselectname,$secondselectname, |
} |
\%selimport_menus,\@order, |
var params = "role=course&files=1&rec="+recurse+"&nonempty="+nonemptydir+"&exc="+exclude+"&inc="+include+"&addtop="+addtopdir+"&path="+relpath; |
$onchangefirst,'',$suffix).'<br />'; |
http.open("POST", url, true); |
} elsif ($possdirs == 1) { |
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); |
$singledir = (keys(%nonemptydirs))[0]; |
http.onreadystatechange = function() { |
if (ref($selimport_menus{$singledir}->{'order'}) eq 'ARRAY') { |
if (http.readyState == 4 && http.status == 200) { |
@singledirfiles = @{$selimport_menus{$singledir}->{'order'}}; |
var data = JSON.parse(http.responseText); |
} |
var selelem; |
delete($selimport_menus{$singledir}); |
if ((setdir) && (dirsel != null) && (dirsel != 'undefined') && (dirsel != '')) { |
} |
if (Array.isArray(data.dirs)) { |
} elsif ($numdirs == 1) { |
selelem = form.elements[dirsel]; |
$singledir = (keys(%files))[0]; |
var i, numdirs = selelem.options.length -1; |
foreach my $file (sort { lc($a) cmp lc($b) } (keys(%{$files{$singledir}}))) { |
if (numdirs >=0) { |
if ($only) { |
for (i = numdirs; i >= 0; i--) { |
my ($ext) = ($file =~ /\.([^.]+)$/); |
selelem.remove(i); |
unless ($possexts{lc($ext)}) { |
} |
next; |
} |
|
var len = data.dirs.length; |
|
if (len) { |
|
selelem.options[selelem.options.length] = new Option('$se',''); |
|
var j; |
|
for (j = 0; j < len; j++) { |
|
selelem.options[selelem.options.length] = new Option(data.dirs[j],data.dirs[j]); |
|
} |
|
selelem.selectedIndex = 0; |
|
} |
|
if (!setfile) { |
|
if ((filesel != null) && (filesel != 'undefined') && (filesel != '')) { |
|
selelem = form.elements[filesel]; |
|
var j, numfiles = selelem.options.length -1; |
|
if (numfiles >=0) { |
|
for (j = numfiles; j >= 0; j--) { |
|
selelem.remove(j); |
|
} |
|
} |
|
if (selelem.options.length == 0) { |
|
selelem.options[selelem.options.length] = new Option('',''); |
|
selelem.selectedIndex = 0; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if ((setfile) && (filesel != null) && (filesel != 'undefined') && (filesel != '')) { |
|
selelem = form.elements[filesel]; |
|
var i, numfiles = selelem.options.length -1; |
|
if (numfiles >=0) { |
|
for (i = numfiles; i >= 0; i--) { |
|
selelem.remove(i); |
|
} |
|
} |
|
var x; |
|
for (x in data.files) { |
|
if (Array.isArray(data.files[x])) { |
|
if (data.files[x].length > 1) { |
|
selelem.options[selelem.options.length] = new Option('$se',''); |
|
} |
|
var len = data.files[x].length; |
|
if (len) { |
|
var k; |
|
for (k = 0; k < len; k++) { |
|
selelem.options[selelem.options.length] = new Option(data.files[x][k],data.files[x][k]); |
|
} |
|
selelem.selectedIndex = 0; |
|
} |
|
} |
|
} |
|
if (selelem.options.length == 0) { |
|
selelem.options[selelem.options.length] = new Option('',''); |
|
selelem.selectedIndex = 0; |
|
} |
} |
} |
} else { |
|
next if ($file =~ /\.rights$/); |
|
} |
} |
push(@singledirfiles,$file); |
|
} |
|
if (@singledirfiles) { |
|
$possdirs = 1; |
|
} |
} |
|
http.send(params); |
} |
} |
if (($possdirs == 1) && (@singledirfiles)) { |
END |
my $showdir = $singledir; |
|
if ($singledir eq '') { |
|
$showdir = '/'; |
|
} |
|
$output = $lt{'dire'}. |
|
'<select name="'.$firstselectname.'">'. |
|
'<option value="'.$singledir.'">'.$showdir.'</option>'."\n". |
|
'</select><br />'. |
|
$lt{'fnam'}.'<select name="'.$secondselectname.'">'."\n". |
|
'<option value="" selected="selected">'.$lt{'se'}.'</option>'."\n"; |
|
foreach my $file (@singledirfiles) { |
|
$output .= '<option value="'.$file.'">'.$file.'</option>'."\n"; |
|
} |
|
$output .= '</select><br />'."\n"; |
|
} |
|
return ($possdirs,$output); |
|
} |
} |
|
|
=pod |
=pod |
Line 2664 sub display_filter {
|
Line 2781 sub display_filter {
|
my $onchange = "javascript:toggleHistoryOptions(this,'containingphrase','$context', |
my $onchange = "javascript:toggleHistoryOptions(this,'containingphrase','$context', |
'$secondid','$thirdid')"; |
'$secondid','$thirdid')"; |
return '<span class="LC_nobreak"><label>'.&mt('Records: [_1]', |
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]', |
Line 3648 sub check_passwd_rules {
|
Line 3765 sub check_passwd_rules {
|
return $warning; |
return $warning; |
} |
} |
|
|
|
sub passwd_validation_js { |
|
my ($currpasswdval,$domain,$context,$id) = @_; |
|
my (%passwdconf,$alertmsg); |
|
if ($context eq 'linkprot') { |
|
my %domconfig = &Apache::lonnet::get_dom('configuration',['ltisec'],$domain); |
|
if (ref($domconfig{'ltisec'}) eq 'HASH') { |
|
if (ref($domconfig{'ltisec'}{'rules'}) eq 'HASH') { |
|
%passwdconf = %{$domconfig{'ltisec'}{'rules'}}; |
|
} |
|
} |
|
if ($id eq 'add') { |
|
$alertmsg = &mt('Secret for added launcher did not satisfy requirement(s):').'\n\n'; |
|
} elsif ($id =~ /^\d+$/) { |
|
my $pos = $id+1; |
|
$alertmsg = &mt('Secret for launcher [_1] did not satisfy requirement(s):','#'.$pos).'\n\n'; |
|
} else { |
|
$alertmsg = &mt('A secret did not satisfy requirement(s):').'\n\n'; |
|
} |
|
} else { |
|
%passwdconf = &Apache::lonnet::get_passwdconf($domain); |
|
$alertmsg = &mt('Initial password did not satisfy requirement(s):').'\n\n'; |
|
} |
|
my ($min,$max,@chars,$numrules,$intargjs,%alert); |
|
$numrules = 0; |
|
$min = $Apache::lonnet::passwdmin; |
|
if (ref($passwdconf{'chars'}) eq 'ARRAY') { |
|
if ($passwdconf{'min'} =~ /^\d+$/) { |
|
if ($passwdconf{'min'} > $min) { |
|
$min = $passwdconf{'min'}; |
|
} |
|
} |
|
if ($passwdconf{'max'} =~ /^\d+$/) { |
|
$max = $passwdconf{'max'}; |
|
$numrules ++; |
|
} |
|
@chars = @{$passwdconf{'chars'}}; |
|
if (@chars) { |
|
$numrules ++; |
|
} |
|
} |
|
if ($min > 0) { |
|
$numrules ++; |
|
} |
|
if (($min > 0) || ($max ne '') || (@chars > 0)) { |
|
if ($min) { |
|
$alert{'min'} = &mt('minimum [quant,_1,character]',$min).'\n'; |
|
} |
|
if ($max) { |
|
$alert{'max'} = &mt('maximum [quant,_1,character]',$max).'\n'; |
|
} |
|
my (@charalerts,@charrules); |
|
if (@chars) { |
|
if (grep(/^uc$/,@chars)) { |
|
push(@charalerts,&mt('contain at least one upper case letter')); |
|
push(@charrules,'uc'); |
|
} |
|
if (grep(/^lc$/,@chars)) { |
|
push(@charalerts,&mt('contain at least one lower case letter')); |
|
push(@charrules,'lc'); |
|
} |
|
if (grep(/^num$/,@chars)) { |
|
push(@charalerts,&mt('contain at least one number')); |
|
push(@charrules,'num'); |
|
} |
|
if (grep(/^spec$/,@chars)) { |
|
push(@charalerts,&mt('contain at least one non-alphanumeric')); |
|
push(@charrules,'spec'); |
|
} |
|
} |
|
$intargjs = qq| var rulesmsg = '';\n|. |
|
qq| var currpwval = $currpasswdval;\n|; |
|
if ($min) { |
|
$intargjs .= qq| |
|
if (currpwval.length < $min) { |
|
rulesmsg += ' - $alert{min}'; |
|
} |
|
|; |
|
} |
|
if ($max) { |
|
$intargjs .= qq| |
|
if (currpwval.length > $max) { |
|
rulesmsg += ' - $alert{max}'; |
|
} |
|
|; |
|
} |
|
if (@chars > 0) { |
|
my $charrulestr = '"'.join('","',@charrules).'"'; |
|
my $charalertstr = '"'.join('","',@charalerts).'"'; |
|
$intargjs .= qq| var brokerules = new Array();\n|. |
|
qq| var charrules = new Array($charrulestr);\n|. |
|
qq| var charalerts = new Array($charalertstr);\n|; |
|
my %rules; |
|
map { $rules{$_} = 1; } @chars; |
|
if ($rules{'uc'}) { |
|
$intargjs .= qq| |
|
var ucRegExp = /[A-Z]/; |
|
if (!ucRegExp.test(currpwval)) { |
|
brokerules.push('uc'); |
|
} |
|
|; |
|
} |
|
if ($rules{'lc'}) { |
|
$intargjs .= qq| |
|
var lcRegExp = /[a-z]/; |
|
if (!lcRegExp.test(currpwval)) { |
|
brokerules.push('lc'); |
|
} |
|
|; |
|
} |
|
if ($rules{'num'}) { |
|
$intargjs .= qq| |
|
var numRegExp = /[0-9]/; |
|
if (!numRegExp.test(currpwval)) { |
|
brokerules.push('num'); |
|
} |
|
|; |
|
} |
|
if ($rules{'spec'}) { |
|
$intargjs .= q| |
|
var specRegExp = /[!"#$%&'()*+,\-.\/:;<=>?@[\\^\]_`{\|}~]/; |
|
if (!specRegExp.test(currpwval)) { |
|
brokerules.push('spec'); |
|
} |
|
|; |
|
} |
|
$intargjs .= qq| |
|
if (brokerules.length > 0) { |
|
for (var i=0; i<brokerules.length; i++) { |
|
for (var j=0; j<charrules.length; j++) { |
|
if (brokerules[i] == charrules[j]) { |
|
rulesmsg += ' - '+charalerts[j]+'\\n'; |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
|; |
|
} |
|
$intargjs .= qq| |
|
if (rulesmsg != '') { |
|
rulesmsg = '$alertmsg'+rulesmsg; |
|
alert(rulesmsg); |
|
return false; |
|
} |
|
|; |
|
} |
|
return ($numrules,$intargjs); |
|
} |
|
|
############################################################### |
############################################################### |
## Get Kerberos Defaults for Domain ## |
## Get Kerberos Defaults for Domain ## |
############################################################### |
############################################################### |
Line 4128 sub syllabuswrapper {
|
Line 4394 sub syllabuswrapper {
|
|
|
# ----------------------------------------------------------------------------- |
# ----------------------------------------------------------------------------- |
|
|
|
sub aboutme_on { |
|
my ($uname,$udom)=@_; |
|
unless ($uname) { $uname=$env{'user.name'}; } |
|
unless ($udom) { $udom=$env{'user.domain'}; } |
|
return if ($udom eq 'public' && $uname eq 'public'); |
|
my $hashkey=$uname.':'.$udom; |
|
my ($aboutme,$cached)=&Apache::lonnet::is_cached_new('aboutme',$hashkey); |
|
if ($cached) { |
|
return $aboutme; |
|
} |
|
$aboutme = &Apache::lonnet::usertools_access($uname,$udom,'aboutme'); |
|
&Apache::lonnet::do_cache_new('aboutme',$hashkey,$aboutme,3600); |
|
return $aboutme; |
|
} |
|
|
|
sub devalidate_aboutme_cache { |
|
my ($uname,$udom)=@_; |
|
if (!$udom) { $udom =$env{'user.domain'}; } |
|
if (!$uname) { $uname=$env{'user.name'}; } |
|
return if ($udom eq 'public' && $uname eq 'public'); |
|
my $id=$uname.':'.$udom; |
|
&Apache::lonnet::devalidate_cache_new('aboutme',$id); |
|
} |
|
|
sub track_student_link { |
sub track_student_link { |
my ($linktext,$sname,$sdom,$target,$start,$only_body) = @_; |
my ($linktext,$sname,$sdom,$target,$start,$only_body) = @_; |
my $link ="/adm/trackstudent?"; |
my $link ="/adm/trackstudent?"; |
Line 5201 sub findallcourses {
|
Line 5491 sub findallcourses {
|
############################################### |
############################################### |
|
|
sub blockcheck { |
sub blockcheck { |
my ($setters,$activity,$uname,$udom,$url,$is_course,$symb,$caller) = @_; |
my ($setters,$activity,$clientip,$uname,$udom,$url,$is_course,$symb,$caller) = @_; |
|
unless (($activity eq 'docs') || ($activity eq 'reinit') || ($activity eq 'alert')) { |
|
my ($has_evb,$check_ipaccess); |
|
my $dom = $env{'user.domain'}; |
|
if ($env{'request.course.id'}) { |
|
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
my $checkrole = "cm./$cdom/$cnum"; |
|
my $sec = $env{'request.course.sec'}; |
|
if ($sec ne '') { |
|
$checkrole .= "/$sec"; |
|
} |
|
if ((&Apache::lonnet::allowed('evb',undef,undef,$checkrole)) && |
|
($env{'request.role'} !~ /^st/)) { |
|
$has_evb = 1; |
|
} |
|
unless ($has_evb) { |
|
if (($activity eq 'printout') || ($activity eq 'grades') || ($activity eq 'search') || |
|
($activity eq 'boards') || ($activity eq 'groups') || ($activity eq 'chat')) { |
|
if ($udom eq $cdom) { |
|
$check_ipaccess = 1; |
|
} |
|
} |
|
} |
|
} elsif (($activity eq 'com') || ($activity eq 'port') || ($activity eq 'blogs') || |
|
($activity eq 'about') || ($activity eq 'wishlist') || ($activity eq 'passwd')) { |
|
my $checkrole; |
|
if ($env{'request.role.domain'} eq '') { |
|
$checkrole = "cm./$env{'user.domain'}/"; |
|
} else { |
|
$checkrole = "cm./$env{'request.role.domain'}/"; |
|
} |
|
if (($checkrole) && (&Apache::lonnet::allowed('evb',undef,undef,$checkrole))) { |
|
$has_evb = 1; |
|
} |
|
} |
|
unless ($has_evb || $check_ipaccess) { |
|
my @machinedoms = &Apache::lonnet::current_machine_domains(); |
|
if (($dom eq 'public') && ($activity eq 'port')) { |
|
$dom = $udom; |
|
} |
|
if (($dom ne '') && (grep(/^\Q$dom\E$/,@machinedoms))) { |
|
$check_ipaccess = 1; |
|
} else { |
|
my $lonhost = $Apache::lonnet::perlvar{'lonHostID'}; |
|
my $internet_names = &Apache::lonnet::get_internet_names($lonhost); |
|
my $prim = &Apache::lonnet::domain($dom,'primary'); |
|
my $intdom = &Apache::lonnet::internet_dom($prim); |
|
if (($intdom ne '') && (ref($internet_names) eq 'ARRAY')) { |
|
if (grep(/^\Q$intdom\E$/,@{$internet_names})) { |
|
$check_ipaccess = 1; |
|
} |
|
} |
|
} |
|
} |
|
if ($check_ipaccess) { |
|
my ($ipaccessref,$cached)=&Apache::lonnet::is_cached_new('ipaccess',$dom); |
|
unless (defined($cached)) { |
|
my %domconfig = |
|
&Apache::lonnet::get_dom('configuration',['ipaccess'],$dom); |
|
$ipaccessref = &Apache::lonnet::do_cache_new('ipaccess',$dom,$domconfig{'ipaccess'},1800); |
|
} |
|
if ((ref($ipaccessref) eq 'HASH') && ($clientip)) { |
|
foreach my $id (keys(%{$ipaccessref})) { |
|
if (ref($ipaccessref->{$id}) eq 'HASH') { |
|
my $range = $ipaccessref->{$id}->{'ip'}; |
|
if ($range) { |
|
if (&Apache::lonnet::ip_match($clientip,$range)) { |
|
if (ref($ipaccessref->{$id}->{'commblocks'}) eq 'HASH') { |
|
if ($ipaccessref->{$id}->{'commblocks'}->{$activity} eq 'on') { |
|
return ('','','',$id,$dom); |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if (($activity eq 'wishlist') || ($activity eq 'annotate')) { |
|
return (); |
|
} |
|
} |
if (defined($udom) && defined($uname)) { |
if (defined($udom) && defined($uname)) { |
# If uname and udom are for a course, check for blocks in the course. |
# If uname and udom are for a course, check for blocks in the course. |
if (($is_course) || (&Apache::lonnet::is_course($udom,$uname))) { |
if (($is_course) || (&Apache::lonnet::is_course($udom,$uname))) { |
Line 5218 sub blockcheck {
|
Line 5590 sub blockcheck {
|
my $startblock = 0; |
my $startblock = 0; |
my $endblock = 0; |
my $endblock = 0; |
my $triggerblock = ''; |
my $triggerblock = ''; |
my %live_courses = &findallcourses(undef,$uname,$udom); |
my %live_courses; |
|
unless (($activity eq 'wishlist') || ($activity eq 'annotate')) { |
|
%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., |
# boards, chat or groups, check for blocking in current course only. |
# boards, chat or groups, check for blocking in current course only. |
Line 5503 sub parse_block_record {
|
Line 5878 sub parse_block_record {
|
} |
} |
|
|
sub blocking_status { |
sub blocking_status { |
my ($activity,$uname,$udom,$url,$is_course,$symb,$caller) = @_; |
my ($activity,$clientip,$uname,$udom,$url,$is_course,$symb,$caller) = @_; |
my %setters; |
my %setters; |
|
|
# check for active blocking |
# check for active blocking |
my ($startblock,$endblock,$triggerblock) = |
if ($clientip eq '') { |
&blockcheck(\%setters,$activity,$uname,$udom,$url,$is_course,$symb,$caller); |
$clientip = &Apache::lonnet::get_requestor_ip(); |
|
} |
|
my ($startblock,$endblock,$triggerblock,$by_ip,$blockdom) = |
|
&blockcheck(\%setters,$activity,$clientip,$uname,$udom,$url,$is_course,$symb,$caller); |
my $blocked = 0; |
my $blocked = 0; |
if ($startblock && $endblock) { |
if (($startblock && $endblock) || ($by_ip)) { |
$blocked = 1; |
$blocked = 1; |
} |
} |
|
|
Line 5564 END_MYBLOCK
|
Line 5942 END_MYBLOCK
|
$text = &mt('Checking Course Update Blocked'); |
$text = &mt('Checking Course Update Blocked'); |
} elsif ($activity eq 'about') { |
} elsif ($activity eq 'about') { |
$text = &mt('Access to User Information Pages Blocked'); |
$text = &mt('Access to User Information Pages Blocked'); |
|
} elsif ($activity eq 'wishlist') { |
|
$text = &mt('Access to Stored Links Blocked'); |
|
} elsif ($activity eq 'annotate') { |
|
$text = &mt('Access to Annotations Blocked'); |
} |
} |
$output .= <<"END_BLOCK"; |
$output .= <<"END_BLOCK"; |
<div class='$class'> |
<div class='$class'> |
Line 5745 sub get_domainconf {
|
Line 6127 sub get_domainconf {
|
} |
} |
} |
} |
} |
} |
|
} elsif ($key eq 'saml') { |
|
if (ref($domconfig{'login'}{$key}) eq 'HASH') { |
|
foreach my $host (keys(%{$domconfig{'login'}{$key}})) { |
|
if (ref($domconfig{'login'}{$key}{$host}) eq 'HASH') { |
|
$designhash{$udom.'.login.'.$key.'_'.$host} = 1; |
|
foreach my $item ('text','img','alt','url','title','window','notsso') { |
|
$designhash{$udom.'.login.'.$key.'_'.$item.'_'.$host} = $domconfig{'login'}{$key}{$host}{$item}; |
|
} |
|
} |
|
} |
|
} |
} else { |
} else { |
foreach my $img (keys(%{$domconfig{'login'}{$key}})) { |
foreach my $img (keys(%{$domconfig{'login'}{$key}})) { |
$designhash{$udom.'.login.'.$key.'_'.$img} = |
$designhash{$udom.'.login.'.$key.'_'.$img} = |
Line 5849 sub domainlogo {
|
Line 6242 sub domainlogo {
|
&Apache::lonnet::repcopy($local_name); |
&Apache::lonnet::repcopy($local_name); |
} |
} |
$imgsrc = &lonhttpdurl($imgsrc); |
$imgsrc = &lonhttpdurl($imgsrc); |
} |
} |
return '<img src="'.$imgsrc.'" alt="'.$domain.'" />'; |
my $alttext = $domain; |
|
if ($designhash{$domain.'.login.alttext_domlogo'} ne '') { |
|
$alttext = $designhash{$domain.'.login.alttext_domlogo'}; |
|
} |
|
return '<img src="'.$imgsrc.'" alt="'.$alttext.'" id="lclogindomlogo" />'; |
} elsif (defined(&Apache::lonnet::domain($domain,'description'))) { |
} elsif (defined(&Apache::lonnet::domain($domain,'description'))) { |
return &Apache::lonnet::domain($domain,'description'); |
return &Apache::lonnet::domain($domain,'description'); |
} else { |
} else { |
Line 5968 sub head_subbox {
|
Line 6365 sub head_subbox {
|
Input: (optional) filename from which breadcrumb trail is built. |
Input: (optional) filename from which breadcrumb trail is built. |
In most cases no input as needed, as $env{'request.filename'} |
In most cases no input as needed, as $env{'request.filename'} |
is appropriate for use in building the breadcrumb trail. |
is appropriate for use in building the breadcrumb trail. |
|
frameset flag |
|
If page header is being requested for use in a frameset, then |
|
the second (option) argument -- frameset will be true, and |
|
the target attribute set for links should be target="_parent". |
|
|
Returns: HTML div with CSTR path and recent box |
Returns: HTML div with CSTR path and recent box |
To be included on Authoring Space pages |
To be included on Authoring Space pages |
Line 5975 Returns: HTML div with CSTR path and rec
|
Line 6376 Returns: HTML div with CSTR path and rec
|
=cut |
=cut |
|
|
sub CSTR_pageheader { |
sub CSTR_pageheader { |
my ($trailfile) = @_; |
my ($trailfile,$frameset) = @_; |
if ($trailfile eq '') { |
if ($trailfile eq '') { |
$trailfile = $env{'request.filename'}; |
$trailfile = $env{'request.filename'}; |
} |
} |
Line 6008 sub CSTR_pageheader {
|
Line 6409 sub CSTR_pageheader {
|
$title = &mt('Authoring Space'); |
$title = &mt('Authoring Space'); |
} |
} |
|
|
my ($target,$crumbtarget) = (' target="_top"','_top'); #FIXME lonpubdir: target="_parent" |
my ($target,$crumbtarget) = (' target="_top"','_top'); |
if (($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) { |
if ($frameset) { |
|
$target = ' target="_parent"'; |
|
$crumbtarget = '_parent'; |
|
} elsif (($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) { |
$target = ''; |
$target = ''; |
$crumbtarget = ''; |
$crumbtarget = ''; |
|
} elsif (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'})) { |
|
$target = ' target="'.$env{'request.deeplink.target'}.'"'; |
|
$crumbtarget = $env{'request.deeplink.target'}; |
} |
} |
|
|
my $output = |
my $output = |
Line 6029 sub CSTR_pageheader {
|
Line 6436 sub CSTR_pageheader {
|
} |
} |
|
|
if ($crsauthor) { |
if ($crsauthor) { |
$output .= '</form>'.&Apache::lonmenu::constspaceform(); |
$output .= '</form>'.&Apache::lonmenu::constspaceform($frameset); |
} else { |
} else { |
$output .= |
$output .= |
'<br />' |
'<br />' |
#FIXME lonpubdir: &Apache::lonhtmlcommon::crumbs($uname.$thisdisfn.'/',$crumbtarget,'/priv','','+1',1)."</b></tt><br />" |
#FIXME lonpubdir: &Apache::lonhtmlcommon::crumbs($uname.$thisdisfn.'/',$crumbtarget,'/priv','','+1',1)."</b></tt><br />" |
.&Apache::lonhtmlcommon::select_recent('construct','recent','this.form.action=this.form.recent.value;this.form.submit()') |
.&Apache::lonhtmlcommon::select_recent('construct','recent','this.form.action=this.form.recent.value;this.form.submit()') |
.'</form>' |
.'</form>' |
.&Apache::lonmenu::constspaceform(); |
.&Apache::lonmenu::constspaceform($frameset); |
} |
} |
$output .= '</div>'; |
$output .= '</div>'; |
|
|
Line 6104 Inputs:
|
Line 6511 Inputs:
|
context, this will contain a reference to hash of items |
context, this will contain a reference to hash of items |
to be included in the page header and/or inline menu. |
to be included in the page header and/or inline menu. |
|
|
|
=item * $menucoll, optional argument, if specific menu collection is in |
|
effect, either set as the default for the course, or set for |
|
the deeplink paramater for $env{'request.deeplink.login'} |
|
then $menucoll will be the number of that collection. |
|
|
|
=item * $menuref, optional argument, reference to a hash, containing the |
|
menu options included for the menu in effect, based on the |
|
configuration for the numbered menu collection in use. |
|
|
|
=item * $showncrumbsref, reference to a scalar. Calls to lonmenu::innerregister |
|
within &bodytag() can result in calls to lonhtmlcommon::breadcrumbs(), |
|
if so, $showncrumbsref is set there to 1, and will propagate back |
|
via &bodytag() to &start_page(), to prevent lonhtmlcommon::breadcrumbs() |
|
being called a second time. |
|
|
=back |
=back |
|
|
Returns: A uniform header for LON-CAPA web pages. |
Returns: A uniform header for LON-CAPA web pages. |
Line 6115 other decorations will be returned.
|
Line 6537 other decorations will be returned.
|
|
|
sub bodytag { |
sub bodytag { |
my ($title,$function,$addentries,$bodyonly,$domain,$forcereg, |
my ($title,$function,$addentries,$bodyonly,$domain,$forcereg, |
$no_nav_bar,$bgcolor,$args,$advtoolsref,$ltiscope,$ltiuri,$ltimenu)=@_; |
$no_nav_bar,$bgcolor,$args,$advtoolsref,$ltiscope,$ltiuri, |
|
$ltimenu,$menucoll,$menuref,$showncrumbsref)=@_; |
|
|
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 6144 sub bodytag {
|
Line 6567 sub bodytag {
|
if ($realm) { |
if ($realm) { |
$realm = '/'.$realm; |
$realm = '/'.$realm; |
} |
} |
if ($role eq 'ca') { |
if ($role eq 'ca') { |
my ($rdom,$rname) = ($realm =~ m{^/($match_domain)/($match_username)$}); |
my ($rdom,$rname) = ($realm =~ m{^/($match_domain)/($match_username)$}); |
$realm = &plainname($rname,$rdom); |
$realm = &plainname($rname,$rdom); |
} |
} |
# realm |
# realm |
|
my ($cid,$sec); |
if ($env{'request.course.id'}) { |
if ($env{'request.course.id'}) { |
|
$cid = $env{'request.course.id'}; |
|
if ($env{'request.course.sec'}) { |
|
$sec = $env{'request.course.sec'}; |
|
} |
|
} elsif ($realm =~ m{^/($match_domain)/($match_courseid)(?:|/(\w+))$}) { |
|
if (&Apache::lonnet::is_course($1,$2)) { |
|
$cid = $1.'_'.$2; |
|
$sec = $3; |
|
} |
|
} |
|
if ($cid) { |
if ($env{'request.role'} !~ /^cr/) { |
if ($env{'request.role'} !~ /^cr/) { |
$role = &Apache::lonnet::plaintext($role,&course_type()); |
$role = &Apache::lonnet::plaintext($role,&course_type()); |
} elsif ($role =~ m{^cr/($match_domain)/\1-domainconfig/(\w+)$}) { |
} elsif ($role =~ m{^cr/($match_domain)/\1-domainconfig/(\w+)$}) { |
Line 6161 sub bodytag {
|
Line 6596 sub bodytag {
|
} else { |
} else { |
$role = (split(/\//,$role,4))[-1]; |
$role = (split(/\//,$role,4))[-1]; |
} |
} |
if ($env{'request.course.sec'}) { |
if ($sec) { |
$role .= (' 'x2).'- '.&mt('section:').' '.$env{'request.course.sec'}; |
$role .= (' 'x2).'- '.&mt('section:').' '.$sec; |
} |
} |
$realm = $env{'course.'.$env{'request.course.id'}.'.description'}; |
$realm = $env{'course.'.$cid.'.description'}; |
} else { |
} else { |
$role = &Apache::lonnet::plaintext($role); |
$role = &Apache::lonnet::plaintext($role); |
} |
} |
Line 6187 sub bodytag {
|
Line 6622 sub bodytag {
|
undef($role); |
undef($role); |
} |
} |
|
|
if (($env{'request.course.id'}) && ($env{'request.lti.login'})) { |
my $showcrstitle = 1; |
|
if (($cid) && ($env{'request.lti.login'})) { |
if (ref($ltimenu) eq 'HASH') { |
if (ref($ltimenu) eq 'HASH') { |
unless ($ltimenu->{'role'}) { |
unless ($ltimenu->{'role'}) { |
undef($role); |
undef($role); |
} |
} |
unless ($ltimenu->{'coursetitle'}) { |
unless ($ltimenu->{'coursetitle'}) { |
$realm=' '; |
$realm=' '; |
|
$showcrstitle = 0; |
|
} |
|
} |
|
} elsif (($cid) && ($menucoll)) { |
|
if (ref($menuref) eq 'HASH') { |
|
unless ($menuref->{'role'}) { |
|
undef($role); |
|
} |
|
unless ($menuref->{'crs'}) { |
|
$realm=' '; |
|
$showcrstitle = 0; |
} |
} |
} |
} |
} |
} |
Line 6202 sub bodytag {
|
Line 6649 sub bodytag {
|
# |
# |
# Extra info if you are the DC |
# Extra info if you are the DC |
my $dc_info = ''; |
my $dc_info = ''; |
if ($env{'user.adv'} && exists($env{'user.role.dc./'. |
if (($env{'user.adv'}) && ($env{'request.course.id'}) && $showcrstitle && |
$env{'course.'.$env{'request.course.id'}. |
(exists($env{'user.role.dc./'.$env{'course.'.$cid.'.domain'}.'/'}))) { |
'.domain'}.'/'})) { |
|
my $cid = $env{'request.course.id'}; |
|
$dc_info = $cid.' '.$env{'course.'.$cid.'.internal.coursecode'}; |
$dc_info = $cid.' '.$env{'course.'.$cid.'.internal.coursecode'}; |
$dc_info =~ s/\s+$//; |
$dc_info =~ s/\s+$//; |
} |
} |
|
|
my $crstype; |
my $crstype; |
if ($env{'request.course.id'}) { |
if ($cid) { |
$crstype = $env{'course.'.$env{'request.course.id'}.'.type'}; |
$crstype = $env{'course.'.$cid.'.type'}; |
} elsif ($args->{'crstype'}) { |
} elsif ($args->{'crstype'}) { |
$crstype = $args->{'crstype'}; |
$crstype = $args->{'crstype'}; |
} |
} |
Line 6232 sub bodytag {
|
Line 6677 sub bodytag {
|
Apache::lonmenu::utilityfunctions($httphost), 'start'); |
Apache::lonmenu::utilityfunctions($httphost), 'start'); |
|
|
unless ($args->{'no_primary_menu'}) { |
unless ($args->{'no_primary_menu'}) { |
my ($left,$right) = Apache::lonmenu::primary_menu($crstype,$ltimenu); |
my ($left,$right) = Apache::lonmenu::primary_menu($crstype,$ltimenu,$menucoll,$menuref, |
|
$args->{'links_disabled'}, |
|
$args->{'links_target'}); |
|
|
if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { |
if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { |
if ($dc_info) { |
if ($dc_info) { |
Line 6263 sub bodytag {
|
Line 6710 sub bodytag {
|
if (!$public){ |
if (!$public){ |
unless ($args->{'no_inline_menu'}) { |
unless ($args->{'no_inline_menu'}) { |
$bodytag .= Apache::lonmenu::secondary_menu($httphost,$ltiscope,$ltimenu, |
$bodytag .= Apache::lonmenu::secondary_menu($httphost,$ltiscope,$ltimenu, |
$args->{'no_primary_menu'}); |
$args->{'no_primary_menu'}, |
|
$menucoll,$menuref, |
|
$args->{'links_disabled'}, |
|
$args->{'links_target'}); |
} |
} |
$bodytag .= Apache::lonmenu::serverform(); |
$bodytag .= Apache::lonmenu::serverform(); |
$bodytag .= Apache::lonhtmlcommon::scripttag('', 'end'); |
$bodytag .= Apache::lonhtmlcommon::scripttag('', 'end'); |
if ($env{'request.state'} eq 'construct') { |
if ($env{'request.state'} eq 'construct') { |
$bodytag .= &Apache::lonmenu::innerregister($forcereg, |
$bodytag .= &Apache::lonmenu::innerregister($forcereg, |
$args->{'bread_crumbs'},'','',$hostname,$ltiscope,$ltiuri); |
$args->{'bread_crumbs'},'','',$hostname, |
|
$ltiscope,$ltiuri,$showncrumbsref); |
} elsif ($forcereg) { |
} elsif ($forcereg) { |
$bodytag .= &Apache::lonmenu::innerregister($forcereg,undef, |
$bodytag .= &Apache::lonmenu::innerregister($forcereg,undef, |
$args->{'group'}, |
$args->{'group'},$args->{'hide_buttons'}, |
$args->{'hide_buttons'}, |
$hostname,$ltiscope,$ltiuri,$showncrumbsref); |
$hostname,$ltiscope,$ltiuri); |
|
} else { |
} else { |
$bodytag .= |
$bodytag .= |
&Apache::lonmenu::prepare_functions($env{'request.noversionuri'}, |
&Apache::lonmenu::prepare_functions($env{'request.noversionuri'}, |
Line 6358 sub endbodytag {
|
Line 6808 sub 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'})) { |
|
my ($endbodyjs,$idattr); |
|
if ($env{'internal.head.to_opener'}) { |
|
my $linkid = 'LC_continue_link'; |
|
$idattr = ' id="'.$linkid.'"'; |
|
my $redirect_for_js = &js_escape($env{'internal.head.redirect'}); |
|
$endbodyjs=<<ENDJS; |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
function ebFunction(evt) { |
|
evt.preventDefault(); |
|
var dest = '$redirect_for_js'; |
|
if (window.opener != null && !window.opener.closed) { |
|
window.opener.location.href=dest; |
|
window.close(); |
|
} else { |
|
window.location.href=dest; |
|
} |
|
return false; |
|
} |
|
|
|
\$(document).ready(function () { |
|
if (document.getElementById('$linkid')) { |
|
var clickelem = document.getElementById('$linkid'); |
|
clickelem.addEventListener('click',ebFunction,false); |
|
} |
|
}); |
|
// ]]> |
|
</script> |
|
ENDJS |
|
} |
$endbodytag= |
$endbodytag= |
"<br /><a href=\"$env{'internal.head.redirect'}\">". |
"$endbodyjs<br /><a href=\"$env{'internal.head.redirect'}\"$idattr>". |
&mt('Continue').'</a>'. |
&mt('Continue').'</a>'. |
$endbodytag; |
$endbodytag; |
} |
} |
Line 7680 fieldset {
|
Line 8160 fieldset {
|
/* overflow: hidden; */ |
/* overflow: hidden; */ |
} |
} |
|
|
|
fieldset#LC_selectuser { |
|
margin: 0; |
|
padding: 0; |
|
} |
|
|
article.geogebraweb div { |
article.geogebraweb div { |
margin: 0; |
margin: 0; |
} |
} |
Line 8223 a#LC_content_toolbar_edittoplevel {
|
Line 8708 a#LC_content_toolbar_edittoplevel {
|
background-image:url(/res/adm/pages/edittoplevel.gif); |
background-image:url(/res/adm/pages/edittoplevel.gif); |
} |
} |
|
|
|
a#LC_content_toolbar_printout { |
|
background-image:url(/res/adm/pages/printout.gif); |
|
} |
|
|
ul#LC_toolbar li a:hover { |
ul#LC_toolbar li a:hover { |
background-position: bottom center; |
background-position: bottom center; |
} |
} |
Line 8340 ul.LC_funclist li {
|
Line 8829 ul.LC_funclist li {
|
cursor:pointer; |
cursor:pointer; |
} |
} |
|
|
|
.LCisDisabled { |
|
cursor: not-allowed; |
|
opacity: 0.5; |
|
} |
|
|
|
a[aria-disabled="true"] { |
|
color: currentColor; |
|
display: inline-block; /* For IE11/ MS Edge bug */ |
|
pointer-events: none; |
|
text-decoration: none; |
|
} |
|
|
pre.LC_wordwrap { |
pre.LC_wordwrap { |
white-space: pre-wrap; |
white-space: pre-wrap; |
white-space: -moz-pre-wrap; |
white-space: -moz-pre-wrap; |
Line 8513 Inputs: $title - optional title for the
|
Line 9014 Inputs: $title - optional title for the
|
3- whether the side effect should occur |
3- whether the side effect should occur |
(side effect of setting |
(side effect of setting |
$env{'internal.head.redirect'} to the url |
$env{'internal.head.redirect'} to the url |
redirected too) |
redirected to) |
|
4- whether the redirect target should be |
|
the opener of the current (pop-up) |
|
window (side effect of setting |
|
$env{'internal.head.to_opener'} to |
|
1, if true. |
|
5- whether encrypt check should be skipped |
domain -> force to color decorate a page for a specific |
domain -> force to color decorate a page for a specific |
domain |
domain |
function -> force usage of a specific rolish color scheme |
function -> force usage of a specific rolish color scheme |
Line 8576 sub headtag {
|
Line 9083 sub headtag {
|
} |
} |
} |
} |
if (ref($args->{'redirect'})) { |
if (ref($args->{'redirect'})) { |
my ($time,$url,$inhibit_continue) = @{$args->{'redirect'}}; |
my ($time,$url,$inhibit_continue,$to_opener,$skip_enc_check) = @{$args->{'redirect'}}; |
$url = &Apache::lonenc::check_encrypt($url); |
if (!$skip_enc_check) { |
|
$url = &Apache::lonenc::check_encrypt($url); |
|
} |
if (!$inhibit_continue) { |
if (!$inhibit_continue) { |
$env{'internal.head.redirect'} = $url; |
$env{'internal.head.redirect'} = $url; |
} |
} |
$result.=<<ADDMETA |
$result.=<<"ADDMETA"; |
<meta http-equiv="pragma" content="no-cache" /> |
<meta http-equiv="pragma" content="no-cache" /> |
|
ADDMETA |
|
if ($to_opener) { |
|
$env{'internal.head.to_opener'} = 1; |
|
my $dest = &js_escape($url); |
|
my $timeout = int($time * 1000); |
|
$result .=<<"ENDJS"; |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
function LC_To_Opener() { |
|
var dest = '$dest'; |
|
if (dest != '') { |
|
if (window.opener != null && !window.opener.closed) { |
|
window.opener.location.href=dest; |
|
window.close(); |
|
} else { |
|
window.location.href=dest; |
|
} |
|
} |
|
} |
|
\$(document).ready(function () { |
|
setTimeout('LC_To_Opener()',$timeout); |
|
}); |
|
// ]]> |
|
</script> |
|
ENDJS |
|
} else { |
|
$result.=<<"ADDMETA"; |
<meta http-equiv="Refresh" content="$time; url=$url" /> |
<meta http-equiv="Refresh" content="$time; url=$url" /> |
ADDMETA |
ADDMETA |
|
} |
} else { |
} else { |
unless (($args->{'frameset'}) || ($args->{'js_ready'}) || ($args->{'only_body'}) || ($args->{'no_nav_bar'})) { |
unless (($args->{'frameset'}) || ($args->{'js_ready'}) || ($args->{'only_body'}) || ($args->{'no_nav_bar'})) { |
my $requrl = $env{'request.uri'}; |
my $requrl = $env{'request.uri'}; |
Line 8599 ADDMETA
|
Line 9136 ADDMETA
|
unless (&Apache::lonnet::allowed('mau',$dom_in_use)) { |
unless (&Apache::lonnet::allowed('mau',$dom_in_use)) { |
my %domdefs = &Apache::lonnet::get_domain_defaults($dom_in_use); |
my %domdefs = &Apache::lonnet::get_domain_defaults($dom_in_use); |
my $lonhost = $Apache::lonnet::perlvar{'lonHostID'}; |
my $lonhost = $Apache::lonnet::perlvar{'lonHostID'}; |
my $offload; |
my ($offload,$offloadoth); |
if (ref($domdefs{'offloadnow'}) eq 'HASH') { |
if (ref($domdefs{'offloadnow'}) eq 'HASH') { |
if ($domdefs{'offloadnow'}{$lonhost}) { |
if ($domdefs{'offloadnow'}{$lonhost}) { |
$offload = 1; |
$offload = 1; |
|
if (($env{'user.domain'} ne '') && ($env{'user.domain'} ne $dom_in_use) && |
|
(!(($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public')))) { |
|
unless (&Apache::lonnet::shared_institution($env{'user.domain'})) { |
|
$offloadoth = 1; |
|
$dom_in_use = $env{'user.domain'}; |
|
} |
|
} |
} |
} |
} |
} |
unless ($offload) { |
unless ($offload) { |
Line 8612 ADDMETA
|
Line 9156 ADDMETA
|
(!(($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public')))) { |
(!(($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public')))) { |
unless (&Apache::lonnet::shared_institution($env{'user.domain'})) { |
unless (&Apache::lonnet::shared_institution($env{'user.domain'})) { |
$offload = 1; |
$offload = 1; |
|
$offloadoth = 1; |
$dom_in_use = $env{'user.domain'}; |
$dom_in_use = $env{'user.domain'}; |
} |
} |
} |
} |
Line 8619 ADDMETA
|
Line 9164 ADDMETA
|
} |
} |
} |
} |
if ($offload) { |
if ($offload) { |
my $newserver = &Apache::lonnet::spareserver(30000,undef,1,$dom_in_use); |
my $newserver = &Apache::lonnet::spareserver(undef,30000,undef,1,$dom_in_use); |
|
if (($newserver eq '') && ($offloadoth)) { |
|
my @domains = &Apache::lonnet::current_machine_domains(); |
|
if (($dom_in_use ne '') && (!grep(/^\Q$dom_in_use\E$/,@domains))) { |
|
($newserver) = &Apache::lonnet::choose_server($dom_in_use); |
|
} |
|
} |
if (($newserver) && ($newserver ne $lonhost)) { |
if (($newserver) && ($newserver ne $lonhost)) { |
my $numsec = 5; |
my $numsec = 5; |
my $timeout = $numsec * 1000; |
my $timeout = $numsec * 1000; |
Line 8633 ADDMETA
|
Line 9184 ADDMETA
|
} |
} |
if ($locknum) { |
if ($locknum) { |
my @lockinfo = sort(values(%locks)); |
my @lockinfo = sort(values(%locks)); |
$msg = &mt('Once the following tasks are complete: ')."\n". |
$msg = &mt('Once the following tasks are complete:')." \n". |
join(", ",sort(values(%locks)))."\n"; |
join(", ",sort(values(%locks)))."\n"; |
if (&show_course()) { |
if (&show_course()) { |
$msg .= &mt('your session will be transferred to a different server, after you click "Courses".'); |
$msg .= &mt('your session will be transferred to a different server, after you click "Courses".'); |
Line 8795 sub print_suppression {
|
Line 9346 sub print_suppression {
|
} |
} |
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
my $blocked = &blocking_status('printout',$cnum,$cdom,undef,1); |
my $clientip = &Apache::lonnet::get_requestor_ip(); |
|
my $blocked = &blocking_status('printout',$clientip,$cnum,$cdom,undef,1); |
if ($blocked) { |
if ($blocked) { |
my $checkrole = "cm./$cdom/$cnum"; |
my $checkrole = "cm./$cdom/$cnum"; |
if ($env{'request.course.sec'} ne '') { |
if ($env{'request.course.sec'} ne '') { |
Line 8914 $args - additional optional args support
|
Line 9466 $args - additional optional args support
|
will contain https://<hostname> if server uses |
will contain https://<hostname> if server uses |
https (as per hosts.tab), but request is for http |
https (as per hosts.tab), but request is for http |
hostname -> hostname, originally from $r->hostname(), (optional). |
hostname -> hostname, originally from $r->hostname(), (optional). |
|
links_disabled -> Links in primary and secondary menus are disabled |
|
(Can enable them once page has loaded - see lonroles.pm |
|
for an example). |
|
links_target -> Target for links, e.g., _parent (optional). |
|
|
=back |
=back |
|
|
Line 8926 sub start_page {
|
Line 9482 sub start_page {
|
#&Apache::lonnet::logthis("start_page ".join(':',caller(0))); |
#&Apache::lonnet::logthis("start_page ".join(':',caller(0))); |
|
|
$env{'internal.start_page'}++; |
$env{'internal.start_page'}++; |
my ($result,@advtools,$ltiscope,$ltiuri,%ltimenu); |
my ($result,@advtools,$ltiscope,$ltiuri,%ltimenu,$menucoll,%menu); |
|
|
if (! exists($args->{'skip_phases'}{'head'}) ) { |
if (! exists($args->{'skip_phases'}{'head'}) ) { |
$result .= &xml_begin($args->{'frameset'}) . &headtag($title, $head_extra, $args); |
$result .= &xml_begin($args->{'frameset'}) . &headtag($title, $head_extra, $args); |
Line 8961 sub start_page {
|
Line 9517 sub start_page {
|
($ltiscope,$ltiuri) = &LONCAPA::ltiutils::lti_provider_scope($env{'request.lti.uri'}, |
($ltiscope,$ltiuri) = &LONCAPA::ltiutils::lti_provider_scope($env{'request.lti.uri'}, |
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
$env{'course.'.$env{'request.course.id'}.'.num'}); |
$env{'course.'.$env{'request.course.id'}.'.num'}); |
|
} elsif ($env{'request.course.id'}) { |
|
my $expiretime=600; |
|
if ((time-$env{'course.'.$env{'request.course.id'}.'.last_cache'}) > $expiretime) { |
|
&Apache::lonnet::coursedescription($env{'request.course.id'},{'freshen_cache' => 1}); |
|
} |
|
my ($deeplinkmenu,$menuref); |
|
($menucoll,$deeplinkmenu,$menuref) = &menucoll_in_effect(); |
|
if ($menucoll) { |
|
if (ref($menuref) eq 'HASH') { |
|
%menu = %{$menuref}; |
|
} |
|
if ($menu{'top'} eq 'n') { |
|
$args->{'no_primary_menu'} = 1; |
|
} |
|
if ($menu{'inline'} eq 'n') { |
|
unless (&Apache::lonnet::allowed('opa')) { |
|
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
my $crstype = &course_type(); |
|
my $now = time; |
|
my $ccrole; |
|
if ($crstype eq 'Community') { |
|
$ccrole = 'co'; |
|
} else { |
|
$ccrole = 'cc'; |
|
} |
|
if ($env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum}) { |
|
my ($start,$end) = split(/\./,$env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum}); |
|
if ((($start) && ($start<0)) || |
|
(($end) && ($end<$now)) || |
|
(($start) && ($now<$start))) { |
|
$args->{'no_inline_menu'} = 1; |
|
} |
|
} else { |
|
$args->{'no_inline_menu'} = 1; |
|
} |
|
} |
|
} |
|
} |
} |
} |
|
|
|
my $showncrumbs; |
if (! exists($args->{'skip_phases'}{'body'}) ) { |
if (! exists($args->{'skip_phases'}{'body'}) ) { |
if ($args->{'frameset'}) { |
if ($args->{'frameset'}) { |
my $attr_string = &make_attr_string($args->{'force_register'}, |
my $attr_string = &make_attr_string($args->{'force_register'}, |
Line 8975 sub start_page {
|
Line 9571 sub start_page {
|
$args->{'only_body'}, $args->{'domain'}, |
$args->{'only_body'}, $args->{'domain'}, |
$args->{'force_register'}, $args->{'no_nav_bar'}, |
$args->{'force_register'}, $args->{'no_nav_bar'}, |
$args->{'bgcolor'}, $args, |
$args->{'bgcolor'}, $args, |
\@advtools,$ltiscope,$ltiuri,\%ltimenu); |
\@advtools,$ltiscope,$ltiuri,\%ltimenu,$menucoll, |
|
\%menu,\$showncrumbs); |
} |
} |
} |
} |
|
|
Line 8997 sub start_page {
|
Line 9594 sub start_page {
|
|
|
#Breadcrumbs |
#Breadcrumbs |
if (exists($args->{'bread_crumbs'}) or exists($args->{'bread_crumbs_component'})) { |
if (exists($args->{'bread_crumbs'}) or exists($args->{'bread_crumbs_component'})) { |
|
unless ($showncrumbs) { |
&Apache::lonhtmlcommon::clear_breadcrumbs(); |
&Apache::lonhtmlcommon::clear_breadcrumbs(); |
#if any br links exists, add them to the breadcrumbs |
#if any br links exists, add them to the breadcrumbs |
if (exists($args->{'bread_crumbs'}) and ref($args->{'bread_crumbs'}) eq 'ARRAY') { |
if (exists($args->{'bread_crumbs'}) and ref($args->{'bread_crumbs'}) eq 'ARRAY') { |
Line 9019 sub start_page {
|
Line 9617 sub start_page {
|
} else { |
} else { |
undef($menulink); |
undef($menulink); |
} |
} |
|
my $linkprotout; |
|
if ($env{'request.deeplink.login'}) { |
|
my $linkprotout = &Apache::lonmenu::linkprot_exit(); |
|
if ($linkprotout) { |
|
&Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$linkprotout); |
|
} |
|
} |
#if bread_crumbs_component exists show it as headline else show only the breadcrumbs |
#if bread_crumbs_component exists show it as headline else show only the breadcrumbs |
if(exists($args->{'bread_crumbs_component'})){ |
if(exists($args->{'bread_crumbs_component'})){ |
$result .= &Apache::lonhtmlcommon::breadcrumbs($args->{'bread_crumbs_component'},'',$menulink); |
$result .= &Apache::lonhtmlcommon::breadcrumbs($args->{'bread_crumbs_component'},'',$menulink); |
} else { |
} else { |
$result .= &Apache::lonhtmlcommon::breadcrumbs('','',$menulink); |
$result .= &Apache::lonhtmlcommon::breadcrumbs('','',$menulink); |
} |
} |
|
} |
} |
} |
return $result; |
return $result; |
} |
} |
Line 9061 sub end_page {
|
Line 9667 sub end_page {
|
return $result; |
return $result; |
} |
} |
|
|
|
sub menucoll_in_effect { |
|
my ($menucoll,$deeplinkmenu,%menu); |
|
if ($env{'request.course.id'}) { |
|
$menucoll = $env{'course.'.$env{'request.course.id'}.'.menudefault'}; |
|
if ($env{'request.deeplink.login'}) { |
|
my ($deeplink_symb,$deeplink,$check_login_symb); |
|
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
if ($env{'request.noversionuri'} =~ m{^/(res|uploaded)/}) { |
|
if ($env{'request.noversionuri'} =~ /\.(page|sequence)$/) { |
|
my $navmap = Apache::lonnavmaps::navmap->new(); |
|
if (ref($navmap)) { |
|
$deeplink = $navmap->get_mapparam(undef, |
|
&Apache::lonnet::declutter($env{'request.noversionuri'}), |
|
'0.deeplink'); |
|
} else { |
|
$check_login_symb = 1; |
|
} |
|
} else { |
|
my $symb = &Apache::lonnet::symbread(); |
|
if ($symb) { |
|
$deeplink = &Apache::lonnet::EXT('resource.0.deeplink',$symb); |
|
} else { |
|
$check_login_symb = 1; |
|
} |
|
} |
|
} else { |
|
$check_login_symb = 1; |
|
} |
|
if ($check_login_symb) { |
|
$deeplink_symb = &deeplink_login_symb($cnum,$cdom); |
|
if ($deeplink_symb =~ /\.(page|sequence)$/) { |
|
my $mapname = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($deeplink_symb))[2]); |
|
my $navmap = Apache::lonnavmaps::navmap->new(); |
|
if (ref($navmap)) { |
|
$deeplink = $navmap->get_mapparam(undef,$mapname,'0.deeplink'); |
|
} |
|
} else { |
|
$deeplink = &Apache::lonnet::EXT('resource.0.deeplink',$deeplink_symb); |
|
} |
|
} |
|
if ($deeplink ne '') { |
|
my ($state,$others,$listed,$scope,$protect,$display,$target) = split(/,/,$deeplink); |
|
if ($display =~ /^\d+$/) { |
|
$deeplinkmenu = 1; |
|
$menucoll = $display; |
|
} |
|
} |
|
} |
|
if ($menucoll) { |
|
%menu = &page_menu($env{'course.'.$env{'request.course.id'}.'.menucollections'},$menucoll); |
|
} |
|
} |
|
return ($menucoll,$deeplinkmenu,\%menu); |
|
} |
|
|
|
sub deeplink_login_symb { |
|
my ($cnum,$cdom) = @_; |
|
my $login_symb; |
|
if ($env{'request.deeplink.login'}) { |
|
$login_symb = &symb_from_tinyurl($env{'request.deeplink.login'},$cnum,$cdom); |
|
} |
|
return $login_symb; |
|
} |
|
|
|
sub symb_from_tinyurl { |
|
my ($url,$cnum,$cdom) = @_; |
|
if ($url =~ m{^\Q/tiny/$cdom/\E(\w+)$}) { |
|
my $key = $1; |
|
my ($tinyurl,$login); |
|
my ($result,$cached)=&Apache::lonnet::is_cached_new('tiny',$cdom."\0".$key); |
|
if (defined($cached)) { |
|
$tinyurl = $result; |
|
} else { |
|
my $configuname = &Apache::lonnet::get_domainconfiguser($cdom); |
|
my %currtiny = &Apache::lonnet::get('tiny',[$key],$cdom,$configuname); |
|
if ($currtiny{$key} ne '') { |
|
$tinyurl = $currtiny{$key}; |
|
&Apache::lonnet::do_cache_new('tiny',$cdom."\0".$key,$currtiny{$key},600); |
|
} |
|
} |
|
if ($tinyurl ne '') { |
|
my ($cnumreq,$symb) = split(/\&/,$tinyurl); |
|
if (wantarray) { |
|
return ($cnumreq,$symb); |
|
} elsif ($cnumreq eq $cnum) { |
|
return $symb; |
|
} |
|
} |
|
} |
|
if (wantarray) { |
|
return (); |
|
} else { |
|
return; |
|
} |
|
} |
|
|
|
sub usable_exttools { |
|
my %tooltypes; |
|
if ($env{'request.course.id'}) { |
|
if ($env{'course.'.$env{'request.course.id'}.'.internal.exttool'}) { |
|
if ($env{'course.'.$env{'request.course.id'}.'.internal.exttool'} eq 'both') { |
|
%tooltypes = ( |
|
crs => 1, |
|
dom => 1, |
|
); |
|
} elsif ($env{'course.'.$env{'request.course.id'}.'.internal.exttool'} eq 'crs') { |
|
$tooltypes{'crs'} = 1; |
|
} elsif ($env{'course.'.$env{'request.course.id'}.'.internal.exttool'} eq 'dom') { |
|
$tooltypes{'dom'} = 1; |
|
} |
|
} else { |
|
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
my $crstype = lc($env{'course.'.$env{'request.course.id'}.'.type'}); |
|
if ($crstype eq '') { |
|
$crstype = 'course'; |
|
} |
|
if ($crstype eq 'course') { |
|
if ($env{'course.'.$env{'request.course.id'}.'internal.coursecode'}) { |
|
$crstype = 'official'; |
|
} elsif ($env{'course.'.$env{'request.course.id'}.'.internal.textbook'}) { |
|
$crstype = 'textbook'; |
|
} elsif ($env{'course.'.$env{'request.course.id'}.'.internal.lti'}) { |
|
$crstype = 'lti'; |
|
} else { |
|
$crstype = 'unofficial'; |
|
} |
|
} |
|
my %domdefaults = &Apache::lonnet::get_domain_defaults($cdom); |
|
if ($domdefaults{$crstype.'domexttool'}) { |
|
$tooltypes{'dom'} = 1; |
|
} |
|
if ($domdefaults{$crstype.'exttool'}) { |
|
$tooltypes{'crs'} = 1; |
|
} |
|
} |
|
} |
|
return %tooltypes; |
|
} |
|
|
sub wishlist_window { |
sub wishlist_window { |
return(<<'ENDWISHLIST'); |
return(<<'ENDWISHLIST'); |
<script type="text/javascript"> |
<script type="text/javascript"> |
Line 9150 ENDLINK
|
Line 9897 ENDLINK
|
} |
} |
|
|
sub modal_adhoc_script { |
sub modal_adhoc_script { |
my ($funcname,$width,$height,$content)=@_; |
my ($funcname,$width,$height,$content,$possmathjax)=@_; |
|
my $mathjax; |
|
if ($possmathjax) { |
|
$mathjax = <<'ENDJAX'; |
|
if (typeof MathJax == 'object') { |
|
MathJax.Hub.Queue(["Typeset",MathJax.Hub]); |
|
} |
|
ENDJAX |
|
} |
return (<<ENDADHOC); |
return (<<ENDADHOC); |
<script type="text/javascript"> |
<script type="text/javascript"> |
// <![CDATA[ |
// <![CDATA[ |
Line 9161 sub modal_adhoc_script {
|
Line 9916 sub modal_adhoc_script {
|
modalWindow.height = $height; |
modalWindow.height = $height; |
modalWindow.content = '$content'; |
modalWindow.content = '$content'; |
modalWindow.open(); |
modalWindow.open(); |
|
$mathjax |
}; |
}; |
// ]]> |
// ]]> |
</script> |
</script> |
Line 9168 ENDADHOC
|
Line 9924 ENDADHOC
|
} |
} |
|
|
sub modal_adhoc_inner { |
sub modal_adhoc_inner { |
my ($funcname,$width,$height,$content)=@_; |
my ($funcname,$width,$height,$content,$possmathjax)=@_; |
my $innerwidth=$width-20; |
my $innerwidth=$width-20; |
$content=&js_ready( |
$content=&js_ready( |
&start_page('Dialog',undef,{'only_body'=>1,'bgcolor'=>'#FFFFFF'}). |
&start_page('Dialog',undef,{'only_body'=>1,'bgcolor'=>'#FFFFFF'}). |
Line 9177 sub modal_adhoc_inner {
|
Line 9933 sub modal_adhoc_inner {
|
&end_scrollbox(). |
&end_scrollbox(). |
&end_page() |
&end_page() |
); |
); |
return &modal_adhoc_script($funcname,$width,$height,$content); |
return &modal_adhoc_script($funcname,$width,$height,$content,$possmathjax); |
} |
} |
|
|
sub modal_adhoc_window { |
sub modal_adhoc_window { |
my ($funcname,$width,$height,$content,$linktext)=@_; |
my ($funcname,$width,$height,$content,$linktext,$possmathjax)=@_; |
return &modal_adhoc_inner($funcname,$width,$height,$content). |
return &modal_adhoc_inner($funcname,$width,$height,$content,$possmathjax). |
"<a href=\"javascript:$funcname();void(0);\">".$linktext."</a>"; |
"<a href=\"javascript:$funcname();void(0);\">".$linktext."</a>"; |
} |
} |
|
|
Line 11057 sub sorted_inst_types {
|
Line 11813 sub sorted_inst_types {
|
} |
} |
|
|
sub get_institutional_codes { |
sub get_institutional_codes { |
my ($settings,$allcourses,$LC_code) = @_; |
my ($cdom,$crs,$settings,$allcourses,$LC_code) = @_; |
# Get complete list of course sections to update |
# Get complete list of course sections to update |
my @currsections = (); |
my @currsections = (); |
my @currxlists = (); |
my @currxlists = (); |
|
my (%unclutteredsec,%unclutteredlcsec); |
my $coursecode = $$settings{'internal.coursecode'}; |
my $coursecode = $$settings{'internal.coursecode'}; |
|
my $crskey = $crs.':'.$coursecode; |
|
@{$unclutteredsec{$crskey}} = (); |
|
@{$unclutteredlcsec{$crskey}} = (); |
|
|
if ($$settings{'internal.sectionnums'} ne '') { |
if ($$settings{'internal.sectionnums'} ne '') { |
@currsections = split(/,/,$$settings{'internal.sectionnums'}); |
@currsections = split(/,/,$$settings{'internal.sectionnums'}); |
Line 11072 sub get_institutional_codes {
|
Line 11832 sub get_institutional_codes {
|
} |
} |
|
|
if (@currxlists > 0) { |
if (@currxlists > 0) { |
foreach (@currxlists) { |
foreach my $xl (@currxlists) { |
if (m/^([^:]+):(\w*)$/) { |
if ($xl =~ /^([^:]+):(\w*)$/) { |
unless (grep/^$1$/,@{$allcourses}) { |
unless (grep/^$1$/,@{$allcourses}) { |
push(@{$allcourses},$1); |
push(@{$allcourses},$1); |
$$LC_code{$1} = $2; |
$$LC_code{$1} = $2; |
Line 11081 sub get_institutional_codes {
|
Line 11841 sub get_institutional_codes {
|
} |
} |
} |
} |
} |
} |
|
|
if (@currsections > 0) { |
if (@currsections > 0) { |
foreach (@currsections) { |
foreach my $sec (@currsections) { |
if (m/^(\w+):(\w*)$/) { |
if ($sec =~ m/^(\w+):(\w*)$/ ) { |
my $sec = $coursecode.$1; |
my $instsec = $1; |
my $lc_sec = $2; |
my $lc_sec = $2; |
unless (grep/^$sec$/,@{$allcourses}) { |
unless (grep/^\Q$instsec\E$/,@{$unclutteredsec{$crskey}}) { |
|
push(@{$unclutteredsec{$crskey}},$instsec); |
|
push(@{$unclutteredlcsec{$crskey}},$lc_sec); |
|
} |
|
} |
|
} |
|
} |
|
|
|
if (@{$unclutteredsec{$crskey}} > 0) { |
|
my %formattedsec = &Apache::lonnet::auto_instsec_reformat($cdom,'clutter',\%unclutteredsec); |
|
if ((ref($formattedsec{$crskey}) eq 'ARRAY') && (ref($unclutteredlcsec{$crskey}) eq 'ARRAY')) { |
|
for (my $i=0; $i<@{$formattedsec{$crskey}}; $i++) { |
|
my $sec = $coursecode.$formattedsec{$crskey}[$i]; |
|
unless (grep/^\Q$sec\E$/,@{$allcourses}) { |
push(@{$allcourses},$sec); |
push(@{$allcourses},$sec); |
$$LC_code{$sec} = $lc_sec; |
$$LC_code{$sec} = $unclutteredlcsec{$crskey}[$i]; |
} |
} |
} |
} |
} |
} |
Line 13697 sub process_extracted_files {
|
Line 14470 sub process_extracted_files {
|
my $url = '/uploaded/'.$docudom.'/'.$docuname.'/'. |
my $url = '/uploaded/'.$docudom.'/'.$docuname.'/'. |
$docstype.'/'.$mapinner{$outer}.'/'.$newidx.'/'. |
$docstype.'/'.$mapinner{$outer}.'/'.$newidx.'/'. |
$title; |
$title; |
if (($outer !~ /\D/) && ($mapinner{$outer} !~ /\D/) && ($newidx !~ /\D/)) { |
if (($outer !~ /\D/) && |
|
(($mapinner{$outer} eq 'default') || ($mapinner{$outer} !~ /\D/)) && |
|
($newidx !~ /\D/)) { |
if (!-e "$prefix$dir/$docstype/$mapinner{$outer}") { |
if (!-e "$prefix$dir/$docstype/$mapinner{$outer}") { |
mkdir("$prefix$dir/$docstype/$mapinner{$outer}",0755); |
mkdir("$prefix$dir/$docstype/$mapinner{$outer}",0755); |
} |
} |
Line 15753 sub assign_category_rows {
|
Line 16528 sub assign_category_rows {
|
|
|
sub commit_customrole { |
sub commit_customrole { |
my ($udom,$uname,$url,$three,$four,$five,$start,$end,$context) = @_; |
my ($udom,$uname,$url,$three,$four,$five,$start,$end,$context) = @_; |
|
my $result = &Apache::lonnet::assigncustomrole( |
|
$udom,$uname,$url,$three,$four,$five,$end,$start,undef,undef,$context); |
my $output = &mt('Assigning custom role').' "'.$five.'" by '.$four.':'.$three.' in '.$url. |
my $output = &mt('Assigning custom role').' "'.$five.'" by '.$four.':'.$three.' in '.$url. |
($start?', '.&mt('starting').' '.localtime($start):''). |
($start?', '.&mt('starting').' '.localtime($start):''). |
($end?', ending '.localtime($end):'').': <b>'. |
($end?', ending '.localtime($end):'').': <b>'.$result.'</b><br />'; |
&Apache::lonnet::assigncustomrole( |
if (wantarray) { |
$udom,$uname,$url,$three,$four,$five,$end,$start,undef,undef,$context). |
return ($output,$result); |
'</b><br />'; |
} else { |
return $output; |
return $output; |
|
} |
} |
} |
|
|
sub commit_standardrole { |
sub commit_standardrole { |
my ($udom,$uname,$url,$three,$start,$end,$one,$two,$sec,$context,$credits) = @_; |
my ($udom,$uname,$url,$three,$start,$end,$one,$two,$sec,$context,$credits) = @_; |
my ($output,$logmsg,$linefeed); |
my ($output,$logmsg,$linefeed,$result); |
if ($context eq 'auto') { |
if ($context eq 'auto') { |
$linefeed = "\n"; |
$linefeed = "\n"; |
} else { |
} else { |
$linefeed = "<br />\n"; |
$linefeed = "<br />\n"; |
} |
} |
if ($three eq 'st') { |
if ($three eq 'st') { |
my $result = &commit_studentrole(\$logmsg,$udom,$uname,$url,$three,$start,$end, |
$result = &commit_studentrole(\$logmsg,$udom,$uname,$url,$three,$start,$end, |
$one,$two,$sec,$context,$credits); |
$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 15792 sub commit_standardrole {
|
Line 16570 sub commit_standardrole {
|
$output = &mt('Assigning').' '.$three.' in '.$url. |
$output = &mt('Assigning').' '.$three.' in '.$url. |
($start?', '.&mt('starting').' '.localtime($start):''). |
($start?', '.&mt('starting').' '.localtime($start):''). |
($end?', '.&mt('ending').' '.localtime($end):'').': '; |
($end?', '.&mt('ending').' '.localtime($end):'').': '; |
my $result = &Apache::lonnet::assignrole($udom,$uname,$url,$three,$end,$start,'','',$context); |
$result = &Apache::lonnet::assignrole($udom,$uname,$url,$three,$end,$start,'','',$context); |
if ($context eq 'auto') { |
if ($context eq 'auto') { |
$output .= $result.$linefeed; |
$output .= $result.$linefeed; |
} else { |
} else { |
$output .= '<b>'.$result.'</b>'.$linefeed; |
$output .= '<b>'.$result.'</b>'.$linefeed; |
} |
} |
} |
} |
return $output; |
if (wantarray) { |
|
return ($output,$result); |
|
} else { |
|
return $output; |
|
} |
} |
} |
|
|
sub commit_studentrole { |
sub commit_studentrole { |
Line 15828 sub commit_studentrole {
|
Line 16610 sub commit_studentrole {
|
} |
} |
$oldsecurl = $uurl; |
$oldsecurl = $uurl; |
$expire_role_result = |
$expire_role_result = |
&Apache::lonnet::assignrole($udom,$uname,$uurl,'st',$now,'','',$context); |
&Apache::lonnet::assignrole($udom,$uname,$uurl,'st',$now,'','','',$context); |
if ($env{'request.course.sec'} ne '') { |
if ($env{'request.course.sec'} ne '') { |
if ($expire_role_result eq 'refused') { |
if ($expire_role_result eq 'refused') { |
my @roles = ('st'); |
my @roles = ('st'); |
Line 16209 sub construct_course {
|
Line 16991 sub construct_course {
|
'plc.users.denied', |
'plc.users.denied', |
'hidefromcat', |
'hidefromcat', |
'checkforpriv', |
'checkforpriv', |
'categories', |
'categories'], |
'internal.uniquecode'], |
|
$$crsudom,$$crsunum); |
$$crsudom,$$crsunum); |
if ($args->{'textbook'}) { |
if ($args->{'textbook'}) { |
$cenv{'internal.textbook'} = $args->{'textbook'}; |
$cenv{'internal.textbook'} = $args->{'textbook'}; |
Line 16225 sub construct_course {
|
Line 17006 sub construct_course {
|
if ($args->{'crstype'}) { |
if ($args->{'crstype'}) { |
$cenv{'type'}=$args->{'crstype'}; |
$cenv{'type'}=$args->{'crstype'}; |
} |
} |
|
if ($args->{'lti'}) { |
|
$cenv{'internal.lti'}=$args->{'lti'}; |
|
} |
if ($args->{'crsid'}) { |
if ($args->{'crsid'}) { |
$cenv{'courseid'}=$args->{'crsid'}; |
$cenv{'courseid'}=$args->{'crsid'}; |
} |
} |
Line 16468 sub construct_course {
|
Line 17252 sub construct_course {
|
# |
# |
unless (($args->{'nonstandard'}) || ($args->{'firstres'} eq 'blank') |
unless (($args->{'nonstandard'}) || ($args->{'firstres'} eq 'blank') |
|| ($cloneid)) { |
|| ($cloneid)) { |
use LONCAPA::map; |
|
$outcome .= &mt('Setting first resource').': '; |
$outcome .= &mt('Setting first resource').': '; |
|
|
my $map = '/uploaded/'.$$crsudom.'/'.$$crsunum.'/default.sequence'; |
my $map = '/uploaded/'.$$crsudom.'/'.$$crsunum.'/default.sequence'; |
Line 16855 sub init_user_environment {
|
Line 17638 sub init_user_environment {
|
my %is_adv = ( is_adv => $env{'user.adv'} ); |
my %is_adv = ( is_adv => $env{'user.adv'} ); |
my %domdef = &Apache::lonnet::get_domain_defaults($domain); |
my %domdef = &Apache::lonnet::get_domain_defaults($domain); |
|
|
foreach my $tool ('aboutme','blog','webdav','portfolio') { |
foreach my $tool ('aboutme','blog','webdav','portfolio','timezone') { |
$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); |
undef,\%userenv,\%domdef,\%is_adv); |
Line 17724 sub needs_coursereinit {
|
Line 18507 sub needs_coursereinit {
|
} |
} |
if (($now-$env{'request.course.timechecked'})>$interval) { |
if (($now-$env{'request.course.timechecked'})>$interval) { |
&Apache::lonnet::appenv({'request.course.timechecked'=>$now}); |
&Apache::lonnet::appenv({'request.course.timechecked'=>$now}); |
my $blocked = &blocking_status('reinit',$cnum,$cdom,undef,1); |
my $blocked = &blocking_status('reinit',undef,$cnum,$cdom,undef,1); |
if ($blocked) { |
if ($blocked) { |
return (); |
return (); |
} |
} |
my $lastchange = &Apache::lonnet::get_coursechange($cdom,$cnum); |
my $update; |
if ($lastchange > $env{'request.course.tied'}) { |
my $lastmainchange = &Apache::lonnet::get_coursechange($cdom,$cnum); |
my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired'); |
my $lastsuppchange = &Apache::lonnet::get_suppchange($cdom,$cnum); |
if ($curr_reqd_hash{'internal.releaserequired'} ne '') { |
if ($lastmainchange > $env{'request.course.tied'}) { |
my $required = $env{'course.'.$cdom.'_'.$cnum.'.internal.releaserequired'}; |
my ($needswitch,$switchwarning,$switchserver) = &switch_for_update($loncaparev,$cdom,$cnum); |
if ($curr_reqd_hash{'internal.releaserequired'} ne $required) { |
if ($needswitch) { |
&Apache::lonnet::appenv({'course.'.$cdom.'_'.$cnum.'.internal.releaserequired' => |
return ('switch',$switchwarning,$switchserver); |
$curr_reqd_hash{'internal.releaserequired'}}); |
} |
my ($switchserver,$switchwarning) = |
$update = 'main'; |
&check_release_required($loncaparev,$cdom.'_'.$cnum,$env{'request.role'}, |
} |
$curr_reqd_hash{'internal.releaserequired'}); |
if ($lastsuppchange > $env{'request.course.suppupdated'}) { |
if ($switchwarning ne '' || $switchserver ne '') { |
if ($update) { |
return ('switch',$switchwarning,$switchserver); |
$update = 'both'; |
} |
} else { |
|
my ($needswitch,$switchwarning,$switchserver) = &switch_for_update($loncaparev,$cdom,$cnum); |
|
if ($needswitch) { |
|
return ('switch',$switchwarning,$switchserver); |
|
} else { |
|
$update = 'supp'; |
} |
} |
} |
} |
return ('update'); |
return ($update); |
|
} |
|
} |
|
return (); |
|
} |
|
|
|
sub switch_for_update { |
|
my ($loncaparev,$cdom,$cnum) = @_; |
|
my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired'); |
|
if ($curr_reqd_hash{'internal.releaserequired'} ne '') { |
|
my $required = $env{'course.'.$cdom.'_'.$cnum.'.internal.releaserequired'}; |
|
if ($curr_reqd_hash{'internal.releaserequired'} ne $required) { |
|
&Apache::lonnet::appenv({'course.'.$cdom.'_'.$cnum.'.internal.releaserequired' => |
|
$curr_reqd_hash{'internal.releaserequired'}}); |
|
my ($switchserver,$switchwarning) = |
|
&check_release_required($loncaparev,$cdom.'_'.$cnum,$env{'request.role'}, |
|
$curr_reqd_hash{'internal.releaserequired'}); |
|
if ($switchwarning ne '' || $switchserver ne '') { |
|
return ('switch',$switchwarning,$switchserver); |
|
} |
} |
} |
} |
} |
return (); |
return (); |
} |
} |
|
|
sub update_content_constraints { |
sub update_content_constraints { |
my ($cdom,$cnum,$chome,$cid,$keeporder) = @_; |
my ($cdom,$cnum,$chome,$cid) = @_; |
my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired'); |
my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired'); |
my ($reqdmajor,$reqdminor) = split(/\./,$curr_reqd_hash{'internal.releaserequired'}); |
my ($reqdmajor,$reqdminor) = split(/\./,$curr_reqd_hash{'internal.releaserequired'}); |
my (%checkresponsetypes,%checkcrsrestypes); |
my (%checkresponsetypes,%checkcrsrestypes); |
Line 17799 sub update_content_constraints {
|
Line 18606 sub update_content_constraints {
|
} |
} |
undef($navmap); |
undef($navmap); |
} |
} |
my (@resources,@order,@resparms,@zombies); |
if (&Apache::lonnet::count_supptools($cnum,$cdom,1)) { |
if ($keeporder) { |
|
use LONCAPA::map; |
|
@resources = @LONCAPA::map::resources; |
|
@order = @LONCAPA::map::order; |
|
@resparms = @LONCAPA::map::resparms; |
|
@zombies = @LONCAPA::map::zombies; |
|
} |
|
my $suppmap = 'supplemental.sequence'; |
|
my ($suppcount,$supptools,$errors) = (0,0,0); |
|
($suppcount,$supptools,$errors) = &recurse_supplemental($cnum,$cdom,$suppmap, |
|
$suppcount,$supptools,$errors); |
|
if ($keeporder) { |
|
@LONCAPA::map::resources = @resources; |
|
@LONCAPA::map::order = @order; |
|
@LONCAPA::map::resparms = @resparms; |
|
@LONCAPA::map::zombies = @zombies; |
|
} |
|
if ($supptools) { |
|
my ($major,$minor) = split(/\./,$checkcrsrestypes{'exttool'}); |
my ($major,$minor) = split(/\./,$checkcrsrestypes{'exttool'}); |
if (($major > $reqdmajor) || ($major == $reqdmajor && $minor > $reqdminor)) { |
if (($major > $reqdmajor) || ($major == $reqdmajor && $minor > $reqdminor)) { |
($reqdmajor,$reqdminor) = ($major,$minor); |
($reqdmajor,$reqdminor) = ($major,$minor); |
Line 17843 sub allmaps_incourse {
|
Line 18632 sub allmaps_incourse {
|
if ($lastchange > $env{'request.course.tied'}) { |
if ($lastchange > $env{'request.course.tied'}) { |
my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum"); |
my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum"); |
unless ($ferr) { |
unless ($ferr) { |
&update_content_constraints($cdom,$cnum,$chome,$cid,1); |
&update_content_constraints($cdom,$cnum,$chome,$cid); |
} |
} |
} |
} |
my $navmap = Apache::lonnavmaps::navmap->new(); |
my $navmap = Apache::lonnavmaps::navmap->new(); |
Line 17869 sub parse_supplemental_title {
|
Line 18658 sub parse_supplemental_title {
|
my $name = &plainname($uname,$udom); |
my $name = &plainname($uname,$udom); |
$name = &HTML::Entities::encode($name,'"<>&\''); |
$name = &HTML::Entities::encode($name,'"<>&\''); |
$renametitle = &HTML::Entities::encode($renametitle,'"<>&\''); |
$renametitle = &HTML::Entities::encode($renametitle,'"<>&\''); |
$title='<i>'.&Apache::lonlocal::locallocaltime($time).'</i> '. |
$title='<i>'.&Apache::lonlocal::locallocaltime($time).'</i> '.$name; |
$name.': <br />'.$foldertitle; |
if ($foldertitle ne '') { |
|
$title .= ': <br />'.$foldertitle; |
|
} |
} |
} |
if (wantarray) { |
if (wantarray) { |
return ($title,$foldertitle,$renametitle); |
return ($title,$foldertitle,$renametitle); |
Line 17878 sub parse_supplemental_title {
|
Line 18669 sub parse_supplemental_title {
|
return $title; |
return $title; |
} |
} |
|
|
|
sub get_supplemental { |
|
my ($cnum,$cdom,$ignorecache,$possdel)=@_; |
|
my $hashid=$cnum.':'.$cdom; |
|
my ($supplemental,$cached,$set_httprefs); |
|
unless ($ignorecache) { |
|
($supplemental,$cached) = &Apache::lonnet::is_cached_new('supplemental',$hashid); |
|
} |
|
unless (defined($cached)) { |
|
my $chome=&Apache::lonnet::homeserver($cnum,$cdom); |
|
unless ($chome eq 'no_host') { |
|
my @order = @LONCAPA::map::order; |
|
my @resources = @LONCAPA::map::resources; |
|
my @resparms = @LONCAPA::map::resparms; |
|
my @zombies = @LONCAPA::map::zombies; |
|
my ($errors,%ids,%hidden); |
|
$errors = |
|
&recurse_supplemental($cnum,$cdom,'supplemental.sequence', |
|
$errors,$possdel,\%ids,\%hidden); |
|
@LONCAPA::map::order = @order; |
|
@LONCAPA::map::resources = @resources; |
|
@LONCAPA::map::resparms = @resparms; |
|
@LONCAPA::map::zombies = @zombies; |
|
$set_httprefs = 1; |
|
if ($env{'request.course.id'} eq $cdom.'_'.$cnum) { |
|
&Apache::lonnet::appenv({'request.course.suppupdated' => time}); |
|
} |
|
$supplemental = { |
|
ids => \%ids, |
|
hidden => \%hidden, |
|
}; |
|
&Apache::lonnet::do_cache_new('supplemental',$hashid,$supplemental,600); |
|
} |
|
} |
|
return ($supplemental,$set_httprefs); |
|
} |
|
|
sub recurse_supplemental { |
sub recurse_supplemental { |
my ($cnum,$cdom,$suppmap,$numfiles,$numexttools,$errors) = @_; |
my ($cnum,$cdom,$suppmap,$errors,$possdel,$suppids,$hiddensupp,$hidden) = @_; |
if ($suppmap) { |
if (($suppmap) && (ref($suppids) eq 'HASH') && (ref($hiddensupp) eq 'HASH')) { |
|
my $mapnum; |
|
if ($suppmap eq 'supplemental.sequence') { |
|
$mapnum = 0; |
|
} else { |
|
($mapnum) = ($suppmap =~ /^supplemental_(\d+)\.sequence$/); |
|
} |
my ($errtext,$fatal) = &LONCAPA::map::mapread('/uploaded/'.$cdom.'/'.$cnum.'/'.$suppmap); |
my ($errtext,$fatal) = &LONCAPA::map::mapread('/uploaded/'.$cdom.'/'.$cnum.'/'.$suppmap); |
if ($fatal) { |
if ($fatal) { |
$errors ++; |
$errors ++; |
} else { |
} else { |
if ($#LONCAPA::map::resources > 0) { |
my @order = @LONCAPA::map::order; |
foreach my $res (@LONCAPA::map::resources) { |
if (@order > 0) { |
my ($title,$src,$ext,$type,$status)=split(/\:/,$res); |
my @resources = @LONCAPA::map::resources; |
|
my @resparms = @LONCAPA::map::resparms; |
|
foreach my $idx (@order) { |
|
my ($title,$src,$ext,$type,$status)=split(/\:/,$resources[$idx]); |
if (($src ne '') && ($status eq 'res')) { |
if (($src ne '') && ($status eq 'res')) { |
|
my $id = $mapnum.':'.$idx; |
|
push(@{$suppids->{$src}},$id); |
|
if (($hidden) || (&get_supp_parameter($resparms[$idx],'parameter_hiddenresource') =~ /^yes/i)) { |
|
$hiddensupp->{$id} = 1; |
|
} |
if ($src =~ m{^\Q/uploaded/$cdom/$cnum/\E(supplemental_\d+\.sequence)$}) { |
if ($src =~ m{^\Q/uploaded/$cdom/$cnum/\E(supplemental_\d+\.sequence)$}) { |
($numfiles,$numexttools,$errors) = &recurse_supplemental($cnum,$cdom,$1, |
$errors = &recurse_supplemental($cnum,$cdom,$1,$errors,$possdel,$suppids, |
$numfiles,$numexttools,$errors); |
$hiddensupp,$hiddensupp->{$id}); |
} else { |
} else { |
if ($src =~ m{^/adm/$cdom/$cnum/\d+/ext\.tool$}) { |
my $allowed; |
$numexttools ++; |
if (($env{'request.role.adv'}) || (!$hiddensupp->{$id})) { |
|
$allowed = 1; |
|
} elsif ($possdel) { |
|
foreach my $item (@{$suppids->{$src}}) { |
|
next if ($item eq $id); |
|
unless ($hiddensupp->{$item}) { |
|
$allowed = 1; |
|
last; |
|
} |
|
} |
|
if ((!$allowed) && (exists($env{'httpref.'.$src}))) { |
|
&Apache::lonnet::delenv('httpref.'.$src); |
|
} |
|
} |
|
if ($allowed && (!exists($env{'httpref.'.$src}))) { |
|
&Apache::lonnet::allowuploaded('/adm/coursedoc',$src); |
} |
} |
$numfiles ++; |
|
} |
} |
} |
} |
} |
} |
} |
} |
} |
} |
} |
} |
return ($numfiles,$numexttools,$errors); |
return $errors; |
|
} |
|
|
|
sub set_supp_httprefs { |
|
my ($cnum,$cdom,$supplemental,$possdel) = @_; |
|
if (ref($supplemental) eq 'HASH') { |
|
if ((ref($supplemental->{'ids'}) eq 'HASH') && (ref($supplemental->{'hidden'}) eq 'HASH')) { |
|
foreach my $src (keys(%{$supplemental->{'ids'}})) { |
|
next if ($src =~ /\.sequence$/); |
|
if (ref($supplemental->{'ids'}->{$src}) eq 'ARRAY') { |
|
my $allowed; |
|
if ($env{'request.role.adv'}) { |
|
$allowed = 1; |
|
} else { |
|
foreach my $id (@{$supplemental->{'ids'}->{$src}}) { |
|
unless ($supplemental->{'hidden'}->{$id}) { |
|
$allowed = 1; |
|
last; |
|
} |
|
} |
|
} |
|
if (exists($env{'httpref.'.$src})) { |
|
if ($possdel) { |
|
unless ($allowed) { |
|
&Apache::lonnet::delenv('httpref.'.$src); |
|
} |
|
} |
|
} elsif ($allowed) { |
|
&Apache::lonnet::allowuploaded('/adm/coursedoc',$src); |
|
} |
|
} |
|
} |
|
if ($env{'request.course.id'} eq $cdom.'_'.$cnum) { |
|
&Apache::lonnet::appenv({'request.course.suppupdated' => time}); |
|
} |
|
} |
|
} |
|
} |
|
|
|
sub get_supp_parameter { |
|
my ($resparm,$name)=@_; |
|
return if ($resparm eq ''); |
|
my $value=undef; |
|
my $ptype=undef; |
|
foreach (split('&&&',$resparm)) { |
|
my ($thistype,$thisname,$thisvalue)=split('___',$_); |
|
if ($thisname eq $name) { |
|
$value=$thisvalue; |
|
$ptype=$thistype; |
|
} |
|
} |
|
return $value; |
} |
} |
|
|
sub symb_to_docspath { |
sub symb_to_docspath { |
Line 17976 sub symb_to_docspath {
|
Line 18882 sub symb_to_docspath {
|
return $path; |
return $path; |
} |
} |
|
|
|
sub validate_folderpath { |
|
my ($supplementalflag,$allowed,$coursenum,$coursedom) = @_; |
|
if ($env{'form.folderpath'} ne '') { |
|
my @items = split(/\&/,$env{'form.folderpath'}); |
|
my ($badpath,$changed,$got_supp,$supppath,%supphidden,%suppids); |
|
for (my $i=0; $i<@items; $i++) { |
|
my $odd = $i%2; |
|
if (($odd) && (!$supplementalflag) && ($items[$i] !~ /^[^:]*:(|\d+):(|1):(|1):(|1):(|1)$/)) { |
|
$badpath = 1; |
|
} elsif ($odd && $supplementalflag) { |
|
my $idx = $i-1; |
|
if ($items[$i] =~ /^([^:]*)::(|1):::$/) { |
|
my $esc_name = $1; |
|
if ((!$allowed) || ($items[$idx] eq 'supplemental')) { |
|
$supppath .= '&'.$esc_name; |
|
$changed = 1; |
|
} else { |
|
$supppath .= '&'.$items[$i]; |
|
} |
|
} elsif (($allowed) && ($items[$idx] ne 'supplemental')) { |
|
$changed = 1; |
|
my $is_hidden; |
|
unless ($got_supp) { |
|
my ($supplemental) = &get_supplemental($coursenum,$coursedom); |
|
if (ref($supplemental) eq 'HASH') { |
|
if (ref($supplemental->{'hidden'}) eq 'HASH') { |
|
%supphidden = %{$supplemental->{'hidden'}}; |
|
} |
|
if (ref($supplemental->{'ids'}) eq 'HASH') { |
|
%suppids = %{$supplemental->{'ids'}}; |
|
} |
|
} |
|
$got_supp = 1; |
|
} |
|
if (ref($suppids{"/uploaded/$coursedom/$coursenum/$items[$idx].sequence"}) eq 'ARRAY') { |
|
my $mapid = $suppids{"/uploaded/$coursedom/$coursenum/$items[$idx].sequence"}->[0]; |
|
if ($supphidden{$mapid}) { |
|
$is_hidden = 1; |
|
} |
|
} |
|
$supppath .= '&'.$items[$i].'::'.$is_hidden.':::'; |
|
} else { |
|
$supppath .= '&'.$items[$i]; |
|
} |
|
} elsif ((!$odd) && ($items[$i] !~ /^(default|supplemental)(|_\d+)$/)) { |
|
$badpath = 1; |
|
} elsif ($supplementalflag) { |
|
$supppath .= '&'.$items[$i]; |
|
} |
|
last if ($badpath); |
|
} |
|
if ($badpath) { |
|
delete($env{'form.folderpath'}); |
|
} elsif ($changed && $supplementalflag) { |
|
$supppath =~ s/^\&//; |
|
$env{'form.folderpath'} = $supppath; |
|
} |
|
} |
|
return; |
|
} |
|
|
sub captcha_display { |
sub captcha_display { |
my ($context,$lonhost,$defdom) = @_; |
my ($context,$lonhost,$defdom) = @_; |
my ($output,$error); |
my ($output,$error); |
Line 18096 sub create_captcha {
|
Line 19063 sub create_captcha {
|
|
|
if (-e $Apache::lonnet::perlvar{'lonCaptchaDir'}.'/'.$md5sum.'.png') { |
if (-e $Apache::lonnet::perlvar{'lonCaptchaDir'}.'/'.$md5sum.'.png') { |
$output = '<input type="hidden" name="crypt" value="'.$md5sum.'" />'."\n". |
$output = '<input type="hidden" name="crypt" value="'.$md5sum.'" />'."\n". |
|
'<span class="LC_nobreak">'. |
&mt('Type in the letters/numbers shown below').' '. |
&mt('Type in the letters/numbers shown below').' '. |
'<input type="text" size="5" name="code" value="" autocomplete="off" />'. |
'<input type="text" size="5" name="code" value="" autocomplete="new-password" />'. |
'<br />'. |
'</span><br />'. |
'<img src="'.$captcha_params{'www_output_dir'}.'/'.$md5sum.'.png" alt="captcha" />'; |
'<img src="'.$captcha_params{'www_output_dir'}.'/'.$md5sum.'.png" alt="captcha" />'; |
last; |
last; |
} |
} |
Line 18144 sub check_captcha {
|
Line 19112 sub check_captcha {
|
sub create_recaptcha { |
sub create_recaptcha { |
my ($pubkey,$version) = @_; |
my ($pubkey,$version) = @_; |
if ($version >= 2) { |
if ($version >= 2) { |
return '<div class="g-recaptcha" data-sitekey="'.$pubkey.'"></div>'; |
return '<div class="g-recaptcha" data-sitekey="'.$pubkey.'"></div>'. |
|
'<div style="padding:0;clear:both;margin:0;border:0"></div>'; |
} else { |
} else { |
my $use_ssl; |
my $use_ssl; |
if ($ENV{'SERVER_PORT'} == 443) { |
if ($ENV{'SERVER_PORT'} == 443) { |
Line 18242 sub cleanup_html {
|
Line 19211 sub cleanup_html {
|
# $context is the calling context -- roles, grades, contents, menu or flip. |
# $context is the calling context -- roles, grades, contents, menu or flip. |
sub critical_redirect { |
sub critical_redirect { |
my ($interval,$context) = @_; |
my ($interval,$context) = @_; |
|
unless (($env{'user.domain'} ne '') && ($env{'user.name'} ne '')) { |
|
return (); |
|
} |
if ((time-$env{'user.criticalcheck.time'})>$interval) { |
if ((time-$env{'user.criticalcheck.time'})>$interval) { |
if (($env{'request.course.id'}) && (($context eq 'flip') || ($context eq 'contents'))) { |
if (($env{'request.course.id'}) && (($context eq 'flip') || ($context eq 'contents'))) { |
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
my $blocked = &blocking_status('alert',$cnum,$cdom,undef,1); |
my $blocked = &blocking_status('alert',undef,$cnum,$cdom,undef,1); |
if ($blocked) { |
if ($blocked) { |
my $checkrole = "cm./$cdom/$cnum"; |
my $checkrole = "cm./$cdom/$cnum"; |
if ($env{'request.course.sec'} ne '') { |
if ($env{'request.course.sec'} ne '') { |
Line 18263 sub critical_redirect {
|
Line 19235 sub critical_redirect {
|
&Apache::lonnet::appenv({'user.criticalcheck.time'=>time}); |
&Apache::lonnet::appenv({'user.criticalcheck.time'=>time}); |
my $redirecturl; |
my $redirecturl; |
if ($what[0]) { |
if ($what[0]) { |
if (($what[0] ne 'con_lost') && ($what[0]!~/^error\:/)) { |
if (($what[0] ne 'con_lost') && ($what[0] ne 'no_such_host') && ($what[0]!~/^error\:/)) { |
$redirecturl='/adm/email?critical=display'; |
$redirecturl='/adm/email?critical=display'; |
my $url=&Apache::lonnet::absolute_url().$redirecturl; |
my $url=&Apache::lonnet::absolute_url().$redirecturl; |
return (1, $url); |
return (1, $url); |
Line 18625 sub is_nonframeable {
|
Line 19597 sub is_nonframeable {
|
return $uselink; |
return $uselink; |
} |
} |
|
|
|
sub page_menu { |
|
my ($menucolls,$menunum) = @_; |
|
my %menu; |
|
foreach my $item (split(/;/,$menucolls)) { |
|
my ($num,$value) = split(/\%/,$item); |
|
if ($num eq $menunum) { |
|
my @entries = split(/\&/,$value); |
|
foreach my $entry (@entries) { |
|
my ($name,$fields) = split(/=/,$entry); |
|
if (($name eq 'top') || ($name eq 'inline') || ($name eq 'foot') || ($name eq 'main')) { |
|
$menu{$name} = $fields; |
|
} else { |
|
my @shown; |
|
if ($fields =~ /,/) { |
|
@shown = split(/,/,$fields); |
|
} else { |
|
@shown = ($fields); |
|
} |
|
if (@shown) { |
|
foreach my $field (@shown) { |
|
next if ($field eq ''); |
|
$menu{$field} = 1; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
return %menu; |
|
} |
|
|
1; |
1; |
__END__; |
__END__; |
|
|