image type
+ # or a tag inside or
+ if (($lctag eq 'label' && defined($parms{'description'}))
+ || ($lctag eq 'image') || ($lctag eq 'import')) {
+ my $next_token=$parser[-1]->get_token();
+ if ($next_token->[0] eq 'T') {
+ $next_token->[1] =~ s/[\n\r\f]+//g;
+ if ($next_token->[1] =~ m{^\Q/res/$coursedom/$coursenum/\E}si) {
+ $next_token->[1] =~ s{^\Q/res/$coursedom/$coursenum/\E}{/res/$cd/$ca/$subdir/}si;
+ $changes ++;
+ }
+ }
+ $parser[-1]->unget_token($next_token);
+ }
+ if ($lctag eq 'applet') {
+ my $havecodebase=0;
+ foreach my $key (keys(%parms)) {
+ if (lc($key) eq 'codebase') {
+ if ($parms{$key} =~ m{^\Q/res/$coursedom/$coursenum/\E}si) {
+ $parms{$key} =~ s{^\Q/res/$coursedom/$coursenum/\E}{/res/$cd/$ca/$subdir/}si;
+ $changes ++;
+ }
+ $havecodebase = 1;
+ }
+ }
+ unless ($havecodebase) {
+ foreach my $key (keys(%parms)) {
+ if ($key =~ /(archive|code|object)/i) {
+ if ($parms{$key} =~ m{^\Q/res/$coursedom/$coursenum/\E}si) {
+ $parms{$key} =~ s{^\Q/res/$coursedom/$coursenum/\E}{/res/$cd/$ca/$subdir/si};
+ $changes ++;
+ }
+ }
+ }
+ }
+ }
+ my $newparmstring='';
+ my $endtag='';
+ foreach my $parkey (keys(%parms)) {
+ if ($parkey eq '/') {
+ $endtag=' /';
+ } else {
+ my $quote=($parms{$parkey}=~/\"/?"'":'"');
+ $newparmstring.=' '.$parkey.'='.$quote.$parms{$parkey}.$quote;
+ }
+ }
+ if (!$endtag) { if ($token->[4]=~m:/>$:) { $endtag=' /'; }; }
+ $outstring.='<'.$tag.$newparmstring.$endtag.'>';
+ if ($lctag eq 'm' || $lctag eq 'answer' || $lctag eq 'display' ||
+ $lctag eq 'tex') {
+ $outstring.=&Apache::lonxml::get_all_text_unbalanced('/'.$lctag,\@parser);
+ } elsif ($lctag eq 'script') {
+ if ($parms{'type'} eq 'loncapa/perl') {
+ $outstring.=&Apache::lonxml::get_all_text_unbalanced('/'.$lctag,\@parser);
+ } else {
+ my $needsupdate;
+ my $script = &Apache::lonxml::get_all_text_unbalanced('/'.$lctag,\@parser);
+ if ($script =~ m{\.addMediaSrc\((["'])((?!\1).+)\1\);}) {
+ my $src = $2;
+ if ($src =~ m{^\Q/res/$coursedom/$coursenum/\E}si) {
+ $needsupdate = 1;
+ }
+ }
+ if ($script =~ /\(document,\s*(['"])script\1,\s*\[([^\]]+)\]\);/s) {
+ my $scriptslist = $2;
+ my @srcs = split(/\s*,\s*/,$scriptslist);
+ foreach my $src (@srcs) {
+ if ($src =~ /(["'])(?:(?!\1).)+\.js\1/) {
+ my $quote = $1;
+ my ($url) = ($src =~ m/\Q$quote\E([^$quote]+)\Q$quote\E/);
+ if ($url =~ m{^\Q/res/$coursedom/$coursenum/\E}si) {
+ $needsupdate = 1;
+ }
+ }
+ }
+ }
+ if ($script =~ m{loadScript\(\s*(['"])((?:(?!\1).)+\.js)\1,\s*function}is) {
+ my $src = $2;
+ if ($src =~ m{^\Q/res/$coursedom/$coursenum/\E}si) {
+ $needsupdate = 1;
+ }
+ }
+ if ($needsupdate) {
+ $script =~ s{^\Q/res/$coursedom/$coursenum/\E}{/res/$cd/$ca/$subdir/gsi};
+ $changes ++;
+ }
+ $outstring .= $script;
+ }
+ }
+ } elsif ($token->[0] eq 'E') {
+ if ($token->[2]) {
+ unless ($token->[1] eq 'allow') {
+ $outstring.=''.$token->[1].'>';
+ }
+ }
+ } else {
+ $outstring.=$token->[1];
+ }
+ }
+ pop(@parser);
+ }
+ if ($changes) {
+ if (open(my $fh,'>',$dest)) {
+ print $fh $outstring;
+ close($fh);
+ }
+ }
+}
+
sub group_import {
my ($coursenum, $coursedom, $folder, $container, $caller, $ltitoolsref, @files) = @_;
my ($donechk,$allmaps,%hierarchy,%titles,%addedmaps,%removefrommap,
@@ -719,7 +1703,7 @@ sub group_import {
$url = $1;
my $marker = $2;
my $info = $3;
- my ($toolid,%toolhash,%toolsettings);
+ my ($toolid,$toolprefix,$tooltype,%toolhash,%toolsettings);
my @extras = ('linktext','explanation','crslabel','crstitle','crsappend');
my @toolinfo = split(/:/,$info);
if ($residx) {
@@ -728,6 +1712,12 @@ sub group_import {
} else {
$toolid = shift(@toolinfo);
}
+ if ($toolid =~ /^c/) {
+ $tooltype = 'crs';
+ $toolprefix = 'c';
+ } else {
+ $tooltype = 'dom';
+ }
$toolid =~ s/\D//g;
($toolhash{'target'},$toolhash{'width'},$toolhash{'height'},
$toolhash{'linktext'},$toolhash{'explanation'},$toolhash{'crslabel'},
@@ -741,127 +1731,130 @@ sub group_import {
$toolhash{'gradable'} =~ s/\D+//g;
}
if (ref($ltitoolsref) eq 'HASH') {
- if (ref($ltitoolsref->{$toolid}) eq 'HASH') {
- my @deleted;
- $toolhash{'id'} = $toolid;
- if (($toolhash{'target'} eq 'iframe') || ($toolhash{'target'} eq 'tab') ||
- ($toolhash{'target'} eq 'window')) {
- if ($toolhash{'target'} eq 'window') {
- foreach my $item ('width','height') {
- $toolhash{$item} =~ s/^\s+//;
- $toolhash{$item} =~ s/\s+$//;
- if ($toolhash{$item} =~ /\D/) {
- delete($toolhash{$item});
- if ($residx) {
- if ($toolsettings{$item}) {
- push(@deleted,$item);
+ if (ref($ltitoolsref->{$tooltype}) eq 'HASH') {
+ if (ref($ltitoolsref->{$tooltype}->{$toolid}) eq 'HASH') {
+ my %tools = %{$ltitoolsref->{$tooltype}->{$toolid}};
+ my @deleted;
+ $toolhash{'id'} = $toolprefix.$toolid;
+ if (($toolhash{'target'} eq 'iframe') || ($toolhash{'target'} eq 'tab') ||
+ ($toolhash{'target'} eq 'window')) {
+ if ($toolhash{'target'} eq 'window') {
+ foreach my $item ('width','height') {
+ $toolhash{$item} =~ s/^\s+//;
+ $toolhash{$item} =~ s/\s+$//;
+ if ($toolhash{$item} =~ /\D/) {
+ delete($toolhash{$item});
+ if ($residx) {
+ if ($toolsettings{$item}) {
+ push(@deleted,$item);
+ }
}
}
}
}
- }
- } elsif ($residx) {
- $toolhash{'target'} = $toolsettings{'target'};
- if ($toolhash{'target'} eq 'window') {
- foreach my $item ('width','height') {
- $toolhash{$item} = $toolsettings{$item};
+ } elsif ($residx) {
+ $toolhash{'target'} = $toolsettings{'target'};
+ if ($toolhash{'target'} eq 'window') {
+ foreach my $item ('width','height') {
+ $toolhash{$item} = $toolsettings{$item};
+ }
+ }
+ } elsif (ref($tools{'display'}) eq 'HASH') {
+ $toolhash{'target'} = $tools{'display'}{'target'};
+ if ($toolhash{'target'} eq 'window') {
+ $toolhash{'width'} = $tools{'display'}{'width'};
+ $toolhash{'height'} = $tools{'display'}{'height'};
}
}
- } elsif (ref($ltitoolsref->{$toolid}->{'display'}) eq 'HASH') {
- $toolhash{'target'} = $ltitoolsref->{$toolid}->{'display'}->{'target'};
- if ($toolhash{'target'} eq 'window') {
- $toolhash{'width'} = $ltitoolsref->{$toolid}->{'display'}->{'width'};
- $toolhash{'height'} = $ltitoolsref->{$toolid}->{'display'}->{'height'};
- }
- }
- if ($toolhash{'target'} eq 'iframe') {
- foreach my $item ('width','height','linktext','explanation') {
- delete($toolhash{$item});
- if ($residx) {
- if ($toolsettings{$item}) {
- push(@deleted,$item);
+ if ($toolhash{'target'} eq 'iframe') {
+ foreach my $item ('width','height','linktext','explanation') {
+ delete($toolhash{$item});
+ if ($residx) {
+ if ($toolsettings{$item}) {
+ push(@deleted,$item);
+ }
}
}
- }
- } elsif ($toolhash{'target'} eq 'tab') {
- foreach my $item ('width','height') {
- delete($toolhash{$item});
- if ($residx) {
- if ($toolsettings{$item}) {
- push(@deleted,$item);
+ } elsif ($toolhash{'target'} eq 'tab') {
+ foreach my $item ('width','height') {
+ delete($toolhash{$item});
+ if ($residx) {
+ if ($toolsettings{$item}) {
+ push(@deleted,$item);
+ }
}
}
}
- }
- if (ref($ltitoolsref->{$toolid}->{'crsconf'}) eq 'HASH') {
- foreach my $item ('label','title','linktext','explanation') {
- my $crsitem;
- if (($item eq 'label') || ($item eq 'title')) {
- $crsitem = 'crs'.$item;
- } else {
- $crsitem = $item;
- }
- if ($ltitoolsref->{$toolid}->{'crsconf'}->{$item}) {
- $toolhash{$crsitem} =~ s/^\s+//;
- $toolhash{$crsitem} =~ s/\s+$//;
- if ($toolhash{$crsitem} eq '') {
+ if (ref($tools{'crsconf'}) eq 'HASH') {
+ foreach my $item ('label','title','linktext','explanation') {
+ my $crsitem;
+ if (($item eq 'label') || ($item eq 'title')) {
+ $crsitem = 'crs'.$item;
+ } else {
+ $crsitem = $item;
+ }
+ if ($tools{'crsconf'}{$item}) {
+ $toolhash{$crsitem} =~ s/^\s+//;
+ $toolhash{$crsitem} =~ s/\s+$//;
+ if ($toolhash{$crsitem} eq '') {
+ delete($toolhash{$crsitem});
+ }
+ } else {
delete($toolhash{$crsitem});
}
- } else {
- delete($toolhash{$crsitem});
- }
- if (($residx) && (exists($toolsettings{$crsitem}))) {
- unless (exists($toolhash{$crsitem})) {
- push(@deleted,$crsitem);
+ if (($residx) && (exists($toolsettings{$crsitem}))) {
+ unless (exists($toolhash{$crsitem})) {
+ push(@deleted,$crsitem);
+ }
}
}
}
- }
- if ($toolhash{'passback'}) {
- my $gradesecret = UUID::Tiny::create_uuid_as_string(UUID_V4);
- $toolhash{'gradesecret'} = $gradesecret;
- $toolhash{'gradesecretdate'} = time;
- }
- if ($toolhash{'roster'}) {
- my $rostersecret = UUID::Tiny::create_uuid_as_string(UUID_V4);
- $toolhash{'rostersecret'} = $rostersecret;
- $toolhash{'rostersecretdate'} = time;
- }
- my $changegradable;
- if (($residx) && ($folder =~ /^default/)) {
- if ($toolsettings{'gradable'}) {
- unless (($toolhash{'gradable'}) || (defined($LONCAPA::map::zombies[$residx]))) {
- push(@deleted,'gradable');
- $changegradable = 1;
- }
- } elsif ($toolhash{'gradable'}) {
- $changegradable = 1;
+ if ($toolhash{'passback'}) {
+ my $gradesecret = UUID::Tiny::create_uuid_as_string(UUID_V4);
+ $toolhash{'gradesecret'} = $gradesecret;
+ $toolhash{'gradesecretdate'} = time;
+ }
+ if ($toolhash{'roster'}) {
+ my $rostersecret = UUID::Tiny::create_uuid_as_string(UUID_V4);
+ $toolhash{'rostersecret'} = $rostersecret;
+ $toolhash{'rostersecretdate'} = time;
}
- if (($caller eq 'londocs') && (defined($LONCAPA::map::zombies[$residx]))) {
- $changegradable = 1;
+ my $changegradable;
+ if (($residx) && ($folder =~ /^default/)) {
if ($toolsettings{'gradable'}) {
- $toolhash{'gradable'} = 1;
+ unless (($toolhash{'gradable'}) || (defined($LONCAPA::map::zombies[$residx]))) {
+ push(@deleted,'gradable');
+ $changegradable = 1;
+ }
+ } elsif ($toolhash{'gradable'}) {
+ $changegradable = 1;
+ }
+ if (($caller eq 'londocs') && (defined($LONCAPA::map::zombies[$residx]))) {
+ $changegradable = 1;
+ if ($toolsettings{'gradable'}) {
+ $toolhash{'gradable'} = 1;
+ }
}
}
- }
- my $putres = &Apache::lonnet::put('exttool_'.$marker,\%toolhash,$coursedom,$coursenum);
- if ($putres eq 'ok') {
- if (@deleted) {
- &Apache::lonnet::del('exttool_'.$marker,\@deleted,$coursedom,$coursenum);
- }
- if (($changegradable) && ($folder =~ /^default/)) {
- my $val;
- if ($toolhash{'gradable'}) {
- $val = 'yes';
- } else {
- $val = 'no';
+ my $putres = &Apache::lonnet::put('exttool_'.$marker,\%toolhash,$coursedom,$coursenum);
+ if ($putres eq 'ok') {
+ if (@deleted) {
+ &Apache::lonnet::del('exttool_'.$marker,\@deleted,$coursedom,$coursenum);
+ }
+ if (($changegradable) && ($folder =~ /^default/)) {
+ my $val;
+ if ($toolhash{'gradable'}) {
+ $val = 'yes';
+ } else {
+ $val = 'no';
+ }
+ &LONCAPA::map::storeparameter($residx,'parameter_0_gradable',$val,
+ 'string_yesno');
+ &remember_parms($residx,'gradable','set',$val);
}
- &LONCAPA::map::storeparameter($residx,'parameter_0_gradable',$val,
- 'string_yesno');
- &remember_parms($residx,'gradable','set',$val);
+ } else {
+ return (&mt('Failed to save update to external tool.'),1);
}
- } else {
- return (&mt('Failed to save update to external tool.'),1);
}
}
}
@@ -1411,7 +2404,7 @@ sub print_paste_buffer {
}
my @currpaste = split(/,/,$env{'docs.markedcopies'});
- my ($pasteitems,@pasteable);
+ my ($pasteitems,@pasteable,$same_institution,$checkedsameinst);
my $clipboardcount = 0;
# Construct identifiers for current contents of user's paste buffer
@@ -1424,11 +2417,13 @@ sub print_paste_buffer {
($url ne '')) {
$clipboardcount ++;
my ($is_external,$othercourse,$fromsupp,$is_uploaded_map,$parent,
- $canpaste,$nopaste,$othercrs,$areachange,$is_exttool);
+ $canpaste,$nopaste,$othercrs,$areachange,$is_exttool,$toolcdom,
+ $toolcnum,$marker);
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+/ext\.tool$}) {
+ } elsif ($url =~ m{^/adm/($match_domain)/($match_courseid)/(\d+)/ext\.tool$}) {
+ ($toolcdom,$toolcnum,$marker) = ($1,$2,$3);
$is_exttool = 1;
}
if ($folder =~ /^supplemental/) {
@@ -1466,17 +2461,56 @@ sub print_paste_buffer {
if ($cid ne $env{'request.course.id'}) {
my ($srcdom,$srcnum) = split(/_/,$cid);
if ($env{"user.priv.cm./$srcdom/$srcnum"} =~ /\Q:mdc&F\E/) {
- if (($is_exttool) && ($srcdom ne $coursedom)) {
- $canpaste = 0;
- $nopaste = &mt('Paste from another domain unavailable.');
- } else {
- $othercrs = ' '.&mt('(from another course)');
+ if ($is_exttool) {
+ if ($toolcdom ne $coursedom) {
+ $canpaste = 0;
+ $nopaste = &mt('Paste from another domain unavailable.');
+ } elsif ($toolcnum ne $coursenum) {
+ my %toolsettings =
+ &Apache::lonnet::dump('exttool_'.$marker,$toolcdom,$toolcnum);
+ my %tooltypes = &Apache::loncommon::usable_exttools();
+ if ((($toolsettings{'id'} =~ /^c\d+$/) && (!$tooltypes{'crs'})) ||
+ (($toolsettings{'id'} =~ /^\d+$/) && (!$tooltypes{'dom'}))) {
+ $canpaste = 0;
+ $nopaste = &mt('Paste from another course unavailable.');
+ } elsif ($toolsettings{'id'} =~ /^c\d+$/) {
+ unless ($checkedsameinst) {
+ my $primary_id = &Apache::lonnet::domain($coursedom,'primary');
+ my $intdom = &Apache::lonnet::internet_dom($primary_id);
+ if ($intdom ne '') {
+ my $internet_names =
+ &Apache::lonnet::get_internet_names($Apache::lonnet::perlvar{'lonHostID'});
+ if (ref($internet_names) eq 'ARRAY') {
+ if (grep(/^\Q$intdom\E$/,@{$internet_names})) {
+ $same_institution = 1;
+ }
+ }
+ }
+ $checkedsameinst = 1;
+ }
+ if ($same_institution) {
+ $othercrs = ' '.&mt('(from another course)');
+ } else {
+ $nopaste = &mt('Paste from another course unavailable.');
+ }
+ } else {
+ $othercrs = ' '.&mt('(from another course)');
+ }
+ }
}
} else {
$canpaste = 0;
$nopaste = &mt('Paste from another course unavailable.');
}
}
+ } elsif ($url =~ m{/res/($match_domain)/($match_username)/}) {
+ my ($audom,$auname) = ($1,$2);
+ unless (($auname eq $coursenum) && ($audom eq $coursedom)) {
+ if (&Apache::lonnet::is_course($audom,$auname)) {
+ $canpaste = 0;
+ $nopaste = &mt('Paste from another course unavailable.');
+ }
+ }
}
if ($canpaste) {
push(@pasteable,$suffix);
@@ -1769,9 +2803,12 @@ sub do_paste_from_buffer {
return();
}
- my (%msgs,%before,%after,@dopaste,%is_map,%notinsupp,%notincrs,%notindom,%duplicate,
- %prefixchg,%srcdom,%srcnum,%srcmapidx,%marktomove,$save_err,$lockerrors,$allresult);
-
+ my (%msgs,%before,%after,@dopaste,%is_map,%notinsupp,%notincrs,%notindom,
+ %othcrstool,%othcrsres,%duplicate,%prefixchg,%srcdom,%srcnum,%srcmapidx,
+ %marktomove,$save_err,$lockerrors,$allresult,%currcrsltitools,
+ %currltititles,$currltimax,$gotcrsltitools);
+ $currltimax = 0;
+ $gotcrsltitools = 0;
foreach my $suffix (@topaste) {
my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url_'.$suffix});
my $cid=&LONCAPA::map::qtescape($env{'docs.markedcopy_crs_'.$suffix});
@@ -1810,13 +2847,53 @@ sub do_paste_from_buffer {
}
}
# When buffer was populated using an active role in a different course
-# disallow pasting of External Tool if course is in a different domain.
- if (($url =~ m{/ext\.tool$}) && ($srcd ne $coursedom)) {
- $notindom{$suffix} = 1;
- next;
+# disallow pasting of External Tool if course is in a different domain,
+# or if External Tool use is not permitted in this course.
+ if ($url =~ m{^/adm/($match_domain)/($match_courseid)/(\d+)/ext\.tool$}) {
+ my ($toolcdom,$toolcnum,$marker) = ($1,$2,$3);
+ if ($toolcdom ne $coursedom) {
+ $notindom{$suffix} = 1;
+ next;
+ } elsif ($toolcnum ne $coursenum) {
+ my %toolsettings =
+ &Apache::lonnet::dump('exttool_'.$marker,$toolcdom,$toolcnum);
+ my %tooltypes = &Apache::loncommon::usable_exttools();
+ if ((($toolsettings{'id'} =~ /^c\d+$/) && (!$tooltypes{'crs'})) ||
+ (($toolsettings{'id'} =~ /^\d+$/) && (!$tooltypes{'dom'}))) {
+ $othcrstool{$suffix} = 1;
+ next;
+ }
+ if ($toolsettings{'id'} =~ /^c\d+$/) {
+ unless ($gotcrsltitools) {
+ %currcrsltitools =
+ &Apache::lonnet::get_course_lti($coursenum,$coursedom,'consumer');
+ foreach my $item (sort(keys(%currcrsltitools))) {
+ if (ref($currcrsltitools{$item}) eq 'HASH') {
+ $currltimax ++;
+ if (ref($currltititles{$currcrsltitools{$item}{'title'}}) eq 'ARRAY') {
+ push(@{$currltititles{$currcrsltitools{$item}{'title'}}},$item);
+ } else {
+ $currltititles{$currcrsltitools{$item}{'title'}} = [$item];
+ }
+ }
+ }
+ $gotcrsltitools = 1;
+ }
+ }
+ }
}
$srcdom{$suffix} = $srcd;
$srcnum{$suffix} = $srcn;
+ } elsif ($url =~ m{^/res/($match_domain)/($match_courseid)/}) {
+ my ($audom,$auname) = ($1,$2);
+# When buffer was populated using an active role in a different course
+# disallow pasting of published resources from Course Authoring Space
+ unless (($auname eq $coursenum) && ($audom eq $coursedom)) {
+ if (&Apache::lonnet::is_course($audom,$auname)) {
+ $othcrsres{$suffix} = 1;
+ next;
+ }
+ }
}
$srcmapidx{$suffix} = $mapidx;
push(@dopaste,$suffix);
@@ -1868,6 +2945,8 @@ sub do_paste_from_buffer {
notinsupp => 'Paste failed: content type is not supported within Supplemental Content',
notincrs => 'Paste failed: Item is from a different course which you do not have rights to edit.',
notindom => 'Paste failed: Item is an external tool from a course in a different domain.',
+ othcrstool => 'Paste failed: Item is an external tool from a different course, for which use is not allowed in this course.',
+ othcrsres => 'Paste failed: Item is a course-authored resource from a different course',
duplicate => 'Paste failed: only one instance of a particular published sequence or page is allowed within each course.',
);
@@ -1896,7 +2975,9 @@ sub do_paste_from_buffer {
# Retrieve information about all course maps in main content area
my $allmaps = {};
- my (@toclear,%mapurls,%lockerrs,%msgerrs,%results,$donechk);
+ my (@toclear,%mapurls,%lockerrs,%msgerrs,%results,$donechk,
+ @updatetoolsenc,$updatetoolscache,$checkedsameinst,
+ $same_institution);
# Loop over the items to paste
foreach my $suffix (@dopaste) {
@@ -1995,12 +3076,27 @@ sub do_paste_from_buffer {
$fromothercrs = 1;
$info{'cdom'} = $srcdom{$suffix};
$info{'cnum'} = $srcnum{$suffix};
+ unless ($checkedsameinst) {
+ my $primary_id = &Apache::lonnet::domain($coursedom,'primary');
+ my $intdom = &Apache::lonnet::internet_dom($primary_id);
+ if ($intdom ne '') {
+ my $internet_names =
+ &Apache::lonnet::get_internet_names($Apache::lonnet::perlvar{'lonHostID'});
+ if (ref($internet_names) eq 'ARRAY') {
+ if (grep(/^\Q$intdom\E$/,@{$internet_names})) {
+ $same_institution = 1;
+ }
+ }
+ }
+ $checkedsameinst = 1;
+ }
}
}
unless (($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') && (!$fromothercrs)) {
my (%lockerr,$msg);
my ($newurl,$result,$errtext) =
- &dbcopy(\%info,$coursedom,$coursenum,\%lockerr);
+ &dbcopy(\%info,$coursedom,$coursenum,\%lockerr,\%currltititles,
+ \$currltimax,\@updatetoolsenc,\$updatetoolscache,$same_institution);
if ($result eq 'ok') {
$url = $newurl;
$title=&mt('Copy of').' '.$title;
@@ -2169,6 +3265,10 @@ sub do_paste_from_buffer {
}
}
}
+ if (($updatetoolscache) || (@updatetoolsenc)) {
+ &update_ltitools_caches($coursedom,$coursenum,$updatetoolscache,
+ \@updatetoolsenc);
+ }
&clear_from_buffer(\@toclear,\@currpaste);
my $msgsarray;
foreach my $suffix (keys(%msgs)) {
@@ -2217,6 +3317,30 @@ sub clear_from_buffer {
return $numdel;
}
+sub update_ltitools_caches {
+ my ($coursedom,$coursenum,$updatetoolscache,$updatetoolsenc) = @_;
+ my $hashid=$coursedom.'_'.$coursenum;
+ if ($updatetoolscache) {
+ &Apache::lonnet::devalidate_cache_new('courseltitools',$hashid);
+ }
+ if ((ref($updatetoolsenc) eq 'ARRAY') &&
+ (@{$updatetoolsenc})) {
+ my @ids=&Apache::lonnet::current_machine_ids();
+ my $updatedone;
+ foreach my $lonhost (@{$updatetoolsenc}) {
+ if (grep(/^\Q$lonhost\E$/,@ids)) {
+ unless ($updatedone) {
+ &Apache::lonnet::devalidate_cache_new('crsltitoolsenc',$hashid);
+ }
+ $updatedone = 1;
+ } else {
+ &Apache::lonnet::remote_devalidate_cache($lonhost,["crsltitoolsenc:$hashid"]);
+ }
+ }
+ }
+ return;
+}
+
sub get_newmap_url {
my ($url,$folder,$prefixchg,$coursedom,$coursenum,$srcdom,$srcnum,
$titleref,$allmaps,$newurls) = @_;
@@ -2278,7 +3402,8 @@ sub get_newmap_url {
}
sub dbcopy {
- my ($dbref,$coursedom,$coursenum,$lockerrorsref) = @_;
+ my ($dbref,$coursedom,$coursenum,$lockerrorsref,$currltititles,
+ $currltimax,$updatetoolsenc,$updatetoolscache,$same_institution) = @_;
my ($url,$result,$errtext);
if (ref($dbref) eq 'HASH') {
$url = $dbref->{'src'};
@@ -2322,6 +3447,117 @@ sub dbcopy {
my %contents=&Apache::lonnet::dump($db_name,
$dbref->{'cdom'},
$dbref->{'cnum'});
+ my ($toolcopyerror,$toolpassback,$toolroster,%toolinfo,$oldtoolid,$defincrs);
+ if ($url eq '/adm/'.$dbref->{'cdom'}.'/'.$dbref->{'cnum'}."/$marker/ext.tool") {
+ if ($contents{'id'} =~ /^(|c)(\d+)$/) {
+ $oldtoolid = $2;
+ if ($1 eq 'c') {
+ $defincrs = 1;
+ %toolinfo =
+ &Apache::lonnet::get('ltitools',[$oldtoolid],$dbref->{'cdom'},$dbref->{'cnum'});
+ } else {
+ %toolinfo= &Apache::lonnet::get_domain_lti($dbref->{'cdom'},'consumer');
+ }
+ if (ref($toolinfo{$oldtoolid}) eq 'HASH') {
+ if ($toolinfo{$oldtoolid}{'passback'}) {
+ $toolpassback = 1;
+ }
+ if ($toolinfo{$oldtoolid}{'roster'}) {
+ $toolroster = 1;
+ }
+ } else {
+ $toolcopyerror = 1;
+ $errtext = &mt('Could not retrieve original settings for pasted external tool.');
+ }
+ }
+ unless (($dbref->{'cnum'} eq $coursenum) && ($dbref->{'cdom'} eq $coursedom)) {
+ $url = "/adm/$coursedom/$coursenum/$marker/ext.tool";
+ if ($contents{'crstitle'} ne '') {
+ $contents{'crstitle'} = $env{'course.'.$coursedom.'_'.$coursenum.'.description'};
+ }
+ if (($defincrs) && (!$toolcopyerror)) {
+ my %newtool;
+ my $oldcdom = $dbref->{'cdom'};
+ my $oldcnum = $dbref->{'cnum'};
+ my $title = $toolinfo{$oldtoolid}{'title'};
+ if (ref($currltititles) eq 'HASH') {
+ if (exists($currltititles->{$title})) {
+ $title .= ' (copied from another course)';
+ }
+ }
+ my ($newid,$iderror) =
+ &Apache::lonnet::get_ltitools_id('course',$coursedom,$coursenum,$title);
+ if ($newid =~ /^\d+$/) {
+ %{$newtool{$newid}} = %{$toolinfo{$oldtoolid}};
+ $newtool{$newid}{'title'} = $title;
+ if (ref($currltimax)) {
+ $newtool{$newid}{'order'} = $$currltimax;
+ }
+ if ($newtool{$newid}{'image'} =~ m{^\Q/uploaded/$oldcdom/$oldcnum/toollogo/$oldtoolid/\E([^/]+)$}) {
+ my $fname = $1;
+ my $content = &Apache::lonnet::getfile($newtool{$newid}{'image'});
+ if ($content eq '-1') {
+ delete($newtool{$newid}{'image'});
+ } else {
+ $env{'form.'.$suffix.'.image'} = $content;
+ my $newlogo =
+ &Apache::lonnet::finishuserfileupload($coursenum,$coursedom,$suffix.'.image',"toollogo/$newid/$fname");
+ delete($env{'form.'.$suffix.'.image'});
+ if ($newlogo =~ m{^/uploaded/}) {
+ $newtool{$newid}{'image'} = $newlogo;
+ } else {
+ delete($newtool{$newid}{'image'});
+ }
+ }
+ }
+ my $newusable;
+ if ($same_institution) {
+ my %oldtoolsenc = &Apache::lonnet::eget('nohist_toolsenc',[$oldtoolid],$oldcdom,$oldcnum);
+ if (ref($oldtoolsenc{$oldtoolid}) eq 'HASH') {
+ my %newtoolsenc;
+ %{$newtoolsenc{$newid}} = %{$oldtoolsenc{$oldtoolid}};
+ my $putres = &Apache::lonnet::put('nohist_toolsenc',\%newtoolsenc,$coursedom,$coursenum,1);
+ if ($putres eq 'ok') {
+ if (ref($updatetoolsenc) eq 'ARRAY') {
+ my $newhome = &Apache::lonnet::homeserver($coursenum,$coursedom);
+ unless (grep(/^\Q$newhome\E$/,@{$updatetoolsenc})) {
+ push(@{$updatetoolsenc},$newhome);
+ }
+ }
+ $newusable = 1;
+ }
+ }
+ }
+ if ($newtool{$newid}{'usable'}) {
+ unless ($newusable) {
+ delete($newtool{$newid}{'usable'});
+ }
+ }
+ my $putres = &Apache::lonnet::put('ltitools',\%newtool,$coursedom,$coursenum);
+ if ($putres eq 'ok') {
+ $contents{'id'} = "c$newid";
+ if (ref($updatetoolscache)) {
+ $$updatetoolscache ++;
+ }
+ if (ref($currltititles->{$title}) eq 'ARRAY') {
+ push(@{$currltititles->{$title}},$newid);
+ } else {
+ $currltititles->{$title} = [$newid];
+ }
+ if (ref($currltimax)) {
+ $$currltimax ++;
+ }
+ } else {
+ $toolcopyerror = 1;
+ $errtext = &mt('Unable to save external tool definition in Course Settings.');
+ }
+ } else {
+ $toolcopyerror = 1;
+ $errtext = &mt('Unable to retrieve new tool ID when adding external tool definition to Course Settings.');
+ }
+ }
+ }
+ }
if (exists($contents{'uploaded.photourl'})) {
my $photo = $contents{'uploaded.photourl'};
my ($subdir,$fname) =
@@ -2341,13 +3577,40 @@ sub dbcopy {
}
}
$db_name =~ s{_\d*$ }{_$suffix}x;
- if (($prefix eq 'exttool') && ($dbref->{'delgradable'}) && ($contents{'gradable'})) {
- delete($contents{'gradable'});
+ if ($prefix eq 'exttool') {
+ unless ($toolcopyerror) {
+ foreach my $key ('oldgradesecret','gradesecret','gradesecretdate','oldrostersecret','rostersecret','rostersecretdate') {
+ if (exists($contents{$key})) {
+ delete($contents{$key});
+ }
+ }
+ if ($dbref->{'delgradable'}) {
+ if (exists($contents{'gradable'})) {
+ delete($contents{'gradable'});
+ }
+ }
+ if ($toolpassback) {
+ if ($contents{'gradable'}) {
+ my $gradesecret = UUID::Tiny::create_uuid_as_string(UUID_V4);
+ $contents{'gradesecret'} = $gradesecret;
+ $contents{'gradesecretdate'} = time;
+ }
+ }
+ if ($toolroster) {
+ my $rostersecret = UUID::Tiny::create_uuid_as_string(UUID_V4);
+ $contents{'rostersecret'} = $rostersecret;
+ $contents{'rostersecretdate'} = time;
+ }
+ }
}
- $result=&Apache::lonnet::put($db_name,\%contents,
- $coursedom,$coursenum);
- if ($result eq 'ok') {
- $url =~ s{/(\d*)/(smppg|bulletinboard|ext\.tool)$}{/$suffix/$2}x;
+ if (($prefix eq 'exttool') && ($toolcopyerror)) {
+ $result = 'error';
+ } else {
+ $result=&Apache::lonnet::put($db_name,\%contents,
+ $coursedom,$coursenum);
+ if ($result eq 'ok') {
+ $url =~ s{/(\d*)/(smppg|bulletinboard|ext\.tool)$}{/$suffix/$2}x;
+ }
}
}
if (($freedlock ne 'ok') && (ref($lockerrorsref) eq 'HASH')) {
@@ -2502,18 +3765,37 @@ sub contained_map_check {
if ($token->[1] eq 'resource') {
next if ($token->[2]->{'type'} eq 'zombie');
my $ressrc = $token->[2]->{'src'};
- if ($ressrc =~ m{^/adm/($match_domain)/$match_courseid/\d+/ext\.tool$}) {
- my $srcdom = $1;
+ if ($ressrc =~ m{^/adm/($match_domain)/($match_courseid)/(\d+)/ext\.tool$}) {
+ my ($srcdom,$srcnum,$marker) = ($1,$2,$3);
unless ($srcdom eq $coursedom) {
$removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;
next;
}
+ unless ($srcnum eq $coursenum) {
+ my %toolsettings =
+ &Apache::lonnet::dump('exttool_'.$marker,$srcdom,$srcnum);
+ my %tooltypes = &Apache::loncommon::usable_exttools();
+ if ((($toolsettings{'id'} =~ /^c\d+$/) && (!$tooltypes{'crs'})) ||
+ (($toolsettings{'id'} =~ /^\d+$/) && (!$tooltypes{'dom'}))) {
+ $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;
+ next;
+ }
+ }
} elsif ($folder =~ /^supplemental/) {
unless (&supp_pasteable($ressrc)) {
$removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;
next;
}
}
+ if ($ressrc =~ m{^/res/($match_domain)/($match_courseid)/}) {
+ my ($srcdom,$srcnum) = ($1,$2);
+ unless (($srcnum eq $coursenum) && ($srcdom eq $coursedom)) {
+ if (&Apache::lonnet::is_course($srcdom,$srcnum)) {
+ $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;
+ next;
+ }
+ }
+ }
if ($ressrc =~ m{^/(res|uploaded)/.+\.(sequence|page)$}) {
if ($1 eq 'uploaded') {
$hierarchy->{$url}{$token->[2]->{'id'}} = $ressrc;
@@ -2648,7 +3930,7 @@ sub url_paste_fixups {
if ($is_exttool) {
$exttoolchg = 1;
}
- } elsif (($rem =~ m{\d+/ext\.tool$}) &&
+ } elsif (($is_exttool) &&
($env{'form.docs.markedcopy_options'} ne 'move')) {
$dbcopies->{$oldurl}{$id}{'src'} = $ressrc;
$dbcopies->{$oldurl}{$id}{'cdom'} = $srcdom;
@@ -2708,7 +3990,9 @@ sub apply_fixups {
$oldurl,$url,$caller) = @_;
my (%rewrites,%zombies,%removefrommap,%removeparam,%dbcopies,%retitles,
%params,%newsubdir,%before,%after,%copies,%docmoves,%mapmoves,@msgs,
- %resdatacopy,%lockerrors,$lockmsg);
+ %resdatacopy,%lockerrors,$lockmsg,%currcrsltitools,$gotcrsltitools,
+ %currltititles,$currltimax);
+ $currltimax = 0;
if (ref($updated) eq 'HASH') {
if (ref($updated->{'rewrites'}) eq 'HASH') {
%rewrites = %{$updated->{'rewrites'}};
@@ -2859,6 +4143,7 @@ sub apply_fixups {
}
}
}
+ my ($updatetoolscache,@updatetoolsenc,$same_institution,$checkedsameinst);
foreach my $key (keys(%updates)) {
my (%torewrite,%toretitle,%toremove,%remparam,%currparam,%zombie,%newdb);
if (ref($rewrites{$key}) eq 'HASH') {
@@ -2879,10 +4164,63 @@ sub apply_fixups {
if (ref($dbcopies{$key}) eq 'HASH') {
foreach my $idx (keys(%{$dbcopies{$key}})) {
if (ref($dbcopies{$key}{$idx}) eq 'HASH') {
+ my $oldurl = $dbcopies{$key}{$idx}{'src'};
+ my $oldcdom = $dbcopies{$key}{$idx}{'cdom'};
+ my $oldcnum = $dbcopies{$key}{$idx}{'cnum'};
+ my $oldmarker;
+ if ($oldurl =~ m{^\Q/adm/$oldcdom/$oldcnum/\E(\d+)/ext\.tool$}) {
+ $oldmarker = $1;
+ unless (($gotcrsltitools) ||
+ (($oldcnum eq $cnum) && ($oldcdom eq $cdom))) {
+ my %oldtoolsettings=&Apache::lonnet::dump('exttool_'.$oldmarker,$oldcdom,$oldcnum);
+ if ($oldtoolsettings{'id'} =~ /^c\d+$/) {
+ unless ($gotcrsltitools) {
+ %currcrsltitools =
+ &Apache::lonnet::get_course_lti($cnum,$cdom,'consumer');
+ foreach my $item (sort(keys(%currcrsltitools))) {
+ if (ref($currcrsltitools{$item}) eq 'HASH') {
+ $currltimax ++;
+ if (ref($currltititles{$currcrsltitools{$item}{'title'}}) eq 'ARRAY') {
+ push(@{$currltititles{$currcrsltitools{$item}{'title'}}},$item);
+ } else {
+ $currltititles{$currcrsltitools{$item}{'title'}} = [$item];
+ }
+ }
+ }
+ $gotcrsltitools = 1;
+ }
+ unless ($checkedsameinst) {
+ my $primary_id = &Apache::lonnet::domain($cdom,'primary');
+ my $intdom = &Apache::lonnet::internet_dom($primary_id);
+ if ($intdom ne '') {
+ my $internet_names =
+ &Apache::lonnet::get_internet_names($Apache::lonnet::perlvar{'lonHostID'});
+ if (ref($internet_names) eq 'ARRAY') {
+ if (grep(/^\Q$intdom\E$/,@{$internet_names})) {
+ $same_institution = 1;
+ }
+ }
+ }
+ $checkedsameinst = 1;
+ }
+ }
+ }
+ }
my ($newurl,$result,$errtext) =
- &dbcopy($dbcopies{$key}{$idx},$cdom,$cnum,\%lockerrors);
+ &dbcopy($dbcopies{$key}{$idx},$cdom,$cnum,\%lockerrors,\%currltititles,
+ \$currltimax,\@updatetoolsenc,\$updatetoolscache,$same_institution);
if ($result eq 'ok') {
$newdb{$idx} = $newurl;
+ if ($newurl =~ /ext\.tool$/) {
+ if ($torewrite{$idx} eq "/adm/$oldcdom/$oldcnum/$oldmarker/ext.tool") {
+ if ($newurl =~ m{^\Q/adm/$cdom/$cnum/\E(\d+)/ext.tool$}) {
+ my $newmarker = $1;
+ unless ($oldmarker eq $newmarker) {
+ $torewrite{$idx} = "/adm/$oldcdom/$oldcnum/$newmarker/ext.tool";
+ }
+ }
+ }
+ }
} elsif (ref($errors) eq 'HASH') {
$errors->{$key} = 1;
}
@@ -3021,6 +4359,10 @@ sub apply_fixups {
}
}
}
+ if (($updatetoolscache) || (@updatetoolsenc)) {
+ &update_ltitools_caches($cdom,$cnum,$updatetoolscache,
+ \@updatetoolsenc);
+ }
}
return ('ok',\@msgs,$lockmsg);
}
@@ -3745,7 +5087,7 @@ sub multiple_check_form {
return unless (ref($listsref) eq 'HASH');
my $disabled;
unless ($canedit) {
- $disabled = 'disabled="disabled"';
+ $disabled = ' disabled="disabled"';
}
my $output =
' '."\n".
''.
''.
- ' '.&mt('Copy').
+ ' '.&mt('Copy').
' '.
''."\n";
}
@@ -4377,7 +5719,7 @@ END
}
$nomodal = 1;
}
- } elsif (($uploaded) && (!$allowed) && ($url ne '/adm/supplemental?')) {
+ } elsif (($uploaded) && ($url ne '/adm/supplemental?') && ($url ne '/adm/coursedocs?')) {
my $embstyle=&Apache::loncommon::fileembstyle($extension);
unless ($embstyle eq 'ssi') {
if (($embstyle eq 'img')
@@ -4483,7 +5825,7 @@ $form_common."\n".
' '.&mt('Random Order').' '.
$form_end;
}
- } elsif ($supplementalflag && !$allowed) {
+ } elsif ($supplementalflag) {
my $isexttool;
if ($url=~m{^/adm/$coursedom/$coursenum/\d+/ext\.tool$}) {
$url='/adm/wrapper'.$url;
@@ -4546,7 +5888,7 @@ $form_end;
} else {
$reinit = &mt('(re-initialize course to access)');
}
- $line.=''.$editlink.$renamelink;
+ $line.=' '.$editlink.$renamelink.' ';
if ($orig_url =~ /$LONCAPA::assess_re/) {
$line.= ' ';
if ($curralias ne '') {
@@ -4557,7 +5899,7 @@ $form_end;
$lt{'sa'}.'';
}
}
- $line.='';
+ $line.=' ';
my ($link,$nolink);
if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) {
if ($allowed && !$env{'request.role.adv'} && !$isfolder && !$ispage) {
@@ -4578,12 +5920,20 @@ $form_end;
$anchor = '#'.&HTML::Entities::encode($anchor,'"<>&');
}
}
- if ((!$supplementalflag) && ($nomodal) && ($hostname ne '')) {
+ if (($nomodal) && ($hostname ne '')) {
$link = 'http://'.$hostname.$url;
} else {
$link = $url;
}
- $link = &js_escape($link.(($url=~/\?/)?'&':'?').'inhibitmenu=yes'.$anchor);
+ my $inhibitmenu;
+ if ((($supplementalflag) && ($allowed) && ($url =~ m{^/adm/wrapper/})) ||
+ (($allowed) && (($url =~ m{^/adm/(viewclasslist|$match_domain/$match_username/aboutme)(\?|$)}) ||
+ ($url =~ m{^/public/$match_domain/$match_courseid/syllabus(\?|$)})))) {
+ $inhibitmenu = 'only_body=1';
+ } else {
+ $inhibitmenu = 'inhibitmenu=yes';
+ }
+ $link = &js_escape($link.(($url=~/\?/)?'&':'?').$inhibitmenu.$anchor);
if ($allowed && !$env{'request.role.adv'} && !$isfolder && !$ispage && !$uploaded) {
if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {
$nolink = 1;
@@ -5037,7 +6387,7 @@ sub short_urls {
}
my %currtiny = &Apache::lonnet::dump('tiny',$cdom,$cnum);
$r->print(&Apache::loncourserespicker::create_picker($navmap,'shorturls',$formname,$crstype,undef,
- undef,undef,undef,undef,undef,\%currtiny,$readonly));
+ undef,undef,undef,undef,undef,\%currtiny,undef,$readonly));
}
$r->print(&endContentScreen());
}
@@ -5512,6 +6862,7 @@ sub handler {
my $crstype = &Apache::loncommon::course_type();
my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'};
my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $coursehome=$env{'course.'.$env{'request.course.id'}.'.home'};
# get docroot
my $londocroot = $r->dir_config('lonDocRoot');
@@ -5527,7 +6878,9 @@ sub handler {
'Load_Map','Supplemental','Score_Upload_Form',
'Adding_Pages','Importing_LON-CAPA_Resource',
'Importing_IMS_Course','Uploading_From_Harddrive',
- 'Course_Roster','Web_Page','Dropbox','Simple_Problem') {
+ 'Course_Roster','Web_Page','Dropbox','Simple_Problem',
+ 'Standard_Problem','Course_Resources',
+ 'Search_LON-CAPA_Resource','Import_Stored_Links') {
$help{$topic}=&Apache::loncommon::help_open_topic('Docs_'.$topic);
}
# Composite help files
@@ -5598,8 +6951,15 @@ sub handler {
&init_breadcrumbs('versions','Check/Set Resource Versions','Docs_Check_Resource_Versions');
&checkversions($r,$canedit);
} elsif ($canedit && $env{'form.dumpcourse'}) {
- &init_breadcrumbs('dumpcourse','Copy '.&Apache::loncommon::course_type().' Content to Authoring Space');
+ &init_breadcrumbs('dumpcourse','Copy uploaded content to Authoring Space');
&dumpcourse($r);
+ } elsif (($canedit || $canview) && ($env{'form.copyauthored'})) {
+ &init_breadcrumbs('copyauthored','Copy from Course Authoring to User Authoring');
+ my $readonly;
+ if (!$canedit) {
+ $readonly = 1;
+ }
+ ©crsauthored($r,$coursenum,$coursedom,$coursehome,$readonly);
} elsif ($canedit && $env{'form.exportcourse'}) {
&init_breadcrumbs('exportcourse','IMS Export');
&Apache::imsexport::exportcourse($r);
@@ -5702,8 +7062,11 @@ sub handler {
}
if ($env{'form.forcesupplement'}) { $supplementalflag=1; }
if ($env{'form.forcestandard'}) { $supplementalflag=0; }
- unless ($allowed) { $supplementalflag=1; }
- unless ($standard) { $supplementalflag=1; }
+ unless (($supplementalflag) ||
+ ($r->uri =~ m{^/adm/coursedocs/showdoc/uploaded/\Q$coursedom\E/\Q$coursenum\E/docs/})) {
+ unless ($allowed) { $supplementalflag=1; }
+ unless ($standard) { $supplementalflag=1; }
+ }
my $toolsflag=0;
if ($env{'form.tools'}) { $toolsflag=1; }
@@ -5725,6 +7088,7 @@ sub handler {
my $containertag;
my $pathitem;
my %ltitools;
+ my $posslti;
my $hiddentop;
my $navmap;
my $filterFunc = sub { my $res = shift; return (!$res->randomout() && !$res->is_map()) };
@@ -5778,9 +7142,9 @@ sub handler {
&Apache::loncommon::validate_folderpath($supplementalflag,$allowed,$coursenum,$coursedom);
}
}
-
-# If we are not allowed to make changes, all we can see are supplemental docs
- if (!$allowed) {
+
+# Set folderpath if we are not allowed to make changes and this is supplemental content
+ if ((!$allowed) && ($supplementalflag)) {
unless ($env{'form.folderpath'} =~ /^supplemental/) {
$env{'form.folderpath'} = &supplemental_base();
}
@@ -5958,8 +7322,19 @@ sub handler {
}
}
my $tabidstr = join("','",@tabids);
- %ltitools = &Apache::lonnet::get_domain_lti($coursedom,'consumer');
- my $posslti = keys(%ltitools);
+ my (%domtools,%crstools);
+ my %tooltypes = &Apache::loncommon::usable_exttools();
+ if ($tooltypes{'dom'}) {
+ %domtools = &Apache::lonnet::get_domain_lti($coursedom,'consumer');
+ }
+ if ($tooltypes{'crs'}) {
+ %crstools = &Apache::lonnet::get_course_lti($coursenum,$coursedom,'consumer');
+ }
+ %ltitools = (
+ dom => \%domtools,
+ crs => \%crstools,
+ );
+ $posslti = scalar(keys(%domtools)) + scalar(keys(%crstools));
my $hostname = $r->hostname();
$script .= &editing_js($udom,$uname,$supplementalflag,$coursedom,$coursenum,$posslti,
$londocroot,$canedit,$hostname,\$navmap).
@@ -6000,7 +7375,8 @@ sub handler {
if ($supplementalflag) {
my $title = &HTML::Entities::encode($env{'form.title'},'\'"<>&');
my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1);
- $args = {'bread_crumbs' => $brcrum};
+ $args = {'bread_crumbs' => $brcrum,
+ 'bread_crumbs_nomenu' => 1};
} else {
$args = {'force_register' => $showdoc};
}
@@ -6029,8 +7405,13 @@ sub handler {
}
}
my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype);
+ my $args = {'bread_crumbs' => $brcrum};
+ unless (($env{'form.folderpath'} eq '') ||
+ ($env{'form.folder'} eq 'supplemental')) {
+ $args->{'bread_crumbs_nomenu'} = 1;
+ }
$r->print(&Apache::loncommon::start_page("Supplemental $crstype Content",undef,
- {'bread_crumbs' => $brcrum,}));
+ $args));
} else {
my ($breadtext,$breadtitle,$helpitem);
$breadtext = "$crstype Editor";
@@ -6115,7 +7496,7 @@ sub handler {
if ($allowed && $toolsflag) {
$r->print(&startContentScreen('tools'));
- $r->print(&generate_admin_menu($crstype,$canedit));
+ $r->print(&generate_admin_menu($crstype,$canedit,$coursenum,$coursedom));
$r->print(&endContentScreen());
} elsif ((!$showdoc) && (!$uploadphase)) {
# -----------------------------------------------------------------------------
@@ -6123,8 +7504,8 @@ sub handler {
'copm' => 'All documents out of a published map into this folder',
'upfi' => 'Upload File',
'upld' => 'Upload Content',
- 'srch' => 'Search',
- 'impo' => 'Import',
+ 'srch' => 'Search Repository',
+ 'impo' => 'Import from Repository',
'lnks' => 'Import from Stored Links',
'impm' => 'Import from Assembled Map',
'imcr' => 'Import from Course Resources',
@@ -6163,6 +7544,7 @@ sub handler {
'dire' => 'Directory:',
'cate' => 'Category:',
'tmpl' => 'Template:',
+ 'empd' => 'No resources found',
'comment' => 'Comment',
'parse' => 'Upload embedded images/multimedia files if HTML file',
'bb5' => 'Blackboard 5',
@@ -6212,10 +7594,7 @@ sub handler {
my $fileupload=(<
-
-
FIUP
-
my $checkbox=(<$lt{'parse'}?
@@ -6235,6 +7614,8 @@ CHBO
$lt{'imsf'}
$fileupload
+
+
$lt{'cms'}:
@@ -6261,6 +7642,8 @@ IMSFORM
$lt{'upfi'}
$fileupload
+
+
$lt{'title'}:
@@ -6299,28 +7682,56 @@ FUFORM
SEDFFORM
- my $importcrsresform;
- my ($numdirs,$pickfile) =
- &Apache::loncommon::import_crsauthor_form('coursepath','coursefile',
- "resize_scrollbox('contentscroll','1','0');",
- undef,'res');
- if ($pickfile) {
- $importcrsresform=(<
';
+ my $crsresform;
+ if (($env{'user.author'}) || ($checkcrsres)) {
+ $crsresform=(<