--- loncom/interface/loncommon.pm 2016/11/08 23:51:11 1.1259
+++ loncom/interface/loncommon.pm 2018/03/23 01:01:21 1.1310
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# a pile of common routines
#
-# $Id: loncommon.pm,v 1.1259 2016/11/08 23:51:11 raeburn Exp $
+# $Id: loncommon.pm,v 1.1310 2018/03/23 01:01:21 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -71,6 +71,7 @@ use Apache::lonuserutils();
use Apache::lonuserstate();
use Apache::courseclassifier();
use LONCAPA qw(:DEFAULT :match);
+use LONCAPA::LWPReq;
use DateTime::TimeZone;
use DateTime::Locale;
use Encode();
@@ -83,6 +84,10 @@ use Crypt::DES;
use DynaLoader; # for Crypt::DES version
use MIME::Lite;
use MIME::Types;
+use File::Copy();
+use File::Path();
+use String::CRC32();
+use Short::URL();
# ---------------------------------------------- Designs
use vars qw(%defaultdesign);
@@ -267,7 +272,7 @@ BEGIN {
next if ($line =~ /^\#/);
chomp($line);
my ($extension,$category)=(split(/\s+/,$line,2));
- push @{$category_extensions{lc($category)}},$extension;
+ push(@{$category_extensions{lc($category)}},$extension);
}
close($fh);
}
@@ -1054,7 +1059,7 @@ sub list_languages {
if ($code) {
my $selector = $supported_codes{$id};
my $description = &plainlanguagedescription($id);
- push (@lang_choices, [$selector, $description]);
+ push(@lang_choices, [$selector, $description]);
}
}
return \@lang_choices;
@@ -1176,7 +1181,7 @@ sub linked_select_forms {
$result.="select2data${suffix}['d_$s1'].texts = new Array(";
my @s2texts;
foreach my $value (@s2values) {
- push @s2texts, $hashref->{$s1}->{'select2'}->{$value};
+ push(@s2texts, $hashref->{$s1}->{'select2'}->{$value});
}
$result.="\"@s2texts\");\n";
}
@@ -2185,7 +2190,7 @@ sub crsauthor_url {
}
sub import_crsauthor_form {
- my ($form,$firstselectname,$secondselectname,$onchangefirst,$only,$suffix) = @_;
+ my ($form,$firstselectname,$secondselectname,$onchangefirst,$only,$suffix,$disabled) = @_;
return (0) unless ($env{'request.course.id'});
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
@@ -2476,10 +2481,24 @@ sub create_text_file {
# ------------------------------------------
sub domain_select {
- my ($name,$value,$multiple)=@_;
+ my ($name,$value,$multiple,$incdoms,$excdoms)=@_;
+ my @possdoms;
+ if (ref($incdoms) eq 'ARRAY') {
+ @possdoms = @{$incdoms};
+ } else {
+ @possdoms = &Apache::lonnet::all_domains();
+ }
+
my %domains=map {
$_ => $_.' '. &Apache::lonnet::domain($_,'description')
- } &Apache::lonnet::all_domains();
+ } @possdoms;
+
+ if ((ref($excdoms) eq 'ARRAY') && (@{$excdoms} > 0)) {
+ foreach my $dom (@{$excdoms}) {
+ delete($domains{$dom});
+ }
+ }
+
if ($multiple) {
$domains{''}=&mt('Any domain');
$domains{'select_form_order'} = [sort {lc($a) cmp lc($b) } (keys(%domains))];
@@ -3008,6 +3027,8 @@ This is not an optimal method, but it wo
=item * authform_filesystem
+=item * authform_lti
+
=back
See loncreateuser.pm for invocation and use examples.
@@ -3424,14 +3445,69 @@ sub authform_filesystem {
$fsyscheck.' onchange="'.$jscall.'" onclick="'.
$jscall.'"'.$disabled.' />';
}
- $autharg = '';
$result = &mt
('[_1] Filesystem Authenticated (with initial password [_2])',
- '');
+ ''.$autharg);
+ return $result;
+}
+
+sub authform_lti {
+ my %in = (
+ formname => 'document.cu',
+ kerb_def_dom => 'MSU.EDU',
+ @_,
+ );
+ my ($lticheck,$result,$authtype,$autharg,$jscall,$disabled);
+ my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'});
+ if ($in{'readonly'}) {
+ $disabled = ' disabled="disabled"';
+ }
+ if (defined($in{'curr_authtype'})) {
+ if ($in{'curr_authtype'} eq 'lti') {
+ if ($can_assign{'lti'}) {
+ $lticheck = 'checked="checked" ';
+ if (defined($in{'mode'})) {
+ if ($in{'mode'} eq 'modifyuser') {
+ $lticheck = '';
+ }
+ }
+ } else {
+ $result = &mt('Currently LTI Authenticated.');
+ return $result;
+ }
+ }
+ } else {
+ if ($authnum == 1) {
+ $authtype = '';
+ }
+ }
+ if (!$can_assign{'lti'}) {
+ return;
+ } elsif ($authtype eq '') {
+ if (defined($in{'mode'})) {
+ if ($in{'mode'} eq 'modifycourse') {
+ if ($authnum == 1) {
+ $authtype = '';
+ }
+ }
+ }
+ }
+ $jscall = "javascript:changed_radio('lti',$in{'formname'});";
+ if (($authtype eq '') && (($in{'mode'} eq 'modifycourse') || ($in{'curr_authtype'} ne 'lti'))) {
+ $authtype = '';
+ }
+ $autharg = '';
+ if ($authtype) {
+ $result = &mt('[_1] LTI Authenticated',
+ ''.$autharg);
+ } else {
+ $result = ''.&mt('LTI Authenticated').''.
+ $autharg;
+ }
return $result;
}
@@ -3445,6 +3521,7 @@ sub get_assignable_auth {
krb5 => 1,
int => 1,
loc => 1,
+ lti => 1,
);
my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom);
if (ref($domconfig{'usercreation'}) eq 'HASH') {
@@ -4562,9 +4639,15 @@ sub get_previous_attempt {
}
$prevattempts.= &end_data_table_row().&end_data_table();
} else {
+ my $msg;
+ if ($symb =~ /ext\.tool$/) {
+ $msg = &mt('No grade passed back.');
+ } else {
+ $msg = &mt('Nothing submitted - no attempts.');
+ }
$prevattempts=
&start_data_table().&start_data_table_row().
- '
'.&mt('Nothing submitted - no attempts.').' | '.
+ ''.$msg.' | '.
&end_data_table_row().&end_data_table();
}
} else {
@@ -4669,6 +4752,9 @@ sub get_student_view {
}
if (defined($target)) { $form{'grade_target'} = $target; }
$feedurl=&Apache::lonnet::clutter($feedurl);
+ if (($feedurl =~ /ext\.tool$/) && ($target eq 'tex')) {
+ $feedurl =~ s{^/adm/wrapper}{};
+ }
my ($userview,$response)=&Apache::lonnet::ssi_body($feedurl,%form);
$userview=~s/\]*\>//gi;
$userview=~s/\<\/body\>//gi;
@@ -4991,7 +5077,8 @@ sub blockcheck {
# boards, chat or groups, check for blocking in current course only.
if (($activity eq 'boards' || $activity eq 'chat' ||
- $activity eq 'groups' || $activity eq 'printout') &&
+ $activity eq 'groups' || $activity eq 'printout' ||
+ $activity eq 'reinit' || $activity eq 'alert') &&
($env{'request.course.id'})) {
foreach my $key (keys(%live_courses)) {
if ($key ne $env{'request.course.id'}) {
@@ -5075,7 +5162,7 @@ sub blockcheck {
$tdom,$spec,$trest,$area);
}
}
- my ($author,$adv) = &Apache::lonnet::set_userprivs(\%userroles,\%allroles);
+ my ($author,$adv,$rar) = &Apache::lonnet::set_userprivs(\%userroles,\%allroles);
if ($userroles{'user.priv.'.$checkrole} =~ /evb\&([^\:]*)/) {
if ($1) {
$no_userblock = 1;
@@ -5097,9 +5184,9 @@ sub blockcheck {
($env{'request.role'} !~ m{^st\./\Q$cdom\E/\Q$cnum\E}));
next if ($no_userblock);
- # Retrieve blocking times and identity of locker for course
+ # Retrieve blocking times and identity of blocker for course
# of specified user, unless user has 'evb' privilege.
-
+
my ($start,$end,$trigger) =
&get_blocks($setters,$activity,$cdom,$cnum,$url);
if (($start != 0) &&
@@ -5186,13 +5273,19 @@ sub get_blocks {
my $end = $start + $env{'course.'.$cdom.'_'.$cnum.'.timerinterval.'.$timersymb};
if ($start && $end) {
if (($start <= time) && ($end >= time)) {
- unless (grep(/^\Q$block\E$/,@blockers)) {
- push(@blockers,$block);
- $triggered{$block} = {
- start => $start,
- end => $end,
- type => $type,
- };
+ if (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);
+ $triggered{$block} = {
+ start => $start,
+ end => $end,
+ type => $type,
+ };
+ }
+ }
+ }
}
}
}
@@ -5302,6 +5395,10 @@ END_MYBLOCK
$text = &mt('Printing Blocked');
} elsif ($activity eq 'passwd') {
$text = &mt('Password Changing Blocked');
+ } elsif ($activity eq 'alert') {
+ $text = &mt('Checking Critical Messages Blocked');
+ } elsif ($activity eq 'reinit') {
+ $text = &mt('Checking Course Update Blocked');
}
$output .= <<"END_BLOCK";
@@ -5809,6 +5906,10 @@ Inputs:
=item * $args, optional argument valid values are
no_auto_mt_title -> prevents &mt()ing the title arg
+ use_absolute -> for external resource or syllabus, this will
+ contain https:// if server uses
+ https (as per hosts.tab), but request is for http
+ hostname -> hostname, from $r->hostname().
=item * $advtoolsref, optional argument, ref to an array containing
inlineremote items to be added in "Functions" menu below
@@ -5834,6 +5935,7 @@ sub bodytag {
}
if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); }
my $httphost = $args->{'use_absolute'};
+ my $hostname = $args->{'hostname'};
$function = &get_users_function() if (!$function);
my $img = &designparm($function.'.img',$domain);
@@ -5862,7 +5964,11 @@ sub bodytag {
if ($env{'request.role'} !~ /^cr/) {
$role = &Apache::lonnet::plaintext($role,&course_type());
} elsif ($role =~ m{^cr/($match_domain)/\1-domainconfig/(\w+)$}) {
- $role = &mt('Helpdesk[_1]',' '.$2);
+ if ($env{'request.role.desc'}) {
+ $role = $env{'request.role.desc'};
+ } else {
+ $role = &mt('Helpdesk[_1]',' '.$2);
+ }
} else {
$role = (split(/\//,$role,4))[-1];
}
@@ -5958,17 +6064,18 @@ sub bodytag {
$bodytag .= Apache::lonhtmlcommon::scripttag('', 'end');
if ($env{'request.state'} eq 'construct') {
$bodytag .= &Apache::lonmenu::innerregister($forcereg,
- $args->{'bread_crumbs'});
+ $args->{'bread_crumbs'},'','',$hostname);
} elsif ($forcereg) {
$bodytag .= &Apache::lonmenu::innerregister($forcereg,undef,
$args->{'group'},
- $args->{'hide_buttons'});
+ $args->{'hide_buttons'},
+ $hostname);
} else {
$bodytag .=
&Apache::lonmenu::prepare_functions($env{'request.noversionuri'},
$forcereg,$args->{'group'},
$args->{'bread_crumbs'},
- $advtoolsref);
+ $advtoolsref,'',$hostname);
}
}else{
# this is to seperate menu from content when there's no secondary
@@ -6430,6 +6537,11 @@ td.LC_menubuttons_text {
background: $tabbg;
}
+td.LC_zero_height {
+ line-height: 0;
+ cellpadding: 0;
+}
+
table.LC_data_table {
border: 1px solid #000000;
border-collapse: separate;
@@ -6751,6 +6863,12 @@ td.LC_parm_overview_restrictions {
border-collapse: collapse;
}
+span.LC_parm_recursive,
+td.LC_parm_recursive {
+ font-weight: bold;
+ font-size: smaller;
+}
+
table.LC_parm_overview_restrictions td {
border-width: 1px 4px 1px 4px;
border-style: solid;
@@ -7102,6 +7220,12 @@ table.LC_data_table tr > td.LC_docs_entr
color: #990000;
}
+.LC_docs_alias {
+ color: #440055;
+}
+
+.LC_domprefs_email,
+.LC_docs_alias_name,
.LC_docs_reinit_warn,
.LC_docs_ext_edit {
font-size: x-small;
@@ -8122,6 +8246,39 @@ section.role-warning>h1:before {
content:url('/adm/daxe/images/section_icons/warning.png');
}
+#LC_minitab_header {
+ float:left;
+ width:100%;
+ background:#DAE0D2 url("/res/adm/pages/minitabmenu_bg.gif") repeat-x bottom;
+ font-size:93%;
+ line-height:normal;
+ margin: 0.5em 0 0.5em 0;
+}
+#LC_minitab_header ul {
+ margin:0;
+ padding:10px 10px 0;
+ list-style:none;
+}
+#LC_minitab_header li {
+ float:left;
+ background:url("/res/adm/pages/minitabmenu_left.gif") no-repeat left top;
+ margin:0;
+ padding:0 0 0 9px;
+}
+#LC_minitab_header a {
+ display:block;
+ background:url("/res/adm/pages/minitabmenu_right.gif") no-repeat right top;
+ padding:5px 15px 4px 6px;
+}
+#LC_minitab_header #LC_current_minitab {
+ background-image:url("/res/adm/pages/minitabmenu_left_on.gif");
+}
+#LC_minitab_header #LC_current_minitab a {
+ background-image:url("/res/adm/pages/minitabmenu_right_on.gif");
+ padding-bottom:5px;
+}
+
+
END
}
@@ -8314,6 +8471,7 @@ OFFLOAD
';
}
+ $result .= ''."\n";
return $result.'';
}
@@ -8493,8 +8651,14 @@ $args - additional optional args support
no_auto_mt_title -> prevent &mt()ing the title arg
bread_crumbs -> Array containing breadcrumbs
bread_crumbs_component -> if exists show it as headline else show only the breadcrumbs
+ bread_crumbs_nomenu -> if true will pass false as the value of $menulink
+ to lonhtmlcommon::breadcrumbs
group -> includes the current group, if page is for a
- specific group
+ specific group
+ use_absolute -> for request for external resource or syllabus, this
+ will contain https:// if server uses
+ https (as per hosts.tab), but request is for http
+ hostname -> hostname, originally from $r->hostname(), (optional).
=back
@@ -8558,15 +8722,21 @@ sub start_page {
if (@advtools > 0) {
&Apache::lonmenu::advtools_crumbs(@advtools);
}
-
+ my $menulink;
+ # if arg: bread_crumbs_nomenu is true pass 0 as $menulink item.
+ if ((exists($args->{'bread_crumbs_nomenu'})) ||
+ ((($args->{'crstype'} eq 'Placement') || (($env{'request.course.id'}) &&
+ ($env{'course.'.$env{'request.course.id'}.'.type'} eq 'Placement'))) &&
+ (!$env{'request.role.adv'}))) {
+ $menulink = 0;
+ } else {
+ undef($menulink);
+ }
#if bread_crumbs_component exists show it as headline else show only the breadcrumbs
if(exists($args->{'bread_crumbs_component'})){
- $result .= &Apache::lonhtmlcommon::breadcrumbs($args->{'bread_crumbs_component'});
- } elsif ($args->{'crstype'} eq 'Placement') {
- $result .= &Apache::lonhtmlcommon::breadcrumbs('','','','','','','','','',
- $args->{'crstype'});
+ $result .= &Apache::lonhtmlcommon::breadcrumbs($args->{'bread_crumbs_component'},'',$menulink);
} else {
- $result .= &Apache::lonhtmlcommon::breadcrumbs();
+ $result .= &Apache::lonhtmlcommon::breadcrumbs('','',$menulink);
}
}
return $result;
@@ -8663,7 +8833,7 @@ var modalWindow = {
};
var openMyModal = function(source,width,height,scrolling,transparency,style)
{
- source = source.replace("'","'");
+ source = source.replace(/'/g,"'");
modalWindow.windowId = "myModal";
modalWindow.width = width;
modalWindow.height = height;
@@ -8792,8 +8962,9 @@ sub end_togglebox {
}
sub LCprogressbar_script {
- my ($id)=@_;
- return(<
//
ENDPROGRESS
+ } else {
+ return(<
+//
+
+ENDPROGRESS
+ }
}
sub LCprogressbarUpdate_script {
return(<
.ui-progressbar { position:relative; }
+.progress-label {position: absolute; width: 100%; text-align: center; top: 1px; font-weight: bold; text-shadow: 1px 1px 0 #fff;margin: 0; line-height: 200%; }
.pblabel { position: absolute; width: 100%; text-align: center; line-height: 1.9em; }
@@ -8832,37 +9025,54 @@ my $LCidcnt;
my $LCcurrentid;
sub LCprogressbar {
- my ($r)=(@_);
+ my ($r,$number_to_do,$preamble)=@_;
$LClastpercent=0;
$LCidcnt++;
$LCcurrentid=$$.'_'.$LCidcnt;
- my $starting=&mt('Starting');
- my $content=(<
$starting
ENDPROGBAR
- &r_print($r,$content.&LCprogressbar_script($LCcurrentid));
+ } else {
+ $starting=&mt('Loading...');
+ $LClastpercent='false';
+ $content=(<
+ $starting
+
+ENDPROGBAR
+ }
+ &r_print($r,$content.&LCprogressbar_script($LCcurrentid,$number_to_do));
}
sub LCprogressbarUpdate {
- my ($r,$val,$text)=@_;
- unless ($val) {
- if ($LClastpercent) {
- $val=$LClastpercent;
- } else {
- $val=0;
- }
+ my ($r,$val,$text,$number_to_do)=@_;
+ if ($number_to_do) {
+ 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.'%'; }
+ } else {
+ $val = 'false';
}
- if ($val<0) { $val=0; }
- if ($val>100) { $val=0; }
- $LClastpercent=$val;
- unless ($text) { $text=$val.'%'; }
$text=&js_ready($text);
&r_print($r,<
//
ENDUPDATE
@@ -9047,14 +9257,21 @@ function expand_div(caller) {
sub simple_error_page {
my ($r,$title,$msg,$args) = @_;
+ my %displayargs;
if (ref($args) eq 'HASH') {
if (!$args->{'no_auto_mt_msg'}) { $msg = &mt($msg); }
+ if ($args->{'only_body'}) {
+ $displayargs{'only_body'} = 1;
+ }
+ if ($args->{'no_nav_bar'}) {
+ $displayargs{'no_nav_bar'} = 1;
+ }
} else {
$msg = &mt($msg);
}
my $page =
- &Apache::loncommon::start_page($title).
+ &Apache::loncommon::start_page($title,'',\%displayargs).
''.$msg.'
'.
&Apache::loncommon::end_page();
if (ref($r)) {
@@ -9982,7 +10199,7 @@ sub get_secgrprole_info {
}
sub user_picker {
- my ($dom,$srch,$forcenewuser,$caller,$cancreate,$usertype,$context,$fixeddom) = @_;
+ my ($dom,$srch,$forcenewuser,$caller,$cancreate,$usertype,$context,$fixeddom,$noinstd) = @_;
my $currdom = $dom;
my @alldoms = &Apache::lonnet::all_domains();
if (@alldoms == 1) {
@@ -10047,10 +10264,21 @@ sub user_picker {
&html_escape(\%html_lt);
&js_escape(\%js_lt);
my $domform;
+ my $allow_blank = 1;
if ($fixeddom) {
- $domform = &select_dom_form($currdom,'srchdomain',1,1,undef,[$currdom]);
+ $allow_blank = 0;
+ $domform = &select_dom_form($currdom,'srchdomain',$allow_blank,1,undef,[$currdom]);
} else {
- $domform = &select_dom_form($currdom,'srchdomain',1,1);
+ my $defdom = $env{'request.role.domain'};
+ my ($trusted,$untrusted);
+ if (($context eq 'requestcrs') || ($context eq 'course')) {
+ ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('enroll',$defdom);
+ } elsif ($context eq 'author') {
+ ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('othcoau',$defdom);
+ } elsif ($context eq 'domain') {
+ ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('domroles',$defdom);
+ }
+ $domform = &select_dom_form($currdom,'srchdomain',$allow_blank,1,undef,$trusted,$untrusted);
}
my $srchinsel = '