version 1.1140, 2013/07/15 17:42:11
|
version 1.1187, 2014/04/25 17:56:43
|
Line 69 use Apache::lontexconvert();
|
Line 69 use Apache::lontexconvert();
|
use Apache::lonclonecourse(); |
use Apache::lonclonecourse(); |
use Apache::lonuserutils(); |
use Apache::lonuserutils(); |
use Apache::lonuserstate(); |
use Apache::lonuserstate(); |
|
use Apache::courseclassifier(); |
use LONCAPA qw(:DEFAULT :match); |
use LONCAPA qw(:DEFAULT :match); |
use DateTime::TimeZone; |
use DateTime::TimeZone; |
use DateTime::Locale::Catalog; |
use DateTime::Locale::Catalog; |
use Text::Aspell; |
use Text::Aspell; |
use Authen::Captcha; |
use Authen::Captcha; |
use Captcha::reCAPTCHA; |
use Captcha::reCAPTCHA; |
|
use Crypt::DES; |
|
use DynaLoader; # for Crypt::DES version |
|
|
# ---------------------------------------------- Designs |
# ---------------------------------------------- Designs |
use vars qw(%defaultdesign); |
use vars qw(%defaultdesign); |
Line 1313 sub helpLatexCheatsheet {
|
Line 1316 sub helpLatexCheatsheet {
|
.&help_open_topic('Other_Symbols',&mt('Other Symbols'),$stayOnPage,undef,600) |
.&help_open_topic('Other_Symbols',&mt('Other Symbols'),$stayOnPage,undef,600) |
.'</span>'; |
.'</span>'; |
unless ($not_author) { |
unless ($not_author) { |
$out .= ' <span>' |
$out .= '<span>' |
.&help_open_topic('Authoring_Output_Tags',&mt('Output Tags'),$stayOnPage,undef,600) |
.&help_open_topic('Authoring_Output_Tags',&mt('Output Tags'),$stayOnPage,undef,600) |
|
.'</span> <span>' |
|
.&help_open_topic('Authoring_Multilingual_Problems',&mt('How to create problems in different languages'),$stayOnPage,undef,600) |
.'</span>'; |
.'</span>'; |
} |
} |
$out .= '</span>'; # End cheatsheet |
$out .= '</span>'; # End cheatsheet |
Line 1380 sub top_nav_help {
|
Line 1385 sub top_nav_help {
|
$text = &mt($text); |
$text = &mt($text); |
my $stay_on_page = 1; |
my $stay_on_page = 1; |
|
|
my $link = ($stay_on_page) ? "javascript:helpMenu('display')" |
my ($link,$banner_link); |
: "javascript:helpMenu('open')"; |
unless ($env{'request.noversionuri'} =~ m{^/adm/helpmenu}) { |
my $banner_link = &update_help_link(undef,undef,undef,undef,$stay_on_page); |
$link = ($stay_on_page) ? "javascript:helpMenu('display')" |
|
: "javascript:helpMenu('open')"; |
|
$banner_link = &update_help_link(undef,undef,undef,undef,$stay_on_page); |
|
} |
my $title = &mt('Get help'); |
my $title = &mt('Get help'); |
|
if ($link) { |
return <<"END"; |
return <<"END"; |
$banner_link |
$banner_link |
<a href="$link" title="$title">$text</a> |
<a href="$link" title="$title">$text</a> |
END |
END |
|
} else { |
|
return ' '.$text.' '; |
|
} |
} |
} |
|
|
sub help_menu_js { |
sub help_menu_js { |
my ($text) = @_; |
my ($httphost) = @_; |
my $stayOnPage = 1; |
my $stayOnPage = 1; |
my $width = 620; |
my $width = 620; |
my $height = 600; |
my $height = 600; |
my $helptopic=&general_help(); |
my $helptopic=&general_help(); |
my $details_link = '/adm/help/'.$helptopic.'.hlp'; |
my $details_link = $httphost.'/adm/help/'.$helptopic.'.hlp'; |
my $nothing=&Apache::lonhtmlcommon::javascript_nothing(); |
my $nothing=&Apache::lonhtmlcommon::javascript_nothing(); |
my $start_page = |
my $start_page = |
&Apache::loncommon::start_page('Help Menu', undef, |
&Apache::loncommon::start_page('Help Menu', undef, |
{'frameset' => 1, |
{'frameset' => 1, |
'js_ready' => 1, |
'js_ready' => 1, |
|
'use_absolute' => $httphost, |
'add_entries' => { |
'add_entries' => { |
'border' => '0', |
'border' => '0', |
'rows' => "110,*",},}); |
'rows' => "110,*",},}); |
my $end_page = |
my $end_page = |
&Apache::loncommon::end_page({'frameset' => 1, |
&Apache::loncommon::end_page({'frameset' => 1, |
Line 1435 function helpMenu(target) {
|
Line 1446 function helpMenu(target) {
|
return; |
return; |
} |
} |
function writeHelp(caller) { |
function writeHelp(caller) { |
caller.document.writeln('$start_page\\n<frame name="bannerframe" src="'+banner_link+'" />\\n<frame name="bodyframe" src="$details_link" />\\n$end_page') |
caller.document.writeln('$start_page\\n<frame name="bannerframe" src="'+banner_link+'" marginwidth="0" marginheight="0" frameborder="0">\\n'); |
caller.document.close() |
caller.document.writeln('<frame name="bodyframe" src="$details_link" marginwidth="0" marginheight="0" frameborder="0">\\n$end_page'); |
caller.focus() |
caller.document.close(); |
|
caller.focus(); |
} |
} |
// END LON-CAPA Internal --> |
// END LON-CAPA Internal --> |
// ]]> |
// ]]> |
Line 1749 RESIZE
|
Line 1761 RESIZE
|
|
|
=head1 Excel and CSV file utility routines |
=head1 Excel and CSV file utility routines |
|
|
=over 4 |
|
|
|
=cut |
=cut |
|
|
############################################################### |
############################################################### |
Line 1758 RESIZE
|
Line 1768 RESIZE
|
|
|
=pod |
=pod |
|
|
|
=over 4 |
|
|
=item * &csv_translate($text) |
=item * &csv_translate($text) |
|
|
Translate $text to allow it to be output as a 'comma separated values' |
Translate $text to allow it to be output as a 'comma separated values' |
Line 2351 Outputs:
|
Line 2363 Outputs:
|
|
|
=item * $clientmobile |
=item * $clientmobile |
|
|
|
=item * $clientinfo |
|
|
=back |
=back |
|
|
=back |
=back |
Line 2381 sub decode_user_agent {
|
Line 2395 sub decode_user_agent {
|
} |
} |
} |
} |
my $clientos='unknown'; |
my $clientos='unknown'; |
|
my $clientinfo; |
if (($httpbrowser=~/linux/i) || |
if (($httpbrowser=~/linux/i) || |
($httpbrowser=~/unix/i) || |
($httpbrowser=~/unix/i) || |
($httpbrowser=~/ux/i) || |
($httpbrowser=~/ux/i) || |
Line 2395 sub decode_user_agent {
|
Line 2410 sub decode_user_agent {
|
if ($httpbrowser=~/(Android|iPod|iPad|iPhone|webOS|Blackberry|Windows Phone|Opera m(?:ob|in)|Fennec)/i) { |
if ($httpbrowser=~/(Android|iPod|iPad|iPhone|webOS|Blackberry|Windows Phone|Opera m(?:ob|in)|Fennec)/i) { |
$clientmobile=lc($1); |
$clientmobile=lc($1); |
} |
} |
|
if ($httpbrowser=~ m{Firefox/(\d+\.\d+)}) { |
|
$clientinfo = 'firefox-'.$1; |
|
} elsif ($httpbrowser=~ m{chromeframe/(\d+\.\d+)\.}) { |
|
$clientinfo = 'chromeframe-'.$1; |
|
} |
return ($httpbrowser,$clientbrowser,$clientversion,$clientmathml, |
return ($httpbrowser,$clientbrowser,$clientversion,$clientmathml, |
$clientunicode,$clientos,$clientmobile); |
$clientunicode,$clientos,$clientmobile,$clientinfo); |
} |
} |
|
|
############################################################### |
############################################################### |
Line 3066 sub get_related_words {
|
Line 3086 sub get_related_words {
|
|
|
=pod |
=pod |
|
|
|
=back |
|
|
=head1 Spell checking |
=head1 Spell checking |
|
|
=over 4 |
=over 4 |
Line 3099 Note: This sub assumes that aspell is in
|
Line 3121 Note: This sub assumes that aspell is in
|
=cut |
=cut |
|
|
|
|
=pod |
|
|
|
=back |
|
|
|
=cut |
|
|
|
sub check_spelling { |
sub check_spelling { |
my ($wordlist, $language) = @_; |
my ($wordlist, $language) = @_; |
my @misspellings; |
my @misspellings; |
Line 3320 sub screenname {
|
Line 3336 sub screenname {
|
# ------------------------------------------------------------- Confirm Wrapper |
# ------------------------------------------------------------- Confirm Wrapper |
=pod |
=pod |
|
|
=item confirmwrapper |
=item * &confirmwrapper($message) |
|
|
Wrap messages about completion of operation in box |
Wrap messages about completion of operation in box |
|
|
Line 3879 sub get_previous_attempt {
|
Line 3895 sub get_previous_attempt {
|
if ($key =~/$regexp$/ && (defined &$gradesub)) { |
if ($key =~/$regexp$/ && (defined &$gradesub)) { |
$value = &$gradesub($value); |
$value = &$gradesub($value); |
} |
} |
$prevattempts.='<td>'.$value.' </td>'; |
$prevattempts.='<td>'. $value.' </td>'; |
} else { |
} else { |
$prevattempts.='<td> </td>'; |
$prevattempts.='<td> </td>'; |
} |
} |
Line 3895 sub get_previous_attempt {
|
Line 3911 sub get_previous_attempt {
|
if ($key =~/$regexp$/ && (defined &$gradesub)) { |
if ($key =~/$regexp$/ && (defined &$gradesub)) { |
$value = &$gradesub($value); |
$value = &$gradesub($value); |
} |
} |
$prevattempts.='<td>'.$value.' </td>'; |
$prevattempts.='<td>'.$value.' </td>'; |
} |
} |
} |
} |
$prevattempts.= &end_data_table_row().&end_data_table(); |
$prevattempts.= &end_data_table_row().&end_data_table(); |
Line 3916 sub get_previous_attempt {
|
Line 3932 sub get_previous_attempt {
|
sub format_previous_attempt_value { |
sub format_previous_attempt_value { |
my ($key,$value) = @_; |
my ($key,$value) = @_; |
if (($key =~ /timestamp/) || ($key=~/duedate/)) { |
if (($key =~ /timestamp/) || ($key=~/duedate/)) { |
$value = &Apache::lonlocal::locallocaltime($value); |
$value = &Apache::lonlocal::locallocaltime($value); |
} elsif (ref($value) eq 'ARRAY') { |
} elsif (ref($value) eq 'ARRAY') { |
$value = '('.join(', ', @{ $value }).')'; |
$value = &HTML::Entities::encode('('.join(', ', @{ $value }).')','"<>&'); |
} elsif ($key =~ /answerstring$/) { |
} elsif ($key =~ /answerstring$/) { |
my %answers = &Apache::lonnet::str2hash($value); |
my %answers = &Apache::lonnet::str2hash($value); |
|
my @answer = %answers; |
|
%answers = map {&HTML::Entities::encode($_, '"<>&')} @answer; |
my @anskeys = sort(keys(%answers)); |
my @anskeys = sort(keys(%answers)); |
if (@anskeys == 1) { |
if (@anskeys == 1) { |
my $answer = $answers{$anskeys[0]}; |
my $answer = $answers{$anskeys[0]}; |
Line 3943 sub format_previous_attempt_value {
|
Line 3961 sub format_previous_attempt_value {
|
} |
} |
} |
} |
} else { |
} else { |
$value = &unescape($value); |
$value = &HTML::Entities::encode(&unescape($value), '"<>&'); |
} |
} |
return $value; |
return $value; |
} |
} |
Line 5120 sub bodytag {
|
Line 5138 sub bodytag {
|
$public = 1; |
$public = 1; |
} |
} |
if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); } |
if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); } |
|
my $httphost = $args->{'use_absolute'}; |
|
|
$function = &get_users_function() if (!$function); |
$function = &get_users_function() if (!$function); |
my $img = &designparm($function.'.img',$domain); |
my $img = &designparm($function.'.img',$domain); |
Line 5135 sub bodytag {
|
Line 5154 sub bodytag {
|
@design{keys(%$addentries)} = @$addentries{keys(%$addentries)}; |
@design{keys(%$addentries)} = @$addentries{keys(%$addentries)}; |
|
|
# role and realm |
# role and realm |
my ($role,$realm) = split(/\./,$env{'request.role'},2); |
my ($role,$realm) = split(m{\./},$env{'request.role'},2); |
|
if ($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); |
Line 5192 sub bodytag {
|
Line 5214 sub bodytag {
|
# } |
# } |
|
|
$bodytag .= Apache::lonhtmlcommon::scripttag( |
$bodytag .= Apache::lonhtmlcommon::scripttag( |
Apache::lonmenu::utilityfunctions(), 'start'); |
Apache::lonmenu::utilityfunctions($httphost), 'start'); |
|
|
my ($left,$right) = Apache::lonmenu::primary_menu(); |
my ($left,$right) = Apache::lonmenu::primary_menu(); |
|
|
Line 5216 sub bodytag {
|
Line 5238 sub bodytag {
|
} |
} |
$bodytag .= qq|<div id="LC_realm">$realm $dc_info</div>|; |
$bodytag .= qq|<div id="LC_realm">$realm $dc_info</div>|; |
|
|
|
#if directed to not display the secondary menu, don't. |
|
if ($args->{'no_secondary_menu'}) { |
|
return $bodytag; |
|
} |
#don't show menus for public users |
#don't show menus for public users |
if (!$public){ |
if (!$public){ |
$bodytag .= Apache::lonmenu::secondary_menu(); |
$bodytag .= Apache::lonmenu::secondary_menu($httphost); |
$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') { |
Line 5278 sub make_attr_string {
|
Line 5304 sub make_attr_string {
|
} |
} |
|
|
my $attr_string; |
my $attr_string; |
foreach my $attr (keys(%$attr_ref)) { |
foreach my $attr (sort(keys(%$attr_ref))) { |
$attr_string .= " $attr=\"".$attr_ref->{$attr}.'" '; |
$attr_string .= " $attr=\"".$attr_ref->{$attr}.'" '; |
} |
} |
return $attr_string; |
return $attr_string; |
Line 6492 div.LC_edit_problem_saves {
|
Line 6518 div.LC_edit_problem_saves {
|
white-space: nowrap; |
white-space: nowrap; |
} |
} |
|
|
|
.LC_edit_problem_latexhelper{ |
|
text-align: right; |
|
} |
|
|
|
#LC_edit_problem_colorful div{ |
|
margin-left: 40px; |
|
} |
|
|
img.stift { |
img.stift { |
border-width: 0; |
border-width: 0; |
vertical-align: middle; |
vertical-align: middle; |
Line 7257 sub headtag {
|
Line 7291 sub headtag {
|
my $function = $args->{'function'} || &get_users_function(); |
my $function = $args->{'function'} || &get_users_function(); |
my $domain = $args->{'domain'} || &determinedomain(); |
my $domain = $args->{'domain'} || &determinedomain(); |
my $bgcolor = $args->{'bgcolor'} || &designparm($function.'.pgbg',$domain); |
my $bgcolor = $args->{'bgcolor'} || &designparm($function.'.pgbg',$domain); |
|
my $httphost = $args->{'use_absolute'}; |
my $url = join(':',$env{'user.name'},$env{'user.domain'}, |
my $url = join(':',$env{'user.name'},$env{'user.domain'}, |
$Apache::lonnet::perlvar{'lonVersion'}, |
$Apache::lonnet::perlvar{'lonVersion'}, |
#time(), |
#time(), |
Line 7267 sub headtag {
|
Line 7302 sub headtag {
|
|
|
my $result = |
my $result = |
'<head>'. |
'<head>'. |
&font_settings(); |
&font_settings($args); |
|
|
my $inhibitprint = &print_suppression(); |
my $inhibitprint = &print_suppression(); |
|
|
Line 7280 sub headtag {
|
Line 7315 sub headtag {
|
if (!$args->{'no_nav_bar'} |
if (!$args->{'no_nav_bar'} |
&& !$args->{'only_body'} |
&& !$args->{'only_body'} |
&& !$args->{'frameset'}) { |
&& !$args->{'frameset'}) { |
$result .= &help_menu_js(); |
$result .= &help_menu_js($httphost); |
$result.=&modal_window(); |
$result.=&modal_window(); |
$result.=&togglebox_script(); |
$result.=&togglebox_script(); |
$result.=&wishlist_window(); |
$result.=&wishlist_window(); |
Line 7315 ADDMETA
|
Line 7350 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.'"'; |
|
if (!$args->{'frameset'}) { |
|
$result .= ' /'; |
|
} |
|
$result .= '>' |
.$inhibitprint |
.$inhibitprint |
.$head_extra; |
.$head_extra; |
if ($env{'browser.mobile'}) { |
if ($env{'browser.mobile'}) { |
Line 7332 ADDMETA
|
Line 7371 ADDMETA
|
|
|
Returns neccessary <meta> to set the proper encoding |
Returns neccessary <meta> to set the proper encoding |
|
|
Inputs: none |
Inputs: optional reference to HASH -- $args passed to &headtag() |
|
|
=cut |
=cut |
|
|
sub font_settings { |
sub font_settings { |
|
my ($args) = @_; |
my $headerstring=''; |
my $headerstring=''; |
if (!$env{'browser.mathml'} && $env{'browser.unicode'}) { |
if ((!$env{'browser.mathml'} && $env{'browser.unicode'}) || |
$headerstring.= |
((ref($args) eq 'HASH') && ($args->{'browser.unicode'}))) { |
'<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'; |
$headerstring.= |
|
'<meta http-equiv="Content-Type" content="text/html; charset=utf-8"'; |
|
if (!$args->{'frameset'}) { |
|
$headerstring.= ' /'; |
|
} |
|
$headerstring .= '>'."\n"; |
} |
} |
return $headerstring; |
return $headerstring; |
} |
} |
Line 7432 Inputs: none
|
Line 7477 Inputs: none
|
=cut |
=cut |
|
|
sub xml_begin { |
sub xml_begin { |
|
my ($is_frameset) = @_; |
my $output=''; |
my $output=''; |
|
|
if ($env{'browser.mathml'}) { |
if ($env{'browser.mathml'}) { |
Line 7443 sub xml_begin {
|
Line 7489 sub xml_begin {
|
.'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">' |
.'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">' |
.'<html xmlns:math="http://www.w3.org/1998/Math/MathML" ' |
.'<html xmlns:math="http://www.w3.org/1998/Math/MathML" ' |
.'xmlns="http://www.w3.org/1999/xhtml">'; |
.'xmlns="http://www.w3.org/1999/xhtml">'; |
|
} elsif ($is_frameset) { |
|
$output='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'."\n". |
|
'<html>'."\n"; |
} else { |
} else { |
$output='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' |
$output='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'."\n". |
.'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'; |
'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'."\n"; |
} |
} |
return $output; |
return $output; |
} |
} |
Line 7512 sub start_page {
|
Line 7561 sub start_page {
|
my ($result,@advtools); |
my ($result,@advtools); |
|
|
if (! exists($args->{'skip_phases'}{'head'}) ) { |
if (! exists($args->{'skip_phases'}{'head'}) ) { |
$result .= &xml_begin() . &headtag($title, $head_extra, $args); |
$result .= &xml_begin($args->{'frameset'}) . &headtag($title, $head_extra, $args); |
} |
} |
|
|
if (! exists($args->{'skip_phases'}{'body'}) ) { |
if (! exists($args->{'skip_phases'}{'body'}) ) { |
Line 7613 function set_wishlistlink(title, path) {
|
Line 7662 function set_wishlistlink(title, path) {
|
title = document.title; |
title = document.title; |
title = title.replace(/^LON-CAPA /,''); |
title = title.replace(/^LON-CAPA /,''); |
} |
} |
|
title = encodeURIComponent(title); |
if (!path) { |
if (!path) { |
path = location.pathname; |
path = location.pathname; |
} |
} |
|
path = encodeURIComponent(path); |
Win = window.open('/adm/wishlist?mode=newLink&setTitle='+title+'&setPath='+path, |
Win = window.open('/adm/wishlist?mode=newLink&setTitle='+title+'&setPath='+path, |
'wishlistNewLink','width=560,height=350,scrollbars=0'); |
'wishlistNewLink','width=560,height=350,scrollbars=0'); |
} |
} |
Line 8040 function expand_div(caller) {
|
Line 8091 function expand_div(caller) {
|
} |
} |
|
|
sub simple_error_page { |
sub simple_error_page { |
my ($r,$title,$msg) = @_; |
my ($r,$title,$msg,$args) = @_; |
|
if (ref($args) eq 'HASH') { |
|
if (!$args->{'no_auto_mt_msg'}) { $msg = &mt($msg); } |
|
} else { |
|
$msg = &mt($msg); |
|
} |
|
|
my $page = |
my $page = |
&Apache::loncommon::start_page($title). |
&Apache::loncommon::start_page($title). |
'<p class="LC_error">'.&mt($msg).'</p>'. |
'<p class="LC_error">'.$msg.'</p>'. |
&Apache::loncommon::end_page(); |
&Apache::loncommon::end_page(); |
if (ref($r)) { |
if (ref($r)) { |
$r->print($page); |
$r->print($page); |
Line 8670 Incoming parameters:
|
Line 8727 Incoming parameters:
|
2. user's domain |
2. user's domain |
3. quota name - portfolio, author, or course |
3. quota name - portfolio, author, or course |
(if no quota name provided, defaults to portfolio). |
(if no quota name provided, defaults to portfolio). |
4. crstype - official, unofficial or community, if quota name is |
4. crstype - official, unofficial, textbook or community, if quota name is |
course |
course |
|
|
Returns: |
Returns: |
1. Disk quota (in Mb) assigned to student. |
1. Disk quota (in MB) assigned to student. |
2. (Optional) Type of setting: custom or default |
2. (Optional) Type of setting: custom or default |
(individually assigned or default for user's |
(individually assigned or default for user's |
institutional status). |
institutional status). |
Line 8744 sub get_user_quota {
|
Line 8801 sub get_user_quota {
|
if ($quota eq '' || wantarray) { |
if ($quota eq '' || wantarray) { |
if ($quotaname eq 'course') { |
if ($quotaname eq 'course') { |
my %domdefs = &Apache::lonnet::get_domain_defaults($udom); |
my %domdefs = &Apache::lonnet::get_domain_defaults($udom); |
if (($crstype eq 'official') || ($crstype eq 'unofficial') || ($crstype eq 'community')) { |
if (($crstype eq 'official') || ($crstype eq 'unofficial') || |
|
($crstype eq 'community') || ($crstype eq 'textbook')) { |
$defquota = $domdefs{$crstype.'quota'}; |
$defquota = $domdefs{$crstype.'quota'}; |
} |
} |
if ($defquota eq '') { |
if ($defquota eq '') { |
Line 8778 Retrieves default quota assigned for sto
|
Line 8836 Retrieves default quota assigned for sto
|
given an (optional) user's institutional status. |
given an (optional) user's institutional status. |
|
|
Incoming parameters: |
Incoming parameters: |
|
|
1. domain |
1. domain |
2. (Optional) institutional status(es). This is a : separated list of |
2. (Optional) institutional status(es). This is a : separated list of |
status types (e.g., faculty, staff, student etc.) |
status types (e.g., faculty, staff, student etc.) |
Line 8788 Incoming parameters:
|
Line 8847 Incoming parameters:
|
(if no quota name provided, defaults to portfolio). |
(if no quota name provided, defaults to portfolio). |
|
|
Returns: |
Returns: |
1. Default disk quota (in Mb) for user portfolios in the domain. |
|
|
1. Default disk quota (in MB) for user portfolios in the domain. |
2. (Optional) institutional type which determined the value of the |
2. (Optional) institutional type which determined the value of the |
default quota. |
default quota. |
|
|
If a value has been stored in the domain's configuration db, |
If a value has been stored in the domain's configuration db, |
it will return that, otherwise it returns 20 (for backwards |
it will return that, otherwise it returns 20 (for backwards |
compatibility with domains which have not set up a configuration |
compatibility with domains which have not set up a configuration |
db file; the original statically defined portfolio quota was 20 Mb). |
db file; the original statically defined portfolio quota was 20 MB). |
|
|
If the user's status includes multiple types (e.g., staff and student), |
If the user's status includes multiple types (e.g., staff and student), |
the largest default quota which applies to the user determines the |
the largest default quota which applies to the user determines the |
default quota returned. |
default quota returned. |
|
|
=back |
|
|
|
=cut |
=cut |
|
|
############################################### |
############################################### |
Line 8880 sub default_quota {
|
Line 8938 sub default_quota {
|
|
|
Returns warning message if upload of file to authoring space, or copying |
Returns warning message if upload of file to authoring space, or copying |
of existing file within authoring space will cause quota for the authoring |
of existing file within authoring space will cause quota for the authoring |
space to be exceeded, |
space to be exceeded. |
|
|
Same, if upload of a file directly to a course/community via Course Editor |
Same, if upload of a file directly to a course/community via Course Editor |
will cause quota for uploaded content for the course to be exceeded. |
will cause quota for uploaded content for the course to be exceeded. |
|
|
Inputs: 6 |
Inputs: 7 |
1. username or coursenum |
1. username or coursenum |
2. domain |
2. domain |
3. context ('author' or 'course') |
3. context ('author' or 'course') |
4. filename of file for which action is being requested |
4. filename of file for which action is being requested |
5. filesize (kB) of file |
5. filesize (kB) of file |
6. action being taken: copy or upload. |
6. action being taken: copy or upload. |
|
7. quotatype (in course context -- official, unofficial, community or textbook). |
|
|
Returns: 1 scalar: HTML to display containing warning if quota would be exceeded, |
Returns: 1 scalar: HTML to display containing warning if quota would be exceeded, |
otherwise return null. |
otherwise return null. |
|
|
|
=back |
|
|
=cut |
=cut |
|
|
sub excess_filesize_warning { |
sub excess_filesize_warning { |
my ($uname,$udom,$context,$filename,$filesize,$action) = @_; |
my ($uname,$udom,$context,$filename,$filesize,$action,$quotatype) = @_; |
my $current_disk_usage = 0; |
my $current_disk_usage = 0; |
my $disk_quota = &get_user_quota($uname,$udom,$context); #expressed in MB |
my $disk_quota = &get_user_quota($uname,$udom,$context,$quotatype); #expressed in MB |
if ($context eq 'author') { |
if ($context eq 'author') { |
my $authorspace = $Apache::lonnet::perlvar{'lonDocRoot'}."/priv/$udom/$uname"; |
my $authorspace = $Apache::lonnet::perlvar{'lonDocRoot'}."/priv/$udom/$uname"; |
$current_disk_usage = &Apache::lonnet::diskusage($udom,$uname,$authorspace); |
$current_disk_usage = &Apache::lonnet::diskusage($udom,$uname,$authorspace); |
Line 8912 sub excess_filesize_warning {
|
Line 8973 sub excess_filesize_warning {
|
} |
} |
$disk_quota = int($disk_quota * 1000); |
$disk_quota = int($disk_quota * 1000); |
if (($current_disk_usage + $filesize) > $disk_quota) { |
if (($current_disk_usage + $filesize) > $disk_quota) { |
return '<p><span class="LC_warning">'. |
return '<p class="LC_warning">'. |
&mt("Unable to $action [_1]. (size = [_2] kilobytes). Disk quota will be exceeded.", |
&mt("Unable to $action [_1]. (size = [_2] kilobytes). Disk quota will be exceeded.", |
'<span class="LC_filename">'.$filename.'</span>',$filesize).'</span>'. |
'<span class="LC_filename">'.$filename.'</span>',$filesize).'</p>'. |
'<br />'.&mt('Disk quota is [_1] kilobytes. Your current disk usage is [_2] kilobytes.', |
'<p>'.&mt('Disk quota is [_1] kilobytes. Your current disk usage is [_2] kilobytes.', |
$disk_quota,$current_disk_usage). |
$disk_quota,$current_disk_usage). |
'</p>'; |
'</p>'; |
} |
} |
Line 9368 sub personal_data_fieldtitles {
|
Line 9429 sub personal_data_fieldtitles {
|
|
|
sub sorted_inst_types { |
sub sorted_inst_types { |
my ($dom) = @_; |
my ($dom) = @_; |
my ($usertypes,$order) = &Apache::lonnet::retrieve_inst_usertypes($dom); |
my ($usertypes,$order); |
|
my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); |
|
if (ref($domdefaults{'inststatus'}) eq 'HASH') { |
|
$usertypes = $domdefaults{'inststatus'}{'inststatustypes'}; |
|
$order = $domdefaults{'inststatus'}{'inststatusorder'}; |
|
} else { |
|
($usertypes,$order) = &Apache::lonnet::retrieve_inst_usertypes($dom); |
|
} |
my $othertitle = &mt('All users'); |
my $othertitle = &mt('All users'); |
if ($env{'request.course.id'}) { |
if ($env{'request.course.id'}) { |
$othertitle = &mt('Any users'); |
$othertitle = &mt('Any users'); |
Line 9766 sub ask_for_embedded_content {
|
Line 9834 sub ask_for_embedded_content {
|
my $numexisting = 0; |
my $numexisting = 0; |
my $numunused = 0; |
my $numunused = 0; |
my ($output,$upload_output,$toplevel,$url,$udom,$uname,$getpropath,$cdom,$cnum, |
my ($output,$upload_output,$toplevel,$url,$udom,$uname,$getpropath,$cdom,$cnum, |
$fileloc,$filename,$delete_output,$modify_output,$title,$symb,$path); |
$fileloc,$filename,$delete_output,$modify_output,$title,$symb,$path,$navmap); |
my $heading = &mt('Upload embedded files'); |
my $heading = &mt('Upload embedded files'); |
my $buttontext = &mt('Upload'); |
my $buttontext = &mt('Upload'); |
|
|
my ($navmap,$cdom,$cnum); |
|
if ($env{'request.course.id'}) { |
if ($env{'request.course.id'}) { |
if ($actionurl eq '/adm/dependencies') { |
if ($actionurl eq '/adm/dependencies') { |
$navmap = Apache::lonnavmaps::navmap->new(); |
$navmap = Apache::lonnavmaps::navmap->new(); |
Line 9854 sub ask_for_embedded_content {
|
Line 9921 sub ask_for_embedded_content {
|
} else { |
} else { |
$embed_file = $file; |
$embed_file = $file; |
} |
} |
my $absolutepath; |
my ($absolutepath,$cleaned_file); |
if ($embed_file =~ m{^\w+://}) { |
if ($embed_file =~ m{^\w+://}) { |
$newfiles{$embed_file} = 1; |
$cleaned_file = $embed_file; |
$mapping{$embed_file} = $embed_file; |
$newfiles{$cleaned_file} = 1; |
|
$mapping{$cleaned_file} = $embed_file; |
} else { |
} else { |
|
$cleaned_file = &clean_path($embed_file); |
if ($embed_file =~ m{^/}) { |
if ($embed_file =~ m{^/}) { |
$absolutepath = $embed_file; |
$absolutepath = $embed_file; |
$embed_file =~ s{^(/+)}{}; |
|
} |
} |
if ($embed_file =~ m{/}) { |
if ($cleaned_file =~ m{/}) { |
my ($path,$fname) = ($embed_file =~ m{^(.+)/([^/]*)$}); |
my ($path,$fname) = ($cleaned_file =~ m{^(.+)/([^/]*)$}); |
$path = &check_for_traversal($path,$url,$toplevel); |
$path = &check_for_traversal($path,$url,$toplevel); |
my $item = $fname; |
my $item = $fname; |
if ($path ne '') { |
if ($path ne '') { |
Line 9881 sub ask_for_embedded_content {
|
Line 9949 sub ask_for_embedded_content {
|
} else { |
} else { |
$dependencies{$embed_file} = 1; |
$dependencies{$embed_file} = 1; |
if ($absolutepath) { |
if ($absolutepath) { |
$mapping{$embed_file} = $absolutepath; |
$mapping{$cleaned_file} = $absolutepath; |
} else { |
} else { |
$mapping{$embed_file} = $embed_file; |
$mapping{$cleaned_file} = $embed_file; |
} |
} |
} |
} |
} |
} |
Line 10257 sub ask_for_embedded_content {
|
Line 10325 sub ask_for_embedded_content {
|
return ($output,$counter,$numpathchg); |
return ($output,$counter,$numpathchg); |
} |
} |
|
|
|
=pod |
|
|
|
=item * clean_path($name) |
|
|
|
Performs clean-up of directories, subdirectories and filename in an |
|
embedded object, referenced in an HTML file which is being uploaded |
|
to a course or portfolio, where |
|
"Upload embedded images/multimedia files if HTML file" checkbox was |
|
checked. |
|
|
|
Clean-up is similar to replacements in lonnet::clean_filename() |
|
except each / between sub-directory and next level is preserved. |
|
|
|
=cut |
|
|
|
sub clean_path { |
|
my ($embed_file) = @_; |
|
$embed_file =~s{^/+}{}; |
|
my @contents; |
|
if ($embed_file =~ m{/}) { |
|
@contents = split(/\//,$embed_file); |
|
} else { |
|
@contents = ($embed_file); |
|
} |
|
my $lastidx = scalar(@contents)-1; |
|
for (my $i=0; $i<=$lastidx; $i++) { |
|
$contents[$i]=~s{\\}{/}g; |
|
$contents[$i]=~s/\s+/\_/g; |
|
$contents[$i]=~s{[^/\w\.\-]}{}g; |
|
if ($i == $lastidx) { |
|
$contents[$i]=~s/\.(\d+)(?=\.)/_$1/g; |
|
} |
|
} |
|
if ($lastidx > 0) { |
|
return join('/',@contents); |
|
} else { |
|
return $contents[0]; |
|
} |
|
} |
|
|
sub embedded_file_element { |
sub embedded_file_element { |
my ($context,$num,$embed_file,$mapping,$allfiles,$codebase,$type) = @_; |
my ($context,$num,$embed_file,$mapping,$allfiles,$codebase,$type) = @_; |
return unless ((ref($mapping) eq 'HASH') && (ref($allfiles) eq 'HASH') && |
return unless ((ref($mapping) eq 'HASH') && (ref($allfiles) eq 'HASH') && |
Line 10381 sub upload_embedded {
|
Line 10489 sub upload_embedded {
|
# Check if extension is valid |
# Check if extension is valid |
if (($fname =~ /\.(\w+)$/) && |
if (($fname =~ /\.(\w+)$/) && |
(&Apache::loncommon::fileembstyle($1) eq 'hdn')) { |
(&Apache::loncommon::fileembstyle($1) eq 'hdn')) { |
$output .= &mt('Invalid file extension ([_1]) - reserved for LONCAPA use - rename the file with a different extension and re-upload. ',$1).'<br />'; |
$output .= &mt('Invalid file extension ([_1]) - reserved for internal use.',$1) |
|
.' '.&mt('Rename the file with a different extension and re-upload.').'<br />'; |
next; |
next; |
} elsif (($fname =~ /\.(\w+)$/) && |
} elsif (($fname =~ /\.(\w+)$/) && |
(!defined(&Apache::loncommon::fileembstyle($1)))) { |
(!defined(&Apache::loncommon::fileembstyle($1)))) { |
Line 10645 sub modify_html_refs {
|
Line 10754 sub modify_html_refs {
|
my $numchg = ($content =~ s{($attrib_regexp\s*=\s*['"]?)\Q$ref\E(['"]?)}{$1$newname$2}gi); |
my $numchg = ($content =~ s{($attrib_regexp\s*=\s*['"]?)\Q$ref\E(['"]?)}{$1$newname$2}gi); |
$count += $numchg; |
$count += $numchg; |
$allfiles{$newname} = $allfiles{$ref}; |
$allfiles{$newname} = $allfiles{$ref}; |
|
delete($allfiles{$ref}); |
} |
} |
if ($env{'form.embedded_codebase_'.$i} ne '') { |
if ($env{'form.embedded_codebase_'.$i} ne '') { |
$codebase = &unescape($env{'form.embedded_codebase_'.$i}); |
$codebase = &unescape($env{'form.embedded_codebase_'.$i}); |
Line 10820 sub check_for_upload {
|
Line 10930 sub check_for_upload {
|
if ($currsize < $filesize) { |
if ($currsize < $filesize) { |
my $extra = $filesize - $currsize; |
my $extra = $filesize - $currsize; |
if (($current_disk_usage + $extra) > $disk_quota) { |
if (($current_disk_usage + $extra) > $disk_quota) { |
my $msg = '<span class="LC_error">'. |
my $msg = '<p class="LC_warning">'. |
&mt('Unable to upload [_1]. (size = [_2] kilobytes). Disk quota will be exceeded if existing (smaller) file with same name (size = [_3] kilobytes) is replaced.', |
&mt('Unable to upload [_1]. (size = [_2] kilobytes). Disk quota will be exceeded if existing (smaller) file with same name (size = [_3] kilobytes) is replaced.', |
'<span class="LC_filename">'.$fname.'</span>',$filesize,$currsize).'</span>'. |
'<span class="LC_filename">'.$fname.'</span>',$filesize,$currsize).'</p>'. |
'<br />'.&mt('Disk quota is [_1] kilobytes. Your current disk usage is [_2] kilobytes.', |
'<p>'.&mt('Disk quota is [_1] kilobytes. Your current disk usage is [_2] kilobytes.', |
$disk_quota,$current_disk_usage); |
$disk_quota,$current_disk_usage).'</p>'; |
return ('will_exceed_quota',$msg); |
return ('will_exceed_quota',$msg); |
} |
} |
} |
} |
Line 10833 sub check_for_upload {
|
Line 10943 sub check_for_upload {
|
} |
} |
} |
} |
if (($current_disk_usage + $filesize) > $disk_quota){ |
if (($current_disk_usage + $filesize) > $disk_quota){ |
my $msg = '<span class="LC_error">'. |
my $msg = '<p class="LC_warning">'. |
&mt('Unable to upload [_1]. (size = [_2] kilobytes). Disk quota will be exceeded.','<span class="LC_filename">'.$fname.'</span>',$filesize).'</span>'. |
&mt('Unable to upload [_1]. (size = [_2] kilobytes). Disk quota will be exceeded.','<span class="LC_filename">'.$fname.'</span>',$filesize).'</p>'. |
'<br />'.&mt('Disk quota is [_1] kilobytes. Your current disk usage is [_2] kilobytes.',$disk_quota,$current_disk_usage); |
'<p>'.&mt('Disk quota is [_1] kilobytes. Your current disk usage is [_2] kilobytes.',$disk_quota,$current_disk_usage).'</p>'; |
return ('will_exceed_quota',$msg); |
return ('will_exceed_quota',$msg); |
} elsif ($found_file) { |
} elsif ($found_file) { |
if ($locked_file) { |
if ($locked_file) { |
my $msg = '<span class="LC_error">'; |
my $msg = '<p class="LC_warning">'; |
$msg .= &mt('Unable to upload [_1]. A locked file by that name was found in [_2].','<span class="LC_filename">'.$fname.'</span>','<span class="LC_filename">'.$port_path.$env{'form.currentpath'}.'</span>'); |
$msg .= &mt('Unable to upload [_1]. A locked file by that name was found in [_2].','<span class="LC_filename">'.$fname.'</span>','<span class="LC_filename">'.$port_path.$env{'form.currentpath'}.'</span>'); |
$msg .= '</span><br />'; |
$msg .= '</p>'; |
$msg .= &mt('You will be able to rename or delete existing [_1] after a grade has been assigned.','<span class="LC_filename">'.$fname.'</span>'); |
$msg .= &mt('You will be able to rename or delete existing [_1] after a grade has been assigned.','<span class="LC_filename">'.$fname.'</span>'); |
return ('file_locked',$msg); |
return ('file_locked',$msg); |
} else { |
} else { |
my $msg = '<span class="LC_error">'; |
my $msg = '<p class="LC_error">'; |
$msg .= &mt(' A file by that name: [_1] was found in [_2].','<span class="LC_filename">'.$fname.'</span>',$port_path.$env{'form.currentpath'}); |
$msg .= &mt(' A file by that name: [_1] was found in [_2].','<span class="LC_filename">'.$fname.'</span>',$port_path.$env{'form.currentpath'}); |
$msg .= '</span>'; |
$msg .= '</p>'; |
return ('existingfile',$msg); |
return ('existingfile',$msg); |
} |
} |
} |
} |
Line 10938 sub decompress_form {
|
Line 11048 sub decompress_form {
|
} |
} |
} |
} |
if ($mimetype =~ m{^application/(x\-)?(compressed|zip)}) { |
if ($mimetype =~ m{^application/(x\-)?(compressed|zip)}) { |
my @camtasia = ("$topdir/","$topdir/index.html", |
my @camtasia6 = ("$topdir/","$topdir/index.html", |
"$topdir/media/", |
"$topdir/media/", |
"$topdir/media/$topdir.mp4", |
"$topdir/media/$topdir.mp4", |
"$topdir/media/FirstFrame.png", |
"$topdir/media/FirstFrame.png", |
"$topdir/media/player.swf", |
"$topdir/media/player.swf", |
"$topdir/media/swfobject.js", |
"$topdir/media/swfobject.js", |
"$topdir/media/expressInstall.swf"); |
"$topdir/media/expressInstall.swf"); |
my @diffs = &compare_arrays(\@paths,\@camtasia); |
my @camtasia8 = ("$topdir/","$topdir/$topdir.html", |
|
"$topdir/$topdir.mp4", |
|
"$topdir/$topdir\_config.xml", |
|
"$topdir/$topdir\_controller.swf", |
|
"$topdir/$topdir\_embed.css", |
|
"$topdir/$topdir\_First_Frame.png", |
|
"$topdir/$topdir\_player.html", |
|
"$topdir/$topdir\_Thumbnails.png", |
|
"$topdir/playerProductInstall.swf", |
|
"$topdir/scripts/", |
|
"$topdir/scripts/config_xml.js", |
|
"$topdir/scripts/handlebars.js", |
|
"$topdir/scripts/jquery-1.7.1.min.js", |
|
"$topdir/scripts/jquery-ui-1.8.15.custom.min.js", |
|
"$topdir/scripts/modernizr.js", |
|
"$topdir/scripts/player-min.js", |
|
"$topdir/scripts/swfobject.js", |
|
"$topdir/skins/", |
|
"$topdir/skins/configuration_express.xml", |
|
"$topdir/skins/express_show/", |
|
"$topdir/skins/express_show/player-min.css", |
|
"$topdir/skins/express_show/spritesheet.png"); |
|
my @diffs = &compare_arrays(\@paths,\@camtasia6); |
if (@diffs == 0) { |
if (@diffs == 0) { |
$is_camtasia = 1; |
$is_camtasia = 6; |
|
} else { |
|
@diffs = &compare_arrays(\@paths,\@camtasia8); |
|
if (@diffs == 0) { |
|
$is_camtasia = 8; |
|
} |
} |
} |
} |
} |
my $output; |
my $output; |
Line 10959 sub decompress_form {
|
Line 11096 sub decompress_form {
|
function camtasiaToggle() { |
function camtasiaToggle() { |
for (var i=0; i<document.uploaded_decompress.autoextract_camtasia.length; i++) { |
for (var i=0; i<document.uploaded_decompress.autoextract_camtasia.length; i++) { |
if (document.uploaded_decompress.autoextract_camtasia[i].checked) { |
if (document.uploaded_decompress.autoextract_camtasia[i].checked) { |
if (document.uploaded_decompress.autoextract_camtasia[i].value == 1) { |
if (document.uploaded_decompress.autoextract_camtasia[i].value == $is_camtasia) { |
|
|
document.getElementById('camtasia_titles').style.display='block'; |
document.getElementById('camtasia_titles').style.display='block'; |
} else { |
} else { |
Line 11022 ENDCAM
|
Line 11159 ENDCAM
|
if ($is_camtasia) { |
if ($is_camtasia) { |
$output .= $lt{'auto'}.'<br />'. |
$output .= $lt{'auto'}.'<br />'. |
'<span class="LC_nobreak">'.$lt{'proa'}.'<label>'. |
'<span class="LC_nobreak">'.$lt{'proa'}.'<label>'. |
'<input type="radio" name="autoextract_camtasia" value="1" onclick="javascript:camtasiaToggle();" checked="checked" />'. |
'<input type="radio" name="autoextract_camtasia" value="'.$is_camtasia.'" onclick="javascript:camtasiaToggle();" checked="checked" />'. |
$lt{'yes'}.'</label> <label>'. |
$lt{'yes'}.'</label> <label>'. |
'<input type="radio" name="autoextract_camtasia" value="0" onclick="javascript:camtasiaToggle();" />'. |
'<input type="radio" name="autoextract_camtasia" value="0" onclick="javascript:camtasiaToggle();" />'. |
$lt{'no'}.'</label></span><br />'. |
$lt{'no'}.'</label></span><br />'. |
Line 11145 sub decompress_uploaded_file {
|
Line 11282 sub decompress_uploaded_file {
|
sub process_decompression { |
sub process_decompression { |
my ($docudom,$docuname,$file,$destination,$dir_root,$hiddenelem) = @_; |
my ($docudom,$docuname,$file,$destination,$dir_root,$hiddenelem) = @_; |
my ($dir,$error,$warning,$output); |
my ($dir,$error,$warning,$output); |
if ($file !~ /\.(zip|tar|bz2|gz|tar.gz|tar.bz2|tgz)$/) { |
if ($file !~ /\.(zip|tar|bz2|gz|tar.gz|tar.bz2|tgz)$/i) { |
$error = &mt('Filename not a supported archive file type.'). |
$error = &mt('Filename not a supported archive file type.'). |
'<br />'.&mt('Filename should end with one of: [_1].', |
'<br />'.&mt('Filename should end with one of: [_1].', |
'.zip, .tar, .bz2, .gz, .tar.gz, .tar.bz2, .tgz'); |
'.zip, .tar, .bz2, .gz, .tar.gz, .tar.bz2, .tgz'); |
Line 11255 sub process_decompression {
|
Line 11392 sub process_decompression {
|
\%titles,\%children); |
\%titles,\%children); |
} |
} |
if ($env{'form.autoextract_camtasia'}) { |
if ($env{'form.autoextract_camtasia'}) { |
|
my $version = $env{'form.autoextract_camtasia'}; |
my %displayed; |
my %displayed; |
my $total = 1; |
my $total = 1; |
$env{'form.archive_directory'} = []; |
$env{'form.archive_directory'} = []; |
Line 11273 sub process_decompression {
|
Line 11411 sub process_decompression {
|
$env{'form.archive_'.$i} = 'display'; |
$env{'form.archive_'.$i} = 'display'; |
$env{'form.archive_title_'.$i} = $env{'form.camtasia_foldername'}; |
$env{'form.archive_title_'.$i} = $env{'form.camtasia_foldername'}; |
$displayed{'folder'} = $i; |
$displayed{'folder'} = $i; |
} elsif ($item eq "$contents[0]/index.html") { |
} elsif ((($item eq "$contents[0]/index.html") && ($version == 6)) || |
|
(($item eq "$contents[0]/$contents[0]".'.html') && ($version == 8))) { |
$env{'form.archive_'.$i} = 'display'; |
$env{'form.archive_'.$i} = 'display'; |
$env{'form.archive_title_'.$i} = $env{'form.camtasia_moviename'}; |
$env{'form.archive_title_'.$i} = $env{'form.camtasia_moviename'}; |
$displayed{'web'} = $i; |
$displayed{'web'} = $i; |
} else { |
} else { |
if ($item eq "$contents[0]/media") { |
if ((($item eq "$contents[0]/media") && ($version == 6)) || |
|
((($item eq "$contents[0]/scripts") || ($item eq "$contents[0]/skins") || |
|
($item eq "$contents[0]/skins/express_show")) && ($version == 8))) { |
push(@{$env{'form.archive_directory'}},$i); |
push(@{$env{'form.archive_directory'}},$i); |
} |
} |
$env{'form.archive_'.$i} = 'dependency'; |
$env{'form.archive_'.$i} = 'dependency'; |
Line 12005 sub cleanup_empty_dirs {
|
Line 12146 sub cleanup_empty_dirs {
|
|
|
=pod |
=pod |
|
|
=item &get_folder_hierarchy() |
=item * &get_folder_hierarchy() |
|
|
Provides hierarchy of names of folders/sub-folders containing the current |
Provides hierarchy of names of folders/sub-folders containing the current |
item, |
item, |
Line 12115 sub get_turnedin_filepath {
|
Line 12256 sub get_turnedin_filepath {
|
my $title = $res->compTitle(); |
my $title = $res->compTitle(); |
$title =~ s/\W+/_/g; |
$title =~ s/\W+/_/g; |
if ($title ne '') { |
if ($title ne '') { |
|
if (($pc > 1) && (length($title) > 12)) { |
|
$title = substr($title,0,12); |
|
} |
push(@pathitems,$title); |
push(@pathitems,$title); |
} |
} |
} |
} |
Line 12123 sub get_turnedin_filepath {
|
Line 12267 sub get_turnedin_filepath {
|
my $maptitle = $mapres->compTitle(); |
my $maptitle = $mapres->compTitle(); |
$maptitle =~ s/\W+/_/g; |
$maptitle =~ s/\W+/_/g; |
if ($maptitle ne '') { |
if ($maptitle ne '') { |
|
if (length($maptitle) > 12) { |
|
$maptitle = substr($maptitle,0,12); |
|
} |
push(@pathitems,$maptitle); |
push(@pathitems,$maptitle); |
} |
} |
unless ($env{'request.state'} eq 'construct') { |
unless ($env{'request.state'} eq 'construct') { |
Line 12163 sub get_turnedin_filepath {
|
Line 12310 sub get_turnedin_filepath {
|
$restitle = time; |
$restitle = time; |
} |
} |
} |
} |
|
if (length($restitle) > 12) { |
|
$restitle = substr($restitle,0,12); |
|
} |
push(@pathitems,$restitle); |
push(@pathitems,$restitle); |
$path .= join('/',@pathitems); |
$path .= join('/',@pathitems); |
} |
} |
Line 13100 sub restore_settings {
|
Line 13250 sub restore_settings {
|
|
|
=item * &build_recipient_list() |
=item * &build_recipient_list() |
|
|
Build recipient lists for five types of e-mail: |
Build recipient lists for following types of e-mail: |
(a) Error Reports, (b) Package Updates, (c) lonstatus warnings/errors |
(a) Error Reports, (b) Package Updates, (c) lonstatus warnings/errors |
(d) Help requests, (e) Course requests needing approval, generated by |
(d) Help requests, (e) Course requests needing approval, (f) loncapa |
lonerrorhandler.pm, CHECKRPMS, loncron, lonsupportreq.pm and |
module change checking, student/employee ID conflict checks, as |
loncoursequeueadmin.pm respectively. |
generated by lonerrorhandler.pm, CHECKRPMS, loncron, |
|
lonsupportreq.pm, loncoursequeueadmin.pm, searchcat.pl respectively. |
|
|
Inputs: |
Inputs: |
defmail (scalar - email address of default recipient), |
defmail (scalar - email address of default recipient), |
mailing type (scalar - errormail, packagesmail, or helpdeskmail), |
mailing type (scalar: errormail, packagesmail, helpdeskmail, |
|
requestsmail, updatesmail, or idconflictsmail). |
|
|
defdom (domain for which to retrieve configuration settings), |
defdom (domain for which to retrieve configuration settings), |
|
|
origmail (scalar - email address of recipient from loncapa.conf, |
origmail (scalar - email address of recipient from loncapa.conf, |
i.e., predates configuration by DC via domainprefs.pm |
i.e., predates configuration by DC via domainprefs.pm |
|
|
Line 13305 sub extract_categories {
|
Line 13459 sub extract_categories {
|
|
|
=pod |
=pod |
|
|
=item *&recurse_categories() |
=item * &recurse_categories() |
|
|
Recursively used to generate breadcrumb trails for course categories. |
Recursively used to generate breadcrumb trails for course categories. |
|
|
Line 13376 sub recurse_categories {
|
Line 13530 sub recurse_categories {
|
|
|
=pod |
=pod |
|
|
=item *&assign_categories_table() |
=item * &assign_categories_table() |
|
|
Create a datatable for display of hierarchical categories in a domain, |
Create a datatable for display of hierarchical categories in a domain, |
with checkboxes to allow a course to be categorized. |
with checkboxes to allow a course to be categorized. |
Line 13453 sub assign_categories_table {
|
Line 13607 sub assign_categories_table {
|
|
|
=pod |
=pod |
|
|
=item *&assign_category_rows() |
=item * &assign_category_rows() |
|
|
Create a datatable row for display of nested categories in a domain, |
Create a datatable row for display of nested categories in a domain, |
with checkboxes to allow a course to be categorized,called recursively. |
with checkboxes to allow a course to be categorized,called recursively. |
Line 13487 sub assign_category_rows {
|
Line 13641 sub assign_category_rows {
|
if (ref($cats->[$depth]{$parent}) eq 'ARRAY') { |
if (ref($cats->[$depth]{$parent}) eq 'ARRAY') { |
my $numchildren = @{$cats->[$depth]{$parent}}; |
my $numchildren = @{$cats->[$depth]{$parent}}; |
my $css_class = $itemcount%2?' class="LC_odd_row"':''; |
my $css_class = $itemcount%2?' class="LC_odd_row"':''; |
$text .= '<td><table class="LC_datatable">'; |
$text .= '<td><table class="LC_data_table">'; |
for (my $j=0; $j<$numchildren; $j++) { |
for (my $j=0; $j<$numchildren; $j++) { |
$name = $cats->[$depth]{$parent}[$j]; |
$name = $cats->[$depth]{$parent}[$j]; |
$item = &escape($name).':'.&escape($parent).':'.$depth; |
$item = &escape($name).':'.&escape($parent).':'.$depth; |
Line 13519 sub assign_category_rows {
|
Line 13673 sub assign_category_rows {
|
return $text; |
return $text; |
} |
} |
|
|
|
=pod |
|
|
|
=back |
|
|
|
=cut |
|
|
############################################################ |
############################################################ |
############################################################ |
############################################################ |
|
|
Line 13771 sub check_clone {
|
Line 13931 sub check_clone {
|
} |
} |
|
|
sub construct_course { |
sub construct_course { |
my ($args,$logmsg,$courseid,$crsudom,$crsunum,$udom,$uname,$context,$cnum,$category) = @_; |
my ($args,$logmsg,$courseid,$crsudom,$crsunum,$udom,$uname,$context,$cnum,$category,$coderef) = @_; |
my $outcome; |
my $outcome; |
my $linefeed = '<br />'."\n"; |
my $linefeed = '<br />'."\n"; |
if ($context eq 'auto') { |
if ($context eq 'auto') { |
Line 13868 sub construct_course {
|
Line 14028 sub construct_course {
|
'plc.users.denied', |
'plc.users.denied', |
'hidefromcat', |
'hidefromcat', |
'checkforpriv', |
'checkforpriv', |
'categories'], |
'categories', |
|
'internal.uniquecode'], |
$$crsudom,$$crsunum); |
$$crsudom,$$crsunum); |
|
if ($args->{'textbook'}) { |
|
$cenv{'internal.textbook'} = $args->{'textbook'}; |
|
} |
} |
} |
|
|
# |
# |
Line 14053 sub construct_course {
|
Line 14217 sub construct_course {
|
} |
} |
} |
} |
|
|
|
# |
|
# generate and store uniquecode (available to course requester), if course should have one. |
|
# |
|
if ($args->{'uniquecode'}) { |
|
my ($code,$error) = &make_unique_code($$crsudom,$$crsunum); |
|
if ($code) { |
|
$cenv{'internal.uniquecode'} = $code; |
|
my %crsinfo = |
|
&Apache::lonnet::courseiddump($$crsudom,'.',1,'.','.',$$crsunum,undef,undef,'.'); |
|
if (ref($crsinfo{$$crsudom.'_'.$$crsunum}) eq 'HASH') { |
|
$crsinfo{$$crsudom.'_'.$$crsunum}{'uniquecode'} = $code; |
|
my $putres = &Apache::lonnet::courseidput($$crsudom,\%crsinfo,$crsuhome,'notime'); |
|
} |
|
if (ref($coderef)) { |
|
$$coderef = $code; |
|
} |
|
} |
|
} |
|
|
if ($args->{'disresdis'}) { |
if ($args->{'disresdis'}) { |
$cenv{'pch.roles.denied'}='st'; |
$cenv{'pch.roles.denied'}='st'; |
} |
} |
Line 14121 sub construct_course {
|
Line 14304 sub construct_course {
|
return (1,$outcome); |
return (1,$outcome); |
} |
} |
|
|
|
sub make_unique_code { |
|
my ($cdom,$cnum) = @_; |
|
# get lock on uniquecodes db |
|
my $lockhash = { |
|
$cnum."\0".'uniquecodes' => $env{'user.name'}. |
|
':'.$env{'user.domain'}, |
|
}; |
|
my $tries = 0; |
|
my $gotlock = &Apache::lonnet::newput_dom('uniquecodes',$lockhash,$cdom); |
|
my ($code,$error); |
|
|
|
while (($gotlock ne 'ok') && ($tries<3)) { |
|
$tries ++; |
|
sleep 1; |
|
$gotlock = &Apache::lonnet::newput_dom('uniquecodes',$lockhash,$cdom); |
|
} |
|
if ($gotlock eq 'ok') { |
|
my %currcodes = &Apache::lonnet::dump_dom('uniquecodes',$cdom); |
|
my $gotcode; |
|
my $attempts = 0; |
|
while ((!$gotcode) && ($attempts < 100)) { |
|
$code = &generate_code(); |
|
if (!exists($currcodes{$code})) { |
|
$gotcode = 1; |
|
unless (&Apache::lonnet::newput_dom('uniquecodes',{ $code => $cnum },$cdom) eq 'ok') { |
|
$error = 'nostore'; |
|
} |
|
} |
|
$attempts ++; |
|
} |
|
my @del_lock = ($cnum."\0".'uniquecodes'); |
|
my $dellockoutcome = &Apache::lonnet::del_dom('uniquecodes',\@del_lock,$cdom); |
|
} else { |
|
$error = 'nolock'; |
|
} |
|
return ($code,$error); |
|
} |
|
|
|
sub generate_code { |
|
my $code; |
|
my @letts = qw(B C D G H J K M N P Q R S T V W X Z); |
|
for (my $i=0; $i<6; $i++) { |
|
my $lettnum = int (rand 2); |
|
my $item = ''; |
|
if ($lettnum) { |
|
$item = $letts[int( rand(18) )]; |
|
} else { |
|
$item = 1+int( rand(8) ); |
|
} |
|
$code .= $item; |
|
} |
|
return $code; |
|
} |
|
|
############################################################ |
############################################################ |
############################################################ |
############################################################ |
|
|
Line 14148 sub group_term {
|
Line 14385 sub group_term {
|
} |
} |
|
|
sub course_types { |
sub course_types { |
my @types = ('official','unofficial','community'); |
my @types = ('official','unofficial','community','textbook'); |
my %typename = ( |
my %typename = ( |
official => 'Official course', |
official => 'Official course', |
unofficial => 'Unofficial course', |
unofficial => 'Unofficial course', |
community => 'Community', |
community => 'Community', |
|
textbook => 'Textbook course', |
); |
); |
return (\@types,\%typename); |
return (\@types,\%typename); |
} |
} |
Line 14285 sub init_user_environment {
|
Line 14523 sub init_user_environment {
|
# ------------------------------------ Check browser type and MathML capability |
# ------------------------------------ Check browser type and MathML capability |
|
|
my ($httpbrowser,$clientbrowser,$clientversion,$clientmathml, |
my ($httpbrowser,$clientbrowser,$clientversion,$clientmathml, |
$clientunicode,$clientos,$clientmobile) = &decode_user_agent($r); |
$clientunicode,$clientos,$clientmobile,$clientinfo) = &decode_user_agent($r); |
|
|
# ------------------------------------------------------------- Get environment |
# ------------------------------------------------------------- Get environment |
|
|
Line 14317 sub init_user_environment {
|
Line 14555 sub init_user_environment {
|
"browser.unicode" => $clientunicode, |
"browser.unicode" => $clientunicode, |
"browser.os" => $clientos, |
"browser.os" => $clientos, |
"browser.mobile" => $clientmobile, |
"browser.mobile" => $clientmobile, |
|
"browser.info" => $clientinfo, |
"server.domain" => $Apache::lonnet::perlvar{'lonDefDomain'}, |
"server.domain" => $Apache::lonnet::perlvar{'lonDefDomain'}, |
"request.course.fn" => '', |
"request.course.fn" => '', |
"request.course.uri" => '', |
"request.course.uri" => '', |
Line 14336 sub init_user_environment {
|
Line 14575 sub init_user_environment {
|
$env{'browser.interface'}=$form->{'interface'}; |
$env{'browser.interface'}=$form->{'interface'}; |
} |
} |
|
|
|
if ($form->{'iptoken'}) { |
|
my $lonhost = $r->dir_config('lonHostID'); |
|
$initial_env{"user.noloadbalance"} = $lonhost; |
|
$env{'user.noloadbalance'} = $lonhost; |
|
} |
|
|
my %is_adv = ( is_adv => $env{'user.adv'} ); |
my %is_adv = ( is_adv => $env{'user.adv'} ); |
my %domdef; |
my %domdef; |
unless ($domain eq 'public') { |
unless ($domain eq 'public') { |
Line 14348 sub init_user_environment {
|
Line 14593 sub init_user_environment {
|
undef,\%userenv,\%domdef,\%is_adv); |
undef,\%userenv,\%domdef,\%is_adv); |
} |
} |
|
|
foreach my $crstype ('official','unofficial','community') { |
foreach my $crstype ('official','unofficial','community','textbook') { |
$userenv{'canrequest.'.$crstype} = |
$userenv{'canrequest.'.$crstype} = |
&Apache::lonnet::usertools_access($username,$domain,$crstype, |
&Apache::lonnet::usertools_access($username,$domain,$crstype, |
'reload','requestcourses', |
'reload','requestcourses', |
Line 14453 sub clean_symb {
|
Line 14698 sub clean_symb {
|
return ($symb,$enc); |
return ($symb,$enc); |
} |
} |
|
|
|
############################################################ |
|
############################################################ |
|
|
|
=pod |
|
|
|
=head1 Routines for building display used to search for courses |
|
|
|
|
|
=over 4 |
|
|
|
=item * &build_filters() |
|
|
|
Create markup for a table used to set filters to use when selecting |
|
courses in a domain. Used by lonpickcourse.pm, lonmodifycourse.pm |
|
and quotacheck.pl |
|
|
|
|
|
Inputs: |
|
|
|
filterlist - anonymous array of fields to include as potential filters |
|
|
|
crstype - course type |
|
|
|
roleelement - fifth arg in selectcourse_link() populates fifth arg in javascript: opencrsbrowser() function, used |
|
to pop-open a course selector (will contain "extra element"). |
|
|
|
multelement - if multiple course selections will be allowed, this will be a hidden form element: name: multiple; value: 1 |
|
|
|
filter - anonymous hash of criteria and their values |
|
|
|
action - form action |
|
|
|
numfiltersref - ref to scalar (count of number of elements in institutional codes -- e.g., 4 for year, semester, department, and number) |
|
|
|
caller - caller context (e.g., set to 'modifycourse' when routine is called from lonmodifycourse.pm) |
|
|
|
cloneruname - username of owner of new course who wants to clone |
|
|
|
clonerudom - domain of owner of new course who wants to clone |
|
|
|
typeelem - text to use for left column in row containing course type (i.e., Course, Community or Course/Community) |
|
|
|
codetitlesref - reference to array of titles of components in institutional codes (official courses) |
|
|
|
codedom - domain |
|
|
|
formname - value of form element named "form". |
|
|
|
fixeddom - domain, if fixed. |
|
|
|
prevphase - value to assign to form element named "phase" when going back to the previous screen |
|
|
|
cnameelement - name of form element in form on opener page which will receive title of selected course |
|
|
|
cnumelement - name of form element in form on opener page which will receive courseID of selected course |
|
|
|
cdomelement - name of form element in form on opener page which will receive domain of selected course |
|
|
|
setroles - includes access constraint identifier when setting a roles-based condition for acces to a portfolio file |
|
|
|
clonetext - hidden form elements containing list of courses cloneable by intended course owner when DC creates a course |
|
|
|
clonewarning - warning message about missing information for intended course owner when DC creates a course |
|
|
|
|
|
Returns: $output - HTML for display of search criteria, and hidden form elements. |
|
|
|
|
|
Side Effects: None |
|
|
|
=cut |
|
|
|
# ---------------------------------------------- search for courses based on last activity etc. |
|
|
|
sub build_filters { |
|
my ($filterlist,$crstype,$roleelement,$multelement,$filter,$action, |
|
$numtitlesref,$caller,$cloneruname,$clonerudom,$typeelement, |
|
$codetitlesref,$codedom,$formname,$fixeddom,$prevphase, |
|
$cnameelement,$cnumelement,$cdomelement,$setroles, |
|
$clonetext,$clonewarning) = @_; |
|
my ($list,$jscript); |
|
my $onchange = 'javascript:updateFilters(this)'; |
|
my ($domainselectform,$sincefilterform,$createdfilterform, |
|
$ownerdomselectform,$persondomselectform,$instcodeform, |
|
$typeselectform,$instcodetitle); |
|
if ($formname eq '') { |
|
$formname = $caller; |
|
} |
|
foreach my $item (@{$filterlist}) { |
|
unless (($item eq 'descriptfilter') || ($item eq 'instcodefilter') || |
|
($item eq 'sincefilter') || ($item eq 'createdfilter')) { |
|
if ($item eq 'domainfilter') { |
|
$filter->{$item} = &LONCAPA::clean_domain($filter->{$item}); |
|
} elsif ($item eq 'coursefilter') { |
|
$filter->{$item} = &LONCAPA::clean_courseid($filter->{$item}); |
|
} elsif ($item eq 'ownerfilter') { |
|
$filter->{$item} = &LONCAPA::clean_username($filter->{$item}); |
|
} elsif ($item eq 'ownerdomfilter') { |
|
$filter->{'ownerdomfilter'} = |
|
&LONCAPA::clean_domain($filter->{$item}); |
|
$ownerdomselectform = &select_dom_form($filter->{'ownerdomfilter'}, |
|
'ownerdomfilter',1); |
|
} elsif ($item eq 'personfilter') { |
|
$filter->{$item} = &LONCAPA::clean_username($filter->{$item}); |
|
} elsif ($item eq 'persondomfilter') { |
|
$persondomselectform = &select_dom_form($filter->{'persondomfilter'}, |
|
'persondomfilter',1); |
|
} else { |
|
$filter->{$item} =~ s/\W//g; |
|
} |
|
if (!$filter->{$item}) { |
|
$filter->{$item} = ''; |
|
} |
|
} |
|
if ($item eq 'domainfilter') { |
|
my $allow_blank = 1; |
|
if ($formname eq 'portform') { |
|
$allow_blank=0; |
|
} elsif ($formname eq 'studentform') { |
|
$allow_blank=0; |
|
} |
|
if ($fixeddom) { |
|
$domainselectform = '<input type="hidden" name="domainfilter"'. |
|
' value="'.$codedom.'" />'. |
|
&Apache::lonnet::domain($codedom,'description'); |
|
} else { |
|
$domainselectform = &select_dom_form($filter->{$item}, |
|
'domainfilter', |
|
$allow_blank,'',$onchange); |
|
} |
|
} else { |
|
$list->{$item} = &HTML::Entities::encode($filter->{$item},'<>&"'); |
|
} |
|
} |
|
|
|
# last course activity filter and selection |
|
$sincefilterform = &timebased_select_form('sincefilter',$filter); |
|
|
|
# course created filter and selection |
|
if (exists($filter->{'createdfilter'})) { |
|
$createdfilterform = &timebased_select_form('createdfilter',$filter); |
|
} |
|
|
|
my %lt = &Apache::lonlocal::texthash( |
|
'cac' => "$crstype Activity", |
|
'ccr' => "$crstype Created", |
|
'cde' => "$crstype Title", |
|
'cdo' => "$crstype Domain", |
|
'ins' => 'Institutional Code', |
|
'inc' => 'Institutional Categorization', |
|
'cow' => "$crstype Owner/Co-owner", |
|
'cop' => "$crstype Personnel Includes", |
|
'cog' => 'Type', |
|
); |
|
|
|
if (($formname eq 'ccrs') || ($formname eq 'requestcrs')) { |
|
my $typeval = 'Course'; |
|
if ($crstype eq 'Community') { |
|
$typeval = 'Community'; |
|
} |
|
$typeselectform = '<input type="hidden" name="type" value="'.$typeval.'" />'; |
|
} else { |
|
$typeselectform = '<select name="type" size="1"'; |
|
if ($onchange) { |
|
$typeselectform .= ' onchange="'.$onchange.'"'; |
|
} |
|
$typeselectform .= '>'."\n"; |
|
foreach my $posstype ('Course','Community') { |
|
$typeselectform.='<option value="'.$posstype.'"'. |
|
($posstype eq $crstype ? ' selected="selected" ' : ''). ">".&mt($posstype)."</option>\n"; |
|
} |
|
$typeselectform.="</select>"; |
|
} |
|
|
|
my ($cloneableonlyform,$cloneabletitle); |
|
if (exists($filter->{'cloneableonly'})) { |
|
my $cloneableon = ''; |
|
my $cloneableoff = ' checked="checked"'; |
|
if ($filter->{'cloneableonly'}) { |
|
$cloneableon = $cloneableoff; |
|
$cloneableoff = ''; |
|
} |
|
$cloneableonlyform = '<span class="LC_nobreak"><label><input type="radio" name="cloneableonly" value="1" '.$cloneableon.'/> '.&mt('Required').'</label>'.(' 'x3).'<label><input type="radio" name="cloneableonly" value="" '.$cloneableoff.' /> '.&mt('No restriction').'</label></span>'; |
|
if ($formname eq 'ccrs') { |
|
$cloneabletitle = &mt('Cloneable for [_1]',$cloneruname.':'.$clonerudom); |
|
} else { |
|
$cloneabletitle = &mt('Cloneable by you'); |
|
} |
|
} |
|
my $officialjs; |
|
if ($crstype eq 'Course') { |
|
if (exists($filter->{'instcodefilter'})) { |
|
# if (($fixeddom) || ($formname eq 'requestcrs') || |
|
# ($formname eq 'modifycourse') || ($formname eq 'filterpicker')) { |
|
if ($codedom) { |
|
$officialjs = 1; |
|
($instcodeform,$jscript,$$numtitlesref) = |
|
&Apache::courseclassifier::instcode_selectors($codedom,'filterpicker', |
|
$officialjs,$codetitlesref); |
|
if ($jscript) { |
|
$jscript = '<script type="text/javascript">'."\n". |
|
'// <![CDATA['."\n". |
|
$jscript."\n". |
|
'// ]]>'."\n". |
|
'</script>'."\n"; |
|
} |
|
} |
|
if ($instcodeform eq '') { |
|
$instcodeform = |
|
'<input type="text" name="instcodefilter" size="10" value="'. |
|
$list->{'instcodefilter'}.'" />'; |
|
$instcodetitle = $lt{'ins'}; |
|
} else { |
|
$instcodetitle = $lt{'inc'}; |
|
} |
|
if ($fixeddom) { |
|
$instcodetitle .= '<br />('.$codedom.')'; |
|
} |
|
} |
|
} |
|
my $output = qq| |
|
<form method="post" name="filterpicker" action="$action"> |
|
<input type="hidden" name="form" value="$formname" /> |
|
|; |
|
if ($formname eq 'modifycourse') { |
|
$output .= '<input type="hidden" name="phase" value="courselist" />'."\n". |
|
'<input type="hidden" name="prevphase" value="'. |
|
$prevphase.'" />'."\n"; |
|
} elsif ($formname ne 'quotacheck') { |
|
my $name_input; |
|
if ($cnameelement ne '') { |
|
$name_input = '<input type="hidden" name="cnameelement" value="'. |
|
$cnameelement.'" />'; |
|
} |
|
$output .= qq| |
|
<input type="hidden" name="cnumelement" value="$cnumelement" /> |
|
<input type="hidden" name="cdomelement" value="$cdomelement" /> |
|
$name_input |
|
$roleelement |
|
$multelement |
|
$typeelement |
|
|; |
|
if ($formname eq 'portform') { |
|
$output .= '<input type="hidden" name="setroles" value="'.$setroles.'" />'."\n"; |
|
} |
|
} |
|
if ($fixeddom) { |
|
$output .= '<input type="hidden" name="fixeddom" value="'.$fixeddom.'" />'."\n"; |
|
} |
|
$output .= "<br />\n".&Apache::lonhtmlcommon::start_pick_box(); |
|
if ($sincefilterform) { |
|
$output .= &Apache::lonhtmlcommon::row_title($lt{'cac'}) |
|
.$sincefilterform |
|
.&Apache::lonhtmlcommon::row_closure(); |
|
} |
|
if ($createdfilterform) { |
|
$output .= &Apache::lonhtmlcommon::row_title($lt{'ccr'}) |
|
.$createdfilterform |
|
.&Apache::lonhtmlcommon::row_closure(); |
|
} |
|
if ($domainselectform) { |
|
$output .= &Apache::lonhtmlcommon::row_title($lt{'cdo'}) |
|
.$domainselectform |
|
.&Apache::lonhtmlcommon::row_closure(); |
|
} |
|
if ($typeselectform) { |
|
if (($formname eq 'ccrs') || ($formname eq 'requestcrs')) { |
|
$output .= $typeselectform; |
|
} else { |
|
$output .= &Apache::lonhtmlcommon::row_title($lt{'cog'}) |
|
.$typeselectform |
|
.&Apache::lonhtmlcommon::row_closure(); |
|
} |
|
} |
|
if ($instcodeform) { |
|
$output .= &Apache::lonhtmlcommon::row_title($instcodetitle) |
|
.$instcodeform |
|
.&Apache::lonhtmlcommon::row_closure(); |
|
} |
|
if (exists($filter->{'ownerfilter'})) { |
|
$output .= &Apache::lonhtmlcommon::row_title($lt{'cow'}). |
|
'<table><tr><td>'.&mt('Username').'<br />'. |
|
'<input type="text" name="ownerfilter" size="20" value="'. |
|
$list->{'ownerfilter'}.'" /></td><td>'.&mt('Domain').'<br />'. |
|
$ownerdomselectform.'</td></tr></table>'. |
|
&Apache::lonhtmlcommon::row_closure(); |
|
} |
|
if (exists($filter->{'personfilter'})) { |
|
$output .= &Apache::lonhtmlcommon::row_title($lt{'cop'}). |
|
'<table><tr><td>'.&mt('Username').'<br />'. |
|
'<input type="text" name="personfilter" size="20" value="'. |
|
$list->{'personfilter'}.'" /></td><td>'.&mt('Domain').'<br />'. |
|
$persondomselectform.'</td></tr></table>'. |
|
&Apache::lonhtmlcommon::row_closure(); |
|
} |
|
if (exists($filter->{'coursefilter'})) { |
|
$output .= &Apache::lonhtmlcommon::row_title(&mt('LON-CAPA course ID')) |
|
.'<input type="text" name="coursefilter" size="25" value="' |
|
.$list->{'coursefilter'}.'" />' |
|
.&Apache::lonhtmlcommon::row_closure(); |
|
} |
|
if ($cloneableonlyform) { |
|
$output .= &Apache::lonhtmlcommon::row_title($cloneabletitle). |
|
$cloneableonlyform.&Apache::lonhtmlcommon::row_closure(); |
|
} |
|
if (exists($filter->{'descriptfilter'})) { |
|
$output .= &Apache::lonhtmlcommon::row_title($lt{'cde'}) |
|
.'<input type="text" name="descriptfilter" size="40" value="' |
|
.$list->{'descriptfilter'}.'" />' |
|
.&Apache::lonhtmlcommon::row_closure(1); |
|
} |
|
$output .= &Apache::lonhtmlcommon::end_pick_box().'<p>'.$clonetext."\n". |
|
'<input type="hidden" name="updater" value="" />'."\n". |
|
'<input type="submit" name="gosearch" value="'. |
|
&mt('Search').'" /></p>'."\n".'</form>'."\n".'<hr />'."\n"; |
|
return $jscript.$clonewarning.$output; |
|
} |
|
|
|
=pod |
|
|
|
=item * &timebased_select_form() |
|
|
|
Create markup for a dropdown list used to select a time-based |
|
filter e.g., Course Activity, Course Created, when searching for courses |
|
or communities |
|
|
|
Inputs: |
|
|
|
item - name of form element (sincefilter or createdfilter) |
|
|
|
filter - anonymous hash of criteria and their values |
|
|
|
Returns: HTML for a select box contained a blank, then six time selections, |
|
with value set in incoming form variables currently selected. |
|
|
|
Side Effects: None |
|
|
|
=cut |
|
|
|
sub timebased_select_form { |
|
my ($item,$filter) = @_; |
|
if (ref($filter) eq 'HASH') { |
|
$filter->{$item} =~ s/[^\d-]//g; |
|
if (!$filter->{$item}) { $filter->{$item}=-1; } |
|
return &select_form( |
|
$filter->{$item}, |
|
$item, |
|
{ '-1' => '', |
|
'86400' => &mt('today'), |
|
'604800' => &mt('last week'), |
|
'2592000' => &mt('last month'), |
|
'7776000' => &mt('last three months'), |
|
'15552000' => &mt('last six months'), |
|
'31104000' => &mt('last year'), |
|
'select_form_order' => |
|
['-1','86400','604800','2592000','7776000', |
|
'15552000','31104000']}); |
|
} |
|
} |
|
|
|
=pod |
|
|
|
=item * &js_changer() |
|
|
|
Create script tag containing Javascript used to submit course search form |
|
when course type or domain is changed, and also to hide 'Searching ...' on |
|
page load completion for page showing search result. |
|
|
|
Inputs: None |
|
|
|
Returns: markup containing updateFilters() and hideSearching() javascript functions. |
|
|
|
Side Effects: None |
|
|
|
=cut |
|
|
|
sub js_changer { |
|
return <<ENDJS; |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
function updateFilters(caller) { |
|
if (typeof(caller) != "undefined") { |
|
document.filterpicker.updater.value = caller.name; |
|
} |
|
document.filterpicker.submit(); |
|
} |
|
|
|
function hideSearching() { |
|
if (document.getElementById('searching')) { |
|
document.getElementById('searching').style.display = 'none'; |
|
} |
|
return; |
|
} |
|
|
|
// ]]> |
|
</script> |
|
|
|
ENDJS |
|
} |
|
|
|
=pod |
|
|
|
=item * &search_courses() |
|
|
|
Process selected filters form course search form and pass to lonnet::courseiddump |
|
to retrieve a hash for which keys are courseIDs which match the selected filters. |
|
|
|
Inputs: |
|
|
|
dom - domain being searched |
|
|
|
type - course type ('Course' or 'Community' or '.' if any). |
|
|
|
filter - anonymous hash of criteria and their values |
|
|
|
numtitles - for institutional codes - number of categories |
|
|
|
cloneruname - optional username of new course owner |
|
|
|
clonerudom - optional domain of new course owner |
|
|
|
domcloner - Optional "domcloner" flag; has value=1 if user has ccc priv in domain being filtered by, |
|
(used when DC is using course creation form) |
|
|
|
codetitles - reference to array of titles of components in institutional codes (official courses). |
|
|
|
|
|
Returns: %courses - hash of courses satisfying search criteria, keys = course IDs, values are corresponding colon-separated escaped description, institutional code, owner and type. |
|
|
|
|
|
Side Effects: None |
|
|
|
=cut |
|
|
|
|
|
sub search_courses { |
|
my ($dom,$type,$filter,$numtitles,$cloneruname,$clonerudom,$domcloner,$codetitles) = @_; |
|
my (%courses,%showcourses,$cloner); |
|
if (($filter->{'ownerfilter'} ne '') || |
|
($filter->{'ownerdomfilter'} ne '')) { |
|
$filter->{'combownerfilter'} = $filter->{'ownerfilter'}.':'. |
|
$filter->{'ownerdomfilter'}; |
|
} |
|
foreach my $item ('descriptfilter','coursefilter','combownerfilter') { |
|
if (!$filter->{$item}) { |
|
$filter->{$item}='.'; |
|
} |
|
} |
|
my $now = time; |
|
my $timefilter = |
|
($filter->{'sincefilter'}==-1?1:$now-$filter->{'sincefilter'}); |
|
my ($createdbefore,$createdafter); |
|
if (($filter->{'createdfilter'} ne '') && ($filter->{'createdfilter'} !=-1)) { |
|
$createdbefore = $now; |
|
$createdafter = $now-$filter->{'createdfilter'}; |
|
} |
|
my ($instcodefilter,$regexpok); |
|
if ($numtitles) { |
|
if ($env{'form.official'} eq 'on') { |
|
$instcodefilter = |
|
&Apache::courseclassifier::instcode_search_str($dom,$numtitles,$codetitles); |
|
$regexpok = 1; |
|
} elsif ($env{'form.official'} eq 'off') { |
|
$instcodefilter = &Apache::courseclassifier::instcode_search_str($dom,$numtitles,$codetitles); |
|
unless ($instcodefilter eq '') { |
|
$regexpok = -1; |
|
} |
|
} |
|
} else { |
|
$instcodefilter = $filter->{'instcodefilter'}; |
|
} |
|
if ($instcodefilter eq '') { $instcodefilter = '.'; } |
|
if ($type eq '') { $type = '.'; } |
|
|
|
if (($clonerudom ne '') && ($cloneruname ne '')) { |
|
$cloner = $cloneruname.':'.$clonerudom; |
|
} |
|
%courses = &Apache::lonnet::courseiddump($dom, |
|
$filter->{'descriptfilter'}, |
|
$timefilter, |
|
$instcodefilter, |
|
$filter->{'combownerfilter'}, |
|
$filter->{'coursefilter'}, |
|
undef,undef,$type,$regexpok,undef,undef, |
|
undef,undef,$cloner,$env{'form.cc_clone'}, |
|
$filter->{'cloneableonly'}, |
|
$createdbefore,$createdafter,undef, |
|
$domcloner); |
|
if (($filter->{'personfilter'} ne '') && ($filter->{'persondomfilter'} ne '')) { |
|
my $ccrole; |
|
if ($type eq 'Community') { |
|
$ccrole = 'co'; |
|
} else { |
|
$ccrole = 'cc'; |
|
} |
|
my %rolehash = &Apache::lonnet::get_my_roles($filter->{'personfilter'}, |
|
$filter->{'persondomfilter'}, |
|
'userroles',undef, |
|
[$ccrole,'in','ad','ep','ta','cr'], |
|
$dom); |
|
foreach my $role (keys(%rolehash)) { |
|
my ($cnum,$cdom,$courserole) = split(':',$role); |
|
my $cid = $cdom.'_'.$cnum; |
|
if (exists($courses{$cid})) { |
|
if (ref($courses{$cid}) eq 'HASH') { |
|
if (ref($courses{$cid}{roles}) eq 'ARRAY') { |
|
if (!grep(/^\Q$courserole\E$/,@{$courses{$cid}{roles}})) { |
|
push (@{$courses{$cid}{roles}},$courserole); |
|
} |
|
} else { |
|
$courses{$cid}{roles} = [$courserole]; |
|
} |
|
$showcourses{$cid} = $courses{$cid}; |
|
} |
|
} |
|
} |
|
%courses = %showcourses; |
|
} |
|
return %courses; |
|
} |
|
|
|
|
|
=pod |
|
|
|
=back |
|
|
|
=cut |
|
|
|
|
sub build_release_hashes { |
sub build_release_hashes { |
my ($checkparms,$checkresponsetypes,$checkcrstypes,$anonsurvey,$randomizetry) = @_; |
my ($checkparms,$checkresponsetypes,$checkcrstypes,$anonsurvey,$randomizetry) = @_; |
return unless((ref($checkparms) eq 'HASH') && (ref($checkresponsetypes) eq 'HASH') && |
return unless((ref($checkparms) eq 'HASH') && (ref($checkresponsetypes) eq 'HASH') && |
Line 14569 sub parse_supplemental_title {
|
Line 15343 sub parse_supplemental_title {
|
return $title; |
return $title; |
} |
} |
|
|
|
sub recurse_supplemental { |
|
my ($cnum,$cdom,$suppmap,$numfiles,$errors) = @_; |
|
if ($suppmap) { |
|
my ($errtext,$fatal) = &LONCAPA::map::mapread('/uploaded/'.$cdom.'/'.$cnum.'/'.$suppmap); |
|
if ($fatal) { |
|
$errors ++; |
|
} else { |
|
if ($#LONCAPA::map::resources > 0) { |
|
foreach my $res (@LONCAPA::map::resources) { |
|
my ($title,$src,$ext,$type,$status)=split(/\:/,$res); |
|
if (($src ne '') && ($status eq 'res')) { |
|
if ($src =~ m{^\Q/uploaded/$cdom/$cnum/\E(supplemental_\d+\.sequence)$}) { |
|
($numfiles,$errors) = &recurse_supplemental($cnum,$cdom,$1,$numfiles,$errors); |
|
} else { |
|
$numfiles ++; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
return ($numfiles,$errors); |
|
} |
|
|
sub symb_to_docspath { |
sub symb_to_docspath { |
my ($symb) = @_; |
my ($symb) = @_; |
return unless ($symb); |
return unless ($symb); |
Line 14598 sub symb_to_docspath {
|
Line 15396 sub symb_to_docspath {
|
my $thistitle = $res->title(); |
my $thistitle = $res->title(); |
$path .= '&'. |
$path .= '&'. |
&Apache::lonhtmlcommon::entity_encode($thisurl).'&'. |
&Apache::lonhtmlcommon::entity_encode($thisurl).'&'. |
&Apache::lonhtmlcommon::entity_encode($thistitle). |
&escape($thistitle). |
':'.$res->randompick(). |
':'.$res->randompick(). |
':'.$res->randomout(). |
':'.$res->randomout(). |
':'.$res->encrypted(). |
':'.$res->encrypted(). |
Line 14614 sub symb_to_docspath {
|
Line 15412 sub symb_to_docspath {
|
} |
} |
$path .= (($path ne '')? '&' : ''). |
$path .= (($path ne '')? '&' : ''). |
&Apache::lonhtmlcommon::entity_encode($mapurl).'&'. |
&Apache::lonhtmlcommon::entity_encode($mapurl).'&'. |
&Apache::lonhtmlcommon::entity_encode($maptitle). |
&escape($maptitle). |
':'.$mapresobj->randompick(). |
':'.$mapresobj->randompick(). |
':'.$mapresobj->randomout(). |
':'.$mapresobj->randomout(). |
':'.$mapresobj->encrypted(). |
':'.$mapresobj->encrypted(). |
Line 14627 sub symb_to_docspath {
|
Line 15425 sub symb_to_docspath {
|
$maptitle = 'Main Content'; |
$maptitle = 'Main Content'; |
} |
} |
$path = &Apache::lonhtmlcommon::entity_encode($mapurl).'&'. |
$path = &Apache::lonhtmlcommon::entity_encode($mapurl).'&'. |
&Apache::lonhtmlcommon::entity_encode($maptitle).':::::'.$ispage; |
&escape($maptitle).':::::'.$ispage; |
} |
} |
unless ($mapurl eq 'default') { |
unless ($mapurl eq 'default') { |
$path = 'default&'. |
$path = 'default&'. |
&Apache::lonhtmlcommon::entity_encode('Main Content'). |
&escape('Main Content'). |
':::::&'.$path; |
':::::&'.$path; |
} |
} |
return $path; |
return $path; |
Line 14644 sub captcha_display {
|
Line 15442 sub captcha_display {
|
if ($captcha eq 'original') { |
if ($captcha eq 'original') { |
$output = &create_captcha(); |
$output = &create_captcha(); |
unless ($output) { |
unless ($output) { |
$error = 'captcha'; |
$error = 'captcha'; |
} |
} |
} elsif ($captcha eq 'recaptcha') { |
} elsif ($captcha eq 'recaptcha') { |
$output = &create_recaptcha($pubkey); |
$output = &create_recaptcha($pubkey); |
unless ($output) { |
unless ($output) { |
$error = 'recaptcha'; |
$error = 'recaptcha'; |
} |
} |
} |
} |
return ($output,$error); |
return ($output,$error,$captcha); |
} |
} |
|
|
sub captcha_response { |
sub captcha_response { |
Line 14728 sub create_captcha {
|
Line 15526 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". |
&mt('Type in the letters/numbers shown below').' '. |
&mt('Type in the letters/numbers shown below').' '. |
'<input type="text" size="5" name="code" value="" /><br />'. |
'<input type="text" size="5" name="code" value="" autocomplete="off" />'. |
'<img src="'.$captcha_params{'www_output_dir'}.'/'.$md5sum.'.png" />'; |
'<br />'. |
|
'<img src="'.$captcha_params{'www_output_dir'}.'/'.$md5sum.'.png" alt="captcha" />'; |
last; |
last; |
} |
} |
} |
} |
Line 14770 sub check_captcha {
|
Line 15569 sub check_captcha {
|
|
|
sub create_recaptcha { |
sub create_recaptcha { |
my ($pubkey) = @_; |
my ($pubkey) = @_; |
|
my $use_ssl; |
|
if ($ENV{'SERVER_PORT'} == 443) { |
|
$use_ssl = 1; |
|
} |
my $captcha = Captcha::reCAPTCHA->new; |
my $captcha = Captcha::reCAPTCHA->new; |
return $captcha->get_options_setter({theme => 'white'})."\n". |
return $captcha->get_options_setter({theme => 'white'})."\n". |
$captcha->get_html($pubkey). |
$captcha->get_html($pubkey,undef,$use_ssl). |
&mt('If either word is hard to read, [_1] will replace them.', |
&mt('If either word is hard to read, [_1] will replace them.', |
'<img src="/res/adm/pages/refresh.gif" alt="reCAPTCHA refresh" />'). |
'<img src="/res/adm/pages/refresh.gif" alt="reCAPTCHA refresh" />'). |
'<br /><br />'; |
'<br /><br />'; |
Line 14795 sub check_recaptcha {
|
Line 15598 sub check_recaptcha {
|
return $captcha_chk; |
return $captcha_chk; |
} |
} |
|
|
=pod |
sub emailusername_info { |
|
my @fields = ('firstname','lastname','institution','web','location','officialemail'); |
|
my %titles = &Apache::lonlocal::texthash ( |
|
lastname => 'Last Name', |
|
firstname => 'First Name', |
|
institution => 'School/college/university', |
|
location => "School's city, state/province, country", |
|
web => "School's web address", |
|
officialemail => 'E-mail address at institution (if different)', |
|
); |
|
return (\@fields,\%titles); |
|
} |
|
|
=back |
sub cleanup_html { |
|
my ($incoming) = @_; |
|
my $outgoing; |
|
if ($incoming ne '') { |
|
$outgoing = $incoming; |
|
$outgoing =~ s/;/;/g; |
|
$outgoing =~ s/\#/#/g; |
|
$outgoing =~ s/\&/&/g; |
|
$outgoing =~ s/</</g; |
|
$outgoing =~ s/>/>/g; |
|
$outgoing =~ s/\(/(/g; |
|
$outgoing =~ s/\)/)/g; |
|
$outgoing =~ s/"/"/g; |
|
$outgoing =~ s/'/'/g; |
|
$outgoing =~ s/\$/$/g; |
|
$outgoing =~ s{/}{/}g; |
|
$outgoing =~ s/=/=/g; |
|
$outgoing =~ s/\\/\/g |
|
} |
|
return $outgoing; |
|
} |
|
|
=cut |
# Use: |
|
# my $answer=reply("encrypt:passwd:$udom:$uname:$upass",$tryserver); |
|
# |
|
################################################## |
|
# password associated functions # |
|
################################################## |
|
sub des_keys { |
|
# Make a new key for DES encryption. |
|
# Each key has two parts which are returned separately. |
|
# Please note: Each key must be passed through the &hex function |
|
# before it is output to the web browser. The hex versions cannot |
|
# be used to decrypt. |
|
my @hexstr=('0','1','2','3','4','5','6','7', |
|
'8','9','a','b','c','d','e','f'); |
|
my $lkey=''; |
|
for (0..7) { |
|
$lkey.=$hexstr[rand(15)]; |
|
} |
|
my $ukey=''; |
|
for (0..7) { |
|
$ukey.=$hexstr[rand(15)]; |
|
} |
|
return ($lkey,$ukey); |
|
} |
|
|
|
sub des_decrypt { |
|
my ($key,$cyphertext) = @_; |
|
my $keybin=pack("H16",$key); |
|
my $cypher; |
|
if ($Crypt::DES::VERSION>=2.03) { |
|
$cypher=new Crypt::DES $keybin; |
|
} else { |
|
$cypher=new DES $keybin; |
|
} |
|
my $plaintext= |
|
$cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,0,16)))); |
|
$plaintext.= |
|
$cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,16,16)))); |
|
$plaintext=substr($plaintext,1,ord(substr($plaintext,0,1)) ); |
|
return $plaintext; |
|
} |
|
|
1; |
1; |
__END__; |
__END__; |