[LON-CAPA-cvs] cvs: doc /loncapafiles loncapafiles.lpml loncom/interface domainprefs.pm londocs.pm lonextresedit.pm lonexttool.pm lonhtmlcommon.pm lonmenu.pm lonsyllabus.pm loncom/rewrites loncapa_rewrite_off.conf loncapa_rewrite_on.conf rat lonuserstate.pm lonwrapper.pm
raeburn
raeburn at source.lon-capa.org
Tue Jan 26 09:30:52 EST 2016
raeburn Tue Jan 26 14:30:52 2016 EDT
Modified files:
/loncom/interface domainprefs.pm londocs.pm lonextresedit.pm
lonexttool.pm lonhtmlcommon.pm lonmenu.pm
lonsyllabus.pm
/loncom/rewrites loncapa_rewrite_off.conf loncapa_rewrite_on.conf
/rat lonuserstate.pm lonwrapper.pm
/doc/loncapafiles loncapafiles.lpml
Log:
- Bug 6754. Make LON-CAPA an LTI Tool Consumer (LTI 1.1). Work in progress.
-------------- next part --------------
Index: loncom/interface/domainprefs.pm
diff -u loncom/interface/domainprefs.pm:1.266 loncom/interface/domainprefs.pm:1.267
--- loncom/interface/domainprefs.pm:1.266 Mon Jun 15 20:11:56 2015
+++ loncom/interface/domainprefs.pm Tue Jan 26 14:30:24 2016
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Handler to set domain-wide configuration settings
#
-# $Id: domainprefs.pm,v 1.266 2015/06/15 20:11:56 raeburn Exp $
+# $Id: domainprefs.pm,v 1.267 2016/01/26 14:30:24 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -173,6 +173,7 @@
use Locale::Language;
use DateTime::TimeZone;
use DateTime::Locale;
+use Time::HiRes qw( sleep );
my $registered_cleanup;
my $modified_urls;
@@ -215,13 +216,14 @@
'contacts','defaults','scantron','coursecategories',
'serverstatuses','requestcourses','helpsettings',
'coursedefaults','usersessions','loadbalancing',
- 'requestauthor','selfenrollment','inststatus'],$dom);
+ 'requestauthor','selfenrollment','inststatus',
+ 'ltitools'],$dom);
my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',
'autoupdate','autocreate','directorysrch','contacts',
'usercreation','selfcreation','usermodification','scantron',
'requestcourses','requestauthor','coursecategories',
- 'serverstatuses','helpsettings',
- 'coursedefaults','selfenrollment','usersessions');
+ 'serverstatuses','helpsettings','coursedefaults',
+ 'ltitools','selfenrollment','usersessions');
my %existing;
if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
%existing = %{$domconfig{'loadbalancing'}};
@@ -472,6 +474,15 @@
print => \&print_loadbalancing,
modify => \&modify_loadbalancing,
},
+ 'ltitools' =>
+ {text => 'External Tools (LTI)',
+ help => 'Domain_configuration_LTI_Tools',
+ header => [{col1 => 'Setting',
+ col2 => 'Value',}],
+ print => \&print_ltitools,
+ modify => \&modify_ltitools,
+ },
+
);
if (keys(%servers) > 1) {
$prefs{'login'} = { text => 'Log-in page options',
@@ -645,6 +656,8 @@
$output = &modify_usersessions($dom,$lastactref,%domconfig);
} elsif ($action eq 'loadbalancing') {
$output = &modify_loadbalancing($dom,%domconfig);
+ } elsif ($action eq 'ltitools') {
+ $output = &modify_ltitools($r,$dom,$action,$lastactref,%domconfig);
}
return $output;
}
@@ -904,7 +917,8 @@
if ($action eq 'quotas') {
$output .= &print_quotas($dom,$settings,\$rowtotal,$action);
} elsif (($action eq 'autoenroll') || ($action eq 'autocreate') || ($action eq 'directorysrch') ||
- ($action eq 'contacts') || ($action eq 'serverstatuses') || ($action eq 'loadbalancing')) {
+ ($action eq 'contacts') || ($action eq 'serverstatuses') || ($action eq 'loadbalancing') ||
+ ($action eq 'ltitools')) {
$output .= $item->{'print'}->($dom,$settings,\$rowtotal);
} elsif ($action eq 'scantron') {
$output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);
@@ -2258,8 +2272,7 @@
(' 'x2).
'<span class="LC_nobreak">'.&mt('Thumbnail:');
if ($image) {
- $datatable .= '<span class="LC_nobreak">'.
- $imgsrc.
+ $datatable .= $imgsrc.
'<label><input type="checkbox" name="'.$type.'_image_del"'.
' value="'.$key.'" />'.&mt('Delete?').'</label></span> '.
'<span class="LC_nobreak"> '.&mt('Replace:').' ';
@@ -2413,6 +2426,74 @@
ENDSCRIPT
}
+sub ltitools_javascript {
+ my ($settings) = @_;
+ return unless(ref($settings) eq 'HASH');
+ my (%ordered,$total,%jstext);
+ $total = 0;
+ foreach my $item (keys(%{$settings})) {
+ if (ref($settings->{$item}) eq 'HASH') {
+ my $num = $settings->{$item}{'order'};
+ $ordered{$num} = $item;
+ }
+ }
+ $total = scalar(keys(%{$settings}));
+ my @jsarray = ();
+ foreach my $item (sort {$a <=> $b } (keys(%ordered))) {
+ push(@jsarray,$ordered{$item});
+ }
+ my $jstext = ' var ltitools = Array('."'".join("','", at jsarray)."'".');'."\n";
+ return <<"ENDSCRIPT";
+<script type="text/javascript">
+// <![CDATA[
+function reorderLTI(form,item) {
+ var changedVal;
+$jstext
+ var newpos = 'ltitools_add_pos';
+ var maxh = 1 + $total;
+ var current = new Array;
+ var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value;
+ if (item == newpos) {
+ changedVal = newitemVal;
+ } else {
+ changedVal = form.elements[item].options[form.elements[item].selectedIndex].value;
+ current[newitemVal] = newpos;
+ }
+ for (var i=0; i<ltitools.length; i++) {
+ var elementName = 'ltitools_'+ltitools[i];
+ if (elementName != item) {
+ if (form.elements[elementName]) {
+ var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;
+ current[currVal] = elementName;
+ }
+ }
+ }
+ var oldVal;
+ for (var j=0; j<maxh; j++) {
+ if (current[j] == undefined) {
+ oldVal = j;
+ }
+ }
+ if (oldVal < changedVal) {
+ for (var k=oldVal+1; k<=changedVal ; k++) {
+ var elementName = current[k];
+ form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;
+ }
+ } else {
+ for (var k=changedVal; k<oldVal; k++) {
+ var elementName = current[k];
+ form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;
+ }
+ }
+ return;
+}
+
+// ]]>
+</script>
+
+ENDSCRIPT
+}
+
sub print_autoenroll {
my ($dom,$settings,$rowtotal) = @_;
my $autorun = &Apache::lonnet::auto_run(undef,$dom),
@@ -2898,6 +2979,325 @@
return ($datatable,$itemcount);
}
+sub print_ltitools {
+ my ($dom,$settings,$rowtotal) = @_;
+ my $rownum = 0;
+ my $css_class;
+ my $itemcount = 1;
+ my $maxnum = 0;
+ my %ordered;
+ if (ref($settings) eq 'HASH') {
+ foreach my $item (keys(%{$settings})) {
+ if (ref($settings->{$item}) eq 'HASH') {
+ my $num = $settings->{$item}{'order'};
+ $ordered{$num} = $item;
+ }
+ }
+ }
+ my $confname = $dom.'-domainconfig';
+ my $switchserver = &check_switchserver($dom,$confname);
+ my $maxnum = scalar(keys(%ordered));
+ my $datatable = <itools_javascript($settings);
+ my %lt = <itools_names();
+ my @courseroles = ('cc','in','ta','ep','st');
+ my @ltiroles = qw(Instructor ContentDeveloper TeachingAssistant Learner);
+ my @fields = ('fullname','firstname','lastname','email','user','roles');
+ if (keys(%ordered)) {
+ my @items = sort { $a <=> $b } keys(%ordered);
+ for (my $i=0; $i<@items; $i++) {
+ $css_class = $itemcount%2?' class="LC_odd_row"':'';
+ my $item = $ordered{$items[$i]};
+ my ($title,$key,$secret,$url,$imgsrc,$version);
+ if (ref($settings->{$item}) eq 'HASH') {
+ $title = $settings->{$item}->{'title'};
+ $url = $settings->{$item}->{'url'};
+ $key = $settings->{$item}->{'key'};
+ $secret = $settings->{$item}->{'secret'};
+ my $image = $settings->{$item}->{'image'};
+ if ($image ne '') {
+ $imgsrc = '<img src="'.$image.'" alt="'.&mt('Tool Provider icon').'" />';
+ }
+ }
+ my $chgstr = ' onchange="javascript:reorderLTI(this.form,'."'ltitools_".$item."'".');"';
+ $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
+ .'<select name="ltitools_'.$item.'"'.$chgstr.'>';
+ for (my $k=0; $k<=$maxnum; $k++) {
+ my $vpos = $k+1;
+ my $selstr;
+ if ($k == $i) {
+ $selstr = ' selected="selected" ';
+ }
+ $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
+ }
+ $datatable .= '</select>'.(' 'x2).
+ '<label><input type="checkbox" name="ltitools_del" value="'.$item.'" />'.
+ &mt('Delete?').'</label></span></td>'.
+ '<td colspan="2">'.
+ '<fieldset><legend>'.&mt('Required settings').'</legend>'.
+ '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="30" name="ltitools_title_'.$i.'" value="'.$title.'" /></span> '.
+ (' 'x2).
+ '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_version_'.$i.'">'.
+ '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '.
+ (' 'x2).
+ '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_msgtype_'.$i.'">'.
+ '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '.
+ '<br /><br />'.
+ '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="30" name="ltitools_url_'.$i.'"'.
+ ' value="'.$url.'" /></span>'.
+ (' 'x2).
+ '<span class="LC_nobreak">'.$lt{'key'}.
+ '<input type="text" size="25" name="ltitools_key_'.$i.'" value="'.$key.'" /></span> '.
+ (' 'x2).
+ '<span class="LC_nobreak">'.$lt{'secret'}.':'.
+ '<input type="password" size="20" name="ltitools_secret_'.$i.'" value="'.$secret.'" />'.
+ '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.ltitools_secret_'.$i.'.type='."'text'".' } else { this.form.ltitools_secret_'.$i.'.type='."'password'".' }" />'.&mt('Visible input').'</label>'.
+ '<input type="hidden" name="ltitools_id_'.$i.'" value="'.$item.'" /></span>'.
+ '</fieldset>'.
+ '<fieldset><legend>'.&mt('Optional settings').'</legend>'.
+ '<span class="LC_nobreak">'.&mt('Display target:');
+ my %currdisp;
+ if (ref($settings->{$item}->{'display'}) eq 'HASH') {
+ if ($settings->{$item}->{'display'}->{'target'} eq 'window') {
+ $currdisp{'window'} = ' checked="checked"';
+ } else {
+ $currdisp{'iframe'} = ' checked="checked"';
+ }
+ if ($settings->{$item}->{'display'}->{'width'} =~ /^(\d+)$/) {
+ $currdisp{'width'} = $1;
+ }
+ if ($settings->{$item}->{'display'}->{'height'} =~ /^(\d+)$/) {
+ $currdisp{'height'} = $1;
+ }
+ } else {
+ $currdisp{'iframe'} = ' checked="checked"';
+ }
+ foreach my $disp ('iframe','window') {
+ $datatable .= '<label><input type="radio" name="ltitools_target_'.$i.'" value="'.$disp.'"'.$currdisp{$disp}.' />'.
+ $lt{$disp}.'</label>'.(' 'x2);
+ }
+ $datatable .= (' 'x4);
+ foreach my $dimen ('width','height') {
+ $datatable .= '<label>'.$lt{$dimen}.' '.
+ '<input type="text" name="ltitools_'.$dimen.'_'.$i.'" size="5" value="'.$currdisp{$dimen}.'" /></label>'.
+ (' 'x2);
+ }
+ $datatable .= '<br />';
+ foreach my $extra ('passback','roster') {
+ my $checkedon = '';
+ my $checkedoff = ' checked="checked"';
+ if ($settings->{$item}->{$extra}) {
+ $checkedon = $checkedoff;
+ $checkedoff = '';
+ }
+ $datatable .= $lt{$extra}.' '.
+ '<label><input type="radio" name="ltitools_'.$extra.'_'.$i.'" value="1"'.$checkedon.' />'.
+ &mt('Yes').'</label>'.(' 'x2).
+ '<label><input type="radio" name="ltitools_'.$extra.'_'.$i.'" value="0"'.$checkedoff.' />'.
+ &mt('No').'</label>'.(' 'x4);
+ }
+ $datatable .= '<br /><br /><span class="LC_nobreak">'.$lt{'icon'}.': ';
+ if ($imgsrc) {
+ $datatable .= $imgsrc.
+ '<label><input type="checkbox" name="ltitools_image_del"'.
+ ' value="'.$item.'" />'.&mt('Delete?').'</label></span> '.
+ '<span class="LC_nobreak"> '.&mt('Replace:').' ';
+ } else {
+ $datatable .= '('.&mt('if larger than 21x21 pixels, image will be scaled').') ';
+ }
+ if ($switchserver) {
+ $datatable .= &mt('Upload to library server: [_1]',$switchserver);
+ } else {
+ $datatable .= '<input type="file" name="ltitools_image_'.$i.'" value="" />';
+ }
+ $datatable .= '</span></fieldset>';
+ my (%checkedfields,%rolemaps);
+ if (ref($settings->{$item}) eq 'HASH') {
+ if (ref($settings->{$item}->{'fields'}) eq 'HASH') {
+ %checkedfields = %{$settings->{$item}->{'fields'}};
+ }
+ if (ref($settings->{$item}->{'roles'}) eq 'HASH') {
+ %rolemaps = %{$settings->{$item}->{'roles'}};
+ $checkedfields{'roles'} = 1;
+ }
+ }
+ $datatable .= '<fieldset><legend>'.&mt('User data sent on launch').'</legend>'.
+ '<span class="LC_nobreak">';
+ foreach my $field (@fields) {
+ my $checked;
+ if ($checkedfields{$field}) {
+ $checked = ' checked="checked"';
+ }
+ $datatable .= '<label>'.
+ '<input type="checkbox" name="ltitools_fields_'.$i.'" value="'.$field.'"'.$checked.' />'.
+ $lt{$field}.'</label>'.(' ' x2);
+ }
+ $datatable .= '</span></fieldset>'.
+ '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>';
+ foreach my $role (@courseroles) {
+ my ($selected,$selectnone);
+ if (!$rolemaps{$role}) {
+ $selectnone = ' selected="selected"';
+ }
+ $datatable .= '<td align="center">'.
+ &Apache::lonnet::plaintext($role,'Course').'<br />'.
+ '<select name="ltitools_roles_'.$role.'_'.$i.'">'.
+ '<option value=""'.$selectnone.'>'.&mt('Select').'</option>';
+ foreach my $ltirole (@ltiroles) {
+ unless ($selectnone) {
+ if ($rolemaps{$role} eq $ltirole) {
+ $selected = ' selected="selected"';
+ } else {
+ $selected = '';
+ }
+ }
+ $datatable .= '<option value="'.$ltirole.'"'.$selected.'>'.$ltirole.'</option>';
+ }
+ $datatable .= '</select></td>';
+ }
+ $datatable .= '</tr></table></fieldset>'.
+ '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'.
+ '<table><tr><th>'.&mt('Action').'</th><th>'.&mt('Name').'</th><th>'.&mt('Value').'</th></tr>';
+ if (ref($settings->{$item}->{'custom'}) eq 'HASH') {
+ my %custom = %{$settings->{$item}->{'custom'}};
+ if (keys(%custom) > 0) {
+ foreach my $key (sort(keys(%custom))) {
+ $datatable .= '<tr><td><span class="LC_nobreak">'.
+ '<label><input type="checkbox" name="ltitools_customdel_'.$i.'" value="'.
+ $key.'" />'.&mt('Delete').'</label></span></td><td>'.$key.'</td>'.
+ '<td><input type="text" name="ltitools_customval_'.$key.'_'.$i.'"'.
+ ' value="'.$custom{$key}.'" /></td></tr>';
+ }
+ }
+ }
+ $datatable .= '<tr><td><span class="LC_nobreak">'.
+ '<label><input type="checkbox" name="ltitools_customadd" value="'.$i.'" />'.
+ &mt('Add').'</label></span></td><td><input type="text" name="ltitools_custom_name_'.$i.'" />'.
+ '</td><td><input type="text" name="ltitools_custom_value_'.$i.'" /></td></tr>';
+ $datatable .= '</table></fieldset></td></tr>'."\n";
+ $itemcount ++;
+ }
+ }
+ $css_class = $itemcount%2?' class="LC_odd_row"':'';
+ my $chgstr = ' onchange="javascript:reorderLTI(this.form,'."'ltitools_add_pos'".');"';
+ $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n".
+ '<input type="hidden" name="ltitools_maxnum" value="'.$maxnum.'" />'."\n".
+ '<select name="ltitools_add_pos"'.$chgstr.'>';
+ for (my $k=0; $k<$maxnum+1; $k++) {
+ my $vpos = $k+1;
+ my $selstr;
+ if ($k == $maxnum) {
+ $selstr = ' selected="selected" ';
+ }
+ $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
+ }
+ $datatable .= '</select> '."\n".
+ '<input type="checkbox" name="ltitools_add" value="1" />'.&mt('Add').'</td>'."\n".
+ '<td colspan="2">'.
+ '<fieldset><legend>'.&mt('Required settings').'</legend>'.
+ '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="30" name="ltitools_add_title" value="" /></span> '."\n".
+ (' 'x2).
+ '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_add_version">'.
+ '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '."\n".
+ (' 'x2).
+ '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_add_msgtype">'.
+ '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '.
+ '<br />'.
+ '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="30" name="ltitools_add_url" value="" /></span> '."\n".
+ (' 'x2).
+ '<span class="LC_nobreak">'.$lt{'key'}.':<input type="text" size="25" name="ltitools_add_key" value="" /></span> '."\n".
+ (' 'x2).
+ '<span class="LC_nobreak">'.$lt{'secret'}.':<input type="password" size="20" name="ltitools_add_secret" value="" />'.
+ '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.ltitools_add_secret.type='."'text'".' } else { this.form.ltitools_add_secret.type='."'password'".' }" />'.&mt('Visible input').'</label></span> '."\n".
+ '</fieldset>'.
+ '<fieldset><legend>'.&mt('Optional settings').'</legend>'.
+ '<span class="LC_nobreak">'.&mt('Display target:');
+ my %defaultdisp;
+ $defaultdisp{'iframe'} = ' checked="checked"';
+ foreach my $disp ('iframe','window') {
+ $datatable .= '<label><input type="radio" name="ltitools_add_target" value="'.$disp.'"'.$defaultdisp{$disp}.' />'.
+ $lt{$disp}.'</label>'.(' 'x2);
+ }
+ $datatable .= (' 'x4);
+ foreach my $dimen ('width','height') {
+ $datatable .= '<label>'.$lt{$dimen}.' '.
+ '<input type="text" name="ltitools_add_'.$dimen.'" size="5" /></label>'.
+ (' 'x2);
+ }
+ $datatable .= '<br />';
+ foreach my $extra ('passback','roster') {
+ $datatable .= $lt{$extra}.' '.
+ '<label><input type="radio" name="ltitools_add_'.$extra.'" value="1" />'.
+ &mt('Yes').'</label>'.(' 'x2).
+ '<label><input type="radio" name="ltitools_add_'.$extra.'" value="0" checked="checked" />'.
+ &mt('No').'</label>'.(' 'x4);
+ }
+ $datatable .= '<br /><br /><span class="LC_nobreak">'.$lt{'icon'}.': '.
+ '('.&mt('if larger than 21x21 pixels, image will be scaled').') ';
+ if ($switchserver) {
+ $datatable .= &mt('Upload to library server: [_1]',$switchserver);
+ } else {
+ $datatable .= '<input type="file" name="ltitools_add_image" value="" />';
+ }
+ $datatable .= '</span></fieldset>'.
+ '<fieldset><legend>'.&mt('User data sent on launch').'</legend>'.
+ '<span class="LC_nobreak">';
+ foreach my $field (@fields) {
+ $datatable .= '<label>'.
+ '<input type="checkbox" name="ltitools_add_fields" value="'.$field.'" />'.
+ $lt{$field}.'</label>'.(' ' x2);
+ }
+ $datatable .= '</span></fieldset>'.
+ '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>';
+ foreach my $role (@courseroles) {
+ my ($checked,$checkednone);
+ $datatable .= '<td align="center">'.
+ &Apache::lonnet::plaintext($role,'Course').'<br />'.
+ '<select name="ltitools_add_roles_'.$role.'">'.
+ '<option value="" selected="selected">'.&mt('Select').'</option>';
+ foreach my $ltirole (@ltiroles) {
+ $datatable .= '<option value="'.$ltirole.'">'.$ltirole.'</option>';
+ }
+ $datatable .= '</select></td>';
+ }
+ $datatable .= '</tr></table></fieldset>'.
+ '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'.
+ '<table><tr><th>'.&mt('Action').'</th><th>'.&mt('Name').'</th><th>'.&mt('Value').'</th></tr>'.
+ '<tr><td><span class="LC_nobreak">'.
+ '<label><input type="checkbox" name="ltitools_add_custom" value="1" />'.
+ &mt('Add').'</label></span></td><td><input type="text" name="ltitools_add_custom_name" />'.
+ '</td><td><input type="text" name="ltitools_add_custom_value" /></td></tr>'.
+ '</table></fieldset></td></tr>'."\n".
+ '</td>'."\n".
+ '</tr>'."\n";
+ $itemcount ++;
+ return $datatable;
+}
+
+sub ltitools_names {
+ my %lt = &Apache::lonlocal::texthash(
+ 'title' => 'Title',
+ 'version' => 'Version',
+ 'msgtype' => 'Message Type',
+ 'url' => 'URL',
+ 'key' => 'Key',
+ 'secret' => 'Secret',
+ 'icon' => 'Icon',
+ 'user' => 'Username:domain',
+ 'fullname' => 'Full Name',
+ 'firstname' => 'First Name',
+ 'lastname' => 'Last Name',
+ 'email' => 'E-mail',
+ 'roles' => 'Role',
+ 'window' => 'Window/Tab',
+ 'iframe' => 'iFrame',
+ 'height' => 'Height',
+ 'width' => 'Width',
+ 'passback' => 'Tool can return grades:',
+ 'roster' => 'Tool can retrieve roster:',
+ );
+ return %lt;
+}
+
sub print_coursedefaults {
my ($position,$dom,$settings,$rowtotal) = @_;
my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked, at toggles);
@@ -6883,7 +7283,7 @@
sub publishlogo {
my ($r,$action,$formname,$dom,$confname,$subdir,$thumbwidth,$thumbheight,$savefileas) = @_;
- my ($output,$fname,$logourl);
+ my ($output,$fname,$logourl,$madethumb);
if ($action eq 'upload') {
$fname=$env{'form.'.$formname.'.filename'};
chop($env{'form.'.$formname});
@@ -7011,6 +7411,7 @@
$r->set_handlers('PerlCleanupHandler' => [\¬ifysubscribed,@{$handlers}]);
$registered_cleanup=1;
}
+ $madethumb = 1;
} else {
print $logfile "\nUnable to write ".$copyfile.
':'.$!."\n";
@@ -7023,7 +7424,7 @@
$output = $versionresult;
}
}
- return ($output,$logourl);
+ return ($output,$logourl,$madethumb);
}
sub logo_versioning {
@@ -7892,6 +8293,495 @@
return ($url,$error);
}
+sub modify_ltitools {
+ my ($r,$dom,$action,$lastactref,%domconfig) = @_;
+ my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
+ my ($newid, at allpos,%changes,%confhash,$errors,$resulttext);
+ my $confname = $dom.'-domainconfig';
+ my $servadm = $r->dir_config('lonAdmEMail');
+ my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);
+ my (%posslti,%possfield);
+ my @courseroles = ('cc','in','ta','ep','st');
+ my @ltiroles = qw(Instructor ContentDeveloper TeachingAssistant Learner);
+ map { $posslti{$_} = 1; } @ltiroles;
+ my @allfields = ('fullname','firstname','lastname','email','user','roles');
+ map { $possfield{$_} = 1; } @allfields;
+ my %lt = <itools_names();
+ if ($env{'form.ltitools_add'}) {
+ my $title = $env{'form.ltitools_add_title'};
+ $title =~ s/(`)/'/g;
+ ($newid,my $error) = &get_ltitools_id($dom,$title);
+ if ($newid) {
+ my $position = $env{'form.ltitools_add_pos'};
+ $position =~ s/\D+//g;
+ if ($position ne '') {
+ $allpos[$position] = $newid;
+ }
+ $changes{$newid} = 1;
+ foreach my $item ('title','url','key','secret') {
+ $env{'form.ltitools_add_'.$item} =~ s/(`)/'/g;
+ if ($env{'form.ltitools_add_'.$item}) {
+ $confhash{$newid}{$item} = $env{'form.ltitools_add_'.$item};
+ }
+ }
+ if ($env{'form.ltitools_add_version'} eq 'LTI-1p0') {
+ $confhash{$newid}{'version'} = $env{'form.ltitools_add_version'};
+ }
+ if ($env{'form.ltitools_add_msgtype'} eq 'basic-lti-launch-request') {
+ $confhash{$newid}{'msgtype'} = $env{'form.ltitools_add_msgtype'};
+ }
+ foreach my $item ('width','height') {
+ $env{'form.ltitools_add_'.$item} =~ s/^\s+//;
+ $env{'form.ltitools_add_'.$item} =~ s/\s+$//;
+ if ($env{'form.ltitools_add_'.$item} =~ /^\d+$/) {
+ $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};
+ }
+ }
+ if ($env{'form.ltitools_add_target'} eq 'window') {
+ $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'};
+ } else {
+ $confhash{$newid}{'display'}{'target'} = 'iframe';
+ }
+ foreach my $item ('passback','roster') {
+ if ($env{'form.ltitools_add_'.$item}) {
+ $confhash{$newid}{$item} = 1;
+ }
+ }
+ if ($env{'form.ltitools_add_image.filename'} ne '') {
+ my ($imageurl,$error) =
+ &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$dom,
+ $configuserok,$switchserver,$author_ok);
+ if ($imageurl) {
+ $confhash{$newid}{'image'} = $imageurl;
+ }
+ if ($error) {
+ &Apache::lonnet::logthis($error);
+ $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
+ }
+ }
+ my @fields = &Apache::loncommon::get_env_multiple('form.ltitools_add_fields');
+ foreach my $field (@fields) {
+ if ($possfield{$field}) {
+ if ($field eq 'roles') {
+ foreach my $role (@courseroles) {
+ my $choice = $env{'form.ltitools_add_roles_'.$role};
+ if (($choice ne '') && ($posslti{$choice})) {
+ $confhash{$newid}{'roles'}{$role} = $choice;
+ if ($role eq 'cc') {
+ $confhash{$newid}{'roles'}{'co'} = $choice;
+ }
+ }
+ }
+ } else {
+ $confhash{$newid}{'fields'}{$field} = 1;
+ }
+ }
+ }
+ if ($env{'form.ltitools_add_custom'}) {
+ my $name = $env{'form.ltitools_add_custom_name'};
+ my $value = $env{'form.ltitools_add_custom_value'};
+ $value =~ s/(`)/'/g;
+ $name =~ s/(`)/'/g;
+ $confhash{$newid}{'custom'}{$name} = $value;
+ }
+ } else {
+ my $error = &mt('Failed to acquire unique ID for new external tool');
+ $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
+ }
+ }
+ if (ref($domconfig{$action}) eq 'HASH') {
+ my %deletions;
+ my @todelete = &Apache::loncommon::get_env_multiple('form.ltitools_del');
+ if (@todelete) {
+ map { $deletions{$_} = 1; } @todelete;
+ }
+ my %customadds;
+ my @newcustom = &Apache::loncommon::get_env_multiple('form.ltitools_customadd');
+ if (@newcustom) {
+ map { $customadds{$_} = 1; } @newcustom;
+ }
+ my %imgdeletions;
+ my @todeleteimages = &Apache::loncommon::get_env_multiple('form.ltitools_image_del');
+ if (@todeleteimages) {
+ map { $imgdeletions{$_} = 1; } @todeleteimages;
+ }
+ my $maxnum = $env{'form.ltitools_maxnum'};
+ for (my $i=0; $i<=$maxnum; $i++) {
+ my $itemid = $env{'form.ltitools_id_'.$i};
+ if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
+ if ($deletions{$itemid}) {
+ if ($domconfig{$action}{$itemid}{'image'}) {
+ #FIXME need to obsolete item in RES space
+ }
+ $changes{$itemid} = $domconfig{$action}{$itemid}{'title'};
+ next;
+ } else {
+ my $newpos = $env{'form.ltitools_'.$itemid};
+ $newpos =~ s/\D+//g;
+ foreach my $item ('title','url','key','secret') {
+ $confhash{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};
+ if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) {
+ $changes{$itemid} = 1;
+ }
+ }
+ if ($env{'form.ltitools_version_'.$i} eq 'LTI-1p0') {
+ $confhash{$itemid}{'version'} = $env{'form.ltitools_version_'.$i};
+ }
+ if ($env{'form.ltitools_msgtype_'.$i} eq 'basic-lti-launch-request') {
+ $confhash{$itemid}{'msgtype'} = $env{'form.ltitools_msgtype_'.$i};
+ }
+ foreach my $size ('width','height') {
+ $env{'form.ltitools_'.$size.'_'.$i} =~ s/^\s+//;
+ $env{'form.ltitools_'.$size.'_'.$i} =~ s/\s+$//;
+ if ($env{'form.ltitools_'.$size.'_'.$i} =~ /^\d+$/) {
+ $confhash{$itemid}{'display'}{$size} = $env{'form.ltitools_'.$size.'_'.$i};
+ if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
+ if ($domconfig{$action}{$itemid}{'display'}{$size} ne $confhash{$itemid}{'display'}{$size}) {
+ $changes{$itemid} = 1;
+ }
+ } else {
+ $changes{$itemid} = 1;
+ }
+ }
+ }
+ if ($env{'form.ltitools_target_'.$i} eq 'window') {
+ $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i};
+ } else {
+ $confhash{$itemid}{'display'}{'target'} = 'iframe';
+ }
+ if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
+ if ($domconfig{$action}{$itemid}{'display'}{'target'} ne $confhash{$itemid}{'display'}{'target'}) {
+ $changes{$itemid} = 1;
+ }
+ } else {
+ $changes{$itemid} = 1;
+ }
+ foreach my $extra ('passback','roster') {
+ if ($env{'form.ltitools_'.$extra.'_'.$i}) {
+ $confhash{$itemid}{$extra} = 1;
+ }
+ if ($domconfig{$action}{$itemid}{$extra} ne $confhash{$itemid}{$extra}) {
+ $changes{$itemid} = 1;
+ }
+ }
+ my @fields = &Apache::loncommon::get_env_multiple('form.ltitools_fields_'.$i);
+ foreach my $field (@fields) {
+ if ($possfield{$field}) {
+ if ($field eq 'roles') {
+ foreach my $role (@courseroles) {
+ my $choice = $env{'form.ltitools_roles_'.$role.'_'.$i};
+ if (($choice ne '') && ($posslti{$choice})) {
+ $confhash{$itemid}{'roles'}{$role} = $choice;
+ if ($role eq 'cc') {
+ $confhash{$itemid}{'roles'}{'co'} = $choice;
+ }
+ }
+ if (ref($domconfig{$action}{$itemid}{'roles'}) eq 'HASH') {
+ if ($domconfig{$action}{$itemid}{'roles'}{$role} ne $confhash{$itemid}{'roles'}{$role}) {
+ $changes{$itemid} = 1;
+ }
+ } elsif ($confhash{$itemid}{'roles'}{$role}) {
+ $changes{$itemid} = 1;
+ }
+ }
+ } else {
+ $confhash{$itemid}{'fields'}{$field} = 1;
+ if (ref($domconfig{$action}{$itemid}{'fields'}) eq 'HASH') {
+ if ($domconfig{$action}{$itemid}{'fields'}{$field} ne $confhash{$itemid}{'fields'}{$field}) {
+ $changes{$itemid} = 1;
+ }
+ } else {
+ $changes{$itemid} = 1;
+ }
+ }
+ }
+ }
+ $allpos[$newpos] = $itemid;
+ }
+ if ($imgdeletions{$itemid}) {
+ $changes{$itemid} = 1;
+ #FIXME need to obsolete item in RES space
+ } elsif ($env{'form.ltitools_image_'.$i.'.filename'}) {
+ my ($imgurl,$error) = &process_ltitools_image($r,$dom,$confname,'ltitools_image_'.$i,
+ $itemid,$configuserok,$switchserver,
+ $author_ok);
+ if ($imgurl) {
+ $confhash{$itemid}{'image'} = $imgurl;
+ $changes{$itemid} = 1;
+ }
+ if ($error) {
+ &Apache::lonnet::logthis($error);
+ $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
+ }
+ } elsif ($domconfig{$action}{$itemid}{'image'}) {
+ $confhash{$itemid}{'image'} =
+ $domconfig{$action}{$itemid}{'image'};
+ }
+ if ($customadds{$i}) {
+ my $name = $env{'form.ltitools_custom_name_'.$i};
+ $name =~ s/(`)/'/g;
+ $name =~ s/^\s+//;
+ $name =~ s/\s+$//;
+ my $value = $env{'form.ltitools_custom_value_'.$i};
+ $value =~ s/(`)/'/g;
+ $value =~ s/^\s+//;
+ $value =~ s/\s+$//;
+ if ($name ne '') {
+ $confhash{$itemid}{'custom'}{$name} = $value;
+ $changes{$itemid} = 1;
+ }
+ }
+ my %customdels;
+ my @customdeletions = &Apache::loncommon::get_env_multiple('form.ltitools_customdel_'.$i);
+ if (@customdeletions) {
+ $changes{$itemid} = 1;
+ }
+ map { $customdels{$_} = 1; } @customdeletions;
+ if (ref($domconfig{$action}{$itemid}{'custom'}) eq 'HASH') {
+ foreach my $key (keys(%{$domconfig{$action}{$itemid}{'custom'}})) {
+ unless ($customdels{$key}) {
+ if ($env{'form.ltitools_customval_'.$key.'_'.$i} ne '') {
+ $confhash{$itemid}{'custom'}{$key} = $env{'form.ltitools_customval_'.$key.'_'.$i};
+ }
+ if ($domconfig{$action}{$itemid}{'custom'}{$key} ne $env{'form.ltitools_customval_'.$key.'_'.$i}) {
+ $changes{$itemid} = 1;
+ }
+ }
+ }
+ }
+ unless ($changes{$itemid}) {
+ foreach my $key (keys(%{$domconfig{$action}{$itemid}})) {
+ if (ref($domconfig{$action}{$itemid}{$key}) eq 'HASH') {
+ if (ref($confhash{$itemid}{$key}) eq 'HASH') {
+ foreach my $innerkey (keys(%{$domconfig{$action}{$itemid}{$key}})) {
+ unless (exists($confhash{$itemid}{$key}{$innerkey})) {
+ $changes{$itemid} = 1;
+ last;
+ }
+ }
+ } elsif (keys(%{$domconfig{$action}{$itemid}{$key}}) > 0) {
+ $changes{$itemid} = 1;
+ }
+ }
+ last if ($changes{$itemid});
+ }
+ }
+ }
+ }
+ }
+ if (@allpos > 0) {
+ my $idx = 0;
+ foreach my $itemid (@allpos) {
+ if ($itemid ne '') {
+ $confhash{$itemid}{'order'} = $idx;
+ if (ref($domconfig{$action}) eq 'HASH') {
+ if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
+ if ($domconfig{$action}{$itemid}{'order'} ne $idx) {
+ $changes{$itemid} = 1;
+ }
+ }
+ }
+ $idx ++;
+ }
+ }
+ }
+ my %ltitoolshash = (
+ $action => { %confhash }
+ );
+ my $putresult = &Apache::lonnet::put_dom('configuration',\%ltitoolshash,
+ $dom);
+ if ($putresult eq 'ok') {
+ if (keys(%changes) > 0) {
+ my $cachetime = 24*60*60;
+ &Apache::lonnet::do_cache_new('ltitools',$dom,\%confhash,$cachetime);
+ if (ref($lastactref) eq 'HASH') {
+ $lastactref->{'ltitools'} = 1;
+ }
+ $resulttext = &mt('Changes made:').'<ul>';
+ my %bynum;
+ foreach my $itemid (sort(keys(%changes))) {
+ my $position = $confhash{$itemid}{'order'};
+ $bynum{$position} = $itemid;
+ }
+ foreach my $pos (sort { $a <=> $b } keys(%bynum)) {
+ my $itemid = $bynum{$pos};
+ if (ref($confhash{$itemid}) ne 'HASH') {
+ $resulttext .= '<li>'.&mt('Deleted: [_1]',$changes{$itemid}).'</li>';
+ } else {
+ $resulttext .= '<li><b>'.$confhash{$itemid}{'title'}.'</b>';
+ if ($confhash{$itemid}{'image'}) {
+ $resulttext .= ' '.
+ '<img src="'.$confhash{$itemid}{'image'}.'"'.
+ ' alt="'.&mt('Tool Provider icon').'" />';
+ }
+ $resulttext .= '</li><ul>';
+ my $position = $pos + 1;
+ $resulttext .= '<li>'.&mt('Order: [_1]',$position).'</li>';
+ foreach my $item ('version','msgtype','url','key') {
+ if ($confhash{$itemid}{$item} ne '') {
+ $resulttext .= '<li>'.$lt{$item}.': '.$confhash{$itemid}{$item}.'</li>';
+ }
+ }
+ if ($confhash{$itemid}{'secret'} ne '') {
+ $resulttext .= '<li>'.$lt{'secret'}.': ';
+ my $num = length($confhash{$itemid}{'secret'});
+ $resulttext .= ('*'x$num).'</li>';
+ }
+ foreach my $item ('passback','roster') {
+ $resulttext .= '<li>'.$lt{$item}.' ';
+ if ($confhash{$itemid}{$item}) {
+ $resulttext .= &mt('Yes');
+ } else {
+ $resulttext .= &mt('No');
+ }
+ $resulttext .= '</li>';
+ }
+ if (ref($confhash{$itemid}{'display'}) eq 'HASH') {
+ my $displaylist;
+ if ($confhash{$itemid}{'display'}{'target'}) {
+ $displaylist = &mt('Display target').': '.
+ $confhash{$itemid}{'display'}{'target'}.',';
+ }
+ foreach my $size ('width','height') {
+ if ($confhash{$itemid}{'display'}{$size}) {
+ $displaylist .= (' 'x2).$lt{$size}.': '.
+ $confhash{$itemid}{'display'}{$size}.',';
+ }
+ }
+ if ($displaylist) {
+ $displaylist =~ s/,$//;
+ $resulttext .= '<li>'.$displaylist.'</li>';
+ }
+ }
+ if (ref($confhash{$itemid}{'fields'}) eq 'HASH') {
+ my $fieldlist;
+ foreach my $field (@allfields) {
+ if ($confhash{$itemid}{'fields'}{$field}) {
+ $fieldlist .= (' 'x2).$lt{$field}.',';
+ }
+ }
+ if ($fieldlist) {
+ $fieldlist =~ s/,$//;
+ $resulttext .= '<li>'.&mt('Data sent').':'.$fieldlist.'</li>';
+ }
+ }
+ if (ref($confhash{$itemid}{'roles'}) eq 'HASH') {
+ my $rolemaps;
+ foreach my $role (@courseroles) {
+ if ($confhash{$itemid}{'roles'}{$role}) {
+ $rolemaps .= (' 'x2).&Apache::lonnet::plaintext($role,'Course').'='.
+ $confhash{$itemid}{'roles'}{$role}.',';
+ }
+ }
+ if ($rolemaps) {
+ $rolemaps =~ s/,$//;
+ $resulttext .= '<li>'.&mt('Role mapping:').$rolemaps.'</li>';
+ }
+ }
+ if (ref($confhash{$itemid}{'custom'}) eq 'HASH') {
+ my $customlist;
+ if (keys(%{$confhash{$itemid}{'custom'}})) {
+ foreach my $key (sort(keys(%{$confhash{$itemid}{'custom'}}))) {
+ $customlist .= $key.':'.$confhash{$itemid}{'custom'}{$key}.(' 'x2);
+ }
+ }
+ if ($customlist) {
+ $resulttext .= '<li>'.&mt('Custom items').':'.$customlist.'</li>';
+ }
+ }
+ $resulttext .= '</ul></li>';
+ }
+ }
+ $resulttext .= '</ul>';
+ } else {
+ $resulttext = &mt('No changes made.');
+ }
+ } else {
+ $errors .= '<li><span class="LC_error">'.&mt('Failed to save changes').'</span></li>';
+ }
+ if ($errors) {
+ $resulttext .= &mt('The following errors occurred: ').'<ul>'.
+ $errors.'</ul>';
+ }
+ return $resulttext;
+}
+
+sub process_ltitools_image {
+ my ($r,$dom,$confname,$caller,$itemid,$configuserok,$switchserver,$author_ok) = @_;
+ my $filename = $env{'form.'.$caller.'.filename'};
+ my ($error,$url);
+ my ($width,$height) = (21,21);
+ if ($configuserok eq 'ok') {
+ if ($switchserver) {
+ $error = &mt('Upload of Tool Provider (LTI) icon is not permitted to this server: [_1]',
+ $switchserver);
+ } elsif ($author_ok eq 'ok') {
+ my ($result,$imageurl,$madethumb) =
+ &publishlogo($r,'upload',$caller,$dom,$confname,
+ "ltitools/$itemid/icon",$width,$height);
+ if ($result eq 'ok') {
+ if ($madethumb) {
+ my ($path,$imagefile) = ($imageurl =~ m{^(.+)/([^/]+)$});
+ my $imagethumb = "$path/tn-".$imagefile;
+ $url = $imagethumb;
+ } else {
+ $url = $imageurl;
+ }
+ } else {
+ $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$filename,$result);
+ }
+ } else {
+ $error = &mt("Upload of [_1] failed because an author role could not be assigned to a Domain Configuration user ([_2]) in domain: [_3]. Error was: [_4].",$filename,$confname,$dom,$author_ok);
+ }
+ } else {
+ $error = &mt("Upload of [_1] failed because a Domain Configuration user ([_2]) could not be created in domain: [_3]. Error was: [_4].",$filename,$confname,$dom,$configuserok);
+ }
+ return ($url,$error);
+}
+
+sub get_ltitools_id {
+ my ($cdom,$title) = @_;
+ # get lock on ltitools db
+ my $lockhash = {
+ lock => $env{'user.name'}.
+ ':'.$env{'user.domain'},
+ };
+ my $tries = 0;
+ my $gotlock = &Apache::lonnet::newput_dom('ltitools',$lockhash,$cdom);
+ my ($id,$error);
+
+ while (($gotlock ne 'ok') && ($tries<10)) {
+ $tries ++;
+ sleep (0.1);
+ $gotlock = &Apache::lonnet::newput_dom('ltitools',$lockhash,$cdom);
+ }
+ if ($gotlock eq 'ok') {
+ my %currids = &Apache::lonnet::dump_dom('ltitools',$cdom);
+ if ($currids{'lock'}) {
+ delete($currids{'lock'});
+ if (keys(%currids)) {
+ my @curr = sort { $a <=> $b } keys(%currids);
+ if ($curr[-1] =~ /^\d+$/) {
+ $id = 1 + $curr[-1];
+ }
+ } else {
+ $id = 1;
+ }
+ if ($id) {
+ unless (&Apache::lonnet::newput_dom('ltitools',{ $id => $title },$cdom) eq 'ok') {
+ $error = 'nostore';
+ }
+ } else {
+ $error = 'nonumber';
+ }
+ }
+ my $dellockoutcome = &Apache::lonnet::del_dom('ltitools',['lock'],$cdom);
+ } else {
+ $error = 'nolock';
+ }
+ return ($id,$error);
+}
+
sub modify_autoenroll {
my ($dom,$lastactref,%domconfig) = @_;
my ($resulttext,%changes);
@@ -12241,7 +13131,7 @@
my %servers = &Apache::lonnet::internet_dom_servers($dom);
my %thismachine;
map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids();
- my @posscached = ('domainconfig','domdefaults');
+ my @posscached = ('domainconfig','domdefaults','ltitools');
if (keys(%servers)) {
foreach my $server (keys(%servers)) {
next if ($thismachine{$server});
Index: loncom/interface/londocs.pm
diff -u loncom/interface/londocs.pm:1.597 loncom/interface/londocs.pm:1.598
--- loncom/interface/londocs.pm:1.597 Sat Sep 12 15:47:57 2015
+++ loncom/interface/londocs.pm Tue Jan 26 14:30:25 2016
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Documents
#
-# $Id: londocs.pm,v 1.597 2015/09/12 15:47:57 raeburn Exp $
+# $Id: londocs.pm,v 1.598 2016/01/26 14:30:25 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -586,7 +586,7 @@
}
sub group_import {
- my ($coursenum, $coursedom, $folder, $container, $caller, @files) = @_;
+ my ($coursenum, $coursedom, $folder, $container, $caller, $ltitoolsref, @files) = @_;
my ($donechk,$allmaps,%hierarchy,%titles,%addedmaps,%removefrommap,
%removeparam,$importuploaded,$fixuperrors);
$allmaps = {};
@@ -615,6 +615,39 @@
}
}
if ($url) {
+ if ($url =~ m{^(/adm/$coursedom/$coursenum/(\d+)/exttool)s?\:?(.*)$}) {
+ $url = $1;
+ my $marker = $2;
+ my $info = $3;
+ my ($toolid,%toolhash);
+ my @toolinfo = split(/:/,$info);
+ if ($residx) {
+ my %toolsettings=&Apache::lonnet::dump('exttool_'.$marker,$coursedom,$coursenum);
+ $toolid = $toolsettings{'id'};
+ } else {
+ $toolid = shift(@toolinfo);
+ }
+ $toolid =~ s/\D//g;
+ ($toolhash{'target'},$toolhash{'width'},$toolhash{'height'}) = @toolinfo;
+ if (ref($ltitoolsref) eq 'HASH') {
+ if (ref($ltitoolsref->{$toolid}) eq 'HASH') {
+ if ($ltitoolsref->{$toolid}->{'url'} =~ m{^https://}) {
+ $url =~ s/exttool$/exttools/;
+ }
+ $toolhash{'id'} = $toolid;
+ if ($toolhash{'target'} eq 'iframe') {
+ delete($toolhash{'width'});
+ delete($toolhash{'height'});
+ } elsif ($toolhash{'target'} eq 'window') {
+ foreach my $item ('width','height') {
+ $toolhash{$item} =~ s/^\s+//;
+ $toolhash{$item} =~ s/\s+$//;
+ }
+ }
+ my $putres = &Apache::lonnet::put('exttool_'.$marker,\%toolhash,$coursedom,$coursenum);
+ }
+ }
+ }
if (($caller eq 'londocs') &&
($folder =~ /^default/)) {
if (($url =~ /\.(page|sequence)$/) && (!$donechk)) {
@@ -1150,10 +1183,12 @@
($url ne '')) {
$clipboardcount ++;
my ($is_external,$othercourse,$fromsupp,$is_uploaded_map,$parent,
- $canpaste,$nopaste,$othercrs,$areachange);
+ $canpaste,$nopaste,$othercrs,$areachange,$is_exttool);
my $extension = (split(/\./,$env{'docs.markedcopy_url_'.$suffix}))[-1];
if ($url =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//} ) {
$is_external = 1;
+ } elsif ($url =~ m{^/adm/$match_domain/$match_courseid/\d+/exttools?$}) {
+ $is_exttool = 1;
}
if ($folder =~ /^supplemental/) {
$canpaste = &supp_pasteable($env{'docs.markedcopy_url_'.$suffix});
@@ -1202,7 +1237,7 @@
}
}
my $buffer;
- if ($is_external) {
+ if (($is_external) || ($is_exttool)) {
$buffer = &mt('External Resource').': '.
&LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix}).' ('.
&LONCAPA::map::qtescape($url).')';
@@ -1362,7 +1397,8 @@
(($url =~ /\.sequence$/) && ($url =~ m{^/uploaded/})) ||
($url =~ m{^/uploaded/$match_domain/$match_courseid/(docs|supplemental)/(default|\d+)/\d+/}) ||
($url =~ m{^/adm/$match_domain/$match_username/aboutme}) ||
- ($url =~ m{^/public/$match_domain/$match_courseid/syllabus})) {
+ ($url =~ m{^/public/$match_domain/$match_courseid/syllabus}) ||
+ ($url =~ m{^/adm/$match_domain/$match_courseid/\d+/exttools?$})) {
return 1;
}
return;
@@ -2880,7 +2916,7 @@
sub editor {
my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$crstype,
- $supplementalflag,$orderhash,$iconpath,$pathitem)=@_;
+ $supplementalflag,$orderhash,$iconpath,$pathitem,$ltitoolsref)=@_;
my ($randompick,$ishidden,$isencrypted,$plain,$is_random_order,$container);
if ($allowed) {
(my $breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,
@@ -3079,6 +3115,17 @@
} else {
return $errortxt;
}
+ } elsif ($url =~ m{^/adm/$coursedom/$coursenum/new/exttool}) {
+ my ($suffix,$errortxt,$locknotfreed) =
+ &new_timebased_suffix($coursedom,$coursenum,'exttool');
+ if ($locknotfreed) {
+ $r->print($locknotfreed);
+ }
+ if ($suffix) {
+ $url =~ s{^(/adm/$coursedom/$coursenum)/new}{$1/$suffix};
+ } else {
+ return $errortxt;
+ }
} elsif ($url =~ m{^/uploaded/$coursedom/$coursenum/(docs|supplemental)/(default|\d+)/new.html$}) {
if ($supplementalflag) {
next unless ($1 eq 'supplemental');
@@ -3101,7 +3148,7 @@
}
($errtext,$fatal,my $fixuperrors) =
&group_import($coursenum, $coursedom, $folder,$container,
- 'londocs', at imports);
+ 'londocs',$ltitoolsref, at imports);
return $errtext if ($fatal);
if ($fixuperrors) {
$r->print($fixuperrors);
@@ -3186,7 +3233,7 @@
$output .= &entryline($idx,$name,$url,$folder,$allowed,$res,
$coursenum,$coursedom,$crstype,
$pathitem,$supplementalflag,$container,
- \%filters,\%curr_groups);
+ \%filters,\%curr_groups,$ltitoolsref);
$idx++;
$shown++;
}
@@ -3552,7 +3599,8 @@
sub entryline {
my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$coursedom,
- $crstype,$pathitem,$supplementalflag,$container,$filtersref,$currgroups)=@_;
+ $crstype,$pathitem,$supplementalflag,$container,$filtersref,$currgroups,
+ $ltitoolsref)=@_;
my ($foldertitle,$renametitle,$oldtitle);
if (&is_supplemental_title($title)) {
($title,$foldertitle,$renametitle) = &Apache::loncommon::parse_supplemental_title($title);
@@ -3643,6 +3691,7 @@
'rn' => 'Rename',
'cp' => 'Copy',
'ex' => 'External Resource',
+ 'et' => 'External Tool',
'ed' => 'Edit',
'pr' => 'Preview',
'sv' => 'Save',
@@ -3660,6 +3709,7 @@
|/aboutme$
|/navmaps$
|/bulletinboard$
+ |/exttools?$
|\.html$)}x)
|| $isexternal) {
$skip_confirm = 1;
@@ -3796,7 +3846,9 @@
}
} elsif ($url=~m|^/ext/|) {
$url='/adm/wrapper'.$url;
- }
+ } elsif ($url=~m{^/adm/$coursedom/$coursenum/\d+/exttools?$}) {
+ $url='/adm/wrapper'.$url;
+ }
if (&Apache::lonnet::symbverify($symb,$url)) {
$url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb);
} else {
@@ -3862,12 +3914,17 @@
$form_end;
}
} elsif ($supplementalflag && !$allowed) {
+ my $isexttool;
+ if ($url=~m{^/adm/$coursedom/$coursenum/\d+/exttools?$}) {
+ $url='/adm/wrapper'.$url;
+ $isexttool = 1;
+ }
$url .= ($url =~ /\?/) ? '&':'?';
$url .= 'folderpath='.&HTML::Entities::encode($esc_path,'<>&"');
if ($title) {
$url .= '&title='.&HTML::Entities::encode($renametitle,'<>&"');
}
- if ($isexternal && $orderidx) {
+ if ((($isexternal) || ($isexttool)) && $orderidx) {
$url .= '&idx='.$orderidx;
}
}
@@ -3878,6 +3935,11 @@
if ($isexternal) {
($editlink,$extresform) =
&Apache::lonextresedit::extedit_form(0,$residx,$orig_url,$title,$pathitem);
+ } elsif ($orig_url =~ m{^/adm/$coursedom/$coursenum/\d+/exttools?$}) {
+ ($editlink,$extresform) =
+ &Apache::lonextresedit::extedit_form(0,$residx,$orig_url,$title,$pathitem,
+ undef,undef,undef,'tool',$coursedom,
+ $coursenum,$ltitoolsref);
} elsif (!$isfolder && !$ispage) {
my ($cfile,$home,$switchserver,$forceedit,$forceview) =
&Apache::lonnet::can_edit_resource($fileloc,$coursenum,$coursedom,$orig_url);
@@ -4789,6 +4851,7 @@
my $container;
my $containertag;
my $pathitem;
+ my %ltitools;
# Do we directly jump somewhere?
@@ -4926,11 +4989,13 @@
}
}
my $tabidstr = join("','", at tabids);
+ %ltitools = &Apache::lonnet::get_domain_ltitools($coursedom);
+ my $exttoolurl = "/adm/$coursedom/$coursenum/new/exttool";
$script .= &editing_js($udom,$uname,$supplementalflag).
&history_tab_js().
&inject_data_js().
&Apache::lonhtmlcommon::resize_scrollbox_js('docs',$tabidstr,$tid).
- &Apache::lonextresedit::extedit_javascript();
+ &Apache::lonextresedit::extedit_javascript(\%ltitools);
$addentries = {
onload => "javascript:resize_scrollbox('contentscroll','1','1');",
};
@@ -5048,6 +5113,8 @@
'impo' => 'Import',
'lnks' => 'Import from Stored Links',
'impm' => 'Import from Assembled Map',
+ 'extr' => 'External Resource',
+ 'extt' => 'External Tool',
'selm' => 'Select Map',
'load' => 'Load Map',
'newf' => 'New Folder',
@@ -5191,6 +5258,11 @@
my $extresourcesform =
&Apache::lonextresedit::extedit_form(0,0,undef,undef,$pathitem,
$help{'Adding_External_Resource'});
+ my $exttoolform =
+ &Apache::lonextresedit::extedit_form(0,0,undef,undef,$pathitem,
+ $help{'Adding_External_Tool'},undef,
+ undef,'tool',$coursedom,$coursenum,
+ \%ltitools);
if ($allowed) {
my $folder = $env{'form.folder'};
if ($folder eq '') {
@@ -5436,6 +5508,11 @@
my @importdoc = (
{'<img class="LC_noBorder LC_middle" src="/res/adm/pages/extres.png" alt="'.$lt{extr}.'" onclick="toggleUpload(\'ext\');" />'=>$extresourcesform}
);
+ if (keys(%ltitools)) {
+ push(@importdoc,
+ {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/extres.png" alt="'.$lt{extt}.'" onclick="toggleUpload(\'tool\');" />'=>$exttoolform},
+ );
+ }
unless ($container eq 'page') {
push(@importdoc,
{'<img class="LC_noBorder LC_middle" src="/res/adm/pages/ims.png" alt="'.$lt{imsf}.'" onclick="javascript:toggleUpload(\'ims\');" />'=>$imspform}
@@ -5477,7 +5554,7 @@
$hadchanges=0;
unless (($supplementalflag || $toolsflag)) {
my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,
- $supplementalflag,\%orderhash,$iconpath,$pathitem);
+ $supplementalflag,\%orderhash,$iconpath,$pathitem,\%ltitools);
if ($error) {
$r->print('<p><span class="LC_error">'.$error.'</span></p>');
}
@@ -5544,6 +5621,12 @@
&Apache::lonextresedit::extedit_form(1,0,undef,undef,$pathitem,
$help{'Adding_External_Resource'});
+ my $supexttoolform =
+ &Apache::lonextresedit::extedit_form(1,0,undef,undef,$pathitem,
+ $help{'Adding_External_Tool'},
+ undef,undef,'tool',$coursedom,
+ $coursenum,\%ltitools);
+
my $supnewsylform=(<<SNSFORM);
<form action="/adm/coursedocs" method="post" name="supnewsyl">
<input type="hidden" name="active" value="ff" />
@@ -5597,10 +5680,16 @@
);
my @supimportdoc = (
{'<img class="LC_noBorder LC_middle" src="/res/adm/pages/extres.png" alt="'.$lt{extr}.'" onclick="javascript:toggleUpload(\'suppext\')" />'
- =>$supextform},
- {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/pdfupload.png" alt="'.$lt{upl}.'" onclick="javascript:toggleUpload(\'suppdoc\');" />'
+ =>$supextform});
+ if (keys(%ltitools)) {
+ push(@supimportdoc,
+ {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/extres.png" alt="'.$lt{extt}.'" onclick="javascript:toggleUpload(\'supptool\')" />'
+ =>$supexttoolform});
+ }
+ push(@supimportdoc,
+ {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/pdfupload.png" alt="'.$lt{upl}.'" onclick="javascript:toggleUpload(\'suppdoc\');" />'
=>$supupdocform},
- );
+ );
$supupdocform = &create_form_ul(&create_list_elements(@supimportdoc));
my %suporderhash = (
@@ -5610,7 +5699,7 @@
);
if ($supplementalflag) {
my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,
- $supplementalflag,\%suporderhash,$iconpath,$pathitem);
+ $supplementalflag,\%suporderhash,$iconpath,$pathitem,\%ltitools);
if ($error) {
$r->print('<p><span class="LC_error">'.$error.'</span></p>');
} else {
@@ -6072,12 +6161,12 @@
$backtourl = '/adm/navmaps';
}
- my $fieldsets = "'ext','doc'";
+ my $fieldsets = "'ext','tool','doc'";
unless ($main_container_page) {
$fieldsets .=",'ims'";
}
if ($supplementalflag) {
- $fieldsets = "'suppext','suppdoc'";
+ $fieldsets = "'suppext','supptool','suppdoc'";
}
return <<ENDNEWSCRIPT;
@@ -6187,6 +6276,19 @@
}
}
document.getElementById('upload'+blocks[i]+'form').style.display=disp;
+ if ((caller == 'tool') || (caller == 'supptool')) {
+ if (disp == 'block') {
+ if (document.getElementById('LC_exttoolid')) {
+ var toolselector = document.getElementById('LC_exttoolid');
+ var suppflag = 0;
+ if (caller == 'supptool') {
+ suppflag = 1;
+ }
+ currForm = document.getElementById('new'+caller);
+ updateExttool(toolselector,currForm,suppflag);
+ }
+ }
+ }
}
resize_scrollbox('contentscroll','1','1');
return;
Index: loncom/interface/lonextresedit.pm
diff -u loncom/interface/lonextresedit.pm:1.8 loncom/interface/lonextresedit.pm:1.9
--- loncom/interface/lonextresedit.pm:1.8 Tue Jun 9 21:22:56 2015
+++ loncom/interface/lonextresedit.pm Tue Jan 26 14:30:25 2016
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Documents
#
-# $Id: lonextresedit.pm,v 1.8 2015/06/09 21:22:56 damieng Exp $
+# $Id: lonextresedit.pm,v 1.9 2016/01/26 14:30:25 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -56,15 +56,19 @@
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};
- my ($supplementalflag,$updated,$output,$errormsg,$residx,$url,$title,$symb);
+ my ($supplementalflag,$updated,$output,$errormsg,$residx,$url,$title,
+ $symb,$type);
if (($env{'form.folderpath'} =~ /^supplemental/) && ($env{'form.suppurl'})) {
$supplementalflag = 1;
+ if (&unescape($env{'form.suppurl'}) =~ m{^/adm/$cdom/$cnum/\d+/exttools?$}) {
+ $type = 'tool';
+ }
}
if (($supplementalflag) || ($env{'form.symb'} =~ /^uploaded/)) {
($updated,$output,$errormsg,$residx,$url,$title,$symb) =
&process_changes($supplementalflag,$cdom,$cnum,$chome);
if ($supplementalflag) {
- if ($url ne $env{'form.suppurl'}) {
+ if ($url ne &unescape($env{'form.suppurl'})) {
$env{'form.suppurl'} = $url;
}
if ($title ne $env{'form.title'}) {
@@ -75,33 +79,48 @@
if ($symb ne $env{'form.symb'}) {
$env{'form.symb'} = $symb;
}
+ if ($url =~ m{/adm/$cdom/$cnum/\d+/exttools?$}) {
+ $type = 'tool';
+ }
}
} else {
$errormsg = &mt('Information about external resource to edit is missing.');
}
if ($updated) {
- $output = &Apache::lonhtmlcommon::confirm_success(&mt('External Resource updated'));
+ my $msg = &mt('External Resource updated');
+ if ($type eq 'tool') {
+ $msg = &mt('External Tool updated');
+ }
+ $output = &Apache::lonhtmlcommon::confirm_success($msg);
}
if ($errormsg) {
$errormsg = '<p class="LC_error">'.$errormsg.'</p>';
}
+ my %ltitools;
+ if ($type eq 'tool') {
+ %ltitools = &Apache::lonnet::get_domain_ltitools($cdom);
+ }
my $js = &Apache::lonhtmlcommon::scripttag(&extedit_javascript());
my $pathitem = '<input type="hidden" name="folderpath" value="'.
&HTML::Entities::encode($env{'form.folderpath'},'<>&"').'" />';
- $r->print(&Apache::loncommon::start_page('External Resource Editor',$js).
+ my $description = 'External Resource Editor';
+ if ($type eq 'tool') {
+ $description = 'External Tool Editor';
+ }
+ $r->print(&Apache::loncommon::start_page($description,$js).
'<div class="LC_left_float">'.
$output.
$errormsg.
&extedit_form($supplementalflag,$residx,$url,$title,$pathitem,undef,
- 'direct',$env{'form.symb'}).
+ 'direct',$env{'form.symb'},$type,$cdom,$cnum,\%ltitools).
'</div>'.&Apache::loncommon::end_page());
return OK;
}
sub process_changes {
my ($supplementalflag,$cdom,$cnum,$chome) = @_;
- my ($folder,$container,$output,$errormsg,$updated,$symb,$oldidx,$oldurl,
- $oldtitle,$newidx,$newurl,$newtitle,$residx,$url,$title);
+ my ($folder,$container,$output,$errormsg,$updated,$symb,$oldidx,$oldurl,$type,
+ $oldtitle,$newidx,$newurl,$newtitle,$residx,$url,$title,$marker,$args);
if ($env{'form.symb'}) {
$symb = $env{'form.symb'};
(my $map,$oldidx,$oldurl)=&Apache::lonnet::decode_symb($symb);
@@ -110,19 +129,27 @@
$container = $3;
}
$oldtitle = &Apache::lonnet::gettitle($env{'form.symb'});
+ if ($oldurl =~ m{^ext/(.+)$}) {
+ my $external = $1;
+ if ($external =~ m{^https://}) {
+ $oldurl = $external;
+ } else {
+ $oldurl = 'http://'.$oldurl;
+ }
+ $type = 'ext';
+ } else {
+ $type = 'tool';
+ }
} elsif ($env{'form.folderpath'}) {
$folder = &unescape( (split('&',$env{'form.folderpath'}))[-2] );
$oldurl = &unescape($env{'form.suppurl'});
$oldtitle = &unescape($env{'form.title'});
$container = 'sequence';
$supplementalflag = 1;
- }
- if ($oldurl =~ m{^ext/(.+)$}) {
- my $external = $1;
- if ($external =~ m{^https://}) {
- $oldurl = $external;
+ if ($oldurl =~ m{^/adm/$cdom/$cnum/\d+/exttools?$}) {
+ $type = 'tool';
} else {
- $oldurl = 'http://'.$oldurl;
+ $type = 'ext';
}
}
$url = $oldurl;
@@ -130,6 +157,11 @@
if ($env{'form.importdetail'}) {
($newtitle,$newurl,$newidx) =
map {&unescape($_)} split(/\=/,$env{'form.importdetail'});
+ if ($newurl =~ m{^(/adm/$cdom/$cnum/(\d+)/exttools?)\:?(.*)$}) {
+ $newurl = $1;
+ $marker = $2;
+ $args = $3;
+ }
}
if ($supplementalflag) {
$residx = $newidx;
@@ -147,7 +179,18 @@
if ($mismatchedid) {
$errormsg = 'Wrong item identifier';
} elsif (($newtitle eq $oldtitle) && ($newurl eq $oldurl)) {
- $output = &mt('No change');
+ if ($type eq 'tool') {
+ if ($args) {
+ ($updated,$errormsg) = &update_exttool($marker,$cdom,$cnum,$args);
+ unless ($updated) {
+ $output = &mt('No change');
+ }
+ } else {
+ $output = &mt('No change');
+ }
+ } else {
+ $output = &mt('No change');
+ }
} else {
my $map = "/uploaded/$cdom/$cnum/$folder.$container";
my ($errtext,$fatal) = &LONCAPA::map::mapread($map);
@@ -156,8 +199,15 @@
} else {
my $saveurl = &LONCAPA::map::qtunescape($newurl);
my $savetitle = &LONCAPA::map::qtunescape($newtitle);
+ my $ext = 'true';
+ if ($type eq 'tool') {
+ if ($args) {
+ ($updated,$errormsg) = &update_exttool($marker,$cdom,$cnum,$args);
+ }
+ $ext = 'false';
+ }
$LONCAPA::map::resources[$residx] =
- join(':', ($savetitle,$saveurl,'true','normal','res'));
+ join(':', ($savetitle,$saveurl,$ext,'normal','res'));
my ($outtext,$errtext) = &LONCAPA::map::storemap($map,1);
if ($errtext) {
$errormsg = &mt('Update failed: [_1].',$errtext);
@@ -166,8 +216,10 @@
$title = $newtitle;
if ($newurl ne $oldurl) {
$url = $newurl;
- $newurl =~ s{^http://}{};
- $newurl = "ext/$newurl";
+ if ($ext eq 'true') {
+ $newurl =~ s{^http://}{};
+ $newurl = "ext/$newurl";
+ }
}
if (!$supplementalflag) {
if ($newurl ne $oldurl) {
@@ -195,45 +247,101 @@
$output = &mt('No change');
}
} else {
- $errormsg = &mt('Information about current external resource is incomplete.');
+ if ($type eq 'tool') {
+ $errormsg = &mt('Information about current external tool is incomplete.');
+ } else {
+ $errormsg = &mt('Information about current external resource is incomplete.');
+ }
}
return ($updated,$output,$errormsg,$residx,$url,$title,$symb);
}
+sub update_exttool {
+ my ($marker,$cdom,$cnum,$args) = @_;
+ my %toolhash=&Apache::lonnet::dump('exttool_'.$marker,$cdom,$cnum);
+ my (%newhash,$changed,$errormsg);
+ ($newhash{'target'},$newhash{'width'},$newhash{'height'}) = split(/:/,$args);
+ my %toolhash=&Apache::lonnet::dump('exttool_'.$marker,$cdom,$cnum);
+ foreach my $item ('target','width','height') {
+ $newhash{$item} =~ s/^\s+//;
+ $newhash{$item} =~ s/\s+$//;
+ unless ($item eq 'target') {
+ if ($newhash{'target'} eq 'iframe') {
+ $newhash{$item} = '';
+ }
+ }
+ if ($toolhash{$item} ne $newhash{$item}) {
+ if ($newhash{$item} eq '') {
+ delete($toolhash{$item});
+ } else {
+ $toolhash{$item} = $newhash{$item};
+ }
+ $changed = 1;
+ }
+ }
+ if ($changed) {
+ my $putres = &Apache::lonnet::put('exttool_'.$marker,\%toolhash,$cdom,$cnum);
+ unless ($putres eq 'ok') {
+ $errormsg = &mt('Failed to save updated settings.').' '.&mt('Error: [_1].',$putres);
+ }
+ }
+ return ($changed,$errormsg);
+}
+
sub extedit_form {
- my ($supplementalflag,$residx,$orig_url,$orig_title,$pathitem,$helpitem,$caller,$symb) = @_;
+ my ($supplementalflag,$residx,$orig_url,$orig_title,$pathitem,$helpitem,$caller,
+ $symb,$type,$cdom,$cnum,$ltitools) = @_;
+ if ($type ne 'tool') {
+ $type = 'ext';
+ }
my %lt = &Apache::lonlocal::texthash(
ex => 'External Resource',
+ et => 'External Tool',
ed => 'Edit',
ee => 'External Resource Editor',
+ te => 'External Tool Editor',
pr => 'Preview',
sv => 'Save',
ul => 'URL',
ti => 'Title',
al => 'Add Link',
+ at => 'Add Tool',
);
- my $formname = 'newext';
my $tabid = 'aa';
- my $toggle = 'ext';
- my $fieldsetid = 'uploadextform';
- my $urlid = 'exturl';
my $size = 60;
if ($supplementalflag) {
- $formname = 'newsuppext';
$tabid = 'ee';
- $toggle = 'suppext';
- $fieldsetid = 'uploadsuppextform';
- $urlid = 'suppexturl';
+ }
+ my ($formname,$formid,$toggle,$fieldsetid,$urlid,$dispdivstyle,$dimendivstyle,
+ $legend,$urlelem,$toolelem,%toolattr);
+ $formname = 'new'.$type;
+ $toggle = $type;
+ $fieldsetid = 'upload'.$type.'form';
+ $urlid = $type.'url';
+ map { $toolattr{$_} = $type.$_; } ('dispdiv','dimendiv','dimenwidth','dimenheight');
+ $dispdivstyle = 'display:none';
+ $dimendivstyle = 'display:none';
+ if ($supplementalflag) {
+ $formname = 'newsupp'.$type;
+ $toggle = 'supp'.$type;
+ $fieldsetid = 'uploadsupp'.$type.'form';
+ $urlid = 'supp'.$type.'url';
+ map { $toolattr{$_} = 'supp'.$toolattr{$_}; } (keys(%toolattr));
}
my ($link,$legend,$active,$srcclass,$extsrc,$preview,$title,$save,
- $fieldsetstyle,$action,$hiddenelem,$form);
+ $fieldsetstyle,$action,$hiddenelem,$form,$width,$height,$tooltarget,%chkstate);
$fieldsetstyle = 'display: none;';
$action = '/adm/coursedocs';
if ($residx) {
if ($caller eq 'direct') {
$fieldsetstyle = 'display: block;';
$action = '/adm/extresedit';
- $legend = "<legend>$lt{'ee'}</legend>";
+ if ($type eq 'tool') {
+ $legend = $lt{'ee'};
+ } else {
+ $legend = $lt{'te'};
+ }
+ $legend = '<legend>'.$legend.'</legend>';
if ($symb) {
$hiddenelem = '<input type="hidden" name="symb" value="'.$symb.'" />';
} elsif ($supplementalflag) {
@@ -242,50 +350,150 @@
'<input type="hidden" name="title" value="'.
&HTML::Entities::encode(&escape($orig_title),'<>&"').'" />';
}
- } else {
- $link = '<a class="LC_docs_ext_edit" href="javascript:editext('."'$residx'".');">'.$lt{'ed'}.'</a> '."\n";
+ } else {
+ $link = '<a class="LC_docs_ext_edit" href="javascript:editext('."'$residx','$type'".');">'.$lt{'ed'}.'</a> '."\n";
$size = 40;
$active = '<input type="hidden" name="active" value="'.$tabid.'" />';
}
- $formname = "editext_$residx";
- $fieldsetid = "uploadext$residx";
- $urlid = "exturl_$residx";
+ $formname = 'edit'.$type.'_'.$residx;
+ $fieldsetid = 'upload'.$type.$residx;
+ $urlid = $type.'url_'.$residx;
+ map { $toolattr{$_} .= '_'.$residx; } (keys(%toolattr));
$srcclass = ' class="LC_nobreak"';
- $extsrc = '<span class="LC_docs_ext_edit">'.$lt{'ul'}.' </span>';
- $preview = ' <a class="LC_docs_ext_edit" href="javascript:extUrlPreview('."'$urlid'".');">'.$lt{'pr'}.'</a>';
+ if ($type eq 'ext') {
+ $extsrc = '<span class="LC_docs_ext_edit">'.$lt{'ul'}.' </span>';
+ $preview = ' <a class="LC_docs_ext_edit" href="javascript:extUrlPreview('."'$urlid'".');">'.$lt{'pr'}.'</a>';
+ }
$title = '<span class="LC_docs_ext_edit">'.$lt{'ti'}.' </span>';
$save = $lt{'sv'};
} else {
- $link = '<a class="LC_menubuttons_link" href="javascript:toggleUpload('."'$toggle'".');">'.$lt{'ex'}.'</a>'.$helpitem;
- $legend = "<legend>$lt{'ex'}</legend>";
- $extsrc = $lt{'ul'}.':<br />';
+ $link = $lt{'ex'};
+ if ($type eq 'tool') {
+ $link = $lt{'et'};
+ }
+ $link = '<a class="LC_menubuttons_link" href="javascript:toggleUpload('."'$toggle'".');">'.$link.'</a>'.$helpitem;
+ if ($type eq 'tool') {
+ $legend = $lt{'te'};
+ } else {
+ $legend = $lt{'ee'};
+ }
+ $legend = '<legend>'.$legend.'</legend>';
$title = $lt{'ti'}.':<br />';
$residx = 0;
- $orig_url = 'http://';
- $orig_title = $lt{'ex'};
- $preview = '<input type="button" name="view" value="'.$lt{'pr'}.'" onclick="javascript:extUrlPreview('."'$urlid'".');" />';
- $save = $lt{'al'};
+ if ($type eq 'ext') {
+ $orig_url = 'http://';
+ $orig_title = $lt{'ex'};
+ $extsrc = $lt{'ul'}.':<br />';
+ $preview = '<input type="button" name="view" value="'.$lt{'pr'}.'" onclick="javascript:extUrlPreview('."'$urlid'".');" />';
+ $save = $lt{'al'};
+ } else {
+ $orig_title = $lt{'et'};
+ $save = $lt{'at'};
+ $orig_url = "/adm/$cdom/$cnum/new/exttool";
+ }
$pathitem .= '<br />';
}
+ $formid = $formname;
+ if ($type eq 'ext') {
+ $urlelem = '<input type="text" size="'.$size.'" name="exturl" id="'.$urlid.'" value="'.$orig_url.'" />';
+ } else {
+ my $class = 'LC_nobreak';
+ if ($residx) {
+ $class = 'LC_docs_ext_edit LC_nobreak';
+ if ($orig_url =~ m{^/adm/$cdom/$cnum/(\d+)/exttools?$}) {
+ my $marker = $1;
+ my %toolhash=&Apache::lonnet::dump('exttool_'.$marker,$cdom,$cnum);
+ if ($toolhash{'id'}) {
+ $dispdivstyle = 'display:block';
+ if (ref($ltitools) eq 'HASH') {
+ if (keys(%{$ltitools})) {
+ if (ref($ltitools->{$toolhash{'id'}}) eq 'HASH') {
+ my $tooltitle = $ltitools->{$toolhash{'id'}}->{'title'};
+ my $icon = $ltitools->{$toolhash{'id'}}->{'image'};
+ my $image;
+ if ($icon) {
+ $image = '<img src="'.$icon.'" alt="'.$tooltitle.'" />';
+ }
+ $tooltarget = $toolhash{'target'};
+ if ($tooltarget eq 'window') {
+ $dimendivstyle = 'display:block';
+ $chkstate{'window'} = 'checked="checked" ';
+ } else {
+ $chkstate{'iframe'} = 'checked="checked" ';
+ }
+ $width = $toolhash{'width'};
+ $height = $toolhash{'height'};
+ $toolelem = '<span class="LC_nobreak">'.$image.' '.$tooltitle.'</span><br />';
+ }
+ }
+ }
+ }
+ }
+ } else {
+ $toolelem = '<span class="LC_docs_ext_edit">'."\n".
+ '<select name="exttoolid" id="LC_exttoolid" onchange="javascript:updateExttool(this,'.
+ 'this.form,'."'$supplementalflag'".');">'."\n".
+ '<option value="" selected="selected">'.&mt('Select').'</option>';
+ my %bynum;
+ if (ref($ltitools) eq 'HASH') {
+ foreach my $id (keys(%{$ltitools})) {
+ if (ref($ltitools->{$id}) eq 'HASH') {
+ my $order = $ltitools->{$id}->{'order'};
+ $bynum{$order} = [$id,$ltitools->{$id}];
+ }
+ }
+ }
+ foreach my $item (sort { $a <=> $b } keys(%bynum)) {
+ if (ref($bynum{$item}) eq 'ARRAY') {
+ if (ref($bynum{$item}->[1]) eq 'HASH') {
+ my $tooltitle = $bynum{$item}->[1]->{'title'};
+ my $icon = $bynum{$item}->[1]->{'image'};
+ $toolelem .= '<option value="'.$bynum{$item}->[0].'">'.$tooltitle.'</option>';
+ }
+ }
+ }
+ $toolelem .= '</select></span>';
+ }
+ $toolelem .= '<div id="'.$toolattr{'dispdiv'}.'" style="'.$dispdivstyle.'">'.
+ '<span class="'.$class.'">'.&mt('Display target:').' '.
+ '<label><input type="radio" name="exttooltarget" value="iframe" '.$chkstate{'iframe'}.'onclick="updateTooldim(this.form,'.
+ "'$toolattr{dimendiv}','$toolattr{dimenwidth}','$toolattr{dimenheight}'".');">'.&mt('iframe').'</label>'.(' 'x2).
+ '<label><input type="radio" name="exttooltarget" value="window" '.$chkstate{'window'}.'onclick="updateTooldim(this.form,'.
+ "'$toolattr{dimendiv}','$toolattr{dimenwidth}','$toolattr{dimenheight}'".');">'.&mt('window').'</label>'.
+ '</span><div id="'.$toolattr{'dimendiv'}.'" style="'.$dimendivstyle.'">'.
+ '<span class="'.$class.'">'.
+ &mt('Width').'<input type="text" id="'.$toolattr{'dimenwidth'}.'" name="exttoolwidth" value="'.$width.'">'.(' 'x2).
+ &mt('Height').'<input type="text" id="'.$toolattr{'dimenheight'}.'" name="exttoolheight" value="'.$height.'"></span>'."\n".
+ '</div></div>';
+ }
+ my $chooser = $toolelem;
+ if ($type eq 'ext') {
+ $chooser = "
+<div>
+<span$srcclass>
+$extsrc
+$urlelem
+$preview
+</span>
+</div>
+";
+ }
$form = <<ENDFORM;
-<form action="$action" method="post" name="$formname">
+<form action="$action" method="post" name="$formname" id="$formid">
<fieldset id="$fieldsetid" style="$fieldsetstyle">
$legend
$active
-<span$srcclass>
-$extsrc
-<input type="text" size="$size" name="exturl" id="$urlid" value="$orig_url" />
-$preview
-</span>
-<br />
+$chooser
+<div>
<span$srcclass>
$title
<input type="text" size="$size" name="exttitle" value="$orig_title" />
<input type="hidden" name="importdetail" value="" />
$pathitem
$hiddenelem
-<input type="button" value="$save" onclick="javascript:setExternal(this.form,'$residx');" />
+<input type="button" value="$save" onclick="javascript:setExternal(this.form,'$residx','$type','$orig_url');" />
</span>
+</div>
</fieldset>
</form>
ENDFORM
@@ -297,8 +505,8 @@
}
sub display_editor {
- my ($url,$folderpath,$symb,$idx) = @_;
- my ($residx,$supplementalflag,$title,$pathitem,$output);
+ my ($url,$folderpath,$symb,$idx,$type,$cdom,$cnum) = @_;
+ my ($residx,$supplementalflag,$title,$pathitem,$output,$js);
if ($folderpath =~ /^supplemental/) {
$supplementalflag = 1;
$residx = $idx;
@@ -311,19 +519,51 @@
my $path = &Apache::loncommon::symb_to_docspath($symb);
$pathitem = '<input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($path,'<>&"').'" />';
}
- my $js = &Apache::lonhtmlcommon::scripttag(&extedit_javascript());
+ my %ltitools;
+ if ($type eq 'tool') {
+ %ltitools = &Apache::lonnet::get_domain_ltitools($cdom);
+ }
+ $js = &Apache::lonhtmlcommon::scripttag(&extedit_javascript());
my $args = { 'force_register' => $env{'form.register'} };
- return &Apache::loncommon::start_page('External Resource Editor',$js,$args).
+ my $description = 'External Resource Editor';
+ if ($type eq 'tool') {
+ $description = 'External Tool Editor';
+ }
+ return &Apache::loncommon::start_page($description,$js,$args).
'<div class="LC_left_float">'.
- &extedit_form($supplementalflag,$residx,$url,$title,$pathitem,undef,'direct',$symb).
+ &extedit_form($supplementalflag,$residx,$url,$title,$pathitem,undef,'direct',
+ $symb,$type,$cdom,$cnum,\%ltitools).
'</div>'.
&Apache::loncommon::end_page();
}
sub extedit_javascript {
+ my ($toolsref) = @_;
+ my $toolsjs;
+ if (ref($toolsref) eq 'HASH') {
+ my $num = scalar(keys(%{$toolsref}));
+ $toolsjs = " var ltitools = new Array($num);\n".
+ " var ltitoolsTarget = new Array($num);\n".
+ " var ltitoolsWidth = new Array($num);\n".
+ " var ltitoolsHeight = new Array($num);\n";
+ my $i = 0;
+ foreach my $key (sort { $a <=> $b } keys(%{$toolsref})) {
+ if (ref($toolsref->{$key})) {
+ my $target = $toolsref->{$key}->{'target'};
+ my $width = $toolsref->{$key}->{'width'};
+ my $height = $toolsref->{$key}->{'height'};
+ $toolsjs .= ' ltitools['.$i.'] = '."'$key';\n".
+ ' ltitoolsTarget['.$i.'] = '."'$target';\n".
+ ' ltitoolsWidth['.$i.'] = '."'$width';\n".
+ ' ltitoolsHeight['.$i.'] = '."'$height';\n";
+ $i++;
+ }
+ }
+ }
my %js_lt = &Apache::lonlocal::texthash(
invurl => 'Invalid URL',
titbl => 'Title is blank',
+ invtool => 'Please select an external tool',
);
&js_escape(\%js_lt);
@@ -335,40 +575,74 @@
var regexp = $urlregexp;
-function setExternal(extform,residx) {
+function setExternal(extform,residx,type,exttoolurl) {
var title=extform.exttitle.value;
if (!String.trim) {
String.prototype.trim = function() {return this.replace(\/^\\s+|\\s+$\/g, "");}; }
- var url=extform.exturl.value;
if (title == null || title.trim()=="") {
alert("$js_lt{'titbl'}");
extform.exttitle.focus();
return;
}
- if (regexp.test(url)) {
- url = escape(url);
+ if (type == 'ext') {
+ var url=extform.exturl.value;
+ if (!regexp.test(url)) {
+ alert("$js_lt{'invurl'}");
+ extform.exturl.focus();
+ return;
+ } else {
+ url = escape(url);
+ title = escape(title);
+ if (residx > 0) {
+ eval("extform.importdetail.value=title+'='+url+'='+residx;extform.submit();");
+ } else {
+ eval("extform.importdetail.value=title+'='+url;extform.submit();");
+ }
+ }
+ } else {
title = escape(title);
+ var info = exttoolurl;
+ if (residx == 0) {
+ var toolid = parseInt(extform.exttoolid.options[extform.exttoolid.selectedIndex].value);
+ if (isNaN(toolid)) {
+ alert("$js_lt{'invtool'}");
+ return;
+ }
+ info += ':'+toolid;
+ }
+ if (extform.exttooltarget.length) {
+ for (var i=0; i<extform.exttooltarget.length; i++) {
+ if (extform.exttooltarget[i].checked) {
+ if (extform.exttooltarget[i].value == 'window') {
+ var width = extform.exttoolwidth.value;
+ width.trim();
+ var height = extform.exttoolheight.value;
+ height.trim();
+ info += ':window:'+width+':'+height;
+ } else {
+ info += ':iframe';
+ }
+ }
+ }
+ }
+ info=escape(info);
if (residx > 0) {
- eval("extform.importdetail.value=title+'='+url+'='+residx;extform.submit();");
+ eval("extform.importdetail.value=title+'='+info+'='+residx;extform.submit();");
} else {
- eval("extform.importdetail.value=title+'='+url;extform.submit();");
+ eval("extform.importdetail.value=title+'='+info;extform.submit();");
}
- } else {
- alert("$js_lt{'invurl'}");
- extform.exturl.focus();
- return;
}
}
-function editext(residx) {
- if (document.getElementById('uploadext'+residx)) {
- var curr = document.getElementById('uploadext'+residx).style.display;
+function editext(residx,type) {
+ if (document.getElementById('upload'+type+residx)) {
+ var curr = document.getElementById('upload'+type+residx).style.display;
if (curr == 'none') {
disp = 'block';
} else {
disp = 'none';
}
- document.getElementById('uploadext'+residx).style.display=disp;
+ document.getElementById('upload'+type+residx).style.display=disp;
}
resize_scrollbox('contentscroll','1','1');
return;
@@ -385,6 +659,90 @@
}
}
+function updateExttool(caller,form,supplementalflag) {
+ var prefix = '';
+ if (supplementalflag == 1) {
+ prefix = 'supp';
+ }
+ dispdiv = prefix+'tooldispdiv';
+ dimendiv = prefix+'tooldimendiv';
+ widthinput = prefix+'toolwidth';
+ heightinput = prefix+'toolheight';
+ if (document.getElementById(dispdiv)) {
+ var toolpick = caller.options[caller.selectedIndex].value;
+ $toolsjs
+ if (toolpick == '') {
+ if (document.getElementById(dispdiv)) {
+ document.getElementById(dispdiv).style.display = 'none';
+ }
+ if (document.getElementById(dimendiv)) {
+ document.getElementById(dimendiv).style.display = 'none';
+ }
+ } else {
+ if (document.getElementById(dispdiv)) {
+ document.getElementById(dispdiv).style.display = 'block';
+ }
+ if (ltitools.length > 0) {
+ for (var j=0; j<ltitools.length; j++) {
+ if (ltitools[j] == toolpick) {
+ if (form.exttooltarget.length) {
+ for (var k=0; k<form.exttooltarget.length; k++) {
+ if (form.exttooltarget[k].value == ltitoolsTarget[j]) {
+ form.exttooltarget[k].checked = true;
+ break;
+ }
+ }
+ }
+ if (ltitoolsTarget[j] == 'window') {
+ dimen = 'block';
+ dimenwidth = ltitoolsWidth[j];
+ dimenheight = ltitoolsHeight[j];
+ } else {
+ dimen = 'none';
+ dimenwidth = '';
+ dimenheight = '';
+ }
+ if (document.getElementById(dimendiv)) {
+ document.getElementById(dimendiv).style.display = dimen;
+ }
+ if (document.getElementById(widthinput)) {
+ document.getElementById(widthinput).value = dimenwidth;
+ }
+ if (document.getElementById(heightinput)) {
+ document.getElementById(heightinput).value = dimenheight;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+function updateTooldim(form,dimendiv,widthinput,heightinput) {
+ if (form.exttooltarget.length) {
+ for (var i=0; i<form.exttooltarget.length; i++) {
+ if (form.exttooltarget[i].checked) {
+ var dimen = 'none';
+ if (form.exttooltarget[i].value == 'window') {
+ dimen = 'block';
+ } else {
+ if (document.getElementById(widthinput)) {
+ document.getElementById(widthinput).value = '';
+ }
+ if (document.getElementById(heightinput)) {
+ document.getElementById(heightinput).value = '';
+ }
+ }
+ if (document.getElementById(dimendiv)) {
+ document.getElementById(dimendiv).style.display = dimen;
+ }
+ break;
+ }
+ }
+ }
+}
+
ENDJS
}
Index: loncom/interface/lonexttool.pm
diff -u loncom/interface/lonexttool.pm:1.2 loncom/interface/lonexttool.pm:1.3
--- loncom/interface/lonexttool.pm:1.2 Mon Jan 25 20:13:02 2016
+++ loncom/interface/lonexttool.pm Tue Jan 26 14:30:25 2016
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Launch External Tool Provider (LTI)
#
-# $Id: lonexttool.pm,v 1.2 2016/01/25 20:13:02 raeburn Exp $
+# $Id: lonexttool.pm,v 1.3 2016/01/26 14:30:25 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -74,15 +74,14 @@
return OK;
}
- my $marker = (split(m{/},$r->uri))[4];
+ my ($marker,$exttool) = (split(m{/},$r->uri))[4,5];
$marker=~s/\D//g;
if (!$marker) {
if ($target ne 'tex') {
- &Apache::loncommon::simple_error_page($r,'Invalid Call',
- 'Invalid Call');
+ $r->print(&mt('Invalid Call'));
} else {
- $r->print('\textbf{Invalid call}\end{document}');
+ $r->print('\textbf{'&mt('Invalid Call').'}\end{document}');
}
return OK;
}
@@ -90,46 +89,47 @@
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};
+ my $is_tool;
- if ($r->uri eq "/adm/$cdom/$cnum/$marker/exttool") {
- my %toolhash=&Apache::lonnet::dump('exttool_'.$marker,$cdom,$cnum);
- if ($target eq 'tex') {
- $r->print(&mt('External Tool'));
- } else {
- if (($toolhash{'key'} ne '') && ($toolhash{'secret'} ne '') && ($toolhash{'url'} ne '')) {
- my %lti = <i_params($r,\%toolhash);
- $r->print(&launch_html($toolhash{'url'},$toolhash{'key'},
- $toolhash{'secret'},$toolhash{'title'},\%lti));
- } else {
- &Apache::loncommon::simple_error_page($r,'External Tool Unavailable',
- 'External Tool Unavailable');
+ if ($r->uri eq "/adm/$cdom/$cnum/$marker/$exttool") {
+ my %toolsettings=&Apache::lonnet::dump('exttool_'.$marker,$cdom,$cnum);
+ if ($toolsettings{'id'}) {
+ my %ltitools = &Apache::lonnet::get_domain_ltitools($cdom);
+ if (ref($ltitools{$toolsettings{'id'}}) eq 'HASH') {
+ my %toolhash = %{$ltitools{$toolsettings{'id'}}};
+ $toolhash{'display'} = {
+ target => $toolsettings{'target'},
+ width => $toolsettings{'width'},
+ height => $toolsettings{'height'},
+ };
+ $is_tool = 1;
+ if ($target eq 'tex') {
+ $r->print(&mt('External Tool'));
+ } else {
+ my $submittext = &mt('Launch [_1]',$toolhash{'title'});
+ if (($toolhash{'key'} ne '') && ($toolhash{'secret'} ne '') && ($toolhash{'url'} ne '')) {
+ my %lti = <i_params($r,$submittext,\%toolhash);
+ $r->print(&launch_html($toolhash{'url'},$toolhash{'key'},
+ $toolhash{'secret'},$submittext,\%lti));
+ } else {
+ $r->print('<div>'.&mt('External Tool Unavailable').'</div>');
+ }
+ }
}
}
- } else {
+ }
+ unless ($is_tool) {
if ($target ne 'tex') {
- &Apache::loncommon::simple_error_page($r,'Invalid Call',
- 'Invalid Call');
+ $r->print('<div>'.&mt('Invalid Call').'</div>');
} else {
- $r->print('\textbf{Invalid call}\end{document}');
+ $r->print('\textbf{'.&mt(Invalid Call).'}\end{document}');
}
- return OK;
}
-
- &print_end_page($r,$target);
return OK;
}
-sub print_end_page {
- my ($r,$target) = @_;
- if ($target ne 'tex') {
- $r->print(&Apache::loncommon::end_page());
- } else {
- $r->print('\end{document}');
- }
-}
-
sub lti_params {
- my ($r,$toolsref) = @_;
+ my ($r,$submittext,$toolsref) = @_;
my ($version,$context_type,$msgtype,$toolname,$passback,$roster,$locale,
%fields,%rolesmap,%display,%custom, at userlangs);
if (ref($toolsref) eq 'HASH') {
@@ -165,7 +165,8 @@
my $uname = $env{'user.name'};
my $udom = $env{'user.domain'};
my @possroles = qw(Instructor ContentDeveloper TeachingAssistant Learner);
- my $ltirole = $rolesmap{$env{'request.role'}};
+ my ($roleprefix) = ($env{'request.role'} =~ /^(\w+)\./);
+ my $ltirole = $rolesmap{$roleprefix};
unless (grep(/^\Q$ltirole\E$/, at possroles)) {
$ltirole = 'Learner';
}
@@ -218,10 +219,10 @@
context_title => $env{'course.'.$env{'request.course.id'}.'.description'},
launch_presentation_locale => $locale,
);
- my $crshostname = $env{'course.'.$env{'request.course.id'}.'.home'};
- my $crsprotocol = $Apache::lonnet::protocol{$crshostname};
+ my $crshome = $env{'course.'.$env{'request.course.id'}.'.home'};
+ my $crshostname = &Apache::lonnet::hostname($crshome);
if ($crshostname) {
- my $crsprotocol = $Apache::lonnet::protocol{$crshostname};
+ my $crsprotocol = $Apache::lonnet::protocol{$crshome};
unless ($crsprotocol eq 'https') {
$crsprotocol = 'http';
}
@@ -260,9 +261,9 @@
if ($fields{'email'}) {
my %emails = &Apache::loncommon::getemails($uname,$udom);
my $contact_email;
- foreach my $email ('permanentemail','critnotification','notification') {
- if ($email =~ /\@/) {
- $contact_email = $email;
+ foreach my $type ('permanentemail','critnotification','notification') {
+ if ($emails{$type} =~ /\@/) {
+ $contact_email = $emails{$type};
last;
}
}
@@ -276,24 +277,27 @@
foreach my $key (keys(%ltiparams)) {
$ltiparams{$key} = &Encode::decode_utf8($ltiparams{$key});
}
+ $ltiparams{'basiclti_submit'} = $submittext;
return %ltiparams;
}
sub launch_html {
- my ($url,$key,$secret,$toolname,$paramsref) = @_;
+ my ($url,$key,$secret,$submittext,$paramsref) = @_;
my $hashref = &sign_params($url,$key,$secret,$paramsref);
- my $submittext = &mt('Launch [_1]',$toolname);
my $form = <<"END";
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<body>
<div id="LCltiLaunch">
-<form name="LCltiLaunchForm" action="$url" method="post" encType="application/x-www-form-urlencoded">
-<input type="submit" name="LCbasicltiSubmit" value="$submittext" />
+<form name="LCltiLaunchForm" id="LCltiLaunchFormId" action="$url" method="post" encType="application/x-www-form-urlencoded">
END
if (ref($hashref) eq 'HASH') {
foreach my $item (keys(%{$hashref})) {
- $form .= '<input type="hidden" name="'.$item.'" value="'.$hashref->{$item}.'" id="id_'.$item.'" />'."\n";
+ my $type = 'hidden';
+ if ($item eq 'basiclti_submit') {
+ $type = 'submit';
+ }
+ $form .= '<input type="'.$type.'" name="'.$item.'" value="'.$hashref->{$item}.'" id="id_'.$item.'" />'."\n";
}
}
$form .= "</form></div>\n";
@@ -302,9 +306,9 @@
document.getElementById("LCltiLaunch").style.display = "none";
nei = document.createElement('input');
nei.setAttribute('type','hidden');
- nei.setAttribute('name','LCbasicltiSubmit');
+ nei.setAttribute('name','basiclti_submit');
nei.setAttribute('value','$submittext');
- document.getElementById("LCltiLaunchForm").appendChild(nei);
+ document.getElementById("LCltiLaunchFormId").appendChild(nei);
document.LCltiLaunchForm.submit();
</script>
ENDJS
Index: loncom/interface/lonhtmlcommon.pm
diff -u loncom/interface/lonhtmlcommon.pm:1.369 loncom/interface/lonhtmlcommon.pm:1.370
--- loncom/interface/lonhtmlcommon.pm:1.369 Sun Aug 16 20:45:41 2015
+++ loncom/interface/lonhtmlcommon.pm Tue Jan 26 14:30:25 2016
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# a pile of common html routines
#
-# $Id: lonhtmlcommon.pm,v 1.369 2015/08/16 20:45:41 raeburn Exp $
+# $Id: lonhtmlcommon.pm,v 1.370 2016/01/26 14:30:25 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -1718,7 +1718,7 @@
(($env{'request.noversionuri'}=~/^\/adm\//) &&
($env{'request.noversionuri'}!~/^\/adm\/wrapper\//) &&
($env{'request.noversionuri'}!~
- m{^/adm/.*/(smppg|bulletinboard)($|\?)})
+ m{^/adm/.*/(smppg|bulletinboard|exttools?)($|\?)})
));
}
Index: loncom/interface/lonmenu.pm
diff -u loncom/interface/lonmenu.pm:1.437 loncom/interface/lonmenu.pm:1.438
--- loncom/interface/lonmenu.pm:1.437 Mon Sep 14 13:45:01 2015
+++ loncom/interface/lonmenu.pm Tue Jan 26 14:30:25 2016
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Routines to control the menu
#
-# $Id: lonmenu.pm,v 1.437 2015/09/14 13:45:01 raeburn Exp $
+# $Id: lonmenu.pm,v 1.438 2016/01/26 14:30:25 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -847,7 +847,7 @@
$is_mobile = 1;
}
- unless ($env{'request.noversionuri'}=~/\/(bulletinboard|smppg|navmaps|syllabus|aboutme|viewclasslist|portfolio)(\?|$)/) {
+ unless ($env{'request.noversionuri'}=~/\/(bulletinboard|smppg|navmaps|syllabus|aboutme|viewclasslist|portfolio|exttools?)(\?|$)/) {
if ((!$env{'request.enc'}) && ($env{'request.noversionuri'} !~ m{^/adm/wrapper/ext/}) && ($env{'request.noversionuri'} !~ m{^/uploaded/$match_domain/$match_courseid/docs/})) {
$menuitems.=(<<ENDREALRES);
s&6&3&catalog.png&Info&info[_1]&catalog_info('$is_mobile')&Show Metadata
@@ -1125,6 +1125,7 @@
if (($env{'form.folderpath'} =~ /^supplemental/) &&
(&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) &&
(($resurl =~ m{^/adm/wrapper/ext/}) ||
+ ($resurl =~ m{^/adm/$cdom/$cnum/\d+/exttools?$}) ||
($resurl =~ m{^/uploaded/$cdom/$cnum/supplemental/}) ||
($resurl eq '/adm/supplemental') ||
($resurl =~ m{^/public/$cdom/$cnum/syllabus$}) ||
Index: loncom/interface/lonsyllabus.pm
diff -u loncom/interface/lonsyllabus.pm:1.138 loncom/interface/lonsyllabus.pm:1.139
--- loncom/interface/lonsyllabus.pm:1.138 Tue Jun 9 21:22:57 2015
+++ loncom/interface/lonsyllabus.pm Tue Jan 26 14:30:25 2016
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Syllabus
#
-# $Id: lonsyllabus.pm,v 1.138 2015/06/09 21:22:57 damieng Exp $
+# $Id: lonsyllabus.pm,v 1.139 2016/01/26 14:30:25 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -164,7 +164,7 @@
'\end{document}');
} else {
$r->print(&Apache::lonwrapper::wrapper($item,undef,$env{'request.use_absolute'},
- undef,$is_pdf,&mt('Syllabus')));
+ undef,$is_pdf,undef,&mt('Syllabus')));
}
}
return OK;
@@ -183,7 +183,7 @@
$is_pdf = 1;
}
$r->print(&Apache::lonwrapper::wrapper($external,undef,$env{'request.use_absolute'},
- $is_ext,$is_pdf,&mt('Syllabus')));
+ $is_ext,$is_pdf,undef,&mt('Syllabus')));
}
return OK;
}
Index: loncom/rewrites/loncapa_rewrite_off.conf
diff -u loncom/rewrites/loncapa_rewrite_off.conf:1.4 loncom/rewrites/loncapa_rewrite_off.conf:1.5
--- loncom/rewrites/loncapa_rewrite_off.conf:1.4 Tue Jan 7 20:03:32 2014
+++ loncom/rewrites/loncapa_rewrite_off.conf Tue Jan 26 14:30:30 2016
@@ -11,6 +11,8 @@
RewriteRule (.*) - [L]
RewriteCond %{REQUEST_URI} ^/adm/jsMath/
RewriteRule (.*) - [L]
+ RewriteCond %{REQUEST_URI} ^(/adm/wrapper|)/adm/.*/exttool$
+ RewriteRule (.*) - [L]
RewriteCond %{HTTPS} !=on
RewriteRule ^/(.*)$ https://%{HTTP_HOST}/$1 [R,L]
</IfModule>
Index: loncom/rewrites/loncapa_rewrite_on.conf
diff -u loncom/rewrites/loncapa_rewrite_on.conf:1.4 loncom/rewrites/loncapa_rewrite_on.conf:1.5
--- loncom/rewrites/loncapa_rewrite_on.conf:1.4 Tue Jan 7 20:03:32 2014
+++ loncom/rewrites/loncapa_rewrite_on.conf Tue Jan 26 14:30:30 2016
@@ -11,6 +11,8 @@
RewriteRule (.*) - [L]
RewriteCond %{REQUEST_URI} ^/adm/jsMath/
RewriteRule (.*) - [L]
+ RewriteCond %{REQUEST_URI} ^(/adm/wrapper|)/adm/.*/exttool$
+ RewriteRule (.*) - [L]
RewriteCond %{HTTPS} !=on
RewriteRule ^/(.*)$ https://%{HTTP_HOST}/$1 [R,L]
</IfModule>
Index: rat/lonuserstate.pm
diff -u rat/lonuserstate.pm:1.149 rat/lonuserstate.pm:1.150
--- rat/lonuserstate.pm:1.149 Mon Dec 15 01:10:19 2014
+++ rat/lonuserstate.pm Tue Jan 26 14:30:40 2016
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Construct and maintain state and binary representation of course for user
#
-# $Id: lonuserstate.pm,v 1.149 2014/12/15 01:10:19 raeburn Exp $
+# $Id: lonuserstate.pm,v 1.150 2016/01/26 14:30:40 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -42,7 +42,7 @@
use Opcode;
use Apache::lonenc;
use Fcntl qw(:flock);
-use LONCAPA;
+use LONCAPA qw(:DEFAULT :match);
use File::Basename;
@@ -475,6 +475,8 @@
} elsif ($turi!~/\.(sequence|page)$/) {
$turi='/adm/coursedocs/showdoc'.$turi;
}
+ } elsif ($turi=~ m{^/adm/$match_domain/$match_courseid/\d+/exttools?$}) {
+ $turi='/adm/wrapper'.$turi;
} elsif ($turi=~/\S/) { # normal non-empty internal resource
my $mapdir=$uri;
$mapdir=~s/[^\/]+$//;
Index: rat/lonwrapper.pm
diff -u rat/lonwrapper.pm:1.49 rat/lonwrapper.pm:1.50
--- rat/lonwrapper.pm:1.49 Tue Jun 17 23:22:21 2014
+++ rat/lonwrapper.pm Tue Jan 26 14:30:40 2016
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Wrapper for external and binary files as standalone resources
#
-# $Id: lonwrapper.pm,v 1.49 2014/06/17 23:22:21 raeburn Exp $
+# $Id: lonwrapper.pm,v 1.50 2016/01/26 14:30:40 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -37,16 +37,17 @@
use Apache::loncommon();
use Apache::lonhtmlcommon();
use Apache::lonextresedit();
+use Apache::lonexttool();
+use LONCAPA qw(:DEFAULT :match);;
# ================================================================ Main Handler
sub wrapper {
- my ($url,$brcrum,$absolute,$is_ext,$is_pdf,$title) = @_;
+ my ($url,$brcrum,$absolute,$is_ext,$is_pdf,$exttool,$title) = @_;
my $forcereg;
unless ($env{'form.folderpath'}) {
$forcereg = 1;
}
-
my %lt = &Apache::lonlocal::texthash(
'noif' => 'No iframe support.',
'show' => 'Show content in pop-up window',
@@ -66,8 +67,8 @@
my $startpage = &Apache::loncommon::start_page('Menu',undef,$args);
my $endpage = &Apache::loncommon::end_page();
-
- if ($env{'browser.mobile'}) {
+
+ if (($env{'browser.mobile'}) || ($exttool eq 'window')) {
my $output = $startpage;
if ($is_pdf) {
if ($title eq '') {
@@ -83,6 +84,11 @@
$output .= $title.'<br />';
}
$output .= '<a href="'.$url.'">'.&mt('Link to PDF (for mobile devices)').'</a>';
+ } elsif ($exttool eq 'window') {
+ $output .= '<div>'.
+ '<a href="'.$url.'" target="LC_LTI" style="padding:0;clear:both;margin:0;border:0">'.
+ &mt('Launch External Tool').'</a>'.
+ '</div>';
} else {
$output .= '<div style="overflow:scroll; -webkit-overflow-scrolling:touch;">'."\n".
'<iframe src="'.$url.'" height="100%" width="100%" frameborder="0">'."\n".
@@ -138,7 +144,7 @@
return OK if $r->header_only;
my $url = $r->uri;
- my ($is_ext,$brcrum,$absolute,$is_pdf);
+ my ($is_ext,$brcrum,$absolute,$is_pdf,$exttool,$cdom,$cnum);
for ($url){
s|^/adm/wrapper||;
@@ -147,27 +153,47 @@
s|:|:|g;
}
+
if ($url =~ /\.pdf$/i) {
$is_pdf = 1;
+ } elsif ($url =~ m{^/adm/($match_domain)/($match_courseid)/(\d+)/exttools?$}) {
+ $cdom = $1;
+ $cnum = $2;
+ my $marker = $3;
+ $exttool = 'iframe';
+ my %toolhash = &Apache::lonnet::get('exttool_'.$marker,['target'],$cdom,$cnum);
+ if ($toolhash{'target'} eq 'window') {
+ $exttool = 'window';
+ }
}
-
- if ($is_ext) {
+ if (($is_ext) || ($exttool)) {
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
['forceedit','register','folderpath','symb','idx','title']);
if (($env{'form.forceedit'}) &&
(&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) &&
(($env{'form.folderpath'} =~ /^supplemental/) ||
($env{'form.symb'} =~ /^uploaded/))) {
+ my $type = 'ext';
+ my %ltitools;
+ if ($exttool) {
+ $type = 'tool';
+ %ltitools = &Apache::lonnet::get_domain_ltitools($cdom);
+ }
$r->print(
&Apache::lonextresedit::display_editor($url,$env{'form.folderpath'},
$env{'form.symb'},
- $env{'form.idx'}));
+ $env{'form.idx'},$type,$cdom,
+ $cnum,\%ltitools));
return OK;
} elsif ($env{'form.folderpath'} =~ /^supplemental/) {
my $crstype = &Apache::loncommon::course_type();
my $title = $env{'form.title'};
if ($title eq '') {
- $title = &mt('External Resource');
+ if ($is_ext) {
+ $title = &mt('External Resource');
+ } else {
+ $title = &mt('External Tool');
+ }
}
$brcrum =
&Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1);
@@ -187,7 +213,7 @@
#
# This is not homework
#
- if ($is_ext) {
+ if (($is_ext) || ($exttool)) {
$absolute = $env{'request.use_absolute'};
$ENV{'QUERY_STRING'} =~ s/(^|\&)symb=[^\&]*/$1/;
$ENV{'QUERY_STRING'} =~ s/\&$//;
@@ -198,9 +224,11 @@
}
# encrypt url if not external
- &Apache::lonenc::check_encrypt(\$url) if $url !~ /^https?\:/ ;
+ unless ($is_ext || $exttool) {
+ &Apache::lonenc::check_encrypt(\$url);
+ }
- $r->print( wrapper($url,$brcrum,$absolute,$is_ext,$is_pdf) );
+ $r->print( wrapper($url,$brcrum,$absolute,$is_ext,$is_pdf,$exttool) );
} # not just the menu
Index: doc/loncapafiles/loncapafiles.lpml
diff -u doc/loncapafiles/loncapafiles.lpml:1.926 doc/loncapafiles/loncapafiles.lpml:1.927
--- doc/loncapafiles/loncapafiles.lpml:1.926 Tue Jan 12 19:07:12 2016
+++ doc/loncapafiles/loncapafiles.lpml Tue Jan 26 14:30:51 2016
@@ -2,7 +2,7 @@
"http://lpml.sourceforge.net/DTD/lpml.dtd">
<!-- loncapafiles.lpml -->
-<!-- $Id: loncapafiles.lpml,v 1.926 2016/01/12 19:07:12 damieng Exp $ -->
+<!-- $Id: loncapafiles.lpml,v 1.927 2016/01/26 14:30:51 raeburn Exp $ -->
<!--
@@ -2511,6 +2511,15 @@
<status>works/unverified</status>
</file>
<file>
+<source>loncom/interface/lonexttool.pm</source>
+<target dist='default'>home/httpd/lib/perl/Apache/lonexttool.pm</target>
+<categoryname>handler</categoryname>
+<description>
+Handler to allow LON-CAPA to operate as an LTI Tool Consumer
+</description>
+<status>works/unverified</status>
+</file>
+<file>
<source>loncom/interface/lonpickcode.pm</source>
<target dist='default'>home/httpd/lib/perl/Apache/lonpickcode.pm</target>
<categoryname>handler</categoryname>
More information about the LON-CAPA-cvs
mailing list