--- loncom/interface/londocs.pm 2016/11/30 18:05:43 1.484.2.68
+++ loncom/interface/londocs.pm 2020/09/02 02:33:04 1.484.2.85.2.5
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Documents
#
-# $Id: londocs.pm,v 1.484.2.68 2016/11/30 18:05:43 raeburn Exp $
+# $Id: londocs.pm,v 1.484.2.85.2.5 2020/09/02 02:33:04 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -43,6 +43,7 @@ use Apache::lonnavdisplay();
use Apache::lonextresedit();
use Apache::lontemplate();
use Apache::lonsimplepage();
+use Apache::loncourserespicker();
use HTML::Entities;
use HTML::TokeParser;
use GDBM_File;
@@ -622,7 +623,7 @@ sub recurse_html {
}
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 = {};
@@ -651,6 +652,112 @@ sub group_import {
}
}
if ($url) {
+ if ($url =~ m{^(/adm/$coursedom/$coursenum/(\d+)/ext\.tool)\:?(.*)$}) {
+ $url = $1;
+ my $marker = $2;
+ my $info = $3;
+ my ($toolid,%toolhash,%toolsettings);
+ my @extras = ('linktext','explanation','crslabel','crstitle');
+ my @toolinfo = split(/:/,$info);
+ if ($residx) {
+ %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'},
+ $toolhash{'linktext'},$toolhash{'explanation'},
+ $toolhash{'crslabel'},$toolhash{'crstitle'}) = @toolinfo;
+ foreach my $item (@extras) {
+ $toolhash{$item} = &unescape($toolhash{$item});
+ }
+ if (ref($ltitoolsref) eq 'HASH') {
+ my @deleted;
+ if (ref($ltitoolsref->{$toolid}) eq 'HASH') {
+ $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);
+ }
+ }
+ }
+ }
+ }
+ } elsif ($residx) {
+ $toolhash{'target'} = $toolsettings{'target'};
+ if ($toolhash{'target'} eq 'window') {
+ foreach my $item ('width','height') {
+ $toolhash{$item} = $toolsettings{$item};
+ }
+ }
+ } 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);
+ }
+ }
+ }
+ } 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 '') {
+ delete($toolhash{$crsitem});
+ }
+ } else {
+ delete($toolhash{$crsitem});
+ }
+ if (($residx) && (exists($toolsettings{$crsitem}))) {
+ unless (exists($toolhash{$crsitem})) {
+ push(@deleted,$crsitem);
+ }
+ }
+ }
+ }
+ 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 (($caller eq 'londocs') &&
($folder =~ /^default/)) {
if (($url =~ /\.(page|sequence)$/) && (!$donechk)) {
@@ -662,8 +769,8 @@ sub group_import {
$donechk = 1;
}
if ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$}) {
- &contained_map_check($url,$folder,\%removefrommap,\%removeparam,
- \%addedmaps,\%hierarchy,\%titles,$allmaps);
+ &contained_map_check($url,$folder,$coursenum,$coursedom,\%removefrommap,
+ \%removeparam,\%addedmaps,\%hierarchy,\%titles,$allmaps);
$importuploaded = 1;
} elsif ($url =~ m{^/res/.+\.(page|sequence)$}) {
next if ($allmaps->{$url});
@@ -834,7 +941,7 @@ sub docs_change_log {
'// '."\n".
@@ -1059,29 +1166,47 @@ sub update_paste_buffer {
# Construct identifiers for current contents of user's paste buffer
if (@currpaste) {
foreach my $suffix (@currpaste) {
- my $cid = $env{'docs.markedcopy_crs_'.$suffix};
- my $url = $env{'docs.markedcopy_url_'.$suffix};
- if (($cid =~ /^$match_domain(?:_)$match_courseid$/) &&
- ($url ne '')) {
- $pasteurls{$cid.'_'.$url} = 1;
- }
+ my $cid = $env{'docs.markedcopy_crs_'.$suffix};
+ my $url = $env{'docs.markedcopy_url_'.$suffix};
+ my $mapidx = $env{'docs.markedcopy_map_'.$suffix};
+ if (($cid =~ /^$match_domain(?:_)$match_courseid$/) &&
+ ($url ne '')) {
+ if ($url eq '/res/lib/templates/simpleproblem.problem') {
+ $pasteurls{$cid.'_'.$mapidx} = 1;
+ } elsif ($url =~ m{^/res/$match_domain/$match_username/}) {
+ $pasteurls{$url} = 1;
+ } else {
+ $pasteurls{$cid.'_'.$url} = 1;
+ }
+ }
}
}
# Mark items for copying (skip any items already in user's paste buffer)
my %addtoenv;
-
+
+ my @pathitems = split(/\&/,$env{'form.folderpath'});
+ my @folderconf = split(/\:/,$pathitems[-1]);
+ my $ispage = $folderconf[5];
+
foreach my $item (@possibles) {
my ($orderidx,$cmd) = split(/:/,$item);
next if ($orderidx =~ /\D/);
next unless (($cmd eq 'cut') || ($cmd eq 'copy') || ($cmd eq 'remove'));
+ my $mapidx = $folder.':'.$orderidx.':'.$ispage;
my ($title,$url)=split(':',$LONCAPA::map::resources[$orderidx]);
my %denied = &action_restrictions($coursenum,$coursedom,
&LONCAPA::map::qtescape($url),
$env{'form.folderpath'},\%curr_groups);
next if ($denied{'copy'});
$url=~s{http(:|:)//https(:|:)//}{https$2//};
- next if (exists($pasteurls{$coursedom.'_'.$coursenum.'_'.$url}));
+ if ($url eq '/res/lib/templates/simpleproblem.problem') {
+ next if (exists($pasteurls{$coursedom.'_'.$coursenum.'_'.$mapidx}));
+ } elsif ($url =~ m{^/res/$match_domain/$match_username/}) {
+ next if (exists($pasteurls{$url}));
+ } else {
+ next if (exists($pasteurls{$coursedom.'_'.$coursenum.'_'.$url}));
+ }
my ($suffix,$errortxt,$locknotfreed) =
&new_timebased_suffix($env{'user.domain'},$env{'user.name'},'paste');
if ($suffix ne '') {
@@ -1100,7 +1225,7 @@ sub update_paste_buffer {
$addtoenv{'docs.markedcopy_url_'.$suffix} = $url,
$addtoenv{'docs.markedcopy_cmd_'.$suffix} = $cmd,
$addtoenv{'docs.markedcopy_crs_'.$suffix} = $env{'request.course.id'};
-
+ $addtoenv{'docs.markedcopy_map_'.$suffix} = $mapidx;
if ($url =~ m{^/uploaded/$match_domain/$match_courseid/(default|supplemental)_?(\d*)\.(page|sequence)$}) {
my $prefix = $1;
my $subdir =$2;
@@ -1108,8 +1233,8 @@ sub update_paste_buffer {
$subdir = $prefix;
}
my (%addedmaps,%removefrommap,%removeparam,%hierarchy,%titles,%allmaps);
- &contained_map_check($url,$folder,\%removefrommap,\%removeparam,\%addedmaps,
- \%hierarchy,\%titles,\%allmaps);
+ &contained_map_check($url,$folder,$coursenum,$coursedom,\%removefrommap,
+ \%removeparam,\%addedmaps,\%hierarchy,\%titles,\%allmaps);
if (ref($hierarchy{$url}) eq 'HASH') {
my ($nested,$nestednames);
&recurse_uploaded_maps($url,$subdir,\%hierarchy,\%titles,\$nested,\$nestednames);
@@ -1178,14 +1303,17 @@ sub print_paste_buffer {
next if ($suffix =~ /\D/);
my $cid = $env{'docs.markedcopy_crs_'.$suffix};
my $url = $env{'docs.markedcopy_url_'.$suffix};
+ my $mapidx = $env{'docs.markedcopy_map_'.$suffix};
if (($cid =~ /^$match_domain\_$match_courseid$/) &&
($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+/ext\.tool$}) {
+ $is_exttool = 1;
}
if ($folder =~ /^supplemental/) {
$canpaste = &supp_pasteable($env{'docs.markedcopy_url_'.$suffix});
@@ -1203,9 +1331,7 @@ sub print_paste_buffer {
if (($srcdom ne $coursedom) || ($srcnum ne $coursenum)) {
$othercourse = 1;
if ($env{"user.priv.cm./$srcdom/$srcnum"} =~ /\Q:mdc&F\E/) {
- if ($canpaste) {
- $othercrs = '
'.&mt('(from another course)');
- }
+ $othercrs = '
'.&mt('(from another course)');
} else {
$canpaste = 0;
$nopaste = &mt('Paste from another course unavailable.');
@@ -1219,16 +1345,35 @@ sub print_paste_buffer {
}
$is_uploaded_map = 1;
}
+ } elsif (($url =~ m{^/res/lib/templates/\w+\.problem$}) ||
+ ($url =~ m{^/adm/($match_domain)/($match_username)/\d+/(bulletinboard|smppg|ext\.tool)$})) {
+ 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)');
+ }
+ } else {
+ $canpaste = 0;
+ $nopaste = &mt('Paste from another course unavailable.');
+ }
+ }
+ }
+ if ($canpaste) {
+ push(@pasteable,$suffix);
}
- }
- if ($canpaste) {
- push(@pasteable,$suffix);
}
my $buffer;
if ($is_external) {
$buffer = &mt('External Resource').': '.
&LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix}).' ('.
&LONCAPA::map::qtescape($url).')';
+ } elsif ($is_exttool) {
+ $buffer = &mt('External Tool').': '.
+ &LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix});
} else {
my $icon = &Apache::loncommon::icon($extension);
if ($extension eq 'sequence' &&
@@ -1284,7 +1429,7 @@ sub print_paste_buffer {
}
$buttons = ''.(' 'x2);
}
- $buttons .= ''.(' 'x2);
+ $buttons .= ''.(' 'x2);
if ($clipboardcount > 1) {
$buttons .=
''.(' 'x20).''.(' 'x2).
@@ -1385,7 +1530,8 @@ sub supp_pasteable {
(($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+/ext\.tool$})) {
return 1;
}
return;
@@ -1507,11 +1653,13 @@ sub do_paste_from_buffer {
return();
}
- my (%msgs,%before,%after,@dopaste,%is_map,%notinsupp,%notincrs,%duplicate,
- %prefixchg,%srcdom,%srcnum,%marktomove,$save_err,$lockerrors,$allresult);
+ my (%msgs,%before,%after,@dopaste,%is_map,%notinsupp,%notincrs,%notindom,%duplicate,
+ %prefixchg,%srcdom,%srcnum,%srcmapidx,%marktomove,$save_err,$lockerrors,$allresult);
foreach my $suffix (@topaste) {
my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url_'.$suffix});
+ my $cid=&LONCAPA::map::qtescape($env{'docs.markedcopy_crs_'.$suffix});
+ my $mapidx=&LONCAPA::map::qtescape($env{'docs.markedcopy_map_'.$suffix});
# Supplemental content may only include certain types of content
# Early out if pasted content is not supported in Supplemental area
if ($folder =~ /^supplemental/) {
@@ -1533,8 +1681,39 @@ sub do_paste_from_buffer {
}
$srcdom{$suffix} = $srcd;
$srcnum{$suffix} = $srcn;
+ } elsif ($url =~ m{^/adm/$match_domain/$match_courseid/\d+/ext\.tool$}) {
+ my ($srcd,$srcn) = split(/_/,$cid);
+# When paste buffer was populated using an active role in a different course
+# check for mdc privilege in the course from which the resource was pasted
+ if (($srcd ne $coursedom) || ($srcn ne $coursenum)) {
+ unless ($env{"user.priv.cm./$srcd/$srcn"} =~ /\Q:mdc&F\E/) {
+ $notincrs{$suffix} = 1;
+ next;
+ }
+ }
+# 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 ($srcd ne $coursedom) {
+ $notindom{$suffix} = 1;
+ next;
+ }
+ $srcdom{$suffix} = $srcd;
+ $srcnum{$suffix} = $srcn;
+ } elsif (($url =~ m{^/res/lib/templates/\w+\.problem$}) ||
+ ($url =~ m{^/adm/$match_domain/$match_username/\d+/(bulletinboard|smppg)$})) {
+ my ($srcd,$srcn) = split(/_/,$cid);
+# When paste buffer was populated using an active role in a different course
+# check for mdc privilege in the course from which the resource was pasted
+ if (($srcd ne $coursedom) || ($srcn ne $coursenum)) {
+ unless ($env{"user.priv.cm./$srcd/$srcn"} =~ /\Q:mdc&F\E/) {
+ $notincrs{$suffix} = 1;
+ next;
+ }
+ }
+ $srcdom{$suffix} = $srcd;
+ $srcnum{$suffix} = $srcn;
}
-
+ $srcmapidx{$suffix} = $mapidx;
push(@dopaste,$suffix);
if ($url=~/\.(page|sequence)$/) {
$is_map{$suffix} = 1;
@@ -1544,7 +1723,7 @@ sub do_paste_from_buffer {
my $oldprefix = $1;
# When pasting content from Main Content to Supplemental Content and vice versa
# URLs will contain different paths (which depend on whether pasted item is
-# a folder/page or a document.
+# a folder/page or a document).
if (($folder =~ /^supplemental/) && (($oldprefix =~ /^default/) || ($oldprefix eq 'docs'))) {
$prefixchg{$suffix} = 'docstosupp';
} elsif (($folder =~ /^default/) && ($oldprefix =~ /^supplemental/)) {
@@ -1584,6 +1763,7 @@ sub do_paste_from_buffer {
%msgs = &Apache::lonlocal::texthash (
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 donain.',
duplicate => 'Paste failed: only one instance of a particular published sequence or page is allowed within each course.',
);
@@ -1612,32 +1792,34 @@ sub do_paste_from_buffer {
# Retrieve information about all course maps in main content area
my $allmaps = {};
- if ($folder =~ /^default/) {
- $allmaps =
- &Apache::loncommon::allmaps_incourse($coursedom,$coursenum,
- $env{"course.$env{'request.course.id'}.home"},
- $env{'request.course.id'});
- }
-
- my (@toclear,%mapurls,%lockerrs,%msgerrs,%results);
+ my (@toclear,%mapurls,%lockerrs,%msgerrs,%results,$donechk);
# Loop over the items to paste
foreach my $suffix (@dopaste) {
# Maps need to be copied first
my (%removefrommap,%removeparam,%addedmaps,%rewrites,%retitles,%copies,
%dbcopies,%zombies,%params,%docmoves,%mapmoves,%mapchanges,%newsubdir,
- %newurls,%tomove);
+ %newurls,%tomove,%resdatacopy);
if (ref($marktomove{$suffix}) eq 'ARRAY') {
map { $tomove{$_} = 1; } @{$marktomove{$suffix}};
}
my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url_'.$suffix});
my $title=&LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix});
+ my $cid=&LONCAPA::map::qtescape($env{'docs.markedcopy_crs_'.$suffix});
my $oldurl = $url;
if ($is_map{$suffix}) {
# If pasting a map, check if map contains other maps
my (%hierarchy,%titles);
- &contained_map_check($url,$folder,\%removefrommap,\%removeparam,
- \%addedmaps,\%hierarchy,\%titles,$allmaps);
+ if (($folder =~ /^default/) && (!$donechk)) {
+ $allmaps =
+ &Apache::loncommon::allmaps_incourse($coursedom,$coursenum,
+ $env{"course.$env{'request.course.id'}.home"},
+ $env{'request.course.id'});
+ $donechk = 1;
+ }
+ &contained_map_check($url,$folder,$coursenum,$coursedom,
+ \%removefrommap,\%removeparam,\%addedmaps,
+ \%hierarchy,\%titles,$allmaps);
if ($url=~ m{^/uploaded/}) {
my $newurl;
unless ($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') {
@@ -1667,7 +1849,7 @@ sub do_paste_from_buffer {
\%retitles,\%copies,\%dbcopies,
\%zombies,\%params,\%mapmoves,
\%mapchanges,\%tomove,\%newsubdir,
- \%newurls)) {
+ \%newurls,\%resdatacopy)) {
$mapmoves{$url} = 1;
}
$url = $newurl;
@@ -1676,10 +1858,10 @@ sub do_paste_from_buffer {
$coursenum,$srcdom{$suffix},$srcnum{$suffix},
$allmaps,\%rewrites,\%retitles,\%copies,\%dbcopies,
\%zombies,\%params,\%mapmoves,\%mapchanges,
- \%tomove,\%newsubdir,\%newurls);
+ \%tomove,\%newsubdir,\%newurls,\%resdatacopy);
}
} elsif ($url=~m {^/res/}) {
-# published map can only exists once, so remove from paste buffer when done
+# published map can only exist once, so remove from paste buffer when done
push(@toclear,$suffix);
# if pasting published map (main content area only) check map not already in course
if ($folder =~ /^default/) {
@@ -1690,15 +1872,23 @@ sub do_paste_from_buffer {
}
}
}
- if ($url=~ m{/(bulletinboard|smppg)$}) {
+ if ($url=~ m{/(bulletinboard|smppg|ext\.tool)$}) {
my $prefix = $1;
+ my $fromothercrs;
#need to copy the db contents to a new one, unless this is a move.
my %info = (
src => $url,
cdom => $coursedom,
cnum => $coursenum,
- );
- unless ($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') {
+ );
+ if (($srcdom{$suffix} =~ /^$match_domain$/) && ($srcnum{$suffix} =~ /^$match_courseid$/)) {
+ unless (($srcdom{$suffix} eq $coursedom) && ($srcnum{$suffix} eq $coursenum)) {
+ $fromothercrs = 1;
+ $info{'cdom'} = $srcdom{$suffix};
+ $info{'cnum'} = $srcnum{$suffix};
+ }
+ }
+ unless (($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') && (!$fromothercrs)) {
my (%lockerr,$msg);
my ($newurl,$result,$errtext) =
&dbcopy(\%info,$coursedom,$coursenum,\%lockerr);
@@ -1710,6 +1900,8 @@ sub do_paste_from_buffer {
$msg = &mt('Paste failed: An error occurred when copying the simple page.').' '.$errtext;
} elsif ($prefix eq 'bulletinboard') {
$msg = &mt('Paste failed: An error occurred when copying the discussion board.').' '.$errtext;
+ } elsif ($prefix eq 'ext.tool') {
+ $msg = &mt('Paste failed: An error occurred when copying the external tool.').' '.$errtext;
}
$results{$suffix} = $result;
$msgerrs{$suffix} = $msg;
@@ -1774,6 +1966,12 @@ sub do_paste_from_buffer {
}
}
}
+ } elsif ($url =~ m{^/res/lib/templates/(\w+)\.problem$}) {
+ my $template = $1;
+ if ($newidx) {
+ ©_templated_files($url,$srcdom{$suffix},$srcnum{$suffix},$srcmapidx{$suffix},
+ $coursedom,$coursenum,$template,$newidx,"$folder.$container");
+ }
}
$LONCAPA::map::resources[$newidx]=$title.':'.&LONCAPA::map::qtunescape($url).
':'.$ext.':normal:res';
@@ -1787,7 +1985,8 @@ sub do_paste_from_buffer {
}
}
-# Apply any changes to maps, or copy dependencies for uploaded HTML pages
+# Apply any changes to maps, or copy dependencies for uploaded HTML pages, or update
+# resourcedata for simpleproblems copied from another course
unless ($allresult eq 'fail') {
my %updated = (
rewrites => \%rewrites,
@@ -1795,6 +1994,7 @@ sub do_paste_from_buffer {
removefrommap => \%removefrommap,
removeparam => \%removeparam,
dbcopies => \%dbcopies,
+ resdatacopy => \%resdatacopy,
retitles => \%retitles,
);
my %info = (
@@ -1959,10 +2159,13 @@ sub get_newmap_url {
sub dbcopy {
my ($dbref,$coursedom,$coursenum,$lockerrorsref) = @_;
my ($url,$result,$errtext);
- $url = $dbref->{'src'};
if (ref($dbref) eq 'HASH') {
- if ($url =~ m{/(smppg|bulletinboard)$}) {
+ $url = $dbref->{'src'};
+ if ($url =~ m{/(smppg|bulletinboard|ext\.tool)$}) {
my $prefix = $1;
+ if ($prefix eq 'ext.tool') {
+ $prefix = 'exttool';
+ }
if (($dbref->{'cdom'} =~ /^$match_domain$/) &&
($dbref->{'cnum'} =~ /^$match_courseid$/)) {
my $db_name;
@@ -1973,6 +2176,8 @@ sub dbcopy {
&Apache::lonsimplepage::get_db_name($url,$marker,
$dbref->{'cdom'},
$dbref->{'cnum'});
+ } elsif ($dbref->{'src'} =~ m{/ext\.tool$}) {
+ $db_name = 'exttool_'.$marker;
} else {
$db_name = 'bulletinpage_'.$marker;
}
@@ -1983,6 +2188,8 @@ sub dbcopy {
if (!$suffix) {
if ($prefix eq 'smppg') {
$errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a simple page [_1].',$url);
+ } elsif ($prefix eq 'exttool') {
+ $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying an external tool [_1].',$url);
} else {
$errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a discussion board [_1].',$url);
}
@@ -2016,7 +2223,7 @@ sub dbcopy {
$result=&Apache::lonnet::put($db_name,\%contents,
$coursedom,$coursenum);
if ($result eq 'ok') {
- $url =~ s{/(\d*)/(smppg|bulletinboard)$}{/$suffix/$2}x;
+ $url =~ s{/(\d*)/(smppg|bulletinboard|ext\.tool)$}{/$suffix/$2}x;
}
}
if (($freedlock ne 'ok') && (ref($lockerrorsref) eq 'HASH')) {
@@ -2026,6 +2233,9 @@ sub dbcopy {
if ($prefix eq 'smppg') {
$lockerrorsref->{$prefix} .=
' '.&mt('This will prevent creation of additional simple pages in this course.');
+ } elsif ($prefix eq 'exttool') {
+ $lockerrorsref->{$prefix} .=
+ ' '.&mt('This will prevent addition of more external tools to this course.');
} else {
$lockerrorsref->{$prefix} .= ' '.&mt('This will prevent creation of additional discussion boards in this course.');
}
@@ -2051,6 +2261,97 @@ sub dbcopy {
return ($url,$result,$errtext);
}
+sub copy_templated_files {
+ my ($srcurl,$srcdom,$srcnum,$srcmapinfo,$coursedom,$coursenum,$template,$newidx,$newmapname) = @_;
+ my ($srcfolder,$srcid,$srcwaspage) = split(/:/,$srcmapinfo);
+ my $srccontainer = 'sequence';
+ if ($srcwaspage) {
+ $srccontainer = 'page';
+ }
+ my $srcsymb = "uploaded/$srcdom/$srcnum/$srcfolder.$srccontainer".
+ '___'.$srcid.'___'.&Apache::lonnet::declutter($srcurl);
+ my $srcprefix = $srcdom.'_'.$srcnum.'.'.$srcsymb;
+ my %srcparms=&Apache::lonnet::dump('resourcedata',$srcdom,$srcnum,$srcprefix);
+ my $newsymb = "uploaded/$coursedom/$coursenum/$newmapname".'___'.$newidx.'___lib/templates/'.
+ $template.'.problem';
+ my $newprefix = $coursedom.'_'.$coursenum.'.'.$newsymb;
+ if ($template eq 'simpleproblem') {
+ $srcprefix .= '.0.';
+ my $weightprefix = $newprefix;
+ $newprefix .= '.0.';
+ my @simpleprobqtypes = qw(radio option string essay numerical);
+ my $qtype=$srcparms{$srcprefix.'questiontype'};
+ if (grep(/^\Q$qtype\E$/,@simpleprobqtypes)) {
+ my %newdata = (
+ $newprefix.'questiontype' => $qtype,
+ );
+ foreach my $type (@simpleprobqtypes) {
+ if ($type eq $qtype) {
+ $newdata{"$weightprefix.$type.weight"}=1;
+ } else {
+ $newdata{"$weightprefix.$type.weight"}=0;
+ }
+ }
+ $newdata{$newprefix.'hiddenparts'} = '!'.$qtype;
+ $newdata{$newprefix.'questiontext'} = $srcparms{$srcprefix.'questiontext'};
+ $newdata{$newprefix.'hinttext'} = $srcparms{$srcprefix.'hinttext'};
+ if ($qtype eq 'numerical') {
+ $newdata{$newprefix.'numericalscript'} = $srcparms{$srcprefix.'numericalscript'};
+ $newdata{$newprefix.'numericalanswer'} = $srcparms{$srcprefix.'numericalanswer'};
+ $newdata{$newprefix.'numericaltolerance'} = $srcparms{$srcprefix.'numericaltolerance'};
+ $newdata{$newprefix.'numericalsigfigs'} = $srcparms{$srcprefix.'numericalsigfigs'};
+ } elsif (($qtype eq 'option') || ($qtype eq 'radio')) {
+ my $maxfoils=$srcparms{$srcprefix.'maxfoils'};
+ unless (defined($maxfoils)) { $maxfoils=10; }
+ unless ($maxfoils=~/^\d+$/) { $maxfoils=10; }
+ if ($maxfoils<=0) { $maxfoils=10; }
+ my $randomize=$srcparms{$srcprefix.'randomize'};
+ unless (defined($randomize)) { $randomize='yes'; }
+ unless ($randomize eq 'no') { $randomize='yes'; }
+ $newdata{$newprefix.'maxfoils'} = $maxfoils;
+ $newdata{$newprefix.'randomize'} = $randomize;
+ if ($qtype eq 'option') {
+ $newdata{$newprefix.'options'} = $srcparms{$srcprefix.'options'};
+ }
+ for (my $i=1; $i<=10; $i++) {
+ $newdata{$newprefix.'value'.$i} = $srcparms{$srcprefix.'value'.$i};
+ $newdata{$newprefix.'position'.$i} = $srcparms{$srcprefix.'position'.$i};
+ $newdata{$newprefix.'text'.$i} = $srcparms{$srcprefix.'text'.$i};
+ }
+
+ } elsif (($qtype eq 'option') || ($qtype eq 'radio')) {
+ my $maxfoils=$srcparms{$srcprefix.'maxfoils'};
+ unless (defined($maxfoils)) { $maxfoils=10; }
+ unless ($maxfoils=~/^\d+$/) { $maxfoils=10; }
+ if ($maxfoils<=0) { $maxfoils=10; }
+ my $randomize=$srcparms{$srcprefix.'randomize'};
+ unless (defined($randomize)) { $randomize='yes'; }
+ unless ($randomize eq 'no') { $randomize='yes'; }
+ $newdata{$newprefix.'maxfoils'} = $maxfoils;
+ $newdata{$newprefix.'randomize'} = $randomize;
+ if ($qtype eq 'option') {
+ $newdata{$newprefix.'options'} = $srcparms{$srcprefix.'options'};
+ }
+ for (my $i=1; $i<=10; $i++) {
+ $newdata{$newprefix.'value'.$i} = $srcparms{$srcprefix.'value'.$i};
+ $newdata{$newprefix.'position'.$i} = $srcparms{$srcprefix.'position'.$i};
+ $newdata{$newprefix.'text'.$i} = $srcparms{$srcprefix.'text'.$i};
+ }
+ } elsif ($qtype eq 'string') {
+ $newdata{$newprefix.'stringanswer'} = $srcparms{$srcprefix.'stringanswer'};
+ $newdata{$newprefix.'stringtype'} = $srcparms{$srcprefix.'stringtype'};
+ }
+ if (keys(%newdata)) {
+ my $putres = &Apache::lonnet::cput('resourcedata',\%newdata,$coursedom,
+ $coursenum);
+ if ($putres eq 'ok') {
+ &Apache::lonnet::devalidatecourseresdata($coursenum,$coursedom);
+ }
+ }
+ }
+ }
+}
+
sub uniqueness_check {
my ($newurl) = @_;
my $unique = 1;
@@ -2066,8 +2367,8 @@ sub uniqueness_check {
}
sub contained_map_check {
- my ($url,$folder,$removefrommap,$removeparam,$addedmaps,$hierarchy,$titles,
- $allmaps) = @_;
+ my ($url,$folder,$coursenum,$coursedom,$removefrommap,$removeparam,$addedmaps,
+ $hierarchy,$titles,$allmaps) = @_;
my $content = &Apache::lonnet::getfile($url);
unless ($content eq '-1') {
my $parser = HTML::TokeParser->new(\$content);
@@ -2096,7 +2397,8 @@ sub contained_map_check {
$addedmaps->{$ressrc} = [$url];
}
}
- &contained_map_check($ressrc,$folder,$removefrommap,$removeparam,
+ &contained_map_check($ressrc,$folder,$coursenum,$coursedom,
+ $removefrommap,$removeparam,
$addedmaps,$hierarchy,$titles,$allmaps);
}
} elsif ($token->[1] eq 'param') {
@@ -2116,7 +2418,7 @@ sub contained_map_check {
sub url_paste_fixups {
my ($oldurl,$folder,$prefixchg,$cdom,$cnum,$fromcdom,$fromcnum,$allmaps,
$rewrites,$retitles,$copies,$dbcopies,$zombies,$params,$mapmoves,
- $mapchanges,$tomove,$newsubdir,$newurls) = @_;
+ $mapchanges,$tomove,$newsubdir,$newurls,$resdatacopy) = @_;
my $checktitle;
if (($prefixchg) &&
($oldurl =~ m{^/uploaded/$match_domain/$match_courseid/supplemental})) {
@@ -2165,7 +2467,7 @@ sub url_paste_fixups {
$srcdom,$srcnum,$allmaps,$rewrites,
$retitles,$copies,$dbcopies,$zombies,
$params,$mapmoves,$mapchanges,$tomove,
- $newsubdir,$newurls);
+ $newsubdir,$newurls,$resdatacopy);
next;
} else {
($newurl,my $error) =
@@ -2189,7 +2491,7 @@ sub url_paste_fixups {
$cnum,$srcdom,$srcnum,$allmaps,
$rewrites,$retitles,$copies,$dbcopies,
$zombies,$params,$mapmoves,$mapchanges,
- $tomove,$newsubdir,$newurls)) {
+ $tomove,$newsubdir,$newurls,$resdatacopy)) {
$mapmoves->{$ressrc} = 1;
}
$changed = 1;
@@ -2218,6 +2520,12 @@ sub url_paste_fixups {
$dbcopies->{$oldurl}{$id}{'cnum'} = $fromcnum;
$changed = 1;
}
+ } elsif ($ressrc eq '/res/lib/templates/simpleproblem.problem') {
+ if (($fromcdom ne $cdom) || ($fromcnum ne $cnum)) {
+ $resdatacopy->{$oldurl}{$id}{'src'} = $ressrc;
+ $resdatacopy->{$oldurl}{$id}{'cdom'} = $fromcdom;
+ $resdatacopy->{$oldurl}{$id}{'cnum'} = $fromcnum;
+ }
} elsif ($ressrc =~ m{^/public/($match_domain)/($match_courseid)/(.+)$}) {
next if ($skip);
my $srcdom = $1;
@@ -2249,7 +2557,7 @@ sub apply_fixups {
$oldurl,$url,$caller) = @_;
my (%rewrites,%zombies,%removefrommap,%removeparam,%dbcopies,%retitles,
%params,%newsubdir,%before,%after,%copies,%docmoves,%mapmoves,@msgs,
- %lockerrors,$lockmsg);
+ %resdatacopy,%lockerrors,$lockmsg);
if (ref($updated) eq 'HASH') {
if (ref($updated->{'rewrites'}) eq 'HASH') {
%rewrites = %{$updated->{'rewrites'}};
@@ -2269,6 +2577,9 @@ sub apply_fixups {
if (ref($updated->{'retitles'}) eq 'HASH') {
%retitles = %{$updated->{'retitles'}};
}
+ if (ref($updated->{'resdatacopy'}) eq 'HASH') {
+ %resdatacopy = %{$updated->{'resdatacopy'}};
+ }
}
if (ref($info) eq 'HASH') {
if (ref($info->{'newsubdir'}) eq 'HASH') {
@@ -2419,6 +2730,36 @@ sub apply_fixups {
}
}
}
+ if (ref($resdatacopy{$key}) eq 'HASH') {
+ my ($gotnewmapname,$newmapname,$srcfolder,$srccontainer);
+ foreach my $idx (keys(%{$resdatacopy{$key}})) {
+ if (ref($resdatacopy{$key}{$idx}) eq 'HASH') {
+ my $srcurl = $resdatacopy{$key}{$idx}{'src'};
+ if ($srcurl =~ m{^/res/lib/templates/(\w+)\.problem$}) {
+ my $template = $1;
+ if (($resdatacopy{$key}{$idx}{'cdom'} =~ /^$match_domain$/) &&
+ ($resdatacopy{$key}{$idx}{'cnum'} =~ /^$match_courseid$/)) {
+ my $srcdom = $resdatacopy{$key}{$idx}{'cdom'};
+ my $srcnum = $resdatacopy{$key}{$idx}{'cnum'};
+ unless ($gotnewmapname) {
+ ($newmapname) = ($key =~ m{/([^/]+)$});
+ ($srcfolder,$srccontainer) = split(/\./,$newmapname);
+ if ($newsubdir{$key}) {
+ $newmapname =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/;
+ }
+ $gotnewmapname = 1;
+ }
+ my $srcmapinfo = $srcfolder.':'.$idx;
+ if ($srccontainer eq 'page') {
+ $srcmapinfo .= ':1';
+ }
+ ©_templated_files($srcurl,$srcdom,$srcnum,$srcmapinfo,$cdom,
+ $cnum,$template,$idx,$newmapname);
+ }
+ }
+ }
+ }
+ }
if (ref($params{$key}) eq 'HASH') {
%currparam = %{$params{$key}};
}
@@ -2434,7 +2775,8 @@ sub apply_fixups {
}
}
}
- for (my $i=0; $i<@LONCAPA::map::order; $i++) {
+ my $total = scalar(@LONCAPA::map::order) - 1;
+ for (my $i=$total; $i>=0; $i--) {
my $idx = $LONCAPA::map::order[$i];
if (defined($LONCAPA::map::resources[$idx])) {
my $changed;
@@ -2444,7 +2786,7 @@ sub apply_fixups {
splice(@LONCAPA::map::order,$i,1);
if (ref($currparam{$idx}) eq 'ARRAY') {
foreach my $name (@{$currparam{$idx}}) {
- &LONCAPA::map::delparameter($idx,'parameter_'.$name);
+ &LONCAPA::map::delparameter($idx,$name);
}
}
next;
@@ -2486,7 +2828,7 @@ sub apply_fixups {
foreach my $idx (keys(%remparam)) {
if (ref($remparam{$idx}) eq 'ARRAY') {
foreach my $name (@{$remparam{$idx}}) {
- &LONCAPA::map::delparameter($idx,'parameter_'.$name);
+ &LONCAPA::map::delparameter($idx,$name);
}
}
}
@@ -2745,8 +3087,8 @@ sub handle_edit_cmd {
sub editor {
my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$crstype,
- $supplementalflag,$orderhash,$iconpath,$pathitem,$canedit,$navmapref,
- $hiddentop)=@_;
+ $supplementalflag,$orderhash,$iconpath,$pathitem,$ltitoolsref,
+ $canedit,$hostname,$navmapref,$hiddentop)=@_;
my ($randompick,$ishidden,$isencrypted,$plain,$is_random_order,$container);
if ($allowed) {
(my $breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,
@@ -2957,6 +3299,17 @@ sub editor {
} else {
return $errortxt;
}
+ } elsif ($url =~ m{^/adm/$coursedom/$coursenum/new/ext\.tool}) {
+ 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');
@@ -2979,7 +3332,7 @@ sub editor {
}
($errtext,$fatal,my $fixuperrors) =
&group_import($coursenum, $coursedom, $folder,$container,
- 'londocs',@imports);
+ 'londocs',$ltitoolsref,@imports);
return $errtext if ($fatal);
if ($fixuperrors) {
$r->print($fixuperrors);
@@ -3065,7 +3418,8 @@ sub editor {
$output .= &entryline($idx,$name,$url,$folder,$allowed,$res,
$coursenum,$coursedom,$crstype,
$pathitem,$supplementalflag,$container,
- \%filters,\%curr_groups,$canedit,$isencrypted,$navmapref);
+ \%filters,\%curr_groups,$ltitoolsref,$canedit,
+ $isencrypted,$navmapref,$hostname);
$idx++;
$shown++;
}
@@ -3444,7 +3798,7 @@ sub is_supplemental_title {
sub entryline {
my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$coursedom,
$crstype,$pathitem,$supplementalflag,$container,$filtersref,$currgroups,
- $canedit,$isencrypted,$navmapref)=@_;
+ $ltitoolsref,$canedit,$isencrypted,$navmapref,$hostname)=@_;
my ($foldertitle,$renametitle,$oldtitle);
if (&is_supplemental_title($title)) {
($title,$foldertitle,$renametitle) = &Apache::loncommon::parse_supplemental_title($title);
@@ -3541,6 +3895,7 @@ END
'rn' => 'Rename',
'cp' => 'Copy',
'ex' => 'External Resource',
+ 'et' => 'External Tool',
'ed' => 'Edit',
'pr' => 'Preview',
'sv' => 'Save',
@@ -3560,6 +3915,7 @@ END
|/aboutme$
|/navmaps$
|/bulletinboard$
+ |/ext\.tool$
|\.html$)}x)
|| $isexternal) {
$skip_confirm = 1;
@@ -3691,14 +4047,22 @@ END
}
}
- my ($editlink,$extresform,$anchor,$hiddenres);
+ my ($editlink,$extresform,$anchor,$hiddenres,$nomodal);
my $orig_url = $url;
$orig_url=~s{http(:|:)//https(:|:)//}{https$2//};
- $url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/};
+ if ($container eq 'page') {
+ $url=~s{^http(|s)(:|:)//}{/ext/};
+ } else {
+ $url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/};
+ }
if (!$supplementalflag && $residx && $symb) {
if ((!$isfolder) && (!$ispage)) {
(undef,undef,$url)=&Apache::lonnet::decode_symb($symb);
- $url=&Apache::lonnet::clutter($url);
+ if (($url =~ m{^ext/}) && ($container eq 'page')) {
+ $url=&Apache::lonnet::clutter_with_no_wrapper($url);
+ } else {
+ $url=&Apache::lonnet::clutter($url);
+ }
if ($url=~/^\/*uploaded\//) {
$url=~/\.(\w+)$/;
my $embstyle=&Apache::loncommon::fileembstyle($1);
@@ -3709,18 +4073,32 @@ END
} elsif ($url!~/\.(sequence|page)$/) {
$url='/adm/coursedocs/showdoc'.$url;
}
- } elsif ($url=~m|^/ext/|) {
- $url='/adm/wrapper'.$url;
+ } elsif ($url=~m{^(|/adm/wrapper)/ext/([^#]+)}) {
+ my $wrapped = $1;
+ my $exturl = $2;
+ if (($wrapped eq '') && ($container ne 'page')) {
+ $url='/adm/wrapper'.$url;
+ }
+ if (($ENV{'SERVER_PORT'} == 443) && ($exturl !~ /^https:/)) {
+ $nomodal = 1;
+ }
+ } elsif ($url=~m{^/adm/$coursedom/$coursenum/\d+/ext\.tool$}) {
+ $url='/adm/wrapper'.$url;
+ } elsif ($url eq "/public/$coursedom/$coursenum/syllabus") {
+ if (($ENV{'SERVER_PORT'} == 443) &&
+ ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) {
+ unless (&Apache::lonnet::uses_sts()) {
+ $url .= '?usehttp=1';
+ }
+ $nomodal = 1;
+ }
}
if (&Apache::lonnet::symbverify($symb,$url)) {
my $shownsymb = $symb;
if ($isexternal) {
- if ($url =~ /^([^#]+)#([^#]+)$/) {
- $url = $1;
- $anchor = $2;
- if ($symb =~ m{^([^#]+)\Q#$anchor\E$}) {
- $shownsymb = $1.&escape('#').$anchor;
- }
+ $url =~ s/\#[^#]+$//;
+ if ($container eq 'page') {
+ $url = &Apache::lonnet::clutter($url);
}
}
unless ($env{'request.role.adv'}) {
@@ -3733,14 +4111,14 @@ END
}
}
if ($url ne '') {
- $url.=(($url=~/\?/)?'&':'?').'symb='.&HTML::Entities::encode($shownsymb,'"<>&');
+ $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($shownsymb);
}
} elsif (!$env{'request.role.adv'}) {
my $checkencrypt;
if (((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i) ||
$isencrypted || (&Apache::lonnet::EXT('resource.0.encrypturl',$symb) =~ /^yes$/i)) {
$checkencrypt = 1;
- } else {
+ } elsif (ref($navmapref)) {
unless (ref($$navmapref)) {
$$navmapref = Apache::lonnavmaps::navmap->new();
}
@@ -3754,7 +4132,7 @@ END
my $shownsymb = &Apache::lonenc::encrypted($symb);
my $shownurl = &Apache::lonenc::encrypted($url);
if (&Apache::lonnet::symbverify($shownsymb,$shownurl)) {
- $url = $shownurl.(($shownurl=~/\?/)?'&':'?').'symb='.&HTML::Entities::encode($shownsymb,'"<>&');
+ $url = $shownurl.(($shownurl=~/\?/)?'&':'?').'symb='.&escape($shownsymb);
if ($env{'request.enc'} ne '') {
delete($env{'request.enc'});
}
@@ -3773,6 +4151,26 @@ END
if ($url =~ /^([^#]+)#([^#]+)$/) {
$url = $1;
$anchor = $2;
+ if (($url =~ m{^(|/adm/wrapper)/ext/(?!https:)}) && ($ENV{'SERVER_PORT'} == 443)) {
+ unless (&Apache::lonnet::uses_sts()) {
+ if ($hostname ne '') {
+ $url = 'http://'.$hostname.$url;
+ }
+ $url .= (($url =~ /\?/) ? '&':'?').'usehttp=1';
+ }
+ $nomodal = 1;
+ }
+ }
+ } elsif ($url =~ m{^\Q/public/$coursedom/$coursenum/syllabus\E}) {
+ if (($ENV{'SERVER_PORT'} == 443) &&
+ ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) {
+ unless (&Apache::lonnet::uses_sts()) {
+ if ($hostname ne '') {
+ $url = 'http://'.$hostname.$url;
+ }
+ $url .= (($url =~ /\?/) ? '&':'?').'usehttp=1';
+ }
+ $nomodal = 1;
}
}
}
@@ -3795,25 +4193,29 @@ END
my $encryptmap = ((&LONCAPA::map::getparameter($orderidx,
'parameter_encrypturl'))[0]=~/^yes$/i);
unless ($hiddenmap) {
- unless (ref($$navmapref)) {
- $$navmapref = Apache::lonnavmaps::navmap->new();
- }
- if (ref($$navmapref)) {
- if (lc($$navmapref->get_mapparam(undef,$folderurl,"0.hiddenresource")) eq 'yes') {
- my @resources = $$navmapref->retrieveResources($folderurl,$filterFunc,1,1);
- unless (@resources) {
- $hiddenmap = 1;
- unless ($env{'request.role.adv'}) {
- $url = '';
- $hiddenfolder = 1;
+ if (ref($navmapref)) {
+ unless (ref($$navmapref)) {
+ $$navmapref = Apache::lonnavmaps::navmap->new();
+ }
+ if (ref($$navmapref)) {
+ if (lc($$navmapref->get_mapparam(undef,$folderurl,"0.hiddenresource")) eq 'yes') {
+ my @resources = $$navmapref->retrieveResources($folderurl,$filterFunc,1,1);
+ unless (@resources) {
+ $hiddenmap = 1;
+ unless ($env{'request.role.adv'}) {
+ $url = '';
+ $hiddenfolder = 1;
+ }
}
}
}
}
}
unless ($encryptmap) {
- if (lc($$navmapref->get_mapparam(undef,$folderurl,"0.encrypturl")) eq 'yes') {
- $encryptmap = 1;
+ if ((ref($navmapref)) && (ref($$navmapref))) {
+ if (lc($$navmapref->get_mapparam(undef,$folderurl,"0.encrypturl")) eq 'yes') {
+ $encryptmap = 1;
+ }
}
}
@@ -3858,12 +4260,17 @@ $form_common."\n".
$form_end;
}
} elsif ($supplementalflag && !$allowed) {
+ my $isexttool;
+ if ($url=~m{^/adm/$coursedom/$coursenum/\d+/ext\.tool$}) {
+ $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;
}
if ($anchor ne '') {
@@ -3877,7 +4284,13 @@ $form_end;
if ($isexternal) {
($editlink,$extresform) =
&Apache::lonextresedit::extedit_form(0,$residx,$orig_url,$title,$pathitem,
- undef,undef,undef,$disabled);
+ undef,undef,undef,undef,undef,undef,
+ undef,$disabled);
+ } elsif ($orig_url =~ m{^/adm/$coursedom/$coursenum/\d+/ext\.tool$}) {
+ ($editlink,$extresform) =
+ &Apache::lonextresedit::extedit_form(0,$residx,$orig_url,$title,$pathitem,
+ undef,undef,undef,'tool',$coursedom,
+ $coursenum,$ltitoolsref,$disabled);
} elsif (!$isfolder && !$ispage) {
my ($cfile,$home,$switchserver,$forceedit,$forceview) =
&Apache::lonnet::can_edit_resource($fileloc,$coursenum,$coursedom,$orig_url);
@@ -3892,7 +4305,8 @@ $form_end;
$forceedit,
undef,$symb,
&escape($env{'form.folderpath'}),
- $renametitle,'','',1,$suppanchor);
+ $renametitle,$hostname,
+ '','',1,$suppanchor);
if ($jscall) {
$editlink = ''.&mt('Edit').' '."\n";
@@ -3909,6 +4323,7 @@ $form_end;
$reinit = &mt('(re-initialize course to access)');
}
$line.='
'.&mt('Created [quant,_1,URL]',$numnew).'
'); + } + if ((ref($errors) eq 'ARRAY') && (@{$errors} > 0)) { + $r->print(&mt('The following errors occurred when processing your request to create shortened URLs:').''.$error.'
'); } if ($hadchanges) { - &mark_hash_old(); + unless (&is_hash_old()) { + &mark_hash_old(); + } } &changewarning($r,''); @@ -5660,6 +6273,11 @@ SNFFORM &Apache::lonextresedit::extedit_form(1,0,undef,undef,$pathitem, $help{'Adding_External_Resource'}, undef,undef,$disabled); + my $supexttoolform = + &Apache::lonextresedit::extedit_form(1,0,undef,undef,$pathitem, + $help{'Adding_External_Tool'}, + undef,undef,'tool',$coursedom, + $coursenum,\%ltitools,$disabled); my $supnewsylform=(<'.$error.'
'); } else { @@ -5748,7 +6372,7 @@ my %suporderhash = ( } } elsif ($supplementalflag) { my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, - $supplementalflag,'',$iconpath,$pathitem); + $supplementalflag,'',$iconpath,$pathitem,'',$hostname); if ($error) { $r->print(''.$error.'
'); } @@ -5782,6 +6406,7 @@ my %suporderhash = ( sub embedded_form_elems { my ($phase,$primaryurl,$newidx) = @_; my $folderpath = &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); + $newidx =~s /\D+//g; return <