'.
''.
@@ -679,7 +678,7 @@ sub process_content {
if ($contents) {
$$content_file = &store_template($contents,$tempexport,$count,$content_type);
}
- } elsif ($symb =~ m-lib/templates/examupload\.problem-m) {
+ } elsif ($symb =~ m-lib/templates/examupload\.problem$-) {
$content_type = 'examupload';
} elsif ($symb =~ m-adm/(\w+)/(\w+)/(\d+)/bulletinboard$-) {
$content_type = 'bulletinboard';
@@ -748,11 +747,13 @@ sub replicate_content {
if ($copiedfile = Apache::File->new('>'.$destination)) {
my $content;
if ($caller eq 'resource') {
- $content = &Apache::lonnet::getfile('/home/httpd/html/res/'.$url);
+ my $respath = $Apache::lonnet::perlvar{'lonDocRoot'}.'/res';
+ my $filepath = &Apache::lonnet::filelocation($respath,$url);
+ $content = &Apache::lonnet::getfile($filepath);
if ($content eq -1) {
$$message = 'Could not copy file '.$filename;
} else {
- &extract_media($content,$count,$tempexport,$href,'resource');
+ &extract_media($url,$cdom,$cnum,\$content,$count,$tempexport,$href,$message,'resource');
$repstatus = 'ok';
}
} elsif ($caller eq 'uploaded' || $caller eq 'templateupload') {
@@ -760,10 +761,10 @@ sub replicate_content {
$repstatus = &Apache::lonnet::getuploaded('GET',$url,$cdom,$cnum,\$content,$rtncode);
if ($repstatus eq 'ok') {
if ($url =~ /\.html?$/i) {
- &extract_media(\$content,$count,$tempexport,$href,'uploaded');
+ &extract_media($url,$cdom,$cnum,\$content,$count,$tempexport,$href,$message,'uploaded');
}
} else {
- $$message = 'Could not render '.$url.' server message - '.$rtncode;
+ $$message = 'Could not render '.$url.' server message - '.$rtncode." \n";
}
} elsif ($caller eq 'noedit') {
# Need to render the resource without the LON-CAPA Internal header and the Post discussion footer, and then set $content equal to this.
@@ -775,10 +776,10 @@ sub replicate_content {
}
close($copiedfile);
} else {
- $$message = 'Could not open destination file for '.$filename."\n";
+ $$message = 'Could not open destination file for '.$filename." \n";
}
} else {
- $$message = 'Could not determine name of file for '.$symb."\n";
+ $$message = 'Could not determine name of file for '.$symb." \n";
}
if ($repstatus eq 'ok') {
$content_name = $count.'/'.$filename;
@@ -787,11 +788,66 @@ sub replicate_content {
}
sub extract_media {
- my ($content,$count,$tempexport,$href,$caller) = @_;
-# @$href will contain path to any embedded resources in the content.
-# For LON-CAPA problems this would be images. applets etc.
-# For uploaded HTML files this would be images etc.
-# paths will be in the form $count/res/$file, and urls in the $content will be rewritten with the new paths.
+ my ($url,$cdom,$cnum,$content,$count,$tempexport,$href,$message,$caller) = @_;
+ my %allfiles = ();
+ my %codebase = ();
+ $url =~ s#([^/]+)$##;
+ &Apache::lonnet::extract_embedded_items(undef,undef,\%allfiles,\%codebase,$content);
+ foreach my $embed_file (keys(%allfiles)) {
+ my $filename;
+ if ($embed_file =~ m#([^/]+)$#) {
+ $filename = $1;
+ } else {
+ $filename = $embed_file;
+ }
+ my $newname = 'res/'.$filename;
+ my ($rtncode,$embed_content,$repstatus);
+ my $embed_url;
+ if ($embed_file =~ m-^/-) {
+ $embed_url = $embed_file; # points to absolute path
+ } else {
+ if ($embed_file =~ m-https?://-) {
+ next; # points to url
+ } else {
+ $embed_url = $url.$embed_file; # points to relative path
+ }
+ }
+ if ($caller eq 'resource') {
+ my $respath = $Apache::lonnet::perlvar{'lonDocRoot'}.'/res';
+ my $embed_path = &Apache::lonnet::filelocation($respath,$embed_url);
+ $embed_content = &Apache::lonnet::getfile($embed_path);
+ unless ($embed_content eq -1) {
+ $repstatus = 'ok';
+ }
+ } elsif ($caller eq 'uploaded') {
+
+ $repstatus = &Apache::lonnet::getuploaded('GET',$embed_url,$cdom,$cnum,\$embed_content,$rtncode);
+ }
+ if ($repstatus eq 'ok') {
+ my $destination = $tempexport.'/resources/'.$count.'/res';
+ if (!-e "$destination") {
+ mkdir($destination,0755);
+ }
+ $destination .= '/'.$filename;
+ my $copiedfile;
+ if ($copiedfile = Apache::File->new('>'.$destination)) {
+ print $copiedfile $embed_content;
+ push @{$href}, .'resources/'.$count.'/res/'.$filename;
+ my $attrib_regexp = '';
+ if (@{$allfiles{$embed_file}} > 1) {
+ $attrib_regexp = join('|',@{$allfiles{$embed_file}});
+ } else {
+ $attrib_regexp = $allfiles{$embed_file}[0];
+ }
+ $$content =~ s#($attrib_regexp\s*=\s*['"]?)\Q$embed_file\E(['"]?)#$1$newname$2#gi;
+ if ($caller eq 'resource' && $url =~ /\.(problem|library)$/) {
+ $$content =~ s#\Q$embed_file\E#$newname#gi;
+ }
+ }
+ } else {
+ $$message .= 'replication of embedded file - '.$embed_file.' in '.$url.' failed, reason -'.$rtncode." \n";
+ }
+ }
return;
}
@@ -840,8 +896,7 @@ sub group_import {
''."\n".
'';
$env{'form.output'}=$newmapstr;
- my $home=&Apache::lonnet::homeserver($coursenum,$coursedom);
- my $result=&Apache::lonnet::finishuserfileupload($coursenum,$coursedom,$home,
+ my $result=&Apache::lonnet::finishuserfileupload($coursenum,$coursedom,
'output',$1.$2);
if ($result != m|^/uploaded/|) {
$errtext.='Map not saved: A network error occured when trying to save the new map. ';
@@ -852,7 +907,7 @@ sub group_import {
}
}
if ($url) {
- my $idx = $#Apache::lonratedt::resources + 1;
+ my $idx = &Apache::lonratedt::getresidx($url);
$Apache::lonratedt::order[$#Apache::lonratedt::order+1]=$idx;
my $ext = 'false';
if ($url=~/^http:\/\//) { $ext = 'true'; }
@@ -904,7 +959,7 @@ sub breadcrumbs {
}
sub editor {
- my ($r,$coursenum,$coursedom,$folder,$allowed)=@_;
+ my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output)=@_;
my $errtext='';
my $fatal=0;
my $container='sequence';
@@ -914,8 +969,10 @@ sub editor {
($errtext,$fatal)=
&mapread($coursenum,$coursedom,$folder.'.'.$container);
if ($#Apache::lonratedt::order<1) {
- $Apache::lonratedt::order[0]=1;
- $Apache::lonratedt::resources[1]='';
+ my $idx=&Apache::lonratedt::getresidx();
+ if ($idx<=0) { $idx=1; }
+ $Apache::lonratedt::order[0]=$idx;
+ $Apache::lonratedt::resources[$idx]='';
}
if (defined($env{'form.markcopy'})) {
# Mark for copying
@@ -1018,7 +1075,7 @@ sub editor {
if ($url=~/^http\:\/\//) { $ext='true'; }
$url=~s/\:/\:/g;
# Now insert the URL at the bottom
- my $newidx=1+$#Apache::lonratedt::resources;
+ my $newidx=&Apache::lonratedt::getresidx($url);
$Apache::lonratedt::resources[$newidx]=
$title.':'.$url.':'.$ext.':normal:res';
$Apache::lonratedt::order[1+$#Apache::lonratedt::order]=$newidx;
@@ -1030,43 +1087,16 @@ sub editor {
}
}
-# upload a file, if present
- if (($env{'form.uploaddoc.filename'}) &&
- ($env{'form.cmd'}=~/^upload_(\w+)/)) {
- if ( ($folder=~/^$1/) || ($1 eq 'default') ) {
-# this is for a course, not a user, so set coursedoc flag
-# probably the only place in the system where this should be "1"
- my $newidx=$#Apache::lonratedt::resources+1;
- my $url=&Apache::lonnet::userfileupload('uploaddoc',1,'docs/'.$newidx);
- my $ext='false';
- if ($url=~/^http\:\/\//) { $ext='true'; }
- $url=~s/\:/\:/g;
- my $comment=$env{'form.comment'};
- $comment=~s/\\<\;/g;
- $comment=~s/\>/\>\;/g;
- $comment=~s/\:/\:/g;
- if ($folder=~/^supplemental/) {
- $comment=time.'___&&&___'.$env{'user.name'}.'___&&&___'.
- $env{'user.domain'}.'___&&&___'.$comment;
- }
- $Apache::lonratedt::resources[$newidx]=
- $comment.':'.$url.':'.$ext.':normal:res';
- $Apache::lonratedt::order[$#Apache::lonratedt::order+1]=
- $newidx;
-
- ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container);
- if ($fatal) {
- $r->print('
'.$errtext.'
');
- return;
- }
- }
- }
+ $r->print($upload_output);
if ($env{'form.cmd'}) {
my ($cmd,$idx)=split(/\_/,$env{'form.cmd'});
if ($cmd eq 'del') {
my (undef,$url)=split(':',$Apache::lonratedt::resources[$Apache::lonratedt::order[$idx]]);
- if ($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) {
+ if (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) &&
+ ($url!~/\.(page|sequence|problem|exam|quiz|assess|survey|form|library)$/)) {
&Apache::lonnet::removeuploadedurl($url);
+ } else {
+ &Apache::lonratedt::makezombie($Apache::lonratedt::order[$idx]);
}
for (my $i=$idx;$i<$#Apache::lonratedt::order;$i++) {
$Apache::lonratedt::order[$i]=
@@ -1075,6 +1105,7 @@ sub editor {
$#Apache::lonratedt::order--;
} elsif ($cmd eq 'cut') {
my (undef,$url)=split(':',$Apache::lonratedt::resources[$Apache::lonratedt::order[$idx]]);
+ &Apache::lonratedt::makezombie($Apache::lonratedt::order[$idx]);
for (my $i=$idx;$i<$#Apache::lonratedt::order;$i++) {
$Apache::lonratedt::order[$i]=
$Apache::lonratedt::order[$i+1];
@@ -1140,8 +1171,8 @@ sub editor {
# Loading a complete map
if (($env{'form.importmap'}) && ($env{'form.loadmap'})) {
foreach (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$env{'form.importmap'}))) {
- my $idx=$#Apache::lonratedt::resources;
- $idx++;
+ my ($title,$url,$ext,$type)=split(/\:/,$_);
+ my $idx=&Apache::lonratedt::getresidx($url);
$Apache::lonratedt::resources[$idx]=$_;
$Apache::lonratedt::order
[$#Apache::lonratedt::order+1]=$idx;
@@ -1199,6 +1230,135 @@ FOLDERINFO
}
}
+sub process_file_upload {
+ my ($upload_output,$coursenum,$coursedom,$allfiles,$codebase,$uploadcmd) = @_;
+# upload a file, if present
+ my $parseaction;
+ if ($env{'form.parserflag'}) {
+ $parseaction = 'parse';
+ }
+ my $phase_status;
+ my $folder=$env{'form.folder'};
+ if ($folder eq '') {
+ $folder='default';
+ }
+ if ( ($folder=~/^$uploadcmd/) || ($uploadcmd eq 'default') ) {
+ my $errtext='';
+ my $fatal=0;
+ my $container='sequence';
+ if ($env{'form.pagepath'}) {
+ $container='page';
+ }
+ ($errtext,$fatal)=
+ &mapread($coursenum,$coursedom,$folder.'.'.$container);
+ if ($#Apache::lonratedt::order<1) {
+ $Apache::lonratedt::order[0]=1;
+ $Apache::lonratedt::resources[1]='';
+ }
+ if ($fatal) {
+ return 'failed';
+ }
+ my $destination = 'docs/';
+ if ($folder =~ /^supplemental/) {
+ $destination = 'supplemental/';
+ }
+ if (($folder eq 'default') || ($folder eq 'supplemental')) {
+ $destination .= 'default/';
+ } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) {
+ $destination .= $2.'/';
+ }
+# this is for a course, not a user, so set coursedoc flag
+# probably the only place in the system where this should be "1"
+ my $newidx=&Apache::lonratedt::getresidx();
+ $destination .= $newidx;
+ my $url=&Apache::lonnet::userfileupload('uploaddoc',1,$destination,
+ $parseaction,$allfiles,
+ $codebase);
+ my $ext='false';
+ if ($url=~/^http\:\/\//) { $ext='true'; }
+ $url=~s/\:/\:/g;
+ my $comment=$env{'form.comment'};
+ $comment=~s/\\<\;/g;
+ $comment=~s/\>/\>\;/g;
+ $comment=~s/\:/\:/g;
+ if ($folder=~/^supplemental/) {
+ $comment=time.'___&&&___'.$env{'user.name'}.'___&&&___'.
+ $env{'user.domain'}.'___&&&___'.$comment;
+ }
+
+ $Apache::lonratedt::resources[$newidx]=
+ $comment.':'.$url.':'.$ext.':normal:res';
+ $Apache::lonratedt::order[$#Apache::lonratedt::order+1]= $newidx;
+ ($errtext,$fatal)=&storemap($coursenum,$coursedom,
+ $folder.'.'.$container);
+ if ($fatal) {
+ $$upload_output .= '
'.$errtext.'
';
+ return 'failed';
+ } else {
+ if ($parseaction eq 'parse') {
+ my $total_embedded = keys(%{$allfiles});
+ if ($total_embedded > 0) {
+ my $num = 0;
+ $$upload_output .= 'This file contains embedded multimedia objects, which need to be uploaded to LON-CAPA.
+ ';
+ } else {
+ $$upload_output .= 'No embedded items identified ';
+ }
+ }
+ }
+ }
+ return $phase_status;
+}
+
+sub process_secondary_uploads {
+ my ($upload_output,$coursedom,$coursenum,$formname,$num,$newidx) = @_;
+ my $folder=$env{'form.folder'};
+ my $destination = 'docs/';
+ if ($folder =~ /^supplemental/) {
+ $destination = 'supplemental/';
+ }
+ if (($folder eq 'default') || ($folder eq 'supplemental')) {
+ $destination .= 'default/';
+ } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) {
+ $destination .= $1.'/';
+ }
+ $destination .= $newidx;
+ my ($url,$filename);
+ $url=&Apache::lonnet::userfileupload($formname.$num,1,$destination);
+ ($filename) = ($url =~ m-^/uploaded/$coursedom/$coursenum/$destination/(.+)$-);
+ return $filename;
+}
+
# --------------------------------------------------------------- An entry line
sub entryline {
@@ -1569,8 +1729,15 @@ sub verifycontent {
&mt('Return to DOCS').'');
}
+
# -------------------------------------------------------------- Check Versions
+sub devalidateversioncache {
+ my $src=shift;
+ &Apache::lonnet::devalidate_cache_new('courseresversion',$env{'request.course.id'}.'_'.
+ &Apache::lonnet::clutter($src));
+}
+
sub checkversions {
my $r=shift;
my $html=&Apache::lonxml::xmlbegin();
@@ -1597,6 +1764,7 @@ sub checkversions {
foreach (keys %hash) {
if ($_=~/^ids\_(\/res\/.+)$/) {
$newsetversions{$1}='mostrecent';
+ &devalidateversioncache($1);
}
}
} elsif ($env{'form.setcurrent'}) {
@@ -1606,6 +1774,7 @@ sub checkversions {
my $getvers=&Apache::lonnet::getversion($1);
if ($getvers>0) {
$newsetversions{$1}=$getvers;
+ &devalidateversioncache($1);
}
}
}
@@ -1616,6 +1785,7 @@ sub checkversions {
my $src=$1;
if (($env{$_}) && ($env{$_} ne $setversions{$src})) {
$newsetversions{$src}=$env{$_};
+ &devalidateversioncache($src);
}
}
}
@@ -1837,26 +2007,30 @@ sub is_hash_old {
}
sub changewarning {
- my ($r,$postexec)=@_;
+ my ($r,$postexec,$message,$url)=@_;
if (!&is_hash_old()) { return; }
my $pathvar='folderpath';
my $path=&Apache::lonnet::escape($env{'form.folderpath'});
- if (defined($env{'form.pagepath'})) {
- $pathvar='pagepath';
- $path=&Apache::lonnet::escape($env{'form.pagepath'});
- $path.='&symb='.&Apache::lonnet::escape($env{'form.pagesymb'});
- }
- $r->print(
-''.
-'');
+&mt($message,' ').
+$help{'Caching'}.''."\n\n");
}
# ================================================================ Main Handler
@@ -1960,7 +2134,7 @@ sub handler {
# graphics settings
- $iconpath = $r->dir_config('lonIconsURL') . "/";
+ $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL') . "/");
my $now=time;
@@ -2101,7 +2275,7 @@ function removeres(folderpath,index,oldt
}
function cutres(folderpath,index,oldtitle,container,pagesymb) {
- if (confirm('WARNING: Cutting a resource makes associated grades and scores inaccessible,\\neven if it is pasted in again elsewhere!\\nCut "'+oldtitle+'"?')) {
+ if (confirm('WARNING: Cutting a resource makes associated grades and scores inaccessible!\\nGrades remain inaccessible if resource is pasted into another folder.\\nCut "'+oldtitle+'"?')) {
this.document.forms.renameform.cmd.value='cut_'+index;
this.document.forms.renameform.markcopy.value=index;
if (container == 'sequence') {
@@ -2136,20 +2310,103 @@ ENDNEWSCRIPT
&Apache::loncommon::bodytag('Course Documents','',$events,
'','',$showdoc).
&Apache::loncommon::help_open_menu('','','','',273,'RAT'));
- unless ($showdoc) {
+ my %allfiles = ();
+ my %codebase = ();
+ my ($upload_result,$upload_output);
+ if ($allowed) {
+ if (($env{'form.uploaddoc.filename'}) && ($env{'form.cmd'}=~/^upload_(\w+)/)) {
+# Process file upload - phase one - upload and parse primary file.
+ $upload_result = &process_file_upload(\$upload_output,$coursenum,
+ $coursedom,\%allfiles,
+ \%codebase,$1);
+ if ($upload_result eq 'phasetwo') {
+ $r->print($upload_output);
+ }
+ } elsif ($env{'form.phasetwo'}) {
+ my %newname = ();
+ my %origname = ();
+ my %attribs = ();
+ my $updateflag = 0;
+ my $residx = $env{'form.newidx'};
+ my $primary_url = &Apache::lonnet::unescape($env{'form.primaryurl'});
+# Process file upload - phase two - gather secondary files.
+ for (my $i=0; $i<$env{'form.phasetwo'}; $i++) {
+ if ($env{'form.embedded_item_'.$i.'.filename'}) {
+ my $javacodebase;
+ $newname{$i} = &process_secondary_uploads(\$upload_output,$coursedom,$coursenum,'embedded_item_',$i,$residx);
+ $origname{$i} = &Apache::lonnet::unescape($env{'form.embedded_orig_'.$i});
+ if (exists($env{'form.embedded_codebase_'.$i})) {
+ $javacodebase = &Apache::lonnet::unescape($env{'form.embedded_codebase_'.$i});
+ $origname{$i} =~ s#^\Q$javacodebase\E/##;
+ }
+ my @attributes = ();
+ if ($env{'form.embedded_attrib_'.$i} =~ /:/) {
+ @attributes = split/:/,$env{'form.embedded_attrib_'.$i};
+ } else {
+ @attributes = ($env{'form.embedded_attrib_'.$i});
+ }
+ foreach (@attributes) {
+ push(@{$attribs{$i}},&Apache::lonnet::unescape($_));
+ }
+ if ($javacodebase) {
+ $codebase{$i} = $javacodebase;
+ $codebase{$i} =~ s#/$##;
+ $updateflag = 1;
+ }
+ }
+ unless ($newname{$i} eq $origname{$i}) {
+ $updateflag = 1;
+ }
+ }
+# Process file upload - phase three - modify primary file
+ if ($updateflag) {
+ my ($content,$rtncode);
+ my $updateflag = 0;
+ my $getstatus = &Apache::lonnet::getuploaded('GET',$primary_url,$coursedom,$coursenum,\$content,\$rtncode);
+ if ($getstatus eq 'ok') {
+ foreach my $item (keys %newname) {
+ if ($newname{$item} ne $origname{$item}) {
+ my $attrib_regexp = '';
+ if (@{$attribs{$item}} > 1) {
+ $attrib_regexp = join('|',@{$attribs{$item}});
+ } else {
+ $attrib_regexp = $attribs{$item}[0];
+ }
+ if ($content =~ m#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#) {
+ }
+ $content =~ s#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#$1$newname{$item}$2#gi;
+ }
+ if (exists($codebase{$item})) {
+ $content =~ s/(codebase\s*=\s*["']?)\Q$codebase{$item}\E(["']?)/$1.$2/i;
+ }
+ }
+# Save edited file.
+ my $saveresult;
+ my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
+ my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $url = &Apache::lonnet::store_edited_file($primary_url,$content,$docudom,$docuname,\$saveresult);
+ } else {
+ &Apache::lonnet::logthis('retrieval of uploaded file - '.$primary_url.' - for editing, failed: '.$getstatus);
+ }
+ }
+ }
+ }
+
+ unless ($showdoc || $upload_result eq 'phasetwo') {
# -----------------------------------------------------------------------------
my %lt=&Apache::lonlocal::texthash(
'uplm' => 'Upload a new main course document',
'upls' => 'Upload a new supplemental course document',
'impp' => 'Import a document',
'pubd' => 'Published documents',
- 'copm' => 'All documents out of a published map',
+ 'copm' => 'All documents out of a published map into this folder',
'spec' => 'Special documents',
'upld' => 'Upload Document',
'srch' => 'Search',
'impo' => 'Import',
'selm' => 'Select Map',
'load' => 'Load Map',
+ 'reco' => 'Recover Deleted Resources',
'newf' => 'New Folder',
'newp' => 'New Composite Page',
'extr' => 'External Resource',
@@ -2164,7 +2421,8 @@ ENDNEWSCRIPT
'imsf' => 'Import IMS package',
'file' => 'File',
'title' => 'Title',
- 'comment' => 'Comment'
+ 'comment' => 'Comment',
+ 'parse' => 'If HTML file, upload embedded images/multimedia files'
);
# -----------------------------------------------------------------------------
if ($allowed) {
@@ -2231,7 +2489,7 @@ ENDCOURSEVERIFY
#$postexec='self.close();';
}
$hadchanges=0;
- &editor($r,$coursenum,$coursedom,$folder,$allowed);
+ &editor($r,$coursenum,$coursedom,$folder,$allowed,$upload_output);
if ($hadchanges) {
&mark_hash_old()
}
@@ -2240,7 +2498,11 @@ ENDCOURSEVERIFY
'.sequence';
my $pageseq = '/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time.
'.page';
-
+ my $container='sequence';
+ if ($env{'form.pagepath'}) {
+ $container='page';
+ }
+ my $readfile='/uploaded/'.$coursedom.'/'.$coursenum.'/'.$folder.'.'.$container;
$r->print(<