version 1.1037, 2011/12/12 02:46:12
|
version 1.1069, 2012/04/11 15:21:43
|
Line 154 sub ssi_with_retries {
|
Line 154 sub ssi_with_retries {
|
# ----------------------------------------------- Filetypes/Languages/Copyright |
# ----------------------------------------------- Filetypes/Languages/Copyright |
my %language; |
my %language; |
my %supported_language; |
my %supported_language; |
|
my %latex_language; # For choosing hyphenation in <transl..> |
|
my %latex_language_bykey; # for choosing hyphenation from metadata |
my %cprtag; |
my %cprtag; |
my %scprtag; |
my %scprtag; |
my %fe; my %fd; my %fm; |
my %fe; my %fd; my %fm; |
Line 186 BEGIN {
|
Line 188 BEGIN {
|
while (my $line = <$fh>) { |
while (my $line = <$fh>) { |
next if ($line=~/^\#/); |
next if ($line=~/^\#/); |
chomp($line); |
chomp($line); |
my ($key,$two,$country,$three,$enc,$val,$sup)=(split(/\t/,$line)); |
my ($key,$two,$country,$three,$enc,$val,$sup,$latex)=(split(/\t/,$line)); |
$language{$key}=$val.' - '.$enc; |
$language{$key}=$val.' - '.$enc; |
if ($sup) { |
if ($sup) { |
$supported_language{$key}=$sup; |
$supported_language{$key}=$sup; |
} |
} |
|
if ($latex) { |
|
$latex_language_bykey{$key} = $latex; |
|
$latex_language{$two} = $latex; |
|
} |
} |
} |
close($fh); |
close($fh); |
} |
} |
Line 1742 Inputs: $workbook
|
Line 1748 Inputs: $workbook
|
|
|
Returns: $format, a hash reference. |
Returns: $format, a hash reference. |
|
|
|
|
=cut |
=cut |
|
|
############################################################### |
############################################################### |
Line 2850 database which holds them.
|
Line 2857 database which holds them.
|
|
|
Uses global $thesaurus_db_file. |
Uses global $thesaurus_db_file. |
|
|
|
|
=cut |
=cut |
|
|
############################################################### |
############################################################### |
Line 3227 sub languagedescription {
|
Line 3235 sub languagedescription {
|
($supported_language{$code}?' ('.&mt('interface available').')':''); |
($supported_language{$code}?' ('.&mt('interface available').')':''); |
} |
} |
|
|
|
=pod |
|
|
|
=item * &plainlanguagedescription |
|
|
|
Returns both the plain language description (e.g. 'Creoles and Pidgins, English-based (Other)') |
|
and the language character encoding (e.g. ISO) separated by a ' - ' string. |
|
|
|
=cut |
|
|
sub plainlanguagedescription { |
sub plainlanguagedescription { |
my $code=shift; |
my $code=shift; |
return $language{$code}; |
return $language{$code}; |
} |
} |
|
|
|
=pod |
|
|
|
=item * &supportedlanguagecode |
|
|
|
Returns the supported language code (e.g. sptutf maps to pt) given a language |
|
code. |
|
|
|
=cut |
|
|
sub supportedlanguagecode { |
sub supportedlanguagecode { |
my $code=shift; |
my $code=shift; |
return $supported_language{$code}; |
return $supported_language{$code}; |
Line 3239 sub supportedlanguagecode {
|
Line 3265 sub supportedlanguagecode {
|
|
|
=pod |
=pod |
|
|
|
=item * &latexlanguage() |
|
|
|
Given a language key code returns the correspondnig language to use |
|
to select the correct hyphenation on LaTeX printouts. This is undef if there |
|
is no supported hyphenation for the language code. |
|
|
|
=cut |
|
|
|
sub latexlanguage { |
|
my $code = shift; |
|
return $latex_language{$code}; |
|
} |
|
|
|
=pod |
|
|
|
=item * &latexhyphenation() |
|
|
|
Same as above but what's supplied is the language as it might be stored |
|
in the metadata. |
|
|
|
=cut |
|
|
|
sub latexhyphenation { |
|
my $key = shift; |
|
return $latex_language_bykey{$key}; |
|
} |
|
|
|
=pod |
|
|
=item * ©rightids() |
=item * ©rightids() |
|
|
returns list of all copyrights |
returns list of all copyrights |
Line 3962 sub findallcourses {
|
Line 4017 sub findallcourses {
|
if ($tstart) { |
if ($tstart) { |
next if ($tstart > $now); |
next if ($tstart > $now); |
} |
} |
my ($cdom,$cnum,$sec,$cnumpart,$secpart,$role,$realsec); |
my ($cdom,$cnum,$sec,$cnumpart,$secpart,$role); |
(undef,$cdom,$cnumpart,$secpart) = split(/\//,$entry); |
(undef,$cdom,$cnumpart,$secpart) = split(/\//,$entry); |
|
my $value = $trole.'/'.$cdom.'/'; |
if ($secpart eq '') { |
if ($secpart eq '') { |
($cnum,$role) = split(/_/,$cnumpart); |
($cnum,$role) = split(/_/,$cnumpart); |
$sec = 'none'; |
$sec = 'none'; |
$realsec = ''; |
$value .= $cnum.'/'; |
} else { |
} else { |
$cnum = $cnumpart; |
$cnum = $cnumpart; |
($sec,$role) = split(/_/,$secpart); |
($sec,$role) = split(/_/,$secpart); |
$realsec = $sec; |
$value .= $cnum.'/'.$sec; |
|
} |
|
if (ref($courses{$cdom.'_'.$cnum}{$sec}) eq 'ARRAY') { |
|
unless (grep(/^\Q$value\E$/,@{$courses{$cdom.'_'.$cnum}{$sec}})) { |
|
push(@{$courses{$cdom.'_'.$cnum}{$sec}},$value); |
|
} |
|
} else { |
|
@{$courses{$cdom.'_'.$cnum}{$sec}} = ($value); |
} |
} |
$courses{$cdom.'_'.$cnum}{$sec} = $trole.'/'.$cdom.'/'.$cnum.'/'.$realsec; |
|
} |
} |
} else { |
} else { |
foreach my $key (keys(%env)) { |
foreach my $key (keys(%env)) { |
Line 3991 sub findallcourses {
|
Line 4053 sub findallcourses {
|
if ($now>$endtime) { $active=0; } |
if ($now>$endtime) { $active=0; } |
} |
} |
if ($active) { |
if ($active) { |
|
my $value = $role.'/'.$cdom.'/'.$cnum.'/'; |
if ($sec eq '') { |
if ($sec eq '') { |
$sec = 'none'; |
$sec = 'none'; |
|
} else { |
|
$value .= $sec; |
|
} |
|
if (ref($courses{$cdom.'_'.$cnum}{$sec}) eq 'ARRAY') { |
|
unless (grep(/^\Q$value\E$/,@{$courses{$cdom.'_'.$cnum}{$sec}})) { |
|
push(@{$courses{$cdom.'_'.$cnum}{$sec}},$value); |
|
} |
|
} else { |
|
@{$courses{$cdom.'_'.$cnum}{$sec}} = ($value); |
} |
} |
$courses{$cdom.'_'.$cnum}{$sec} = |
|
$role.'/'.$cdom.'/'.$cnum.'/'.$sec; |
|
} |
} |
} |
} |
} |
} |
Line 4006 sub findallcourses {
|
Line 4076 sub findallcourses {
|
############################################### |
############################################### |
|
|
sub blockcheck { |
sub blockcheck { |
my ($setters,$activity,$uname,$udom) = @_; |
my ($setters,$activity,$uname,$udom,$url) = @_; |
|
|
if (!defined($udom)) { |
if (!defined($udom)) { |
$udom = $env{'user.domain'}; |
$udom = $env{'user.domain'}; |
Line 4018 sub blockcheck {
|
Line 4088 sub blockcheck {
|
# If uname and udom are for a course, check for blocks in the course. |
# If uname and udom are for a course, check for blocks in the course. |
|
|
if (&Apache::lonnet::is_course($udom,$uname)) { |
if (&Apache::lonnet::is_course($udom,$uname)) { |
my %records = &Apache::lonnet::dump('comm_block',$udom,$uname); |
my ($startblock,$endblock,$triggerblock) = |
my ($startblock,$endblock)=&get_blocks($setters,$activity,$udom,$uname); |
&get_blocks($setters,$activity,$udom,$uname,$url); |
return ($startblock,$endblock); |
return ($startblock,$endblock,$triggerblock); |
} |
} |
|
|
my $startblock = 0; |
my $startblock = 0; |
my $endblock = 0; |
my $endblock = 0; |
|
my $triggerblock = ''; |
my %live_courses = &findallcourses(undef,$uname,$udom); |
my %live_courses = &findallcourses(undef,$uname,$udom); |
|
|
# If uname is for a user, and activity is course-specific, i.e., |
# If uname is for a user, and activity is course-specific, i.e., |
Line 4088 sub blockcheck {
|
Line 4159 sub blockcheck {
|
if ($otheruser) { |
if ($otheruser) { |
# Resource belongs to user other than current user. |
# Resource belongs to user other than current user. |
# Assemble privs for that user, and check for 'evb' priv. |
# Assemble privs for that user, and check for 'evb' priv. |
my ($trole,$tdom,$tnum,$tsec); |
my (%allroles,%userroles); |
my $entry = $live_courses{$course}{$sec}; |
if (ref($live_courses{$course}{$sec}) eq 'ARRAY') { |
if ($entry =~ /^cr/) { |
foreach my $entry (@{$live_courses{$course}{$sec}}) { |
($trole,$tdom,$tnum,$tsec) = |
my ($trole,$tdom,$tnum,$tsec); |
($entry =~ m|^(cr/$match_domain/$match_username/\w+)\./($match_domain)/($match_username)/?(\w*)$|); |
if ($entry =~ /^cr/) { |
} else { |
($trole,$tdom,$tnum,$tsec) = |
($trole,$tdom,$tnum,$tsec) = split(/\//,$entry); |
($entry =~ m|^(cr/$match_domain/$match_username/\w+)\./($match_domain)/($match_username)/?(\w*)$|); |
} |
} else { |
my ($spec,$area,$trest,%allroles,%userroles); |
($trole,$tdom,$tnum,$tsec) = split(/\//,$entry); |
$area = '/'.$tdom.'/'.$tnum; |
} |
$trest = $tnum; |
my ($spec,$area,$trest); |
if ($tsec ne '') { |
$area = '/'.$tdom.'/'.$tnum; |
$area .= '/'.$tsec; |
$trest = $tnum; |
$trest .= '/'.$tsec; |
if ($tsec ne '') { |
} |
$area .= '/'.$tsec; |
$spec = $trole.'.'.$area; |
$trest .= '/'.$tsec; |
if ($trole =~ /^cr/) { |
} |
&Apache::lonnet::custom_roleprivs(\%allroles,$trole, |
$spec = $trole.'.'.$area; |
$tdom,$spec,$trest,$area); |
if ($trole =~ /^cr/) { |
} else { |
&Apache::lonnet::custom_roleprivs(\%allroles,$trole, |
&Apache::lonnet::standard_roleprivs(\%allroles,$trole, |
$tdom,$spec,$trest,$area); |
$tdom,$spec,$trest,$area); |
} else { |
} |
&Apache::lonnet::standard_roleprivs(\%allroles,$trole, |
my ($author,$adv) = &Apache::lonnet::set_userprivs(\%userroles,\%allroles); |
$tdom,$spec,$trest,$area); |
if ($userroles{'user.priv.'.$checkrole} =~ /evb\&([^\:]*)/) { |
} |
if ($1) { |
} |
$no_userblock = 1; |
my ($author,$adv) = &Apache::lonnet::set_userprivs(\%userroles,\%allroles); |
last; |
if ($userroles{'user.priv.'.$checkrole} =~ /evb\&([^\:]*)/) { |
|
if ($1) { |
|
$no_userblock = 1; |
|
last; |
|
} |
} |
} |
} |
} |
} else { |
} else { |
Line 4135 sub blockcheck {
|
Line 4210 sub blockcheck {
|
# Retrieve blocking times and identity of locker for course |
# Retrieve blocking times and identity of locker for course |
# of specified user, unless user has 'evb' privilege. |
# of specified user, unless user has 'evb' privilege. |
|
|
my ($start,$end)=&get_blocks($setters,$activity,$cdom,$cnum); |
my ($start,$end,$trigger) = |
|
&get_blocks($setters,$activity,$cdom,$cnum,$url); |
if (($start != 0) && |
if (($start != 0) && |
(($startblock == 0) || ($startblock > $start))) { |
(($startblock == 0) || ($startblock > $start))) { |
$startblock = $start; |
$startblock = $start; |
|
if ($trigger ne '') { |
|
$triggerblock = $trigger; |
|
} |
} |
} |
if (($end != 0) && |
if (($end != 0) && |
(($endblock == 0) || ($endblock < $end))) { |
(($endblock == 0) || ($endblock < $end))) { |
$endblock = $end; |
$endblock = $end; |
|
if ($trigger ne '') { |
|
$triggerblock = $trigger; |
|
} |
} |
} |
} |
} |
return ($startblock,$endblock); |
return ($startblock,$endblock,$triggerblock); |
} |
} |
|
|
sub get_blocks { |
sub get_blocks { |
my ($setters,$activity,$cdom,$cnum) = @_; |
my ($setters,$activity,$cdom,$cnum,$url) = @_; |
my $startblock = 0; |
my $startblock = 0; |
my $endblock = 0; |
my $endblock = 0; |
|
my $triggerblock = ''; |
my $course = $cdom.'_'.$cnum; |
my $course = $cdom.'_'.$cnum; |
$setters->{$course} = {}; |
$setters->{$course} = {}; |
$setters->{$course}{'staff'} = []; |
$setters->{$course}{'staff'} = []; |
$setters->{$course}{'times'} = []; |
$setters->{$course}{'times'} = []; |
my %records = &Apache::lonnet::dump('comm_block',$cdom,$cnum); |
$setters->{$course}{'triggers'} = []; |
foreach my $record (keys(%records)) { |
my (@blockers,%triggered); |
my ($start,$end) = ($record =~ m/^(\d+)____(\d+)$/); |
my $now = time; |
if ($start <= time && $end >= time) { |
my %commblocks = &Apache::lonnet::get_comm_blocks($cdom,$cnum); |
my ($staff_name,$staff_dom,$title,$blocks) = |
if ($activity eq 'docs') { |
&parse_block_record($records{$record}); |
@blockers = &Apache::lonnet::has_comm_blocking('bre',undef,$url,\%commblocks); |
if ($blocks->{$activity} eq 'on') { |
foreach my $block (@blockers) { |
push(@{$$setters{$course}{'staff'}},[$staff_name,$staff_dom]); |
if ($block =~ /^firstaccess____(.+)$/) { |
push(@{$$setters{$course}{'times'}}, [$start,$end]); |
my $item = $1; |
if ( ($startblock == 0) || ($startblock > $start) ) { |
my $type = 'map'; |
$startblock = $start; |
my $timersymb = $item; |
|
if ($item eq 'course') { |
|
$type = 'course'; |
|
} elsif ($item =~ /___\d+___/) { |
|
$type = 'resource'; |
|
} else { |
|
$timersymb = &Apache::lonnet::symbread($item); |
} |
} |
if ( ($endblock == 0) || ($endblock < $end) ) { |
my $start = $env{'course.'.$cdom.'_'.$cnum.'.firstaccess.'.$timersymb}; |
$endblock = $end; |
my $end = $start + $env{'course.'.$cdom.'_'.$cnum.'.timerinterval.'.$timersymb}; |
|
$triggered{$block} = { |
|
start => $start, |
|
end => $end, |
|
type => $type, |
|
}; |
|
} |
|
} |
|
} else { |
|
foreach my $block (keys(%commblocks)) { |
|
if ($block =~ m/^(\d+)____(\d+)$/) { |
|
my ($start,$end) = ($1,$2); |
|
if ($start <= time && $end >= time) { |
|
if (ref($commblocks{$block}) eq 'HASH') { |
|
if (ref($commblocks{$block}{'blocks'}) eq 'HASH') { |
|
if ($commblocks{$block}{'blocks'}{$activity} eq 'on') { |
|
unless(grep(/^\Q$block\E$/,@blockers)) { |
|
push(@blockers,$block); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} elsif ($block =~ /^firstaccess____(.+)$/) { |
|
my $item = $1; |
|
my $timersymb = $item; |
|
my $type = 'map'; |
|
if ($item eq 'course') { |
|
$type = 'course'; |
|
} elsif ($item =~ /___\d+___/) { |
|
$type = 'resource'; |
|
} else { |
|
$timersymb = &Apache::lonnet::symbread($item); |
|
} |
|
my $start = $env{'course.'.$cdom.'_'.$cnum.'.firstaccess.'.$timersymb}; |
|
my $end = $start + $env{'course.'.$cdom.'_'.$cnum.'.timerinterval.'.$timersymb}; |
|
if ($start && $end) { |
|
if (($start <= time) && ($end >= time)) { |
|
unless (grep(/^\Q$block\E$/,@blockers)) { |
|
push(@blockers,$block); |
|
$triggered{$block} = { |
|
start => $start, |
|
end => $end, |
|
type => $type, |
|
}; |
|
} |
|
} |
} |
} |
} |
} |
} |
} |
} |
} |
return ($startblock,$endblock); |
foreach my $blocker (@blockers) { |
|
my ($staff_name,$staff_dom,$title,$blocks) = |
|
&parse_block_record($commblocks{$blocker}); |
|
push(@{$$setters{$course}{'staff'}},[$staff_name,$staff_dom]); |
|
my ($start,$end,$triggertype); |
|
if ($blocker =~ m/^(\d+)____(\d+)$/) { |
|
($start,$end) = ($1,$2); |
|
} elsif (ref($triggered{$blocker}) eq 'HASH') { |
|
$start = $triggered{$blocker}{'start'}; |
|
$end = $triggered{$blocker}{'end'}; |
|
$triggertype = $triggered{$blocker}{'type'}; |
|
} |
|
if ($start) { |
|
push(@{$$setters{$course}{'times'}}, [$start,$end]); |
|
if ($triggertype) { |
|
push(@{$$setters{$course}{'triggers'}},$triggertype); |
|
} else { |
|
push(@{$$setters{$course}{'triggers'}},0); |
|
} |
|
if ( ($startblock == 0) || ($startblock > $start) ) { |
|
$startblock = $start; |
|
if ($triggertype) { |
|
$triggerblock = $blocker; |
|
} |
|
} |
|
if ( ($endblock == 0) || ($endblock < $end) ) { |
|
$endblock = $end; |
|
if ($triggertype) { |
|
$triggerblock = $blocker; |
|
} |
|
} |
|
} |
|
} |
|
return ($startblock,$endblock,$triggerblock); |
} |
} |
|
|
sub parse_block_record { |
sub parse_block_record { |
Line 4198 sub parse_block_record {
|
Line 4366 sub parse_block_record {
|
} |
} |
|
|
sub blocking_status { |
sub blocking_status { |
my ($activity,$uname,$udom) = @_; |
my ($activity,$uname,$udom,$url) = @_; |
my %setters; |
my %setters; |
|
|
# check for active blocking |
|
my ($startblock,$endblock)=&blockcheck(\%setters,$activity,$uname,$udom); |
|
|
|
my $blocked = $startblock && $endblock ? 1 : 0; |
# check for active blocking |
|
my ($startblock,$endblock,$triggerblock) = |
# caller just wants to know whether a block is active |
&blockcheck(\%setters,$activity,$uname,$udom,$url); |
if (!wantarray) { return $blocked; } |
my $blocked = 0; |
|
if ($startblock && $endblock) { |
# build a link to a popup window containing the details |
$blocked = 1; |
my $querystring = "?activity=$activity"; |
} |
# $uname and $udom decide whose portfolio the user is trying to look at |
|
$querystring .= "&udom=$udom" if $udom; |
# caller just wants to know whether a block is active |
$querystring .= "&uname=$uname" if $uname; |
if (!wantarray) { return $blocked; } |
|
|
my $output .= <<'END_MYBLOCK'; |
# build a link to a popup window containing the details |
function openWindow(url, wdwName, w, h, toolbar,scrollbar) { |
my $querystring = "?activity=$activity"; |
var options = "width=" + w + ",height=" + h + ","; |
# $uname and $udom decide whose portfolio the user is trying to look at |
options += "resizable=yes,scrollbars="+scrollbar+",status=no,"; |
if ($activity eq 'port') { |
options += "menubar=no,toolbar="+toolbar+",location=no,directories=no"; |
$querystring .= "&udom=$udom" if $udom; |
var newWin = window.open(url, wdwName, options); |
$querystring .= "&uname=$uname" if $uname; |
newWin.focus(); |
} elsif ($activity eq 'docs') { |
} |
$querystring .= '&url='.&HTML::Entities::encode($url,'&"'); |
|
} |
|
|
|
my $output .= <<'END_MYBLOCK'; |
|
function openWindow(url, wdwName, w, h, toolbar,scrollbar) { |
|
var options = "width=" + w + ",height=" + h + ","; |
|
options += "resizable=yes,scrollbars="+scrollbar+",status=no,"; |
|
options += "menubar=no,toolbar="+toolbar+",location=no,directories=no"; |
|
var newWin = window.open(url, wdwName, options); |
|
newWin.focus(); |
|
} |
END_MYBLOCK |
END_MYBLOCK |
|
|
$output = Apache::lonhtmlcommon::scripttag($output); |
$output = Apache::lonhtmlcommon::scripttag($output); |
|
|
my $popupUrl = "/adm/blockingstatus/$querystring"; |
my $popupUrl = "/adm/blockingstatus/$querystring"; |
my $text = mt('Communication Blocked'); |
my $text = &mt('Communication Blocked'); |
|
if ($activity eq 'docs') { |
$output .= <<"END_BLOCK"; |
$text = &mt('Content Access Blocked'); |
|
} elsif ($activity eq 'printout') { |
|
$text = &mt('Printing Blocked'); |
|
} |
|
$output .= <<"END_BLOCK"; |
<div class='LC_comblock'> |
<div class='LC_comblock'> |
<a onclick='openWindow("$popupUrl","Blocking Table",600,300,"no","no");return false;' href='/adm/blockingstatus/$querystring' |
<a onclick='openWindow("$popupUrl","Blocking Table",600,300,"no","no");return false;' href='/adm/blockingstatus/$querystring' |
title='$text'> |
title='$text'> |
Line 4241 END_MYBLOCK
|
Line 4420 END_MYBLOCK
|
|
|
END_BLOCK |
END_BLOCK |
|
|
return ($blocked, $output); |
return ($blocked, $output); |
} |
} |
|
|
############################################### |
############################################### |
Line 4835 sub bodytag {
|
Line 5014 sub bodytag {
|
sub dc_courseid_toggle { |
sub dc_courseid_toggle { |
my ($dc_info) = @_; |
my ($dc_info) = @_; |
return ' <span id="dccidtext" class="LC_cusr_subheading LC_nobreak">'. |
return ' <span id="dccidtext" class="LC_cusr_subheading LC_nobreak">'. |
'<a href="javascript:showCourseID();">'. |
'<a href="javascript:showCourseID();" class="LC_menubuttons_link">'. |
&mt('(More ...)').'</a></span>'. |
&mt('(More ...)').'</a></span>'. |
'<div id="dccid" class="LC_dccid">'.$dc_info.'</div>'; |
'<div id="dccid" class="LC_dccid">'.$dc_info.'</div>'; |
} |
} |
Line 4940 sub standard_css {
|
Line 5119 sub standard_css {
|
my $mono = 'monospace'; |
my $mono = 'monospace'; |
my $data_table_head = $sidebg; |
my $data_table_head = $sidebg; |
my $data_table_light = '#FAFAFA'; |
my $data_table_light = '#FAFAFA'; |
my $data_table_dark = '#F0F0F0'; |
my $data_table_dark = '#E0E0E0'; |
my $data_table_darker = '#CCCCCC'; |
my $data_table_darker = '#CCCCCC'; |
my $data_table_highlight = '#FFFF00'; |
my $data_table_highlight = '#FFFF00'; |
my $mail_new = '#FFBB77'; |
my $mail_new = '#FFBB77'; |
Line 4980 body {
|
Line 5159 body {
|
a:focus, |
a:focus, |
a:focus img { |
a:focus img { |
color: red; |
color: red; |
background: yellow; |
|
} |
} |
|
|
form, .inline { |
form, .inline { |
Line 5075 div.LC_confirm_box .LC_success img {
|
Line 5253 div.LC_confirm_box .LC_success img {
|
} |
} |
|
|
.LC_discussion { |
.LC_discussion { |
background: $tabbg; |
background: $data_table_dark; |
border: 1px solid black; |
border: 1px solid black; |
margin: 2px; |
margin: 2px; |
} |
} |
|
|
.LC_disc_action_links_bar { |
|
background: $tabbg; |
|
border: none; |
|
margin: 4px; |
|
} |
|
|
|
.LC_disc_action_left { |
.LC_disc_action_left { |
|
background: $sidebg; |
text-align: left; |
text-align: left; |
|
padding: 4px; |
|
margin: 2px; |
} |
} |
|
|
.LC_disc_action_right { |
.LC_disc_action_right { |
|
background: $sidebg; |
text-align: right; |
text-align: right; |
|
padding: 4px; |
|
margin: 2px; |
} |
} |
|
|
.LC_disc_new_item { |
.LC_disc_new_item { |
background: white; |
background: white; |
border: 2px solid red; |
border: 2px solid red; |
margin: 2px; |
margin: 4px; |
|
padding: 4px; |
} |
} |
|
|
.LC_disc_old_item { |
.LC_disc_old_item { |
background: white; |
background: white; |
border: 1px solid black; |
margin: 4px; |
margin: 2px; |
padding: 4px; |
} |
} |
|
|
table.LC_pastsubmission { |
table.LC_pastsubmission { |
Line 5225 td.LC_table_cell_checkbox {
|
Line 5404 td.LC_table_cell_checkbox {
|
vertical-align: middle; |
vertical-align: middle; |
} |
} |
|
|
li.LC_menubuttons_inline_text img,a { |
li.LC_menubuttons_inline_text img { |
cursor:pointer; |
cursor:pointer; |
text-decoration: none; |
text-decoration: none; |
} |
} |
Line 6027 div.LC_edit_problem_footer {
|
Line 6206 div.LC_edit_problem_footer {
|
font-weight: normal; |
font-weight: normal; |
font-size: medium; |
font-size: medium; |
margin: 2px; |
margin: 2px; |
|
background-color: $sidebg; |
} |
} |
|
|
div.LC_edit_problem_header, |
div.LC_edit_problem_header, |
Line 6043 div.LC_edit_problem_header_title {
|
Line 6223 div.LC_edit_problem_header_title {
|
font-size: larger; |
font-size: larger; |
background: $tabbg; |
background: $tabbg; |
padding: 3px; |
padding: 3px; |
|
margin: 0 0 5px 0; |
} |
} |
|
|
table.LC_edit_problem_header_title { |
table.LC_edit_problem_header_title { |
Line 6080 div.LC_createcourse {
|
Line 6261 div.LC_createcourse {
|
display:none; |
display:none; |
} |
} |
|
|
a:hover, |
|
ol.LC_primary_menu a:hover, |
ol.LC_primary_menu a:hover, |
ol#LC_MenuBreadcrumbs a:hover, |
ol#LC_MenuBreadcrumbs a:hover, |
ol#LC_PathBreadcrumbs a:hover, |
ol#LC_PathBreadcrumbs a:hover, |
Line 6314 ul.LC_TabContent li.active a {
|
Line 6494 ul.LC_TabContent li.active a {
|
background:#FFFFFF; |
background:#FFFFFF; |
outline: none; |
outline: none; |
} |
} |
|
|
|
ul.LC_TabContent li.goback { |
|
float: left; |
|
border-left: none; |
|
} |
|
|
#maincoursedoc { |
#maincoursedoc { |
clear:both; |
clear:both; |
} |
} |
Line 6563 a#LC_content_toolbar_changefolder_toggle
|
Line 6749 a#LC_content_toolbar_changefolder_toggle
|
background-image:url(/res/adm/pages/open-all-folders.gif); |
background-image:url(/res/adm/pages/open-all-folders.gif); |
} |
} |
|
|
|
a#LC_content_toolbar_edittoplevel { |
|
background-image:url(/res/adm/pages/edittoplevel.gif); |
|
} |
|
|
ul#LC_toolbar li a:hover { |
ul#LC_toolbar li a:hover { |
background-position: bottom center; |
background-position: bottom center; |
} |
} |
Line 6726 sub headtag {
|
Line 6916 sub headtag {
|
'<head>'. |
'<head>'. |
&font_settings(); |
&font_settings(); |
|
|
|
my $inhibitprint = &print_suppression(); |
|
|
if (!$args->{'frameset'}) { |
if (!$args->{'frameset'}) { |
$result .= &Apache::lonhtmlcommon::htmlareaheaders(); |
$result .= &Apache::lonhtmlcommon::htmlareaheaders(); |
} |
} |
Line 6737 sub headtag {
|
Line 6929 sub headtag {
|
&& !$args->{'frameset'}) { |
&& !$args->{'frameset'}) { |
$result .= &help_menu_js(); |
$result .= &help_menu_js(); |
$result.=&modal_window(); |
$result.=&modal_window(); |
|
$result.=&togglebox_script(); |
$result.=&wishlist_window(); |
$result.=&wishlist_window(); |
|
$result.=&LCprogressbarUpdate_script(); |
} else { |
} else { |
if ($args->{'add_modal'}) { |
if ($args->{'add_modal'}) { |
$result.=&modal_window(); |
$result.=&modal_window(); |
Line 6745 sub headtag {
|
Line 6939 sub headtag {
|
if ($args->{'add_wishlist'}) { |
if ($args->{'add_wishlist'}) { |
$result.=&wishlist_window(); |
$result.=&wishlist_window(); |
} |
} |
|
if ($args->{'add_togglebox'}) { |
|
$result.=&togglebox_script(); |
|
} |
|
if ($args->{'add_progressbar'}) { |
|
$result.=&LCprogressbarUpdate_script(); |
|
} |
} |
} |
if (ref($args->{'redirect'})) { |
if (ref($args->{'redirect'})) { |
my ($time,$url,$inhibit_continue) = @{$args->{'redirect'}}; |
my ($time,$url,$inhibit_continue) = @{$args->{'redirect'}}; |
Line 6763 ADDMETA
|
Line 6963 ADDMETA
|
if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); } |
if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); } |
$result .= '<title> LON-CAPA '.$title.'</title>' |
$result .= '<title> LON-CAPA '.$title.'</title>' |
.'<link rel="stylesheet" type="text/css" href="'.$url.'" />' |
.'<link rel="stylesheet" type="text/css" href="'.$url.'" />' |
|
.$inhibitprint |
.$head_extra; |
.$head_extra; |
return $result.'</head>'; |
return $result.'</head>'; |
} |
} |
Line 6788 sub font_settings {
|
Line 6989 sub font_settings {
|
|
|
=pod |
=pod |
|
|
|
=item * &print_suppression() |
|
|
|
In course context returns css which causes the body to be blank when media="print", |
|
if printout generation is unavailable for the current resource. |
|
|
|
This could be because: |
|
|
|
(a) printstartdate is in the future |
|
|
|
(b) printenddate is in the past |
|
|
|
(c) there is an active exam block with "printout" |
|
functionality blocked |
|
|
|
Users with pav, pfo or evb privileges are exempt. |
|
|
|
Inputs: none |
|
|
|
=cut |
|
|
|
|
|
sub print_suppression { |
|
my $noprint; |
|
if ($env{'request.course.id'}) { |
|
my $scope = $env{'request.course.id'}; |
|
if ((&Apache::lonnet::allowed('pav',$scope)) || |
|
(&Apache::lonnet::allowed('pfo',$scope))) { |
|
return; |
|
} |
|
if ($env{'request.course.sec'} ne '') { |
|
$scope .= "/$env{'request.course.sec'}"; |
|
if ((&Apache::lonnet::allowed('pav',$scope)) || |
|
(&Apache::lonnet::allowed('pfo',$scope))) { |
|
return; |
|
} |
|
} |
|
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
my $blocked = &blocking_status('printout',$cnum,$cdom); |
|
if ($blocked) { |
|
my $checkrole = "cm./$cdom/$cnum"; |
|
if ($env{'request.course.sec'} ne '') { |
|
$checkrole .= "/$env{'request.course.sec'}"; |
|
} |
|
unless ((&Apache::lonnet::allowed('evb',undef,undef,$checkrole)) && |
|
($env{'request.role'} !~ m{^st\./$cdom/$cnum})) { |
|
$noprint = 1; |
|
} |
|
} |
|
unless ($noprint) { |
|
my $symb = &Apache::lonnet::symbread(); |
|
if ($symb ne '') { |
|
my $navmap = Apache::lonnavmaps::navmap->new(); |
|
if (ref($navmap)) { |
|
my $res = $navmap->getBySymb($symb); |
|
if (ref($res)) { |
|
if (!$res->resprintable()) { |
|
$noprint = 1; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if ($noprint) { |
|
return <<"ENDSTYLE"; |
|
<style type="text/css" media="print"> |
|
body { display:none } |
|
</style> |
|
ENDSTYLE |
|
} |
|
} |
|
return; |
|
} |
|
|
|
=pod |
|
|
=item * &xml_begin() |
=item * &xml_begin() |
|
|
Returns the needed doctype and <html> |
Returns the needed doctype and <html> |
Line 6961 sub end_page {
|
Line 7238 sub end_page {
|
|
|
sub wishlist_window { |
sub wishlist_window { |
return(<<'ENDWISHLIST'); |
return(<<'ENDWISHLIST'); |
<script type="text/javascript" lang="javascript"> |
<script type="text/javascript"> |
// <![CDATA[ |
// <![CDATA[ |
// <!-- BEGIN LON-CAPA Internal |
// <!-- BEGIN LON-CAPA Internal |
function set_wishlistlink(title, path) { |
function set_wishlistlink(title, path) { |
Line 6983 ENDWISHLIST
|
Line 7260 ENDWISHLIST
|
|
|
sub modal_window { |
sub modal_window { |
return(<<'ENDMODAL'); |
return(<<'ENDMODAL'); |
<script type="text/javascript" lang="javascript"> |
<script type="text/javascript"> |
// <![CDATA[ |
// <![CDATA[ |
// <!-- BEGIN LON-CAPA Internal |
// <!-- BEGIN LON-CAPA Internal |
var modalWindow = { |
var modalWindow = { |
Line 7027 ENDMODAL
|
Line 7304 ENDMODAL
|
} |
} |
|
|
sub modal_link { |
sub modal_link { |
my ($link,$linktext,$width,$height,$target,$scrolling)=@_; |
my ($link,$linktext,$width,$height,$target,$scrolling,$title)=@_; |
unless ($width) { $width=480; } |
unless ($width) { $width=480; } |
unless ($height) { $height=400; } |
unless ($height) { $height=400; } |
unless ($scrolling) { $scrolling='yes'; } |
unless ($scrolling) { $scrolling='yes'; } |
return '<a href="'.$link.'" target="'.$target.'" onclick="openMyModal(\''.$link.'\','.$width.','.$height.',\''.$scrolling.'\'); return false;">'. |
return '<a href="'.$link.'" target="'.$target.'" title="'.$title.'" onclick="openMyModal(\''.$link.'\','.$width.','.$height.',\''.$scrolling.'\'); return false;">'. |
$linktext.'</a>'; |
$linktext.'</a>'; |
} |
} |
|
|
sub modal_adhoc_script { |
sub modal_adhoc_script { |
my ($funcname,$width,$height,$content)=@_; |
my ($funcname,$width,$height,$content)=@_; |
return (<<ENDADHOC); |
return (<<ENDADHOC); |
<script type="text/javascript" lang="javascript"> |
<script type="text/javascript"> |
// <![CDATA[ |
// <![CDATA[ |
var $funcname = function() |
var $funcname = function() |
{ |
{ |
Line 7053 sub modal_adhoc_script {
|
Line 7330 sub modal_adhoc_script {
|
ENDADHOC |
ENDADHOC |
} |
} |
|
|
sub modal_adhoc_window { |
sub modal_adhoc_inner { |
my ($funcname,$width,$height,$content,$linktext)=@_; |
my ($funcname,$width,$height,$content)=@_; |
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 7063 sub modal_adhoc_window {
|
Line 7340 sub modal_adhoc_window {
|
&end_scrollbox(). |
&end_scrollbox(). |
&end_page() |
&end_page() |
); |
); |
return &modal_adhoc_script($funcname,$width,$height,$content). |
return &modal_adhoc_script($funcname,$width,$height,$content); |
"<a href=\"javascript:$funcname();void(0);\">".$linktext."</a>"; |
} |
|
|
|
sub modal_adhoc_window { |
|
my ($funcname,$width,$height,$content,$linktext)=@_; |
|
return &modal_adhoc_inner($funcname,$width,$height,$content). |
|
"<a href=\"javascript:$funcname();void(0);\">".$linktext."</a>"; |
|
} |
|
|
|
sub modal_adhoc_launch { |
|
my ($funcname,$width,$height,$content)=@_; |
|
return &modal_adhoc_inner($funcname,$width,$height,$content).(<<ENDLAUNCH); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
$funcname(); |
|
// ]]> |
|
</script> |
|
ENDLAUNCH |
|
} |
|
|
|
sub modal_adhoc_close { |
|
return (<<ENDCLOSE); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
modalWindow.close(); |
|
// ]]> |
|
</script> |
|
ENDCLOSE |
|
} |
|
|
|
sub togglebox_script { |
|
return(<<ENDTOGGLE); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
function LCtoggleDisplay(id,hidetext,showtext) { |
|
link = document.getElementById(id + "link").childNodes[0]; |
|
with (document.getElementById(id).style) { |
|
if (display == "none" ) { |
|
display = "inline"; |
|
link.nodeValue = hidetext; |
|
} else { |
|
display = "none"; |
|
link.nodeValue = showtext; |
|
} |
|
} |
|
} |
|
// ]]> |
|
</script> |
|
ENDTOGGLE |
|
} |
|
|
|
sub start_togglebox { |
|
my ($id,$heading,$headerbg,$hidetext,$showtext)=@_; |
|
unless ($heading) { $heading=''; } else { $heading.=' '; } |
|
unless ($showtext) { $showtext=&mt('show'); } |
|
unless ($hidetext) { $hidetext=&mt('hide'); } |
|
unless ($headerbg) { $headerbg='#FFFFFF'; } |
|
return &start_data_table(). |
|
&start_data_table_header_row(). |
|
'<td bgcolor="'.$headerbg.'">'.$heading. |
|
'[<a id="'.$id.'link" href="javascript:LCtoggleDisplay(\''.$id.'\',\''.$hidetext.'\',\''. |
|
$showtext.'\')">'.$showtext.'</a>]</td>'. |
|
&end_data_table_header_row(). |
|
'<tr id="'.$id.'" style="display:none""><td>'; |
|
} |
|
|
|
sub end_togglebox { |
|
return '</td></tr>'.&end_data_table(); |
|
} |
|
|
|
sub LCprogressbar_script { |
|
my ($id)=@_; |
|
return(<<ENDPROGRESS); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
\$('#progressbar$id').progressbar({ |
|
value: 0, |
|
change: function(event, ui) { |
|
var newVal = \$(this).progressbar('option', 'value'); |
|
\$('.pblabel', this).text(LCprogressTxt); |
|
} |
|
}); |
|
// ]]> |
|
</script> |
|
ENDPROGRESS |
|
} |
|
|
|
sub LCprogressbarUpdate_script { |
|
return(<<ENDPROGRESSUPDATE); |
|
<style type="text/css"> |
|
.ui-progressbar { position:relative; } |
|
.pblabel { position: absolute; width: 100%; text-align: center; line-height: 1.9em; } |
|
</style> |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
var LCprogressTxt='---'; |
|
|
|
function LCupdateProgress(percent,progresstext,id) { |
|
LCprogressTxt=progresstext; |
|
\$('#progressbar'+id).progressbar('value',percent); |
|
} |
|
// ]]> |
|
</script> |
|
ENDPROGRESSUPDATE |
|
} |
|
|
|
my $LClastpercent; |
|
my $LCidcnt; |
|
my $LCcurrentid; |
|
|
|
sub LCprogressbar { |
|
my ($r)=(@_); |
|
$LClastpercent=0; |
|
$LCidcnt++; |
|
$LCcurrentid=$$.'_'.$LCidcnt; |
|
my $starting=&mt('Starting'); |
|
my $content=(<<ENDPROGBAR); |
|
<p> |
|
<div id="progressbar$LCcurrentid"> |
|
<span class="pblabel">$starting</span> |
|
</div> |
|
</p> |
|
ENDPROGBAR |
|
&r_print($r,$content.&LCprogressbar_script($LCcurrentid)); |
|
} |
|
|
|
sub LCprogressbarUpdate { |
|
my ($r,$val,$text)=@_; |
|
unless ($val) { |
|
if ($LClastpercent) { |
|
$val=$LClastpercent; |
|
} else { |
|
$val=0; |
|
} |
|
} |
|
if ($val<0) { $val=0; } |
|
if ($val>100) { $val=0; } |
|
$LClastpercent=$val; |
|
unless ($text) { $text=$val.'%'; } |
|
$text=&js_ready($text); |
|
&r_print($r,<<ENDUPDATE); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
LCupdateProgress($val,'$text','$LCcurrentid'); |
|
// ]]> |
|
</script> |
|
ENDUPDATE |
|
} |
|
|
|
sub LCprogressbarClose { |
|
my ($r)=@_; |
|
$LClastpercent=0; |
|
&r_print($r,<<ENDCLOSE); |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
\$("#progressbar$LCcurrentid").hide('slow'); |
|
// ]]> |
|
</script> |
|
ENDCLOSE |
|
} |
|
|
|
sub r_print { |
|
my ($r,$to_print)=@_; |
|
if ($r) { |
|
$r->print($to_print); |
|
$r->rflush(); |
|
} else { |
|
print($to_print); |
|
} |
} |
} |
|
|
sub html_encode { |
sub html_encode { |
Line 7074 sub html_encode {
|
Line 7518 sub html_encode {
|
|
|
return $result; |
return $result; |
} |
} |
|
|
sub js_ready { |
sub js_ready { |
my ($result) = @_; |
my ($result) = @_; |
|
|
Line 8404 sub get_standard_codeitems {
|
Line 8849 sub get_standard_codeitems {
|
|
|
=item * sorted_slots() |
=item * sorted_slots() |
|
|
Sorts an array of slot names in order of slot start time (earliest first). |
Sorts an array of slot names in order of an optional sort key, |
|
default sort is by slot start time (earliest first). |
|
|
Inputs: |
Inputs: |
|
|
Line 8414 slotsarr - Reference to array of unsort
|
Line 8860 slotsarr - Reference to array of unsort
|
|
|
slots - Reference to hash of hash, where outer hash keys are slot names. |
slots - Reference to hash of hash, where outer hash keys are slot names. |
|
|
|
sortkey - Name of key in inner hash to be sorted on (e.g., starttime). |
|
|
=back |
=back |
|
|
Returns: |
Returns: |
|
|
=over 4 |
=over 4 |
|
|
sorted - An array of slot names sorted by the start time of the slot. |
sorted - An array of slot names sorted by a specified sort key |
|
(default sort key is start time of the slot). |
=back |
|
|
|
=back |
=back |
|
|
Line 8430 sorted - An array of slot names sorted
|
Line 8877 sorted - An array of slot names sorted
|
|
|
|
|
sub sorted_slots { |
sub sorted_slots { |
my ($slotsarr,$slots) = @_; |
my ($slotsarr,$slots,$sortkey) = @_; |
|
if ($sortkey eq '') { |
|
$sortkey = 'starttime'; |
|
} |
my @sorted; |
my @sorted; |
if ((ref($slotsarr) eq 'ARRAY') && (ref($slots) eq 'HASH')) { |
if ((ref($slotsarr) eq 'ARRAY') && (ref($slots) eq 'HASH')) { |
@sorted = |
@sorted = |
sort { |
sort { |
if (ref($slots->{$a}) && ref($slots->{$b})) { |
if (ref($slots->{$a}) && ref($slots->{$b})) { |
return $slots->{$a}{'starttime'} <=> $slots->{$b}{'starttime'} |
return $slots->{$a}{$sortkey} <=> $slots->{$b}{$sortkey} |
} |
} |
if (ref($slots->{$a})) { return -1;} |
if (ref($slots->{$a})) { return -1;} |
if (ref($slots->{$b})) { return 1;} |
if (ref($slots->{$b})) { return 1;} |
Line 8446 sub sorted_slots {
|
Line 8896 sub sorted_slots {
|
return @sorted; |
return @sorted; |
} |
} |
|
|
|
=pod |
|
|
|
=item * get_future_slots() |
|
|
|
Inputs: |
|
|
|
=over 4 |
|
|
|
cnum - course number |
|
|
|
cdom - course domain |
|
|
|
now - current UNIX time |
|
|
|
symb - optional symb |
|
|
|
=back |
|
|
|
Returns: |
|
|
|
=over 4 |
|
|
|
sorted_reservable - ref to array of student_schedulable slots currently |
|
reservable, ordered by end date of reservation period. |
|
|
|
reservable_now - ref to hash of student_schedulable slots currently |
|
reservable. |
|
|
|
Keys in inner hash are: |
|
(a) symb: either blank or symb to which slot use is restricted. |
|
(b) endreserve: end date of reservation period. |
|
|
|
sorted_future - ref to array of student_schedulable slots reservable in |
|
the future, ordered by start date of reservation period. |
|
|
|
future_reservable - ref to hash of student_schedulable slots reservable |
|
in the future. |
|
|
|
Keys in inner hash are: |
|
(a) symb: either blank or symb to which slot use is restricted. |
|
(b) startreserve: start date of reservation period. |
|
|
|
=back |
|
|
|
=cut |
|
|
|
sub get_future_slots { |
|
my ($cnum,$cdom,$now,$symb) = @_; |
|
my (%reservable_now,%future_reservable,@sorted_reservable,@sorted_future); |
|
my %slots = &Apache::lonnet::get_course_slots($cnum,$cdom); |
|
foreach my $slot (keys(%slots)) { |
|
next unless($slots{$slot}->{'type'} eq 'schedulable_student'); |
|
if ($symb) { |
|
next if (($slots{$slot}->{'symb'} ne '') && |
|
($slots{$slot}->{'symb'} ne $symb)); |
|
} |
|
if (($slots{$slot}->{'starttime'} > $now) && |
|
($slots{$slot}->{'endtime'} > $now)) { |
|
if (($slots{$slot}->{'allowedsections'}) || ($slots{$slot}->{'allowedusers'})) { |
|
my $userallowed = 0; |
|
if ($slots{$slot}->{'allowedsections'}) { |
|
my @allowed_sec = split(',',$slots{$slot}->{'allowedsections'}); |
|
if (!defined($env{'request.role.sec'}) |
|
&& grep(/^No section assigned$/,@allowed_sec)) { |
|
$userallowed=1; |
|
} else { |
|
if (grep(/^\Q$env{'request.role.sec'}\E$/,@allowed_sec)) { |
|
$userallowed=1; |
|
} |
|
} |
|
unless ($userallowed) { |
|
if (defined($env{'request.course.groups'})) { |
|
my @groups = split(/:/,$env{'request.course.groups'}); |
|
foreach my $group (@groups) { |
|
if (grep(/^\Q$group\E$/,@allowed_sec)) { |
|
$userallowed=1; |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if ($slots{$slot}->{'allowedusers'}) { |
|
my @allowed_users = split(',',$slots{$slot}->{'allowedusers'}); |
|
my $user = $env{'user.name'}.':'.$env{'user.domain'}; |
|
if (grep(/^\Q$user\E$/,@allowed_users)) { |
|
$userallowed = 1; |
|
} |
|
} |
|
next unless($userallowed); |
|
} |
|
my $startreserve = $slots{$slot}->{'startreserve'}; |
|
my $endreserve = $slots{$slot}->{'endreserve'}; |
|
my $symb = $slots{$slot}->{'symb'}; |
|
if (($startreserve < $now) && |
|
(!$endreserve || $endreserve > $now)) { |
|
my $lastres = $endreserve; |
|
if (!$lastres) { |
|
$lastres = $slots{$slot}->{'starttime'}; |
|
} |
|
$reservable_now{$slot} = { |
|
symb => $symb, |
|
endreserve => $lastres |
|
}; |
|
} elsif (($startreserve > $now) && |
|
(!$endreserve || $endreserve > $startreserve)) { |
|
$future_reservable{$slot} = { |
|
symb => $symb, |
|
startreserve => $startreserve |
|
}; |
|
} |
|
} |
|
} |
|
my @unsorted_reservable = keys(%reservable_now); |
|
if (@unsorted_reservable > 0) { |
|
@sorted_reservable = |
|
&sorted_slots(\@unsorted_reservable,\%reservable_now,'endreserve'); |
|
} |
|
my @unsorted_future = keys(%future_reservable); |
|
if (@unsorted_future > 0) { |
|
@sorted_future = |
|
&sorted_slots(\@unsorted_future,\%future_reservable,'startreserve'); |
|
} |
|
return (\@sorted_reservable,\%reservable_now,\@sorted_future,\%future_reservable); |
|
} |
|
|
=pod |
=pod |
|
|
|
=back |
|
|
=head1 HTTP Helpers |
=head1 HTTP Helpers |
|
|
=over 4 |
=over 4 |
Line 9340 sub check_for_traversal {
|
Line 9917 sub check_for_traversal {
|
return $cleanpath; |
return $cleanpath; |
} |
} |
|
|
|
sub is_archive_file { |
|
my ($mimetype) = @_; |
|
if (($mimetype eq 'application/octet-stream') || |
|
($mimetype eq 'application/x-stuffit') || |
|
($mimetype =~ m{^application/(x\-)?(compressed|tar|zip|tgz|gz|gtar|gzip|gunzip|bz|bz2|bzip2)})) { |
|
return 1; |
|
} |
|
return; |
|
} |
|
|
|
sub decompress_form { |
|
my ($mimetype,$archiveurl,$action,$noextract,$hiddenelements,$dirlist) = @_; |
|
my %lt = &Apache::lonlocal::texthash ( |
|
this => 'This file is an archive file.', |
|
camt => 'This file is a Camtasia archive file.', |
|
itsc => 'Its contents are as follows:', |
|
youm => 'You may wish to extract its contents.', |
|
extr => 'Extract contents', |
|
auto => 'LON-CAPA can process the files automatically, or you can decide how each should be handled.', |
|
proa => 'Process automatically?', |
|
yes => 'Yes', |
|
no => 'No', |
|
fold => 'Title for folder containing movie', |
|
movi => 'Title for page containing embedded movie', |
|
); |
|
my $fileloc = &Apache::lonnet::filelocation(undef,$archiveurl); |
|
my ($is_camtasia,$topdir,%toplevel,@paths); |
|
my $info = &list_archive_contents($fileloc,\@paths); |
|
if (@paths) { |
|
foreach my $path (@paths) { |
|
$path =~ s{^/}{}; |
|
if ($path =~ m{^([^/]+)/$}) { |
|
$topdir = $1; |
|
} |
|
if ($path =~ m{^([^/]+)/}) { |
|
$toplevel{$1} = $path; |
|
} else { |
|
$toplevel{$path} = $path; |
|
} |
|
} |
|
} |
|
if ($mimetype =~ m{^application/(x\-)?(compressed|zip)}) { |
|
my @camtasia = ("$topdir/","$topdir/index.html", |
|
"$topdir/media/", |
|
"$topdir/media/$topdir.mp4", |
|
"$topdir/media/FirstFrame.png", |
|
"$topdir/media/player.swf", |
|
"$topdir/media/swfobject.js", |
|
"$topdir/media/expressInstall.swf"); |
|
my @diffs = &compare_arrays(\@paths,\@camtasia); |
|
if (@diffs == 0) { |
|
$is_camtasia = 1; |
|
} |
|
} |
|
my $output; |
|
if ($is_camtasia) { |
|
$output = <<"ENDCAM"; |
|
<script type="text/javascript" language="Javascript"> |
|
// <![CDATA[ |
|
|
|
function camtasiaToggle() { |
|
for (var i=0; i<document.uploaded_decompress.autoextract_camtasia.length; i++) { |
|
if (document.uploaded_decompress.autoextract_camtasia[i].checked) { |
|
if (document.uploaded_decompress.autoextract_camtasia[i].value == 1) { |
|
|
|
document.getElementById('camtasia_titles').style.display='block'; |
|
} else { |
|
document.getElementById('camtasia_titles').style.display='none'; |
|
} |
|
} |
|
} |
|
return; |
|
} |
|
|
|
// ]]> |
|
</script> |
|
<p>$lt{'camt'}</p> |
|
ENDCAM |
|
} else { |
|
$output = '<p>'.$lt{'this'}; |
|
if ($info eq '') { |
|
$output .= ' '.$lt{'youm'}.'</p>'."\n"; |
|
} else { |
|
$output .= ' '.$lt{'itsc'}.'</p>'."\n". |
|
'<div><pre>'.$info.'</pre></div>'; |
|
} |
|
} |
|
$output .= '<form name="uploaded_decompress" action="'.$action.'" method="post">'."\n"; |
|
my $duplicates; |
|
my $num = 0; |
|
if (ref($dirlist) eq 'ARRAY') { |
|
foreach my $item (@{$dirlist}) { |
|
if (ref($item) eq 'ARRAY') { |
|
if (exists($toplevel{$item->[0]})) { |
|
$duplicates .= |
|
&start_data_table_row(). |
|
'<td><label><input type="radio" name="archive_overwrite_'.$num.'" '. |
|
'value="0" checked="checked" />'.&mt('No').'</label>'. |
|
' <label><input type="radio" name="archive_overwrite_'.$num.'" '. |
|
'value="1" />'.&mt('Yes').'</label>'. |
|
'<input type="hidden" name="archive_overwrite_name_'.$num.'" value="'.$item->[0].'" /></td>'."\n". |
|
'<td>'.$item->[0].'</td>'; |
|
if ($item->[2]) { |
|
$duplicates .= '<td>'.&mt('Directory').'</td>'; |
|
} else { |
|
$duplicates .= '<td>'.&mt('File').'</td>'; |
|
} |
|
$duplicates .= '<td>'.$item->[3].'</td>'. |
|
'<td>'. |
|
&Apache::lonlocal::locallocaltime($item->[4]). |
|
'</td>'. |
|
&end_data_table_row(); |
|
$num ++; |
|
} |
|
} |
|
} |
|
} |
|
my $itemcount; |
|
if (@paths > 0) { |
|
$itemcount = scalar(@paths); |
|
} else { |
|
$itemcount = 1; |
|
} |
|
if ($is_camtasia) { |
|
$output .= $lt{'auto'}.'<br />'. |
|
'<span class="LC_nobreak">'.$lt{'proa'}.'<label>'. |
|
'<input type="radio" name="autoextract_camtasia" value="1" onclick="javascript:camtasiaToggle();" checked="checked" />'. |
|
$lt{'yes'}.'</label> <label>'. |
|
'<input type="radio" name="autoextract_camtasia" value="0" onclick="javascript:camtasiaToggle();" />'. |
|
$lt{'no'}.'</label></span><br />'. |
|
'<div id="camtasia_titles" style="display:block">'. |
|
&Apache::lonhtmlcommon::start_pick_box(). |
|
&Apache::lonhtmlcommon::row_title($lt{'fold'}). |
|
'<input type="textbox" name="camtasia_foldername" value="'.$env{'form.comment'}.'" />'."\n". |
|
&Apache::lonhtmlcommon::row_closure(). |
|
&Apache::lonhtmlcommon::row_title($lt{'movi'}). |
|
'<input type="textbox" name="camtasia_moviename" value="" />'."\n". |
|
&Apache::lonhtmlcommon::row_closure(1). |
|
&Apache::lonhtmlcommon::end_pick_box(). |
|
'</div>'; |
|
} |
|
$output .= |
|
'<input type="hidden" name="archive_overwrite_total" value="'.$num.'" />'. |
|
'<input type="hidden" name="archive_itemcount" value="'.$itemcount.'" />'. |
|
"\n"; |
|
if ($duplicates ne '') { |
|
$output .= '<p><span class="LC_warning">'. |
|
&mt('Warning: decompression of the archive will overwrite the following items which already exist:').'</span><br />'. |
|
&start_data_table(). |
|
&start_data_table_header_row(). |
|
'<th>'.&mt('Overwrite?').'</th>'. |
|
'<th>'.&mt('Name').'</th>'. |
|
'<th>'.&mt('Type').'</th>'. |
|
'<th>'.&mt('Size').'</th>'. |
|
'<th>'.&mt('Last modified').'</th>'. |
|
&end_data_table_header_row(). |
|
$duplicates. |
|
&end_data_table(). |
|
'</p>'; |
|
} |
|
$output .= '<input type="hidden" name="archiveurl" value="'.$archiveurl.'" />'."\n"; |
|
if (ref($hiddenelements) eq 'HASH') { |
|
foreach my $hidden (sort(keys(%{$hiddenelements}))) { |
|
$output .= '<input type="hidden" name="'.$hidden.'" value="'.$hiddenelements->{$hidden}.'" />'."\n"; |
|
} |
|
} |
|
$output .= <<"END"; |
|
<br /> |
|
<input type="submit" name="decompress" value="$lt{'extr'}" /> |
|
</form> |
|
$noextract |
|
END |
|
return $output; |
|
} |
|
|
|
sub decompression_utility { |
|
my ($program) = @_; |
|
my @utilities = ('tar','gunzip','bunzip2','unzip'); |
|
my $location; |
|
if (grep(/^\Q$program\E$/,@utilities)) { |
|
foreach my $dir ('/bin/','/usr/bin/','/usr/local/bin/','/sbin/', |
|
'/usr/sbin/') { |
|
if (-x $dir.$program) { |
|
$location = $dir.$program; |
|
last; |
|
} |
|
} |
|
} |
|
return $location; |
|
} |
|
|
|
sub list_archive_contents { |
|
my ($file,$pathsref) = @_; |
|
my (@cmd,$output); |
|
my $needsregexp; |
|
if ($file =~ /\.zip$/) { |
|
@cmd = (&decompression_utility('unzip'),"-l"); |
|
$needsregexp = 1; |
|
} elsif (($file =~ m/\.tar\.gz$/) || |
|
($file =~ /\.tgz$/)) { |
|
@cmd = (&decompression_utility('tar'),"-ztf"); |
|
} elsif ($file =~ /\.tar\.bz2$/) { |
|
@cmd = (&decompression_utility('tar'),"-jtf"); |
|
} elsif ($file =~ m|\.tar$|) { |
|
@cmd = (&decompression_utility('tar'),"-tf"); |
|
} |
|
if (@cmd) { |
|
undef($!); |
|
undef($@); |
|
if (open(my $fh,"-|", @cmd, $file)) { |
|
while (my $line = <$fh>) { |
|
$output .= $line; |
|
chomp($line); |
|
my $item; |
|
if ($needsregexp) { |
|
($item) = ($line =~ /^\s*\d+\s+[\d\-]+\s+[\d:]+\s*(.+)$/); |
|
} else { |
|
$item = $line; |
|
} |
|
if ($item ne '') { |
|
unless (grep(/^\Q$item\E$/,@{$pathsref})) { |
|
push(@{$pathsref},$item); |
|
} |
|
} |
|
} |
|
close($fh); |
|
} |
|
} |
|
return $output; |
|
} |
|
|
|
sub decompress_uploaded_file { |
|
my ($file,$dir) = @_; |
|
&Apache::lonnet::appenv({'cgi.file' => $file}); |
|
&Apache::lonnet::appenv({'cgi.dir' => $dir}); |
|
my $result = &Apache::lonnet::ssi_body('/cgi-bin/decompress.pl'); |
|
my ($handle) = ($env{'user.environment'} =~m{/([^/]+)\.id$}); |
|
my $lonidsdir = $Apache::lonnet::perlvar{'lonIDsDir'}; |
|
&Apache::lonnet::transfer_profile_to_env($lonidsdir,$handle,1); |
|
my $decompressed = $env{'cgi.decompressed'}; |
|
&Apache::lonnet::delenv('cgi.file'); |
|
&Apache::lonnet::delenv('cgi.dir'); |
|
&Apache::lonnet::delenv('cgi.decompressed'); |
|
return ($decompressed,$result); |
|
} |
|
|
|
sub process_decompression { |
|
my ($docudom,$docuname,$file,$destination,$dir_root,$hiddenelem) = @_; |
|
my ($dir,$error,$warning,$output); |
|
if ($file !~ /\.(zip|tar|bz2|gz|tar.gz|tar.bz2|tgz)$/) { |
|
$error = &mt('File name not a supported archive file type.'). |
|
'<br />'.&mt('File name should end with one of: [_1].', |
|
'.zip, .tar, .bz2, .gz, .tar.gz, .tar.bz2, .tgz'); |
|
} else { |
|
my $docuhome = &Apache::lonnet::homeserver($docuname,$docudom); |
|
if ($docuhome eq 'no_host') { |
|
$error = &mt('Could not determine home server for course.'); |
|
} else { |
|
my @ids=&Apache::lonnet::current_machine_ids(); |
|
my $currdir = "$dir_root/$destination"; |
|
if (grep(/^\Q$docuhome\E$/,@ids)) { |
|
$dir = &LONCAPA::propath($docudom,$docuname). |
|
"$dir_root/$destination"; |
|
} else { |
|
$dir = $Apache::lonnet::perlvar{'lonDocRoot'}. |
|
"$dir_root/$docudom/$docuname/$destination"; |
|
unless (&Apache::lonnet::repcopy_userfile("$dir/$file") eq 'ok') { |
|
$error = &mt('Archive file not found.'); |
|
} |
|
} |
|
my (@to_overwrite,@to_skip); |
|
if ($env{'form.archive_overwrite_total'} > 0) { |
|
my $total = $env{'form.archive_overwrite_total'}; |
|
for (my $i=0; $i<$total; $i++) { |
|
if ($env{'form.archive_overwrite_'.$i} == 1) { |
|
push(@to_overwrite,$env{'form.archive_overwrite_name_'.$i}); |
|
} elsif ($env{'form.archive_overwrite_'.$i} == 0) { |
|
push(@to_skip,$env{'form.archive_overwrite_name_'.$i}); |
|
} |
|
} |
|
} |
|
my $numskip = scalar(@to_skip); |
|
if (($numskip > 0) && |
|
($numskip == $env{'form.archive_itemcount'})) { |
|
$warning = &mt('All items in the archive file already exist, and no overwriting of existing files has been requested.'); |
|
} elsif ($dir eq '') { |
|
$error = &mt('Directory containing archive file unavailable.'); |
|
} elsif (!$error) { |
|
my ($decompressed,$display); |
|
if ($numskip > 0) { |
|
my $tempdir = time.'_'.$$.int(rand(10000)); |
|
mkdir("$dir/$tempdir",0755); |
|
system("mv $dir/$file $dir/$tempdir/$file"); |
|
($decompressed,$display) = |
|
&decompress_uploaded_file($file,"$dir/$tempdir"); |
|
foreach my $item (@to_skip) { |
|
if (($item ne '') && ($item !~ /\.\./)) { |
|
if (-f "$dir/$tempdir/$item") { |
|
unlink("$dir/$tempdir/$item"); |
|
} elsif (-d "$dir/$tempdir/$item") { |
|
system("rm -rf $dir/$tempdir/$item"); |
|
} |
|
} |
|
} |
|
system("mv $dir/$tempdir/* $dir"); |
|
rmdir("$dir/$tempdir"); |
|
} else { |
|
($decompressed,$display) = |
|
&decompress_uploaded_file($file,$dir); |
|
} |
|
if ($decompressed eq 'ok') { |
|
$output = '<p class="LC_info">'. |
|
&mt('Files extracted successfully from archive.'). |
|
'</p>'."\n"; |
|
my ($warning,$result,@contents); |
|
my ($newdirlistref,$newlisterror) = |
|
&Apache::lonnet::dirlist($currdir,$docudom, |
|
$docuname,1); |
|
my (%is_dir,%changes,@newitems); |
|
my $dirptr = 16384; |
|
if (ref($newdirlistref) eq 'ARRAY') { |
|
foreach my $dir_line (@{$newdirlistref}) { |
|
my ($item,undef,undef,$testdir)=split(/\&/,$dir_line,5); |
|
unless (($item =~ /^\.+$/) || ($item eq $file) || |
|
((@to_skip > 0) && (grep(/^\Q$item\E$/,@to_skip)))) { |
|
push(@newitems,$item); |
|
if ($dirptr&$testdir) { |
|
$is_dir{$item} = 1; |
|
} |
|
$changes{$item} = 1; |
|
} |
|
} |
|
} |
|
if (keys(%changes) > 0) { |
|
foreach my $item (sort(@newitems)) { |
|
if ($changes{$item}) { |
|
push(@contents,$item); |
|
} |
|
} |
|
} |
|
if (@contents > 0) { |
|
my $wantform; |
|
unless ($env{'form.autoextract_camtasia'}) { |
|
$wantform = 1; |
|
} |
|
my (%children,%parent,%dirorder,%titles); |
|
my ($count,$datatable) = &get_extracted($docudom,$docuname, |
|
$currdir,\%is_dir, |
|
\%children,\%parent, |
|
\@contents,\%dirorder, |
|
\%titles,$wantform); |
|
if ($datatable ne '') { |
|
$output .= &archive_options_form('decompressed',$datatable, |
|
$count,$hiddenelem); |
|
my $startcount = 6; |
|
$output .= &archive_javascript($startcount,$count, |
|
\%titles,\%children); |
|
} |
|
if ($env{'form.autoextract_camtasia'}) { |
|
my %displayed; |
|
my $total = 1; |
|
$env{'form.archive_directory'} = []; |
|
foreach my $i (sort { $a <=> $b } keys(%dirorder)) { |
|
my $path = join('/',map { $titles{$_}; } @{$dirorder{$i}}); |
|
$path =~ s{/$}{}; |
|
my $item; |
|
if ($path ne '') { |
|
$item = "$path/$titles{$i}"; |
|
} else { |
|
$item = $titles{$i}; |
|
} |
|
$env{'form.archive_content_'.$i} = "$dir_root/$destination/$item"; |
|
if ($item eq $contents[0]) { |
|
push(@{$env{'form.archive_directory'}},$i); |
|
$env{'form.archive_'.$i} = 'display'; |
|
$env{'form.archive_title_'.$i} = $env{'form.camtasia_foldername'}; |
|
$displayed{'folder'} = $i; |
|
} elsif ($item eq "$contents[0]/index.html") { |
|
$env{'form.archive_'.$i} = 'display'; |
|
$env{'form.archive_title_'.$i} = $env{'form.camtasia_moviename'}; |
|
$displayed{'web'} = $i; |
|
} else { |
|
if ($item eq "$contents[0]/media") { |
|
push(@{$env{'form.archive_directory'}},$i); |
|
} |
|
$env{'form.archive_'.$i} = 'dependency'; |
|
} |
|
$total ++; |
|
} |
|
for (my $i=1; $i<$total; $i++) { |
|
next if ($i == $displayed{'web'}); |
|
next if ($i == $displayed{'folder'}); |
|
$env{'form.archive_dependent_on_'.$i} = $displayed{'web'}; |
|
} |
|
$env{'form.phase'} = 'decompress_cleanup'; |
|
$env{'form.archivedelete'} = 1; |
|
$env{'form.archive_count'} = $total-1; |
|
$output .= |
|
&process_extracted_files('coursedocs',$docudom, |
|
$docuname,$destination, |
|
$dir_root,$hiddenelem); |
|
} |
|
} else { |
|
$warning = &mt('No new items extracted from archive file.'); |
|
} |
|
} else { |
|
$output = $display; |
|
$error = &mt('An error occurred during extraction from the archive file.'); |
|
} |
|
} |
|
} |
|
} |
|
if ($error) { |
|
$output .= '<p class="LC_error">'.&mt('Not extracted.').'<br />'. |
|
$error.'</p>'."\n"; |
|
} |
|
if ($warning) { |
|
$output .= '<p class="LC_warning">'.$warning.'</p>'."\n"; |
|
} |
|
return $output; |
|
} |
|
|
|
sub get_extracted { |
|
my ($docudom,$docuname,$currdir,$is_dir,$children,$parent,$contents,$dirorder, |
|
$titles,$wantform) = @_; |
|
my $count = 0; |
|
my $depth = 0; |
|
my $datatable; |
|
my @hierarchy; |
|
return unless ((ref($is_dir) eq 'HASH') && (ref($children) eq 'HASH') && |
|
(ref($parent) eq 'HASH') && (ref($contents) eq 'ARRAY') && |
|
(ref($dirorder) eq 'HASH') && (ref($titles) eq 'HASH')); |
|
foreach my $item (@{$contents}) { |
|
$count ++; |
|
@{$dirorder->{$count}} = @hierarchy; |
|
$titles->{$count} = $item; |
|
&archive_hierarchy($depth,$count,$parent,$children); |
|
if ($wantform) { |
|
$datatable .= &archive_row($is_dir->{$item},$item, |
|
$currdir,$depth,$count); |
|
} |
|
if ($is_dir->{$item}) { |
|
$depth ++; |
|
push(@hierarchy,$count); |
|
$parent->{$depth} = $count; |
|
$datatable .= |
|
&recurse_extracted_archive("$currdir/$item",$docudom,$docuname, |
|
\$depth,\$count,\@hierarchy,$dirorder, |
|
$children,$parent,$titles,$wantform); |
|
$depth --; |
|
pop(@hierarchy); |
|
} |
|
} |
|
return ($count,$datatable); |
|
} |
|
|
|
sub recurse_extracted_archive { |
|
my ($currdir,$docudom,$docuname,$depth,$count,$hierarchy,$dirorder, |
|
$children,$parent,$titles,$wantform) = @_; |
|
my $result=''; |
|
unless ((ref($depth)) && (ref($count)) && (ref($hierarchy) eq 'ARRAY') && |
|
(ref($children) eq 'HASH') && (ref($parent) eq 'HASH') && |
|
(ref($dirorder) eq 'HASH')) { |
|
return $result; |
|
} |
|
my $dirptr = 16384; |
|
my ($newdirlistref,$newlisterror) = |
|
&Apache::lonnet::dirlist($currdir,$docudom,$docuname,1); |
|
if (ref($newdirlistref) eq 'ARRAY') { |
|
foreach my $dir_line (@{$newdirlistref}) { |
|
my ($item,undef,undef,$testdir)=split(/\&/,$dir_line,5); |
|
unless ($item =~ /^\.+$/) { |
|
$$count ++; |
|
@{$dirorder->{$$count}} = @{$hierarchy}; |
|
$titles->{$$count} = $item; |
|
&archive_hierarchy($$depth,$$count,$parent,$children); |
|
|
|
my $is_dir; |
|
if ($dirptr&$testdir) { |
|
$is_dir = 1; |
|
} |
|
if ($wantform) { |
|
$result .= &archive_row($is_dir,$item,$currdir,$$depth,$$count); |
|
} |
|
if ($is_dir) { |
|
$$depth ++; |
|
push(@{$hierarchy},$$count); |
|
$parent->{$$depth} = $$count; |
|
$result .= |
|
&recurse_extracted_archive("$currdir/$item",$docudom, |
|
$docuname,$depth,$count, |
|
$hierarchy,$dirorder,$children, |
|
$parent,$titles,$wantform); |
|
$$depth --; |
|
pop(@{$hierarchy}); |
|
} |
|
} |
|
} |
|
} |
|
return $result; |
|
} |
|
|
|
sub archive_hierarchy { |
|
my ($depth,$count,$parent,$children) =@_; |
|
if ((ref($parent) eq 'HASH') && (ref($children) eq 'HASH')) { |
|
if (exists($parent->{$depth})) { |
|
$children->{$parent->{$depth}} .= $count.':'; |
|
} |
|
} |
|
return; |
|
} |
|
|
|
sub archive_row { |
|
my ($is_dir,$item,$currdir,$depth,$count) = @_; |
|
my ($name) = ($item =~ m{([^/]+)$}); |
|
my %choices = &Apache::lonlocal::texthash ( |
|
'display' => 'Add as file', |
|
'dependency' => 'Include as dependency', |
|
'discard' => 'Discard', |
|
); |
|
if ($is_dir) { |
|
$choices{'display'} = &mt('Add as folder'); |
|
} |
|
my $output = &start_data_table_row().'<td align="right">'.$count.'</td>'."\n"; |
|
my $offset = 0; |
|
foreach my $action ('display','dependency','discard') { |
|
$offset ++; |
|
if ($action ne 'display') { |
|
$offset ++; |
|
} |
|
$output .= '<td><span class="LC_nobreak">'. |
|
'<label><input type="radio" name="archive_'.$count. |
|
'" id="archive_'.$action.'_'.$count.'" value="'.$action.'"'; |
|
my $text = $choices{$action}; |
|
if ($is_dir) { |
|
$output .= ' onclick="javascript:propagateCheck(this.form,'."'$count'".');"'; |
|
if ($action eq 'display') { |
|
$text = &mt('Add as folder'); |
|
} |
|
} else { |
|
$output .= ' onclick="javascript:dependencyCheck(this.form,'."$count,$offset".');"'; |
|
|
|
} |
|
$output .= ' /> '.$choices{$action}.'</label></span>'; |
|
if ($action eq 'dependency') { |
|
$output .= '<div id="arc_depon_'.$count.'" style="display:none;">'."\n". |
|
&mt('Used by:').' <select name="archive_dependent_on_'.$count.'" '. |
|
'onchange="propagateSelect(this.form,'."$count,$offset".')">'."\n". |
|
'<option value=""></option>'."\n". |
|
'</select>'."\n". |
|
'</div>'; |
|
} elsif ($action eq 'display') { |
|
$output .= '<div id="arc_title_'.$count.'" style="display:none;">'."\n". |
|
&mt('Title:').' <input type="text" name="archive_title_'.$count.'" id="archive_title_'.$count.'" />'."\n". |
|
'</div>'; |
|
} |
|
$output .= '</td>'; |
|
} |
|
$output .= '<td><input type="hidden" name="archive_content_'.$count.'" value="'. |
|
&HTML::Entities::encode("$currdir/$item",'"<>&').'" />'.(' ' x 2); |
|
for (my $i=0; $i<$depth; $i++) { |
|
$output .= ('<img src="/adm/lonIcons/whitespace1.gif" class="LC_docs_spacer" alt="" />' x2)."\n"; |
|
} |
|
if ($is_dir) { |
|
$output .= '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" /> '."\n". |
|
'<input type="hidden" name="archive_directory" value="'.$count.'" />'."\n"; |
|
} else { |
|
$output .= '<input type="hidden" name="archive_file" value="'.$count.'" />'."\n"; |
|
} |
|
$output .= ' '.$name.'</td>'."\n". |
|
&end_data_table_row(); |
|
return $output; |
|
} |
|
|
|
sub archive_options_form { |
|
my ($form,$display,$count,$hiddenelem) = @_; |
|
my %lt = &Apache::lonlocal::texthash( |
|
perm => 'Permanently remove archive file?', |
|
hows => 'How should each extracted item be incorporated in the course?', |
|
cont => 'Content actions for all', |
|
addf => 'Add as folder/file', |
|
incd => 'Include as dependency for a displayed file', |
|
disc => 'Discard', |
|
no => 'No', |
|
yes => 'Yes', |
|
save => 'Save', |
|
); |
|
my $output = <<"END"; |
|
<form name="$form" method="post" action=""> |
|
<p><span class="LC_nobreak">$lt{'perm'} |
|
<label> |
|
<input type="radio" name="archivedelete" value="0" checked="checked" />$lt{'no'} |
|
</label> |
|
|
|
<label> |
|
<input type="radio" name="archivedelete" value="1" />$lt{'yes'}</label> |
|
</span> |
|
</p> |
|
<input type="hidden" name="phase" value="decompress_cleanup" /> |
|
<br />$lt{'hows'} |
|
<div class="LC_columnSection"> |
|
<fieldset> |
|
<legend>$lt{'cont'}</legend> |
|
<input type="button" value="$lt{'addf'}" onclick="javascript:checkAll(document.$form,'display');" /> |
|
<input type="button" value="$lt{'incd'}" onclick="javascript:checkAll(document.$form,'dependency');" /> |
|
<input type="button" value="$lt{'disc'}" onclick="javascript:checkAll(document.$form,'discard');" /> |
|
</fieldset> |
|
</div> |
|
END |
|
return $output. |
|
&start_data_table()."\n". |
|
$display."\n". |
|
&end_data_table()."\n". |
|
'<input type="hidden" name="archive_count" value="'.$count.'" />'. |
|
$hiddenelem. |
|
'<br /><input type="submit" name="archive_submit" value="'.$lt{'save'}.'" />'. |
|
'</form>'; |
|
} |
|
|
|
sub archive_javascript { |
|
my ($startcount,$numitems,$titles,$children) = @_; |
|
return unless ((ref($titles) eq 'HASH') && (ref($children) eq 'HASH')); |
|
my $maintitle = $env{'form.comment'}; |
|
my $scripttag = <<START; |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
|
|
function checkAll(form,prefix) { |
|
var idstr = new RegExp("^archive_"+prefix+"_\\\\d+\$"); |
|
for (var i=0; i < form.elements.length; i++) { |
|
var id = form.elements[i].id; |
|
if ((id != '') && (id != undefined)) { |
|
if (idstr.test(id)) { |
|
if (form.elements[i].type == 'radio') { |
|
form.elements[i].checked = true; |
|
var nostart = i-$startcount; |
|
var offset = nostart%7; |
|
var count = (nostart-offset)/7; |
|
dependencyCheck(form,count,offset); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
function propagateCheck(form,count) { |
|
if (count > 0) { |
|
var startelement = $startcount + ((count-1) * 7); |
|
for (var j=1; j<6; j++) { |
|
if ((j != 2) && (j != 4)) { |
|
var item = startelement + j; |
|
if (form.elements[item].type == 'radio') { |
|
if (form.elements[item].checked) { |
|
containerCheck(form,count,j); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
numitems = $numitems |
|
var titles = new Array(numitems); |
|
var parents = new Array(numitems); |
|
for (var i=0; i<numitems; i++) { |
|
parents[i] = new Array; |
|
} |
|
var maintitle = '$maintitle'; |
|
|
|
START |
|
|
|
foreach my $container (sort { $a <=> $b } (keys(%{$children}))) { |
|
my @contents = split(/:/,$children->{$container}); |
|
for (my $i=0; $i<@contents; $i ++) { |
|
$scripttag .= 'parents['.$container.']['.$i.'] = '.$contents[$i]."\n"; |
|
} |
|
} |
|
|
|
foreach my $key (sort { $a <=> $b } (keys(%{$titles}))) { |
|
$scripttag .= "titles[$key] = '".$titles->{$key}."';\n"; |
|
} |
|
|
|
$scripttag .= <<END; |
|
|
|
function containerCheck(form,count,offset) { |
|
if (count > 0) { |
|
dependencyCheck(form,count,offset); |
|
var item = (offset+$startcount)+7*(count-1); |
|
form.elements[item].checked = true; |
|
if(Object.prototype.toString.call(parents[count]) === '[object Array]') { |
|
if (parents[count].length > 0) { |
|
for (var j=0; j<parents[count].length; j++) { |
|
containerCheck(form,parents[count][j],offset); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
function dependencyCheck(form,count,offset) { |
|
if (count > 0) { |
|
var chosen = (offset+$startcount)+7*(count-1); |
|
var depitem = $startcount + ((count-1) * 7) + 4; |
|
var currtype = form.elements[depitem].type; |
|
if (form.elements[chosen].value == 'dependency') { |
|
document.getElementById('arc_depon_'+count).style.display='block'; |
|
form.elements[depitem].options.length = 0; |
|
form.elements[depitem].options[0] = new Option('Select','',true,true); |
|
for (var i=1; i<count; i++) { |
|
var startelement = $startcount + (i-1) * 7; |
|
for (var j=1; j<6; j++) { |
|
if ((j != 2) && (j!= 4)) { |
|
var item = startelement + j; |
|
if (form.elements[item].type == 'radio') { |
|
if (form.elements[item].checked) { |
|
if (form.elements[item].value == 'display') { |
|
var n = form.elements[depitem].options.length; |
|
form.elements[depitem].options[n] = new Option(titles[i],i,false,false); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} else { |
|
document.getElementById('arc_depon_'+count).style.display='none'; |
|
form.elements[depitem].options.length = 0; |
|
form.elements[depitem].options[0] = new Option('Select','',true,true); |
|
} |
|
titleCheck(form,count,offset); |
|
} |
|
} |
|
|
|
function propagateSelect(form,count,offset) { |
|
if (count > 0) { |
|
var item = (1+offset+$startcount)+7*(count-1); |
|
var picked = form.elements[item].options[form.elements[item].selectedIndex].value; |
|
if (Object.prototype.toString.call(parents[count]) === '[object Array]') { |
|
if (parents[count].length > 0) { |
|
for (var j=0; j<parents[count].length; j++) { |
|
containerSelect(form,parents[count][j],offset,picked); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
function containerSelect(form,count,offset,picked) { |
|
if (count > 0) { |
|
var item = (offset+$startcount)+7*(count-1); |
|
if (form.elements[item].type == 'radio') { |
|
if (form.elements[item].value == 'dependency') { |
|
if (form.elements[item+1].type == 'select-one') { |
|
for (var i=0; i<form.elements[item+1].options.length; i++) { |
|
if (form.elements[item+1].options[i].value == picked) { |
|
form.elements[item+1].selectedIndex = i; |
|
break; |
|
} |
|
} |
|
} |
|
if (Object.prototype.toString.call(parents[count]) === '[object Array]') { |
|
if (parents[count].length > 0) { |
|
for (var j=0; j<parents[count].length; j++) { |
|
containerSelect(form,parents[count][j],offset,picked); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
function titleCheck(form,count,offset) { |
|
if (count > 0) { |
|
var chosen = (offset+$startcount)+7*(count-1); |
|
var depitem = $startcount + ((count-1) * 7) + 2; |
|
var currtype = form.elements[depitem].type; |
|
if (form.elements[chosen].value == 'display') { |
|
document.getElementById('arc_title_'+count).style.display='block'; |
|
if ((count==1) && ((parents[count].length > 0) || (numitems == 1))) { |
|
document.getElementById('archive_title_'+count).value=maintitle; |
|
} |
|
} else { |
|
document.getElementById('arc_title_'+count).style.display='none'; |
|
if (currtype == 'text') { |
|
document.getElementById('archive_title_'+count).value=''; |
|
} |
|
} |
|
} |
|
return; |
|
} |
|
|
|
// ]]> |
|
</script> |
|
END |
|
return $scripttag; |
|
} |
|
|
|
sub process_extracted_files { |
|
my ($context,$docudom,$docuname,$destination,$dir_root,$hiddenelem) = @_; |
|
my $numitems = $env{'form.archive_count'}; |
|
return unless ($numitems); |
|
my @ids=&Apache::lonnet::current_machine_ids(); |
|
my ($prefix,$pathtocheck,$dir,$ishome,$error,$warning,%toplevelitems,%is_dir, |
|
%folders,%containers,%mapinner,%prompttofetch); |
|
my $docuhome = &Apache::lonnet::homeserver($docuname,$docudom); |
|
if (grep(/^\Q$docuhome\E$/,@ids)) { |
|
$prefix = &LONCAPA::propath($docudom,$docuname); |
|
$pathtocheck = "$dir_root/$destination"; |
|
$dir = $dir_root; |
|
$ishome = 1; |
|
} else { |
|
$prefix = $Apache::lonnet::perlvar{'lonDocRoot'}; |
|
$pathtocheck = "$dir_root/$docudom/$docuname/$destination"; |
|
$dir = "$dir_root/$docudom/$docuname"; |
|
} |
|
my $currdir = "$dir_root/$destination"; |
|
(my $docstype,$mapinner{'0'}) = ($destination =~ m{^(docs|supplemental)/(\w+)/}); |
|
if ($env{'form.folderpath'}) { |
|
my @items = split('&',$env{'form.folderpath'}); |
|
$folders{'0'} = $items[-2]; |
|
$containers{'0'}='sequence'; |
|
} elsif ($env{'form.pagepath'}) { |
|
my @items = split('&',$env{'form.pagepath'}); |
|
$folders{'0'} = $items[-2]; |
|
$containers{'0'}='page'; |
|
} |
|
my @archdirs = &get_env_multiple('form.archive_directory'); |
|
if ($numitems) { |
|
for (my $i=1; $i<=$numitems; $i++) { |
|
my $path = $env{'form.archive_content_'.$i}; |
|
if ($path =~ m{^\Q$pathtocheck\E/([^/]+)$}) { |
|
my $item = $1; |
|
$toplevelitems{$item} = $i; |
|
if (grep(/^\Q$i\E$/,@archdirs)) { |
|
$is_dir{$item} = 1; |
|
} |
|
} |
|
} |
|
} |
|
my ($output,%children,%parent,%titles,%dirorder,$result); |
|
if (keys(%toplevelitems) > 0) { |
|
my @contents = sort(keys(%toplevelitems)); |
|
(my $count,undef) = &get_extracted($docudom,$docuname,$currdir,\%is_dir,\%children, |
|
\%parent,\@contents,\%dirorder,\%titles); |
|
} |
|
my (%referrer,%orphaned,%todelete,%todeletedir,%newdest,%newseqid); |
|
if ($numitems) { |
|
for (my $i=1; $i<=$numitems; $i++) { |
|
my $path = $env{'form.archive_content_'.$i}; |
|
if ($path =~ /^\Q$pathtocheck\E/) { |
|
if ($env{'form.archive_'.$i} eq 'discard') { |
|
if ($prefix ne '' && $path ne '') { |
|
if (-e $prefix.$path) { |
|
if ((@archdirs > 0) && |
|
(grep(/^\Q$i\E$/,@archdirs))) { |
|
$todeletedir{$prefix.$path} = 1; |
|
} else { |
|
$todelete{$prefix.$path} = 1; |
|
} |
|
} |
|
} |
|
} elsif ($env{'form.archive_'.$i} eq 'display') { |
|
my ($docstitle,$title,$url,$outer); |
|
($title) = ($path =~ m{/([^/]+)$}); |
|
$docstitle = $env{'form.archive_title_'.$i}; |
|
if ($docstitle eq '') { |
|
$docstitle = $title; |
|
} |
|
$outer = 0; |
|
if (ref($dirorder{$i}) eq 'ARRAY') { |
|
if (@{$dirorder{$i}} > 0) { |
|
foreach my $item (reverse(@{$dirorder{$i}})) { |
|
if ($env{'form.archive_'.$item} eq 'display') { |
|
$outer = $item; |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
my ($errtext,$fatal) = |
|
&LONCAPA::map::mapread('/uploaded/'.$docudom.'/'.$docuname. |
|
'/'.$folders{$outer}.'.'. |
|
$containers{$outer}); |
|
next if ($fatal); |
|
if ((@archdirs > 0) && (grep(/^\Q$i\E$/,@archdirs))) { |
|
if ($context eq 'coursedocs') { |
|
$mapinner{$i} = time; |
|
$folders{$i} = 'default_'.$mapinner{$i}; |
|
$containers{$i} = 'sequence'; |
|
my $url = '/uploaded/'.$docudom.'/'.$docuname.'/'. |
|
$folders{$i}.'.'.$containers{$i}; |
|
my $newidx = &LONCAPA::map::getresidx(); |
|
$LONCAPA::map::resources[$newidx]= |
|
$docstitle.':'.$url.':false:normal:res'; |
|
push(@LONCAPA::map::order,$newidx); |
|
my ($outtext,$errtext) = |
|
&LONCAPA::map::storemap('/uploaded/'.$docudom.'/'. |
|
$docuname.'/'.$folders{$outer}. |
|
'.'.$containers{$outer},1); |
|
$newseqid{$i} = $newidx; |
|
unless ($errtext) { |
|
$result .= '<li>'.&mt('Folder: [_1] added to course',$docstitle).'</li>'."\n"; |
|
} |
|
} |
|
} else { |
|
if ($context eq 'coursedocs') { |
|
my $newidx=&LONCAPA::map::getresidx(); |
|
my $url = '/uploaded/'.$docudom.'/'.$docuname.'/'. |
|
$docstype.'/'.$mapinner{$outer}.'/'.$newidx.'/'. |
|
$title; |
|
if (!-e "$prefix$dir/$docstype/$mapinner{$outer}") { |
|
mkdir("$prefix$dir/$docstype/$mapinner{$outer}",0755); |
|
} |
|
if (!-e "$prefix$dir/$docstype/$mapinner{$outer}/$newidx") { |
|
mkdir("$prefix$dir/$docstype/$mapinner{$outer}/$newidx"); |
|
} |
|
if (-e "$prefix$dir/$docstype/$mapinner{$outer}/$newidx") { |
|
system("mv $prefix$path $prefix$dir/$docstype/$mapinner{$outer}/$newidx/$title"); |
|
$newdest{$i} = "$prefix$dir/$docstype/$mapinner{$outer}/$newidx"; |
|
unless ($ishome) { |
|
my $fetch = "$newdest{$i}/$title"; |
|
$fetch =~ s/^\Q$prefix$dir\E//; |
|
$prompttofetch{$fetch} = 1; |
|
} |
|
} |
|
$LONCAPA::map::resources[$newidx]= |
|
$docstitle.':'.$url.':false:normal:res'; |
|
push(@LONCAPA::map::order, $newidx); |
|
my ($outtext,$errtext)= |
|
&LONCAPA::map::storemap('/uploaded/'.$docudom.'/'. |
|
$docuname.'/'.$folders{$outer}. |
|
'.'.$containers{$outer},1); |
|
unless ($errtext) { |
|
if (-e "$prefix$dir/$docstype/$mapinner{$outer}/$newidx/$title") { |
|
$result .= '<li>'.&mt('File: [_1] added to course',$docstitle).'</li>'."\n"; |
|
} |
|
} |
|
} |
|
} |
|
} elsif ($env{'form.archive_'.$i} eq 'dependency') { |
|
my ($title) = ($path =~ m{/([^/]+)$}); |
|
$referrer{$i} = $env{'form.archive_dependent_on_'.$i}; |
|
if ($env{'form.archive_'.$referrer{$i}} eq 'display') { |
|
if (ref($dirorder{$i}) eq 'ARRAY') { |
|
my ($itemidx,$fullpath,$relpath); |
|
for (my $j=0; $j<@{$dirorder{$i}}; $j++) { |
|
if (ref($dirorder{$referrer{$i}}) eq 'ARRAY') { |
|
my $container = $dirorder{$referrer{$i}}->[-1]; |
|
for (my $j=0; $j<@{$dirorder{$i}}; $j++) { |
|
if ($dirorder{$i}->[$j] eq $container) { |
|
$itemidx = $j; |
|
} |
|
} |
|
} |
|
} |
|
if ($itemidx ne '') { |
|
if (grep(/^\Q$referrer{$i}\E$/,@archdirs)) { |
|
if ($mapinner{$referrer{$i}}) { |
|
$fullpath = "$prefix$dir/$docstype/$mapinner{$referrer{$i}}"; |
|
for (my $j=$itemidx; $j<@{$dirorder{$i}}; $j++) { |
|
if (grep(/^\Q$dirorder{$i}->[$j]\E$/,@archdirs)) { |
|
unless (defined($newseqid{$dirorder{$i}->[$j]})) { |
|
$fullpath .= '/'.$titles{$dirorder{$i}->[$j]}; |
|
$relpath .= '/'.$titles{$dirorder{$i}->[$j]}; |
|
if (!-e $fullpath) { |
|
mkdir($fullpath,0755); |
|
} |
|
} |
|
} else { |
|
last; |
|
} |
|
} |
|
} |
|
} elsif ($newdest{$referrer{$i}}) { |
|
$fullpath = $newdest{$referrer{$i}}; |
|
for (my $j=$itemidx; $j<@{$dirorder{$i}}; $j++) { |
|
if ($env{'form.archive_'.$dirorder{$i}->[$j]} eq 'discard') { |
|
$orphaned{$i} = $env{'form.archive_'.$dirorder{$i}->[$j]}; |
|
last; |
|
} elsif (grep(/^\Q$dirorder{$i}->[$j]\E$/,@archdirs)) { |
|
unless (defined($newseqid{$dirorder{$i}->[$j]})) { |
|
$fullpath .= '/'.$titles{$dirorder{$i}->[$j]}; |
|
$relpath .= '/'.$titles{$dirorder{$i}->[$j]}; |
|
if (!-e $fullpath) { |
|
mkdir($fullpath,0755); |
|
} |
|
} |
|
} else { |
|
last; |
|
} |
|
} |
|
} |
|
if ($fullpath ne '') { |
|
if (-e "$prefix$path") { |
|
system("mv $prefix$path $fullpath/$title"); |
|
} |
|
if (-e "$fullpath/$title") { |
|
my $showpath; |
|
if ($relpath ne '') { |
|
$showpath = "$relpath/$title"; |
|
} else { |
|
$showpath = "/$title"; |
|
} |
|
$result .= '<li>'.&mt('[_1] included as a dependency',$showpath).'</li>'."\n"; |
|
} |
|
unless ($ishome) { |
|
my $fetch = "$fullpath/$title"; |
|
$fetch =~ s/^\Q$prefix$dir\E//; |
|
$prompttofetch{$fetch} = 1; |
|
} |
|
} |
|
} |
|
} |
|
} elsif ($env{'form.archive_'.$referrer{$i}} eq 'discard') { |
|
$warning .= &mt('[_1] is a dependency of [_2], which was discarded.', |
|
$path,$env{'form.archive_content_'.$referrer{$i}}).'<br />'; |
|
} |
|
} |
|
} else { |
|
$warning .= &mt('Item extracted from archive: [_1] has unexpected path.',$path).'<br />'; |
|
} |
|
} |
|
if (keys(%todelete)) { |
|
foreach my $key (keys(%todelete)) { |
|
unlink($key); |
|
} |
|
} |
|
if (keys(%todeletedir)) { |
|
foreach my $key (keys(%todeletedir)) { |
|
rmdir($key); |
|
} |
|
} |
|
foreach my $dir (sort(keys(%is_dir))) { |
|
if (($pathtocheck ne '') && ($dir ne '')) { |
|
&cleanup_empty_dirs($prefix."$pathtocheck/$dir"); |
|
} |
|
} |
|
if ($result ne '') { |
|
$output .= '<ul>'."\n". |
|
$result."\n". |
|
'</ul>'; |
|
} |
|
unless ($ishome) { |
|
my $replicationfail; |
|
foreach my $item (keys(%prompttofetch)) { |
|
my $fetchresult= &Apache::lonnet::reply('fetchuserfile:'.$item,$docuhome); |
|
unless ($fetchresult eq 'ok') { |
|
$replicationfail .= '<li>'.$item.'</li>'."\n"; |
|
} |
|
} |
|
if ($replicationfail) { |
|
$output .= '<p class="LC_error">'. |
|
&mt('Course home server failed to retrieve:').'<ul>'. |
|
$replicationfail. |
|
'</ul></p>'; |
|
} |
|
} |
|
} else { |
|
$warning = &mt('No items found in archive.'); |
|
} |
|
if ($error) { |
|
$output .= '<p class="LC_error">'.&mt('Not extracted.').'<br />'. |
|
$error.'</p>'."\n"; |
|
} |
|
if ($warning) { |
|
$output .= '<p class="LC_warning">'.$warning.'</p>'."\n"; |
|
} |
|
return $output; |
|
} |
|
|
|
sub cleanup_empty_dirs { |
|
my ($path) = @_; |
|
if (($path ne '') && (-d $path)) { |
|
if (opendir(my $dirh,$path)) { |
|
my @dircontents = grep(!/^\./,readdir($dirh)); |
|
my $numitems = 0; |
|
foreach my $item (@dircontents) { |
|
if (-d "$path/$item") { |
|
&recurse_dirs("$path/$item"); |
|
if (-e "$path/$item") { |
|
$numitems ++; |
|
} |
|
} else { |
|
$numitems ++; |
|
} |
|
} |
|
if ($numitems == 0) { |
|
rmdir($path); |
|
} |
|
closedir($dirh); |
|
} |
|
} |
|
return; |
|
} |
|
|
|
=pod |
|
|
|
=item &get_folder_hierarchy() |
|
|
|
Provides hierarchy of names of folders/sub-folders containing the current |
|
item, |
|
|
|
Inputs: 3 |
|
- $navmap - navmaps object |
|
|
|
- $map - url for map (either the trigger itself, or map containing |
|
the resource, which is the trigger). |
|
|
|
- $showitem - 1 => show title for map itself; 0 => do not show. |
|
|
|
Outputs: 1 @pathitems - array of folder/subfolder names. |
|
|
|
=cut |
|
|
|
sub get_folder_hierarchy { |
|
my ($navmap,$map,$showitem) = @_; |
|
my @pathitems; |
|
if (ref($navmap)) { |
|
my $mapres = $navmap->getResourceByUrl($map); |
|
if (ref($mapres)) { |
|
my $pcslist = $mapres->map_hierarchy(); |
|
if ($pcslist ne '') { |
|
my @pcs = split(/,/,$pcslist); |
|
foreach my $pc (@pcs) { |
|
if ($pc == 1) { |
|
push(@pathitems,&mt('Main Course Documents')); |
|
} else { |
|
my $res = $navmap->getByMapPc($pc); |
|
if (ref($res)) { |
|
my $title = $res->compTitle(); |
|
$title =~ s/\W+/_/g; |
|
if ($title ne '') { |
|
push(@pathitems,$title); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if ($showitem) { |
|
if ($mapres->{ID} eq '0.0') { |
|
push(@pathitems,&mt('Main Course Documents')); |
|
} else { |
|
my $maptitle = $mapres->compTitle(); |
|
$maptitle =~ s/\W+/_/g; |
|
if ($maptitle ne '') { |
|
push(@pathitems,$maptitle); |
|
} |
|
} |
|
} |
|
} |
|
return @pathitems; |
|
} |
|
|
=pod |
=pod |
|
|
=item * &get_turnedin_filepath() |
=item * &get_turnedin_filepath() |
Line 11485 sub init_user_environment {
|
Line 13218 sub init_user_environment {
|
|
|
# See if old ID present, if so, remove |
# See if old ID present, if so, remove |
|
|
my ($filename,$cookie,$userroles); |
my ($filename,$cookie,$userroles,$firstaccenv,$timerintenv); |
my $now=time; |
my $now=time; |
|
|
if ($public) { |
if ($public) { |
Line 11523 sub init_user_environment {
|
Line 13256 sub init_user_environment {
|
|
|
# Initialize roles |
# Initialize roles |
|
|
$userroles=&Apache::lonnet::rolesinit($domain,$username,$authhost); |
($userroles,$firstaccenv,$timerintenv) = |
|
&Apache::lonnet::rolesinit($domain,$username,$authhost); |
} |
} |
# ------------------------------------ Check browser type and MathML capability |
# ------------------------------------ Check browser type and MathML capability |
|
|
Line 11598 sub init_user_environment {
|
Line 13332 sub init_user_environment {
|
} |
} |
|
|
$env{'user.environment'} = "$lonids/$cookie.id"; |
$env{'user.environment'} = "$lonids/$cookie.id"; |
|
|
if (tie(my %disk_env,'GDBM_File',"$lonids/$cookie.id", |
if (tie(my %disk_env,'GDBM_File',"$lonids/$cookie.id", |
&GDBM_WRCREAT(),0640)) { |
&GDBM_WRCREAT(),0640)) { |
&_add_to_env(\%disk_env,\%initial_env); |
&_add_to_env(\%disk_env,\%initial_env); |
&_add_to_env(\%disk_env,\%userenv,'environment.'); |
&_add_to_env(\%disk_env,\%userenv,'environment.'); |
&_add_to_env(\%disk_env,$userroles); |
&_add_to_env(\%disk_env,$userroles); |
|
if (ref($firstaccenv) eq 'HASH') { |
|
&_add_to_env(\%disk_env,$firstaccenv); |
|
} |
|
if (ref($timerintenv) eq 'HASH') { |
|
&_add_to_env(\%disk_env,$timerintenv); |
|
} |
if (ref($args->{'extra_env'})) { |
if (ref($args->{'extra_env'})) { |
&_add_to_env(\%disk_env,$args->{'extra_env'}); |
&_add_to_env(\%disk_env,$args->{'extra_env'}); |
} |
} |