--- loncom/interface/londocs.pm 2012/12/13 02:45:27 1.484.2.15
+++ loncom/interface/londocs.pm 2013/03/31 22:36:01 1.538
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Documents
#
-# $Id: londocs.pm,v 1.484.2.15 2012/12/13 02:45:27 raeburn Exp $
+# $Id: londocs.pm,v 1.538 2013/03/31 22:36:01 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -40,7 +40,7 @@ use Apache::lonxml;
use Apache::lonclonecourse;
use Apache::lonnavmaps;
use Apache::lonnavdisplay();
-use Apache::lonuserstate();
+use Apache::lonextresedit();
use HTML::Entities;
use HTML::TokeParser;
use GDBM_File;
@@ -152,7 +152,7 @@ sub dumpcourse {
$r->print(&endContentScreen());
return '';
}
- my ($ca,$cd)=split(/\@/,$env{'form.authorspace'});
+ my ($ca,$cd)=split(/\:/,$env{'form.authorspace'});
$r->print('
+
+
+
+$name
+
+
+$initialtext
+
+
+END
+ $env{'form.output'}=$newhtml;
+ my $result =
+ &Apache::lonnet::finishuserfileupload($coursenum,$coursedom,
+ 'output',
+ "$filepath/$residx/$fname.html");
+ if ($result =~ m{^/uploaded/}) {
+ $url = $result;
+ if ($filepath =~ /^supplemental/) {
+ $name = time.'___&&&___'.$env{'user.name'}.'___&&&___'.
+ $env{'user.domain'}.'___&&&___'.$name;
+ }
+ } else {
+ return (&mt('Failed to save new web page.'),1);
+ }
+ }
+ $url = &LONCAPA::map::qtunescape($url);
$LONCAPA::map::resources[$residx] =
join(':', ($name, $url, $ext, 'normal', 'res'));
}
}
- return &storemap($coursenum, $coursedom, $folder.'.'.$container,1);
-}
-
-sub breadcrumbs {
- my ($allowed,$crstype)=@_;
- &Apache::lonhtmlcommon::clear_breadcrumbs();
- my (@folders);
- if ($env{'form.pagepath'}) {
- @folders = split('&',$env{'form.pagepath'});
- } else {
- @folders=split('&',$env{'form.folderpath'});
- }
- my $folderpath;
- my $plain='';
- my $randompick=-1;
- my $isencrypted=0;
- my $ishidden=0;
- my $is_random_order=0;
- while (@folders) {
- my $folder=shift(@folders);
- my $foldername=shift(@folders);
- if ($folderpath) {$folderpath.='&';}
- $folderpath.=$folder.'&'.$foldername;
- my $url;
- if ($allowed) {
- $url = '/adm/coursedocs?folderpath=';
- } else {
- $url = '/adm/supplemental?folderpath=';
- }
- $url .= &escape($folderpath);
- my $name=&unescape($foldername);
-# randompick number, hidden, encrypted, random order, is appended with ":"s to the foldername
- $name=~s/\:(\d*)\:(\w*)\:(\w*):(\d*)$//;
- if ($1 ne '') {
- $randompick=$1;
- } else {
- $randompick=-1;
- }
- if ($2) { $ishidden=1; }
- if ($3) { $isencrypted=1; }
- if ($4 ne '') { $is_random_order = 1; }
- if ($folder eq 'supplemental') {
- $name = &mt('Supplemental '.$crstype.' Content');
- }
- &Apache::lonhtmlcommon::add_breadcrumb(
- {'href'=>$url,
- 'title'=>$name,
- 'text'=>$name,
- 'no_mt'=>1,
- });
- $plain.=$name.' > ';
- }
- $plain=~s/\>\;\s*$//;
- return (&Apache::lonhtmlcommon::breadcrumbs(undef,undef,0,'nohelp',
- undef, undef, 1 ),$randompick,$ishidden,
- $isencrypted,$plain,$is_random_order);
+ if ($importuploaded) {
+ my %import_errors;
+ my %updated = (
+ removefrommap => \%removefrommap,
+ removeparam => \%removeparam,
+ );
+ my ($result,$msgsarray,$lockerror) =
+ &apply_fixups($folder,1,$coursedom,$coursenum,\%import_errors,\%updated);
+ if (keys(%import_errors) > 0) {
+ $fixuperrors =
+ ''."\n".
+ &mt('The following files are either dependencies of a web page or references within a folder and/or composite page for which errors occurred during import:')."\n".
+ '
'."\n";
+ foreach my $key (sort(keys(%import_errors))) {
+ $fixuperrors .= ''.$key.' '."\n";
+ }
+ $fixuperrors .= ' '."\n";
+ }
+ if (ref($msgsarray) eq 'ARRAY') {
+ if (@{$msgsarray} > 0) {
+ $fixuperrors .= ''.
+ join(' ',@{$msgsarray}).
+ '
';
+ }
+ }
+ if ($lockerror) {
+ $fixuperrors .= ''.
+ $lockerror.
+ '
';
+ }
+ }
+ my ($errtext,$fatal) =
+ &storemap($coursenum, $coursedom, $folder.'.'.$container,1);
+ return ($errtext,$fatal,$fixuperrors);
}
sub log_docs {
@@ -445,17 +485,15 @@ sub docs_change_log {
my %orderhash;
my $container='sequence';
my $pathitem;
- if ($env{'form.pagepath'}) {
+ if ($env{'form.folderpath'} =~ /\:1$/) {
$container='page';
- $pathitem = ' ';
- } else {
- my $folderpath=$env{'form.folderpath'};
- if ($folderpath eq '') {
- $folderpath = 'default&'.&escape(&mt('Main '.$crstype.' Documents'));
- }
- $pathitem = ' ';
}
+ my $folderpath=$env{'form.folderpath'};
+ if ($folderpath eq '') {
+ $folderpath = 'default&'.&escape(&mt('Main '.$crstype.' Content').':::::');
+ }
+ $pathitem = ' ';
my $readfile="/uploaded/$coursedom/$coursenum/$folder.$container";
my $jumpto = $readfile;
$jumpto =~ s{^/}{};
@@ -463,7 +501,8 @@ sub docs_change_log {
if ($supplementalflag) {
$tid = 2;
}
- my ($breadcrumbtrail) = &breadcrumbs($allowed,$crstype);
+ my ($breadcrumbtrail) =
+ &Apache::lonhtmlcommon::docs_breadcrumbs($allowed,$crstype,1);
$r->print($breadcrumbtrail.
&generate_edit_table($tid,\%orderhash,undef,$iconpath,$jumpto,
$readfile));
@@ -537,7 +576,7 @@ sub docs_change_log {
':'.$docslog{$id}{'exe_udom'}.''.
$send_msg_link.''.
$docslog{$id}{'logentry'}{'folder'}.' ');
- my $is_supp = 0;
+ my $is_supp = 0;
if ($docslog{$id}{'logentry'}{'currentfolder'} =~ /^supplemental/) {
$is_supp = 1;
}
@@ -560,7 +599,7 @@ sub docs_change_log {
if ($is_supp) {
$shown = &Apache::loncommon::parse_supplemental_title($shown);
}
- $r->print(''.$shown.' ');
+ $r->print(''.$shown.' ');
}
}
$r->print('');
@@ -616,57 +655,115 @@ sub docs_change_log {
sub update_paste_buffer {
my ($coursenum,$coursedom,$folder) = @_;
+ my (@possibles,%removals,%cuts);
+ if ($env{'form.multiremove'}) {
+ $env{'form.multiremove'} =~ s/,$//;
+ map { $removals{$_} = 1; } split(/,/,$env{'form.multiremove'});
+ }
+ if (($env{'form.multicopy'}) || ($env{'form.multicut'})) {
+ if ($env{'form.multicut'}) {
+ $env{'form.multicut'} =~ s/,$//;
+ foreach my $item (split(/,/,$env{'form.multicut'})) {
+ unless ($removals{$item}) {
+ $cuts{$item} = 1;
+ push(@possibles,$item.':cut');
+ }
+ }
+ }
+ if ($env{'form.multicopy'}) {
+ $env{'form.multicopy'} =~ s/,$//;
+ foreach my $item (split(/,/,$env{'form.multicopy'})) {
+ unless ($removals{$item} || $cuts{$item}) {
+ push(@possibles,$item.':copy');
+ }
+ }
+ }
+ } elsif ($env{'form.markcopy'}) {
+ @possibles = split(/,/,$env{'form.markcopy'});
+ }
- return if (!defined($env{'form.markcopy'}));
+ return if (@possibles == 0);
return if (!defined($env{'form.copyfolder'}));
- return if ($env{'form.markcopy'} < 0);
my ($errtext,$fatal) = &mapread($coursenum,$coursedom,
$env{'form.copyfolder'});
-
return if ($fatal);
-# Mark for copying
- my ($title,$url)=split(':',$LONCAPA::map::resources[$LONCAPA::map::order[$env{'form.markcopy'}]]);
- if (&is_supplemental_title($title)) {
- &Apache::lonnet::appenv({'docs.markedcopy_supplemental' => $title});
- ($title) = &Apache::loncommon::parse_supplemental_title($title);
- } elsif ($env{'docs.markedcopy_supplemental'}) {
- &Apache::lonnet::delenv('docs.markedcopy_supplemental');
- }
- $url=~s{http(:|:)//https(:|:)//}{https$2//};
-
- (my $cmd,undef)=split('_',$env{'form.cmd'});
-
- my %addtoenv = (
- 'docs.markedcopy_title' => $title,
- 'docs.markedcopy_url' => $url,
- 'docs.markedcopy_cmd' => $cmd,
- );
- &Apache::lonnet::delenv('docs.markedcopy_nested');
- &Apache::lonnet::delenv('docs.markedcopy_nestednames');
- if ($url =~ m{^/uploaded/$match_domain/$match_courseid/(default|supplemental)_?(\d*)\.(page|sequence)$}) {
- my $prefix = $1;
- my $subdir =$2;
- if ($subdir eq '') {
- $subdir = $prefix;
- }
- my (%addedmaps,%removefrommap,%removeparam,%hierarchy,%titles,%allmaps);
- &contained_map_check($url,$folder,\%removefrommap,\%removeparam,\%addedmaps,
- \%hierarchy,\%titles,\%allmaps);
- if (ref($hierarchy{$url}) eq 'HASH') {
- my ($nested,$nestednames);
- &recurse_uploaded_maps($url,$subdir,\%hierarchy,\%titles,\$nested,\$nestednames);
- $nested =~ s/\&$//;
- $nestednames =~ s/\Q___&&&___\E$//;
- if ($nested ne '') {
- $addtoenv{'docs.markedcopy_nested'} = $nested;
- }
- if ($nestednames ne '') {
- $addtoenv{'docs.markedcopy_nestednames'} = $nestednames;
+ my %curr_groups = &Apache::longroup::coursegroups();
+
+# Retrieve current paste buffer suffixes.
+ my @currpaste = split(/,/,$env{'docs.markedcopies'});
+ my (%pasteurls,@newpaste);
+
+# 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};
+ }
+ }
+ }
+
+# Mark items for copying (skip any items already in user's paste buffer)
+ my %addtoenv;
+
+ 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 ($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}));
+ my ($suffix,$errortxt,$locknotfreed) =
+ &new_timebased_suffix($env{'user.domain'},$env{'user.name'},'paste');
+ push(@newpaste,$suffix);
+ if ($locknotfreed) {
+ return $locknotfreed;
+ last;
+ }
+ if (&is_supplemental_title($title)) {
+ &Apache::lonnet::appenv({'docs.markedcopy_supplemental_'.$suffix => $title});
+ ($title) = &Apache::loncommon::parse_supplemental_title($title);
+ }
+
+ $addtoenv{'docs.markedcopy_title_'.$suffix} = $title,
+ $addtoenv{'docs.markedcopy_url_'.$suffix} = $url,
+ $addtoenv{'docs.markedcopy_cmd_'.$suffix} = $cmd,
+ $addtoenv{'docs.markedcopy_crs_'.$suffix} = $env{'request.course.id'};
+
+ if ($url =~ m{^/uploaded/$match_domain/$match_courseid/(default|supplemental)_?(\d*)\.(page|sequence)$}) {
+ my $prefix = $1;
+ my $subdir =$2;
+ if ($subdir eq '') {
+ $subdir = $prefix;
+ }
+ my (%addedmaps,%removefrommap,%removeparam,%hierarchy,%titles,%allmaps);
+ &contained_map_check($url,$folder,\%removefrommap,\%removeparam,\%addedmaps,
+ \%hierarchy,\%titles,\%allmaps);
+ if (ref($hierarchy{$url}) eq 'HASH') {
+ my ($nested,$nestednames);
+ &recurse_uploaded_maps($url,$subdir,\%hierarchy,\%titles,\$nested,\$nestednames);
+ $nested =~ s/\&$//;
+ $nestednames =~ s/\Q___&&&___\E$//;
+ if ($nested ne '') {
+ $addtoenv{'docs.markedcopy_nested_'.$suffix} = $nested;
+ }
+ if ($nestednames ne '') {
+ $addtoenv{'docs.markedcopy_nestednames_'.$suffix} = $nestednames;
+ }
}
}
}
+ if (@newpaste) {
+ $addtoenv{'docs.markedcopies'} = join(',',(@currpaste,@newpaste));
+ }
&Apache::lonnet::appenv(\%addtoenv);
delete($env{'form.markcopy'});
}
@@ -698,145 +795,200 @@ sub recurse_uploaded_maps {
sub print_paste_buffer {
my ($r,$container,$folder,$coursedom,$coursenum) = @_;
- return if (!defined($env{'docs.markedcopy_url'}));
+ return if (!defined($env{'docs.markedcopies'}));
- my ($is_external,$othercourse,$fromsupp,$is_uploaded_map,$parent);
- my $extension = (split(/\./,$env{'docs.markedcopy_url'}))[-1];
- if ($env{'docs.markedcopy_url'} =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//} ) {
- $is_external = 1;
+ unless (($env{'form.pastemarked'}) || ($env{'form.clearmarked'})) {
+ return if ($env{'docs.markedcopies'} eq '');
}
- my ($canpaste,$nopaste,$othercrs,$areachange,$is_uploaded_map);
- if ($folder =~ /^supplemental/) {
- $canpaste = &supp_pasteable($env{'docs.markedcopy_url'});
- unless ($canpaste) {
- $nopaste = &mt('Paste into Supplemental Content unavailable for this type of content.');
- }
- } else {
- $canpaste = 1;
- }
+ my @currpaste = split(/,/,$env{'docs.markedcopies'});
+ my ($pasteitems,@pasteable);
- if ($canpaste) {
- if ($env{'docs.markedcopy_url'} =~ m{^/uploaded/($match_domain)/($match_courseid)/(.+)$}) {
- my $srcdom = $1;
- my $srcnum = $2;
- my $rem = $3;
- 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).');
- }
- } else {
- $canpaste = 0;
- $nopaste = &mt('Paste from another course unavailable.')
- }
+# Construct identifiers for current contents of user's paste buffer
+ foreach my $suffix (@currpaste) {
+ next if ($suffix =~ /\D/);
+ my $cid = $env{'docs.markedcopy_crs_'.$suffix};
+ my $url = $env{'docs.markedcopy_url_'.$suffix};
+ if (($cid =~ /^$match_domain\_$match_courseid$/) &&
+ ($url ne '')) {
+ my ($is_external,$othercourse,$fromsupp,$is_uploaded_map,$parent,
+ $canpaste,$nopaste,$othercrs,$areachange);
+ my $extension = (split(/\./,$env{'docs.markedcopy_url_'.$suffix}))[-1];
+ if ($url =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//} ) {
+ $is_external = 1;
}
- if ($rem =~ m{^(default|supplemental)_?(\d*)\.(?:page|sequence)$}) {
- my $prefix = $1;
- $parent = $2;
- if ($folder !~ /^\Q$prefix\E/) {
- $areachange = 1;
- }
- $is_uploaded_map = 1;
+ if ($folder =~ /^supplemental/) {
+ $canpaste = &supp_pasteable($env{'docs.markedcopy_url_'.$suffix});
+ unless ($canpaste) {
+ $nopaste = &mt('Paste into Supplemental Content unavailable.');
+ }
+ } else {
+ $canpaste = 1;
}
- }
- }
-
- $r->print(''
- .''.&mt('Clipboard').' ');
- my ($type,$buffer);
- if ($is_external) {
- $type = &mt('External Resource');
- $buffer = $type.': '.
- &LONCAPA::map::qtescape($env{'docs.markedcopy_title'}).' ('.
- &LONCAPA::map::qtescape($env{'docs.markedcopy_url'}).')';
- } else {
- my $icon = &Apache::loncommon::icon($extension);
- if ($extension eq 'sequence' &&
- $env{'docs.markedcopy_url'} =~ m{/default_\d+\.sequence$ }x) {
- $icon = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL'));
- $icon .= '/navmap.folder.closed.gif';
- }
- $icon = ' ';
- $buffer = $icon.$type.': '. &Apache::loncommon::parse_supplemental_title(&LONCAPA::map::qtescape($env{'docs.markedcopy_title'}));
- }
- if ($canpaste) {
- $r->print('');
+ $buttons .= ' '.
+ ' ';
+ $form_end = '';
+ } else {
+ $pasteitems = &mt('Clipboard is empty');
+ }
+ $r->print($form_start
+ .''
+ .''.&mt('Clipboard').(' ' x2).$buttons.' '
+ .$pasteitems
+ .' '
+ .$form_end);
+}
+
+sub paste_options {
+ my ($suffix,$is_uploaded_map,$parent) = @_;
+ my ($copytext,$movetext);
+ if ($is_uploaded_map) {
+ $copytext = &mt('Copy to new folder');
+ $movetext = &mt('Move old');
+ } elsif ($env{'docs.markedcopy_url_'.$suffix} =~ /bulletinboard$/) {
+ $copytext = &mt('Copy to new board');
+ $movetext = &mt('Move (not posts)');
+ } elsif ($env{'docs.markedcopy_url_'.$suffix} =~ /smppg$/) {
+ $copytext = &mt('Copy to new page');
+ $movetext = &mt('Move');
} else {
- $r->print(&mt('Paste buffer contains:').' '.$buffer.
- ''.$nopaste.'
');
+ $copytext = &mt('Copy to new file');
+ $movetext = &mt('Move');
+ }
+ my $output = ' '.
+ ' '.
+ ''.(' 'x 4).
+ ''.
+ ' '.
+ $copytext.' '.(' 'x2).' '.
+ '
'.
+ ' '.
+ $movetext.' ';
+ if (($is_uploaded_map) && ($env{'docs.markedcopy_nested_'.$suffix})) {
+ $output .= '
'.&mt('Folder to paste contains sub-folders').
+ ' ';
+ my @pastemaps = split(/\&/,$env{'docs.markedcopy_nested_'.$suffix});
+ my @titles = split(/\Q___&&&___\E/,$env{'docs.markedcopy_nestednames_'.$suffix});
+ my $lastdir = $parent;
+ my %depths = (
+ $lastdir => 0,
+ );
+ my (%display,%deps);
+ for (my $i=0; $i<@pastemaps; $i++) {
+ ($lastdir,my $subfolderstr) = split(/\:/,$pastemaps[$i]);
+ my ($namedir,$esctitlestr) = split(/\:/,$titles[$i]);
+ my @subfolders = split(/,/,$subfolderstr);
+ $deps{$lastdir} = \@subfolders;
+ my @subfoldertitles = map { &unescape($_); } split(/,/,$esctitlestr);
+ my $depth = $depths{$lastdir} + 1;
+ my $offset = int($depth * 4);
+ my $indent = (' ' x $offset);
+ for (my $j=0; $j<@subfolders; $j++) {
+ $depths{$subfolders[$j]} = $depth;
+ $display{$subfolders[$j]} =
+ ''.$indent.$subfoldertitles[$j].' '.
+ ''.
+ ' '.&mt('Copy to new').' '.(' ' x2).
+ ''.
+ ' '.
+ &mt('Move old').' '.
+ ' ';
+ }
+ }
+ &recurse_print(\$output,$parent,\%deps,\%display);
+ $output .= '
';
}
- $r->print('');
+ $output .= '
';
+ return $output;
}
sub recurse_print {
- my ($r,$dir,$deps,$display) = @_;
- $r->print($display->{$dir}."\n");
+ my ($outputref,$dir,$deps,$display) = @_;
+ $$outputref .= $display->{$dir}."\n";
if (ref($deps->{$dir}) eq 'ARRAY') {
foreach my $subdir (@{$deps->{$dir}}) {
- &recurse_print($r,$subdir,$deps,$display);
+ &recurse_print($outputref,$subdir,$deps,$display);
}
}
}
@@ -855,22 +1007,34 @@ sub supp_pasteable {
sub paste_popup_js {
my %lt = &Apache::lonlocal::texthash(
- show => 'Show Paste Options',
- hide => 'Hide Paste Options',
+ show => 'Show Options',
+ hide => 'Hide Options',
);
return <<"END";
-function showPasteOptions() {
- document.getElementById('pasteoptions').style.display='block';
- document.getElementById('pasteoptions').style.textAlign='left';
- document.getElementById('pasteoptions').style.textFace='normal';
- document.getElementById('pasteoptionstext').innerHTML =' ';
+function showPasteOptions(suffix) {
+ document.getElementById('pasteoptions_'+suffix).style.display='block';
+ document.getElementById('pasteoptionstext_'+suffix).innerHTML = ' ';
+ return;
+}
+
+function hidePasteOptions(suffix) {
+ document.getElementById('pasteoptions_'+suffix).style.display='none';
+ document.getElementById('pasteoptionstext_'+suffix).innerHTML =' ';
return;
}
-function hidePasteOptions() {
- document.getElementById('pasteoptions').style.display='none';
- document.getElementById('pasteoptionstext').innerHTML ='';
+function showOptions(caller,suffix) {
+ if (document.getElementById('pasteoptionstext_'+suffix)) {
+ if (caller.checked) {
+ document.getElementById('pasteoptionstext_'+suffix).innerHTML =' ';
+ } else {
+ document.getElementById('pasteoptionstext_'+suffix).innerHTML ='';
+ }
+ if (document.getElementById('pasteoptions_'+suffix)) {
+ document.getElementById('pasteoptions_'+suffix).style.display='none';
+ }
+ }
return;
}
@@ -882,249 +1046,423 @@ END
sub do_paste_from_buffer {
my ($coursenum,$coursedom,$folder,$container,$errors) = @_;
+# Array of items in paste buffer
+ my (@currpaste,%pastebuffer,%allerrors);
+ @currpaste = split(/,/,$env{'docs.markedcopies'});
+
# Early out if paste buffer is empty
- if (!$env{'form.pastemarked'}) {
+ if (@currpaste == 0) {
return ();
+ }
+ map { $pastebuffer{$_} = 1; } @currpaste;
+
+# Array of items selected items to paste
+ my @reqpaste = &Apache::loncommon::get_env_multiple('form.pasting');
+
+# Early out if nothing selected to paste
+ if (@reqpaste == 0) {
+ return();
+ }
+ my @topaste;
+ foreach my $suffix (@reqpaste) {
+ next if ($suffix =~ /\D/);
+ next unless (exists($pastebuffer{$suffix}));
+ push(@topaste,$suffix);
}
-# Supplemental content may only include certain types of content
-# Early out if pasted content is not supported in Supplemental area
- if ($folder =~ /^supplemental/) {
- unless (&supp_pasteable($env{'docs.markedcopy_url'})) {
- return (&mt('Paste failed: content type is not supported within Supplemental Content'));
- }
+# Early out if nothing available to paste
+ if (@topaste == 0) {
+ return();
}
-# Prepare to paste resource at end of list
- my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url'});
- my $title=&LONCAPA::map::qtescape($env{'docs.markedcopy_title'});
+ my (%msgs,%before,%after,@dopaste,%is_map,%notinsupp,%notincrs,%duplicate,
+ %prefixchg,%srcdom,%srcnum,%marktomove,$save_err,$lockerrors,$allresult,
+ %msgs);
- my ($is_map,$srcdom,$srcnum,$prefixchg,%before,%after,%mapchanges,%tomove);
- if ($url=~/\.(page|sequence)$/) {
- $is_map = 1;
- }
- if ($url =~ m{^/uploaded/($match_domain)/($match_courseid)/([^/]+)}) {
- $srcdom = $1;
- $srcnum = $2;
- my $oldprefix = $3;
+ foreach my $suffix (@topaste) {
+ my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url_'.$suffix});
+# Supplemental content may only include certain types of content
+# Early out if pasted content is not supported in Supplemental area
+ if ($folder =~ /^supplemental/) {
+ unless (&supp_pasteable($url)) {
+ $notinsupp{$suffix} = 1;
+ next;
+ }
+ }
+ if ($url =~ m{^/uploaded/($match_domain)/($match_courseid)/}) {
+ my $srcd = $1;
+ my $srcn = $2;
# 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 (($srcdom ne $coursedom) || ($srcnum ne $coursenum)) {
- unless ($env{"user.priv.cm./$srcdom/$srcnum"} =~ /\Q:mdc&F\E/) {
- return (&mt('Paste failed: Item is from a different course which you do not have rights to edit.'));
+ 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;
}
-# 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.
- if (($folder =~ /^supplemental/) && (($oldprefix =~ /^default/) || ($oldprefix eq 'docs'))) {
- $prefixchg = 1;
- %before = ( map => 'default',
- doc => 'docs');
- %after = ( map => 'supplemental',
- doc => 'supplemental' );
- } elsif (($folder =~ /^default/) && ($oldprefix =~ /^supplemental/)) {
- $prefixchg = 1;
- %before = ( map => 'supplemental',
- doc => 'supplemental');
- %after = ( map => 'default',
- doc => 'docs');
+
+ push(@dopaste,$suffix);
+ if ($url=~/\.(page|sequence)$/) {
+ $is_map{$suffix} = 1;
}
+ if ($url =~ m{^/uploaded/$match_domain/$match_courseid/([^/]+)}) {
+ 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.
+ if (($folder =~ /^supplemental/) && (($oldprefix =~ /^default/) || ($oldprefix eq 'docs'))) {
+ $prefixchg{$suffix} = 'docstosupp';
+ } elsif (($folder =~ /^default/) && ($oldprefix =~ /^supplemental/)) {
+ $prefixchg{$suffix} = 'supptodocs';
+ }
+
# If pasting an uploaded map, get list of contained uploaded maps.
- my @nested;
- if ($env{'docs.markedcopy_nested'}) {
- my ($type) = ($oldprefix =~ /^(default|supplemental)/);
- my @items = split(/\&/,$env{'docs.markedcopy_nested'});
- my @deps = map { /\d+:([\d,]+$)/ } @items;
- foreach my $dep (@deps) {
- if ($dep =~ /,/) {
- push(@nested,split(/,/,$dep));
- } else {
- push(@nested,$dep);
+ if ($env{'docs.markedcopy_nested_'.$suffix}) {
+ my @nested;
+ my ($type) = ($oldprefix =~ /^(default|supplemental)/);
+ my @items = split(/\&/,$env{'docs.markedcopy_nested_'.$suffix});
+ my @deps = map { /\d+:([\d,]+$)/ } @items;
+ foreach my $dep (@deps) {
+ if ($dep =~ /,/) {
+ push(@nested,split(/,/,$dep));
+ } else {
+ push(@nested,$dep);
+ }
}
- }
- foreach my $item (@nested) {
- if ($env{'form.docs.markedcopy_'.$item} eq 'move') {
- $tomove{$type.'_'.$item} = 1;
+ foreach my $item (@nested) {
+ if ($env{'form.docs.markedcopy_'.$suffix.'_'.$item} eq 'move') {
+ push(@{$marktomove{$suffix}},$type.'_'.$item);
+ }
}
}
}
}
+# Early out if nothing available to paste
+ if (@dopaste == 0) {
+ return ();
+ }
+
+# Populate message hash and hashes used for main content <=> supplemental content
+# changes
+
+ %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.',
+ duplicate => 'Paste failed: only one instance of a particular published sequence or page is allowed within each course.',
+ );
+
+ %before = (
+ docstosupp => {
+ map => 'default',
+ doc => 'docs',
+ },
+ supptodocs => {
+ map => 'supplemental',
+ doc => 'supplemental',
+ },
+ );
+
+ %after = (
+ docstosupp => {
+ map => 'supplemental',
+ doc => 'supplemental'
+ },
+ supptodocs => {
+ map => 'default',
+ doc => 'docs',
+ },
+ );
+
+# 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);
+
+# Loop over the items to paste
+ foreach my $suffix (@dopaste) {
# Maps need to be copied first
- my ($oldurl,%removefrommap,%removeparam,%addedmaps,%rewrites,%retitles,%copies,
- %dbcopies,%zombies,%params,%docmoves,%mapmoves,%newsubdir,%newurls);
- $oldurl = $url;
- if ($is_map) {
- if ($folder =~ /^default/) {
- my $lastchange = &Apache::lonnet::get_coursechange($coursedom,$coursenum);
- if ($lastchange > $env{'request.course.tied'}) {
- &reinit_role($coursedom,$coursenum,$env{"course.$env{'request.course.id'}.home"});
- }
- }
+ my (%removefrommap,%removeparam,%addedmaps,%rewrites,%retitles,%copies,
+ %dbcopies,%zombies,%params,%docmoves,%mapmoves,%mapchanges,%newsubdir,
+ %newurls,%tomove);
+ 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 $oldurl = $url;
+ if ($is_map{$suffix}) {
# If pasting a map, check if map contains other maps
- my (%allmaps,%hierarchy,%titles);
- if ($folder =~ /^default/) {
- my $navmap = Apache::lonnavmaps::navmap->new();
- if (defined($navmap)) {
- foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_map() },1,0,1)) {
- $allmaps{$res->src()} = 1;
- }
- }
- }
- &contained_map_check($url,$folder,\%removefrommap,\%removeparam,
- \%addedmaps,\%hierarchy,\%titles,\%allmaps);
- if ($url=~ m{^/uploaded/}) {
- my $newurl;
- unless ($env{'form.docs.markedcopy_options'} eq 'move') {
- ($newurl,my $error) =
- &get_newmap_url($url,$folder,$prefixchg,$coursedom,$coursenum,
- $srcdom,$srcnum,\$title,\%allmaps,\%newurls);
- if ($error) {
- return ($error);
- }
- if ($newurl ne '') {
- if ($newurl ne $url) {
- if ($newurl =~ /(?:default|supplemental)_(\d+).(?:sequence|page)$/) {
- $newsubdir{$url} = $1;
+ my (%hierarchy,%titles);
+ &contained_map_check($url,$folder,\%removefrommap,\%removeparam,
+ \%addedmaps,\%hierarchy,\%titles,$allmaps);
+ if ($url=~ m{^/uploaded/}) {
+ my $newurl;
+ unless ($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') {
+ ($newurl,my $error) =
+ &get_newmap_url($url,$folder,$prefixchg{$suffix},$coursedom,
+ $coursenum,$srcdom{$suffix},$srcnum{$suffix},
+ \$title,$allmaps,\%newurls);
+ if ($error) {
+ $allerrors{$suffix} = $error;
+ next;
+ }
+ if ($newurl ne '') {
+ if ($newurl ne $url) {
+ if ($newurl =~ /(?:default|supplemental)_(\d+).(?:sequence|page)$/) {
+ $newsubdir{$url} = $1;
+ }
+ $mapchanges{$url} = 1;
}
- $mapchanges{$url} = 1;
+ }
+ }
+ if (($srcdom{$suffix} ne $coursedom) ||
+ ($srcnum{$suffix} ne $coursenum) ||
+ ($prefixchg{$suffix}) || (($newurl ne '') && ($newurl ne $url))) {
+ unless (&url_paste_fixups($url,$folder,$prefixchg{$suffix},
+ $coursedom,$coursenum,$srcdom{$suffix},
+ $srcnum{$suffix},$allmaps,\%rewrites,
+ \%retitles,\%copies,\%dbcopies,
+ \%zombies,\%params,\%mapmoves,
+ \%mapchanges,\%tomove,\%newsubdir,
+ \%newurls)) {
+ $mapmoves{$url} = 1;
+ }
+ $url = $newurl;
+ } elsif ($env{'docs.markedcopy_nested_'.$suffix}) {
+ &url_paste_fixups($url,$folder,$prefixchg{$suffix},$coursedom,
+ $coursenum,$srcdom{$suffix},$srcnum{$suffix},
+ $allmaps,\%rewrites,\%retitles,\%copies,\%dbcopies,
+ \%zombies,\%params,\%mapmoves,\%mapchanges,
+ \%tomove,\%newsubdir,\%newurls);
+ }
+ } elsif ($url=~m {^/res/}) {
+# published map can only exists 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/) {
+ if ((ref($allmaps) eq 'HASH') && ($allmaps->{$url})) {
+ $duplicate{$suffix} = 1;
+ next;
}
}
}
- if (($srcdom ne $coursedom) || ($srcnum ne $coursenum) || ($prefixchg) ||
- (($newurl ne '') && ($newurl ne $url))) {
- unless (&url_paste_fixups($url,$folder,$prefixchg,$coursedom,$coursenum,
- \%allmaps,\%rewrites,\%retitles,\%copies,\%dbcopies,
- \%zombies,\%params,\%mapmoves,\%mapchanges,\%tomove,
- \%newsubdir,\%newurls)) {
- $mapmoves{$url} = 1;
- }
- $url = $newurl;
- } elsif ($env{'docs.markedcopy_nested'}) {
- &url_paste_fixups($url,$folder,$prefixchg,$coursedom,$coursenum,\%allmaps,\%rewrites,
- \%retitles,\%copies,\%dbcopies,\%zombies,\%params,\%mapmoves,
- \%mapchanges,\%tomove,\%newsubdir,\%newurls);
- }
- } elsif ($url=~m {^/res/}) {
-# published maps can only exists once, so remove it from paste buffer when done
- &Apache::lonnet::delenv('docs.markedcopy');
-# if pasting published map (main content are only) check map is not already in course
- if ($folder =~ /^default/) {
- if ($allmaps{$url}) {
- return (&mt('Paste failed: only one instance of a particular published sequence or page is allowed within each course.'));
+ }
+ if ($url=~ m{/(bulletinboard|smppg)$}) {
+ my $prefix = $1;
+ #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') {
+ my (%lockerr,$msg);
+ my ($newurl,$result,$errtext) =
+ &dbcopy(\%info,$coursedom,$coursenum,\%lockerr);
+ if ($result eq 'ok') {
+ $url = $newurl;
+ $title=&mt('Copy of').' '.$title;
+ } else {
+ if ($prefix eq 'smppg') {
+ $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 bulletin board.').' '.$errtext;
+ }
+ $results{$suffix} = $result;
+ $msgerrs{$suffix} = $msg;
+ $lockerrs{$suffix} = $lockerr{$prefix};
+ next;
+ }
+ if ($lockerr{$prefix}) {
+ $lockerrs{$suffix} = $lockerr{$prefix};
}
}
}
- }
- if ($url=~ m{/smppg$}) {
- my $db_name = &Apache::lonsimplepage::get_db_name($url);
- if ($db_name =~ /^smppage_/) {
- #simple pages, need to copy the db contents to a new one.
- my %contents=&Apache::lonnet::dump($db_name,$coursedom,$coursenum);
- my $now = time();
- $db_name =~ s{_\d*$ }{_$now}x;
- my $dbresult=&Apache::lonnet::put($db_name,\%contents,
- $coursedom,$coursenum);
- if ($dbresult eq 'ok') {
- $url =~ s{/(\d*)/smppg$ }{/$now/smppg}x;
- $title=&mt('Copy of').' '.$title;
- } else {
- return (&mt('Paste failed: An error occurred when copying the simple page.'));
+ $title = &LONCAPA::map::qtunescape($title);
+ my $ext='false';
+ if ($url=~m{^http(|s)://}) { $ext='true'; }
+ if ($env{'docs.markedcopy_supplemental_'.$suffix}) {
+ if ($folder !~ /^supplemental/) {
+ (undef,undef,$title) =
+ &Apache::loncommon::parse_supplemental_title($env{'docs.markedcopy_supplemental_'.$suffix});
+ }
+ } else {
+ if ($folder=~/^supplemental/) {
+ $title=time.'___&&&___'.$env{'user.name'}.'___&&&___'.
+ $env{'user.domain'}.'___&&&___'.$title;
}
}
- }
- $title = &LONCAPA::map::qtunescape($title);
- my $ext='false';
- if ($url=~m{^http(|s)://}) { $ext='true'; }
- $url = &LONCAPA::map::qtunescape($url);
# For uploaded files (excluding pages/sequences) path in copied file is changed
# if paste is from Main to Supplemental (or vice versa), or if pasting between
# courses.
- my $newidx;
- unless ($is_map) {
+ unless ($is_map{$suffix}) {
+ my $newidx;
# Now insert the URL at the bottom
- $newidx = &LONCAPA::map::getresidx($url);
- if ($url =~ m{^/uploaded/$match_domain/$match_courseid/(?:docs|supplemental)/(.+)$}) {
- my $relpath = $1;
- if ($relpath ne '') {
- my ($prefix,$subdir,$rem) = ($relpath =~ m{^(default|\d+)/(\d+)/(.+)$});
- my ($newloc,$newdocsdir) = ($folder =~ /^(default|supplemental)_?(\d*)/);
- my $newprefix = $newloc;
- if ($newloc eq 'default') {
- $newprefix = 'docs';
- }
- if ($newdocsdir eq '') {
- $newdocsdir = 'default';
- }
- if (($prefixchg) || ($srcdom ne $coursedom) || ($srcnum ne $coursenum)) {
- my $newpath = "$newprefix/$newdocsdir/$newidx/$rem";
- $url =
- &Apache::lonclonecourse::writefile($env{'request.course.id'},$newpath,
- &Apache::lonnet::getfile($oldurl));
- if ($url eq '/adm/notfound.html') {
- return (&mt('Paste failed: an error occurred saving the file.'));
- } else {
- my ($newsubpath) = ($newpath =~ m{^(.*/)[^/]*$});
- $newsubpath =~ s{/+$}{/};
- $docmoves{$oldurl} = $newsubpath;
+ $newidx = &LONCAPA::map::getresidx(&LONCAPA::map::qtunescape($url));
+ if ($url =~ m{^/uploaded/$match_domain/$match_courseid/(?:docs|supplemental)/(.+)$}) {
+ my $relpath = $1;
+ if ($relpath ne '') {
+ my ($prefix,$subdir,$rem) = ($relpath =~ m{^(default|\d+)/(\d+)/(.+)$});
+ my ($newloc,$newdocsdir) = ($folder =~ /^(default|supplemental)_?(\d*)/);
+ my $newprefix = $newloc;
+ if ($newloc eq 'default') {
+ $newprefix = 'docs';
+ }
+ if ($newdocsdir eq '') {
+ $newdocsdir = 'default';
+ }
+ if (($prefixchg{$suffix}) ||
+ ($srcdom{$suffix} ne $coursedom) ||
+ ($srcnum{$suffix} ne $coursenum) ||
+ ($env{'form.docs.markedcopy_options_'.$suffix} ne 'move')) {
+ my $newpath = "$newprefix/$newdocsdir/$newidx/$rem";
+ $url =
+ &Apache::lonclonecourse::writefile($env{'request.course.id'},$newpath,
+ &Apache::lonnet::getfile($oldurl));
+ if ($url eq '/adm/notfound.html') {
+ $msgs{$suffix} = &mt('Paste failed: an error occurred saving the file.');
+ next;
+ } else {
+ my ($newsubpath) = ($newpath =~ m{^(.*/)[^/]*$});
+ $newsubpath =~ s{/+$}{/};
+ $docmoves{$oldurl} = $newsubpath;
+ }
}
}
}
- }
- }
-# Apply any changes to maps, or copy dependencies for uploaded HTML pages
- my ($result,$save_err);
- $result =
- &apply_fixups($folder,$is_map,$prefixchg,$coursedom,$coursenum,$oldurl,
- $url,\%removefrommap,\%removeparam,\%rewrites,\%retitles,
- \%copies,\%dbcopies,\%zombies,\%params,\%docmoves,
- \%mapmoves,\%newsubdir,$errors,\%before,\%after);
- if ($result eq 'ok') {
- if ($is_map) {
- my ($errtext,$fatal) = &mapread($coursenum,$coursedom,
- $folder.'.'.$container);
- return $errtext if ($fatal);
-
- if ($#LONCAPA::map::order<1) {
- my $idx=&LONCAPA::map::getresidx();
- if ($idx<=0) { $idx=1; }
- $LONCAPA::map::order[0]=$idx;
- $LONCAPA::map::resources[$idx]='';
- }
- $newidx = &LONCAPA::map::getresidx($url);
- }
- if ($env{'docs.markedcopy_supplemental'}) {
- if ($folder !~ /^supplemental/) {
- (undef,undef,$title) =
- &Apache::loncommon::parse_supplemental_title($env{'docs.markedcopy_supplemental'});
- }
- } else {
- if ($folder=~/^supplemental/) {
- $title=time.'___&&&___'.$env{'user.name'}.'___&&&___'.
- $env{'user.domain'}.'___&&&___'.$title;
+ $LONCAPA::map::resources[$newidx]=$title.':'.&LONCAPA::map::qtunescape($url).
+ ':'.$ext.':normal:res';
+ push(@LONCAPA::map::order,$newidx);
+# Store the result
+ my ($errtext,$fatal) =
+ &storemap($coursenum,$coursedom,$folder.'.'.$container,1);
+ if ($fatal) {
+ $save_err .= $errtext;
+ $allresult = 'fail';
}
}
- $LONCAPA::map::resources[$newidx]= $title.':'.$url.':'.$ext.':normal:res';
- push(@LONCAPA::map::order, $newidx);
+
+# Apply any changes to maps, or copy dependencies for uploaded HTML pages
+ unless ($allresult eq 'fail') {
+ my %updated = (
+ rewrites => \%rewrites,
+ zombies => \%zombies,
+ removefrommap => \%removefrommap,
+ removeparam => \%removeparam,
+ dbcopies => \%dbcopies,
+ retitles => \%retitles,
+ );
+ my %info = (
+ newsubdir => \%newsubdir,
+ params => \%params,
+ );
+ if ($prefixchg{$suffix}) {
+ $info{'before'} = $before{$prefixchg{$suffix}};
+ $info{'after'} = $after{$prefixchg{$suffix}};
+ }
+ my %moves = (
+ copies => \%copies,
+ docmoves => \%docmoves,
+ mapmoves => \%mapmoves,
+ );
+ (my $result,$msgs{$suffix},my $lockerror) =
+ &apply_fixups($folder,$is_map{$suffix},$coursedom,$coursenum,$errors,
+ \%updated,\%info,\%moves,$prefixchg{$suffix},$oldurl,
+ $url,'paste');
+ $lockerrors .= $lockerror;
+ if ($result eq 'ok') {
+ if ($is_map{$suffix}) {
+ my ($errtext,$fatal) = &mapread($coursenum,$coursedom,
+ $folder.'.'.$container);
+ if ($fatal) {
+ $allresult = 'failread';
+ } else {
+ if ($#LONCAPA::map::order<1) {
+ my $idx=&LONCAPA::map::getresidx();
+ if ($idx<=0) { $idx=1; }
+ $LONCAPA::map::order[0]=$idx;
+ $LONCAPA::map::resources[$idx]='';
+ }
+ my $newidx = &LONCAPA::map::getresidx(&LONCAPA::map::qtunescape($url));
+ $LONCAPA::map::resources[$newidx]=$title.':'.&LONCAPA::map::qtunescape($url).
+ ':'.$ext.':normal:res';
+ push(@LONCAPA::map::order,$newidx);
# Store the result
- my ($errtext,$fatal) =
- &storemap($coursenum,$coursedom,$folder.'.'.$container,1);
- if ($fatal) {
- $save_err = $errtext;
+ my ($errtext,$fatal) =
+ &storemap($coursenum,$coursedom,$folder.'.'.$container,1);
+ if ($fatal) {
+ $save_err .= $errtext;
+ $allresult = 'failstore';
+ }
+ }
+ }
+ if ($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') {
+ push(@toclear,$suffix);
+ }
+ }
}
}
+ &clear_from_buffer(\@toclear,\@currpaste);
+ my $msgsarray;
+ foreach my $suffix (keys(%msgs)) {
+ if (ref($msgs{$suffix}) eq 'ARRAY') {
+ $msgsarray .= join(',',@{$msgs{$suffix}});
+ }
+ }
+ return ($allresult,$save_err,$msgsarray,$lockerrors);
+}
- if ($env{'form.docs.markedcopy_options'} eq 'move') {
- &Apache::lonnet::delenv('docs.markedcopy');
- &Apache::lonnet::delenv('docs.markedcopy_nested');
- &Apache::lonnet::delenv('docs.markedcopy_nestednames');
+sub do_buffer_empty {
+ my @currpaste = split(/,/,$env{'docs.markedcopies'});
+ if (@currpaste == 0) {
+ return &mt('Clipboard is already empty');
+ }
+ my @toclear = &Apache::loncommon::get_env_multiple('form.pasting');
+ if (@toclear == 0) {
+ return &mt('Nothing selected to clear from clipboard');
}
- return ($result,$save_err);
+ my $numdel = &clear_from_buffer(\@toclear,\@currpaste);
+ if ($numdel) {
+ return &mt('[quant,_1,item] cleared from clipboard',$numdel);
+ } else {
+ return &mt('Clipboard unchanged');
+ }
+ return;
+}
+
+sub clear_from_buffer {
+ my ($toclear,$currpaste) = @_;
+ return unless ((ref($toclear) eq 'ARRAY') && (ref($currpaste) eq 'ARRAY'));
+ my %pastebuffer;
+ map { $pastebuffer{$_} = 1; } @{$currpaste};
+ my $numdel = 0;
+ foreach my $suffix (@{$toclear}) {
+ next if ($suffix =~ /\D/);
+ next unless (exists($pastebuffer{$suffix}));
+ my $regexp = 'docs.markedcopy_[a-z]+_'.$suffix;
+ if (&Apache::lonnet::delenv($regexp,1) eq 'ok') {
+ delete($pastebuffer{$suffix});
+ $numdel ++;
+ }
+ }
+ my $newbuffer = join(',',sort(keys(%pastebuffer)));
+ &Apache::lonnet::appenv({'docs.markedcopies' => $newbuffer});
+ return $numdel;
}
sub get_newmap_url {
@@ -1188,20 +1526,96 @@ sub get_newmap_url {
}
sub dbcopy {
- my ($url,$coursedom,$coursenum) = @_;
- if ($url=~ m{/smppg$}) {
- my $db_name = &Apache::lonsimplepage::get_db_name($url);
- if ($db_name =~ /^smppage_/) {
- #simple pages, need to copy the db contents to a new one.
- my %contents=&Apache::lonnet::dump($db_name,$coursedom,$coursenum);
- my $now = time();
- $db_name =~ s{_\d*$ }{_$now}x;
- my $result=&Apache::lonnet::put($db_name,\%contents,
- $coursedom,$coursenum);
- $url =~ s{/(\d*)/smppg$ }{/$now/smppg}x;
+ my ($dbref,$coursedom,$coursenum,$lockerrorsref) = @_;
+ my ($url,$result,$errtext);
+ my $url = $dbref->{'src'};
+ if (ref($dbref) eq 'HASH') {
+ if ($url =~ m{/(smppg|bulletinboard)$}) {
+ my $prefix = $1;
+ if (($dbref->{'cdom'} =~ /^$match_domain$/) &&
+ ($dbref->{'cnum'} =~ /^$match_courseid$/)) {
+ my $db_name;
+ my $marker = (split(m{/},$url))[4];
+ $marker=~s/\D//g;
+ if ($dbref->{'src'} =~ m{/smppg$}) {
+ $db_name =
+ &Apache::lonsimplepage::get_db_name($url,$marker,
+ $dbref->{'cdom'},
+ $dbref->{'cnum'});
+ } else {
+ $db_name = 'bulletinpage_'.$marker;
+ }
+ my ($suffix,$freedlock,$error) =
+ &Apache::lonnet::get_timebased_id($prefix,'num','templated',
+ $coursedom,$coursenum,
+ 'concat');
+ if (!$suffix) {
+ if ($prefix eq 'smppg') {
+ $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a simple page [_1].',$url);
+ } else {
+ $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a bulletin board [_1].',$url);
+ }
+ if ($error) {
+ $errtext .= ' '.$error;
+ }
+ } else {
+ #need to copy the db contents to a new one.
+ my %contents=&Apache::lonnet::dump($db_name,
+ $dbref->{'cdom'},
+ $dbref->{'cnum'});
+ if (exists($contents{'uploaded.photourl'})) {
+ my $photo = $contents{'uploaded.photourl'};
+ my ($subdir,$fname) =
+ ($photo =~ m{^/uploaded/$match_domain/$match_courseid/+(bulletin|simplepage)/(?:|\d+/)([^/]+)$});
+ my $newphoto;
+ if ($fname ne '') {
+ my $content = &Apache::lonnet::getfile($photo);
+ unless ($content eq '-1') {
+ $env{'form.'.$suffix.'.photourl'} = $content;
+ $newphoto =
+ &Apache::lonnet::finishuserfileupload($coursenum,$coursedom,$suffix.'.photourl',"$subdir/$suffix/$fname");
+ delete($env{'form.'.$suffix.'.photourl'});
+ }
+ }
+ if ($newphoto =~ m{^/uploaded/}) {
+ $contents{'uploaded.photourl'} = $newphoto;
+ }
+ }
+ $db_name =~ s{_\d*$ }{_$suffix}x;
+ $result=&Apache::lonnet::put($db_name,\%contents,
+ $coursedom,$coursenum);
+ if ($result eq 'ok') {
+ $url =~ s{/(\d*)/(smppg|bulletinboard)$}{/$suffix/$2}x;
+ }
+ }
+ if (($freedlock ne 'ok') && (ref($lockerrorsref) eq 'HASH')) {
+ $lockerrorsref->{$prefix} =
+ ''.
+ &mt('There was a problem removing a lockfile.');
+ if ($prefix eq 'smppg') {
+ $lockerrorsref->{$prefix} .=
+ &mt('This will prevent creation of additional simple pages in this course.');
+ } else {
+ $lockerrorsref->{$prefix} .= &mt('This will prevent creation of additional bulletin boards in this course.');
+ }
+ $lockerrorsref->{$prefix} .= &mt('Please contact the domain coordinator for your LON-CAPA domain.').'
';
+ }
+ }
+ } elsif ($url =~ m{/syllabus$}) {
+ if (($dbref->{'cdom'} =~ /^$match_domain$/) &&
+ ($dbref->{'cnum'} =~ /^$match_courseid$/)) {
+ if (($dbref->{'cdom'} ne $coursedom) ||
+ ($dbref->{'cnum'} ne $coursenum)) {
+ my %contents=&Apache::lonnet::dump('syllabus',
+ $dbref->{'cdom'},
+ $dbref->{'cnum'});
+ $result=&Apache::lonnet::put('syllabus',\%contents,
+ $coursedom,$coursenum);
+ }
+ }
}
}
- return $url;
+ return ($url,$result,$errtext);
}
sub uniqueness_check {
@@ -1257,7 +1671,7 @@ sub contained_map_check {
if (ref($removeparam->{$url}{$token->[2]->{'to'}}) eq 'ARRAY') {
push(@{$removeparam->{$url}{$token->[2]->{'to'}}},$token->[2]->{'name'});
} else {
- $removeparam->{$url}{$token->[2]->{'to'}} = [$token->[2]->{'name'}];
+ $removeparam->{$url}{$token->[2]->{'to'}} = [$token->[2]->{'name'}];
}
}
}
@@ -1266,18 +1680,10 @@ sub contained_map_check {
return;
}
-sub reinit_role {
- my ($cdom,$cnum,$chome) = @_;
- my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum");
- unless ($ferr) {
- &Apache::loncommon::update_content_constraints($cdom,$cnum,$chome,$cdom.'_'.$cnum);
- }
- return;
-}
-
sub url_paste_fixups {
- my ($oldurl,$folder,$prefixchg,$cdom,$cnum,$allmaps,$rewrites,$retitles,$copies,
- $dbcopies,$zombies,$params,$mapmoves,$mapchanges,$tomove,$newsubdir,$newurls) = @_;
+ my ($oldurl,$folder,$prefixchg,$cdom,$cnum,$fromcdom,$fromcnum,$allmaps,
+ $rewrites,$retitles,$copies,$dbcopies,$zombies,$params,$mapmoves,
+ $mapchanges,$tomove,$newsubdir,$newurls) = @_;
my $checktitle;
if (($prefixchg) &&
($oldurl =~ m{^/uploaded/$match_domain/$match_courseid/supplemental})) {
@@ -1304,13 +1710,13 @@ sub url_paste_fixups {
my $title = $token->[2]->{'title'};
if ($checktitle) {
if ($title =~ m{\d+\Q___&&&___\E$match_username\Q___&&&___\E$match_domain\Q___&&&___\E(.+)$}) {
- $retitles->{$oldurl}{$ressrc} = $id;
+ $retitles->{$oldurl}{$id} = $ressrc;
}
}
next if ($token->[2]->{'type'} eq 'external');
if ($token->[2]->{'type'} eq 'zombie') {
- next if ($skip);
- $zombies->{$oldurl}{$ressrc} = $id;
+ next if ($skip);
+ $zombies->{$oldurl}{$id} = $ressrc;
$changed = 1;
} elsif ($ressrc =~ m{^/uploaded/($match_domain)/($match_courseid)/(.+)$}) {
my $srcdom = $1;
@@ -1322,10 +1728,11 @@ sub url_paste_fixups {
my $prefix = $1;
$mapname = $prefix.$2;
if ($tomove->{$mapname}) {
- &url_paste_fixups($ressrc,$folder,$prefixchg,$cdom,$cnum,$allmaps,
- $rewrites,$retitles,$copies,$dbcopies,$zombies,
- $params,$mapmoves,$mapchanges,$tomove,$newsubdir,
- $newurls);
+ &url_paste_fixups($ressrc,$folder,$prefixchg,$cdom,$cnum,
+ $srcdom,$srcnum,$allmaps,$rewrites,
+ $retitles,$copies,$dbcopies,$zombies,
+ $params,$mapmoves,$mapchanges,$tomove,
+ $newsubdir,$newurls);
next;
} else {
($newurl,my $error) =
@@ -1341,30 +1748,41 @@ sub url_paste_fixups {
}
if (($srcdom ne $cdom) || ($srcnum ne $cnum) || ($prefixchg) ||
($mapchanges->{$oldurl}) || (($newurl ne '') && ($newurl ne $oldurl))) {
-
+
if ($rem =~ /^(default|supplemental)(_?\d*).(sequence|page)$/) {
- $rewrites->{$oldurl}{$ressrc} = $id;
+ $rewrites->{$oldurl}{$id} = $ressrc;
$mapchanges->{$ressrc} = 1;
- unless (&url_paste_fixups($ressrc,$folder,$prefixchg,$cdom,$cnum,$allmaps,
- $rewrites,$retitles,$copies,$dbcopies,$zombies,
- $params,$mapmoves,$mapchanges,$tomove,$newsubdir,
- $newurls)) {
+ unless (&url_paste_fixups($ressrc,$folder,$prefixchg,$cdom,
+ $cnum,$srcdom,$srcnum,$allmaps,
+ $rewrites,$retitles,$copies,$dbcopies,
+ $zombies,$params,$mapmoves,$mapchanges,
+ $tomove,$newsubdir,$newurls)) {
$mapmoves->{$ressrc} = 1;
}
$changed = 1;
} else {
- $rewrites->{$oldurl}{$ressrc} = $id;
+ $rewrites->{$oldurl}{$id} = $ressrc;
$copies->{$oldurl}{$ressrc} = $id;
$changed = 1;
}
}
- } elsif ($ressrc =~ m{^/adm/($match_domain)/($match_courseid)/(.+)$}) {
+ } elsif ($ressrc =~ m{^/adm/($match_domain)/($match_courseid)/.+$}) {
next if ($skip);
my $srcdom = $1;
my $srcnum = $2;
if (($srcdom ne $cdom) || ($srcnum ne $cnum)) {
- $rewrites->{$oldurl}{$ressrc} = $id;
- $dbcopies->{$oldurl}{$ressrc} = $id;
+ $rewrites->{$oldurl}{$id} = $ressrc;
+ $dbcopies->{$oldurl}{$id}{'src'} = $ressrc;
+ $dbcopies->{$oldurl}{$id}{'cdom'} = $srcdom;
+ $dbcopies->{$oldurl}{$id}{'cnum'} = $srcnum;
+ $changed = 1;
+ }
+ } elsif ($ressrc =~ m{^/adm/$match_domain/$match_username/\d+/(smppg|bulletinboard)$}) {
+ if (($fromcdom ne $cdom) || ($fromcnum ne $cnum) ||
+ ($env{'form.docs.markedcopy_options'} ne 'move')) {
+ $dbcopies->{$oldurl}{$id}{'src'} = $ressrc;
+ $dbcopies->{$oldurl}{$id}{'cdom'} = $fromcdom;
+ $dbcopies->{$oldurl}{$id}{'cnum'} = $fromcnum;
$changed = 1;
}
} elsif ($ressrc =~ m{^/public/($match_domain)/($match_courseid)/(.+)$}) {
@@ -1372,14 +1790,15 @@ sub url_paste_fixups {
my $srcdom = $1;
my $srcnum = $2;
if (($srcdom ne $cdom) || ($srcnum ne $cnum)) {
- $rewrites->{$oldurl}{$ressrc} = $id;
- $dbcopies->{$oldurl}{$ressrc} = $id;
+ $dbcopies->{$oldurl}{$id}{'src'} = $ressrc;
+ $dbcopies->{$oldurl}{$id}{'cdom'} = $srcdom;
+ $dbcopies->{$oldurl}{$id}{'cnum'} = $srcnum;
$changed = 1;
}
}
} elsif ($token->[1] eq 'param') {
next if ($skip);
- my $to = $token->[2]->{'to'};
+ my $to = $token->[2]->{'to'};
if ($to ne '') {
if (ref($params->{$oldurl}{$to}) eq 'ARRAY') {
push(@{$params->{$oldurl}{$to}},$token->[2]->{'name'});
@@ -1393,54 +1812,103 @@ sub url_paste_fixups {
}
sub apply_fixups {
- my ($folder,$is_map,$prefixchg,$cdom,$cnum,$oldurl,$url,$removefrommap,
- $removeparam,$rewrites,$retitles,$copies,$dbcopies,$zombies,$params,
- $docmoves,$mapmoves,$newsubdir,$errors,$before,$after) = @_;
- foreach my $key (keys(%{$copies}),keys(%{$docmoves})) {
+ my ($folder,$is_map,$cdom,$cnum,$errors,$updated,$info,$moves,$prefixchg,
+ $oldurl,$url,$caller) = @_;
+ my (%rewrites,%zombies,%removefrommap,%removeparam,%dbcopies,%retitles,
+ %params,%newsubdir,%before,%after,%copies,%docmoves,%mapmoves,@msgs,
+ %lockerrors,$lockmsg);
+ if (ref($updated) eq 'HASH') {
+ if (ref($updated->{'rewrites'}) eq 'HASH') {
+ %rewrites = %{$updated->{'rewrites'}};
+ }
+ if (ref($updated->{'zombies'}) eq 'HASH') {
+ %zombies = %{$updated->{'zombies'}};
+ }
+ if (ref($updated->{'removefrommap'}) eq 'HASH') {
+ %removefrommap = %{$updated->{'removefrommap'}};
+ }
+ if (ref($updated->{'removeparam'}) eq 'HASH') {
+ %removeparam = %{$updated->{'removeparam'}};
+ }
+ if (ref($updated->{'dbcopies'}) eq 'HASH') {
+ %dbcopies = %{$updated->{'dbcopies'}};
+ }
+ if (ref($updated->{'retitles'}) eq 'HASH') {
+ %retitles = %{$updated->{'retitles'}};
+ }
+ }
+ if (ref($info) eq 'HASH') {
+ if (ref($info->{'newsubdir'}) eq 'HASH') {
+ %newsubdir = %{$info->{'newsubdir'}};
+ }
+ if (ref($info->{'params'}) eq 'HASH') {
+ %params = %{$info->{'params'}};
+ }
+ if (ref($info->{'before'}) eq 'HASH') {
+ %before = %{$info->{'before'}};
+ }
+ if (ref($info->{'after'}) eq 'HASH') {
+ %after = %{$info->{'after'}};
+ }
+ }
+ if (ref($moves) eq 'HASH') {
+ if (ref($moves->{'copies'}) eq 'HASH') {
+ %copies = %{$moves->{'copies'}};
+ }
+ if (ref($moves->{'docmoves'}) eq 'HASH') {
+ %docmoves = %{$moves->{'docmoves'}};
+ }
+ if (ref($moves->{'mapmoves'}) eq 'HASH') {
+ %mapmoves = %{$moves->{'mapmoves'}};
+ }
+ }
+ foreach my $key (keys(%copies),keys(%docmoves)) {
my @allcopies;
- if (ref($copies->{$key}) eq 'HASH') {
- my %added;
- foreach my $innerkey (keys(%{$copies->{$key}})) {
- if (($innerkey ne '') && (!$added{$innerkey})) {
- push(@allcopies,$innerkey);
- $added{$innerkey} = 1;
+ if (exists($copies{$key})) {
+ if (ref($copies{$key}) eq 'HASH') {
+ my %added;
+ foreach my $innerkey (keys(%{$copies{$key}})) {
+ if (($innerkey ne '') && (!$added{$innerkey})) {
+ push(@allcopies,$innerkey);
+ $added{$innerkey} = 1;
+ }
}
+ undef(%added);
}
- undef(%added);
}
if ($key eq $oldurl) {
- if ((exists($docmoves->{$key}))) {
- unless (grep(/^\Q$oldurl\E/,@allcopies)) {
+ if ((exists($docmoves{$key}))) {
+ unless (grep(/^\Q$oldurl\E$/,@allcopies)) {
push(@allcopies,$oldurl);
}
}
}
if (@allcopies > 0) {
foreach my $item (@allcopies) {
- my ($relpath,$oldsubdir,$fname) =
+ my ($relpath,$oldsubdir,$fname) =
($item =~ m{^(/uploaded/$match_domain/$match_courseid/(?:docs|supplemental)/(default|\d+)/.*/)([^/]+)$});
if ($fname ne '') {
my $content = &Apache::lonnet::getfile($item);
unless ($content eq '-1') {
my $storefn;
- if (($key eq $oldurl) && (ref($docmoves) eq 'HASH') && (exists($docmoves->{$key}))) {
- $storefn = $docmoves->{$key};
+ if (($key eq $oldurl) && (exists($docmoves{$key}))) {
+ $storefn = $docmoves{$key};
} else {
$storefn = $relpath;
$storefn =~s{^/uploaded/$match_domain/$match_courseid/}{};
- if ($prefixchg) {
- $storefn =~ s/^\Q$before->{'doc'}\E/$after->{'doc'}/;
+ if ($prefixchg && $before{'doc'} && $after{'doc'}) {
+ $storefn =~ s/^\Q$before{'doc'}\E/$after{'doc'}/;
}
- if ($newsubdir->{$key}) {
- $storefn =~ s#^(docs|supplemental)/\Q$oldsubdir\E/#$1/$newsubdir->{$key}#;
+ if ($newsubdir{$key}) {
+ $storefn =~ s#^(docs|supplemental)/\Q$oldsubdir\E/#$1/$newsubdir{$key}/#;
}
}
©_dependencies($item,$storefn,$relpath,$errors,\$content);
- my $copyurl =
+ my $copyurl =
&Apache::lonclonecourse::writefile($env{'request.course.id'},
$storefn.$fname,$content);
if ($copyurl eq '/adm/notfound.html') {
- if ((ref($docmoves) eq 'HASH') && (exists($docmoves->{$oldurl}))) {
+ if (exists($docmoves{$oldurl})) {
return &mt('Paste failed: an error occurred copying the file.');
} elsif (ref($errors) eq 'HASH') {
$errors->{$item} = 1;
@@ -1451,14 +1919,14 @@ sub apply_fixups {
}
}
}
- foreach my $key (keys(%{$mapmoves})) {
+ foreach my $key (keys(%mapmoves)) {
my $storefn=$key;
$storefn=~s{^/uploaded/$match_domain/$match_courseid/}{};
- if ($prefixchg) {
- $storefn =~ s/^\Q$before->{'map'}\E/$after->{'map'}/;
+ if ($prefixchg && $before{'map'} && $after{'map'}) {
+ $storefn =~ s/^\Q$before{'map'}\E/$after{'map'}/;
}
- if ($newsubdir->{$key}) {
- $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir->{$key}/;
+ if ($newsubdir{$key}) {
+ $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/;
}
my $mapcontent = &Apache::lonnet::getfile($key);
if ($mapcontent eq '-1') {
@@ -1478,115 +1946,120 @@ sub apply_fixups {
}
my %updates;
if ($is_map) {
- foreach my $key (keys(%{$rewrites})) {
- $updates{$key} = 1;
- }
- foreach my $key (keys(%{$zombies})) {
- $updates{$key} = 1;
- }
- foreach my $key (keys(%{$removefrommap})) {
- $updates{$key} = 1;
- }
- foreach my $key (keys(%{$removeparam})) {
- $updates{$key} = 1;
- }
- foreach my $key (keys(%{$dbcopies})) {
- $updates{$key} = 1;
- }
- foreach my $key (keys(%{$retitles})) {
- $updates{$key} = 1;
+ if (ref($updated) eq 'HASH') {
+ foreach my $type (keys(%{$updated})) {
+ if (ref($updated->{$type}) eq 'HASH') {
+ foreach my $key (keys(%{$updated->{$type}})) {
+ $updates{$key} = 1;
+ }
+ }
+ }
}
foreach my $key (keys(%updates)) {
my (%torewrite,%toretitle,%toremove,%remparam,%currparam,%zombie,%newdb);
- if (ref($rewrites->{$key}) eq 'HASH') {
- %torewrite = %{$rewrites->{$key}};
+ if (ref($rewrites{$key}) eq 'HASH') {
+ %torewrite = %{$rewrites{$key}};
}
- if (ref($retitles->{$key}) eq 'HASH') {
- %toretitle = %{$retitles->{$key}};
+ if (ref($retitles{$key}) eq 'HASH') {
+ %toretitle = %{$retitles{$key}};
}
- if (ref($removefrommap->{$key}) eq 'HASH') {
- %toremove = %{$removefrommap->{$key}};
+ if (ref($removefrommap{$key}) eq 'HASH') {
+ %toremove = %{$removefrommap{$key}};
}
- if (ref($removeparam->{$key}) eq 'HASH') {
- %remparam = %{$removeparam->{$key}};
- }
- if (ref($zombies->{$key}) eq 'HASH') {
- %zombie = %{$zombies->{$key}};
- }
- if (ref($dbcopies->{$key}) eq 'HASH') {
- foreach my $item (keys(%{$dbcopies->{$key}})) {
- $newdb{$item} = &dbcopy($item);
+ if (ref($removeparam{$key}) eq 'HASH') {
+ %remparam = %{$removeparam{$key}};
+ }
+ if (ref($zombies{$key}) eq 'HASH') {
+ %zombie = %{$zombies{$key}};
+ }
+ if (ref($dbcopies{$key}) eq 'HASH') {
+ foreach my $idx (keys(%{$dbcopies{$key}})) {
+ if (ref($dbcopies{$key}{$idx}) eq 'HASH') {
+ my ($newurl,$result,$errtext) =
+ &dbcopy($dbcopies{$key}{$idx},$cdom,$cnum,\%lockerrors);
+ if ($result eq 'ok') {
+ $newdb{$idx} = $newurl;
+ } elsif (ref($errors) eq 'HASH') {
+ $errors->{$key} = 1;
+ }
+ push(@msgs,$errtext);
+ }
}
}
- if (ref($params->{$key}) eq 'HASH') {
- %currparam = %{$params->{$key}};
+ if (ref($params{$key}) eq 'HASH') {
+ %currparam = %{$params{$key}};
}
my ($errtext,$fatal) = &LONCAPA::map::mapread($key);
if ($fatal) {
- return $errtext;
+ return ($errtext);
}
for (my $i=0; $i<@LONCAPA::map::zombies; $i++) {
if (defined($LONCAPA::map::zombies[$i])) {
my ($title,$src,$ext,$type)=split(/\:/,$LONCAPA::map::zombies[$i]);
- if ($zombie{$src} eq $i) {
+ if ($zombie{$i} eq $src) {
undef($LONCAPA::map::zombies[$i]);
}
}
}
- for (my $i=0; $i<@LONCAPA::map::resources; $i++) {
- if (defined($LONCAPA::map::resources[$i])) {
+ for (my $i=0; $i<@LONCAPA::map::order; $i++) {
+ my $idx = $LONCAPA::map::order[$i];
+ if (defined($LONCAPA::map::resources[$idx])) {
my $changed;
- my ($title,$src,$ext,$type)=split(/\:/,$LONCAPA::map::resources[$i]);
- if ($toremove{$src} eq $i) {
+ my ($title,$src,$ext,$type)=split(/\:/,$LONCAPA::map::resources[$idx]);
+ if ((exists($toremove{$idx})) &&
+ ($toremove{$idx} eq &LONCAPA::map::qtescape($src))) {
splice(@LONCAPA::map::order,$i,1);
- if (ref($currparam{$i}) eq 'ARRAY') {
- foreach my $name (@{$currparam{$i}}) {
- &LONCAPA::map::delparameter($i,'parameter_'.$name);
+ if (ref($currparam{$idx}) eq 'ARRAY') {
+ foreach my $name (@{$currparam{$idx}}) {
+ &LONCAPA::map::delparameter($idx,'parameter_'.$name);
}
}
next;
}
my $origsrc = $src;
- if ((exists($toretitle{$src})) && ($toretitle{$src} eq $i)) {
+ if ((exists($toretitle{$idx})) && ($toretitle{$idx} eq $src)) {
if ($title =~ m{^\d+\Q___&&&___\E$match_username\Q___&&&___\E$match_domain\Q___&&&___\E(.+)$}) {
$changed = 1;
}
}
- if ((exists($torewrite{$src})) && ($torewrite{$src} eq $i)) {
+ if ((exists($torewrite{$idx})) && ($torewrite{$idx} eq $src)) {
$src =~ s{^/(uploaded|adm|public)/$match_domain/$match_courseid/}{/$1/$cdom/$cnum/};
if ($origsrc =~ m{^/uploaded/}) {
- if ($prefixchg) {
+ if ($prefixchg && $before{'map'} && $after{'map'}) {
if ($src =~ /\.(page|sequence)$/) {
- $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before->{'map'}\E#$1$after->{'map'}#;
+ $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before{'map'}\E#$1$after{'map'}#;
} else {
- $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before->{'doc'}\E#$1$after->{'doc'}#;
+ $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before{'doc'}\E#$1$after{'doc'}#;
}
}
- if ($newsubdir->{$origsrc}) {
- if ($src =~ /\.(page|sequence)$/) {
- $src =~ s#^(/uploaded/$match_domain/$match_courseid/(?:default|supplemental)_)(\d+)#$1$newsubdir->{$origsrc}#;
- } else {
- $src =~ s#^(/uploaded/$match_domain/$match_courseid/\w+/)(\d+)#$1$newsubdir->{$origsrc}#;
+ if ($origsrc =~ /\.(page|sequence)$/) {
+ if ($newsubdir{$origsrc}) {
+ $src =~ s#^(/uploaded/$match_domain/$match_courseid/(?:default|supplemental)_)(\d+)#$1$newsubdir{$origsrc}#;
}
+ } elsif ($newsubdir{$key}) {
+ $src =~ s#^(/uploaded/$match_domain/$match_courseid/\w+/)(\d+)#$1$newsubdir{$key}#;
}
}
$changed = 1;
- } elsif ($newdb{$src} ne '') {
- $src = $newdb{$src};
+ } elsif ($newdb{$idx} ne '') {
+ $src = $newdb{$idx};
$changed = 1;
}
if ($changed) {
- $LONCAPA::map::resources[$i] = join(':',($title,$src,$ext,$type));
+ $LONCAPA::map::resources[$idx] = join(':',($title,&LONCAPA::map::qtunescape($src),$ext,$type));
}
}
}
foreach my $idx (keys(%remparam)) {
if (ref($remparam{$idx}) eq 'ARRAY') {
- foreach my $name (@{$remparam{$idx}}) {
+ foreach my $name (@{$remparam{$idx}}) {
&LONCAPA::map::delparameter($idx,'parameter_'.$name);
}
}
}
+ if (values(%lockerrors) > 0) {
+ $lockmsg = join(' ',values(%lockerrors));
+ }
my $storefn;
if ($key eq $oldurl) {
$storefn = $url;
@@ -1594,25 +2067,27 @@ sub apply_fixups {
} else {
$storefn = $key;
$storefn=~s{^/uploaded/$match_domain/$match_courseid/}{};
- if ($prefixchg) {
- $storefn =~ s/^\Q$before->{'map'}\E/$after->{'map'}/;
+ if ($prefixchg && $before{'map'} && $after{'map'}) {
+ $storefn =~ s/^\Q$before{'map'}\E/$after{'map'}/;
}
- if ($newsubdir->{$key}) {
- $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir->{$key}/;
+ if ($newsubdir{$key}) {
+ $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/;
}
}
my $report;
if ($folder !~ /^supplemental/) {
$report = 1;
}
- my ($outtext,$errtext) =
+ (my $outtext,$errtext) =
&LONCAPA::map::storemap("/uploaded/$cdom/$cnum/$storefn",1,$report);
if ($errtext) {
- return &mt('Paste failed: an error occurred saving the folder or page.');
+ if ($caller eq 'paste') {
+ return (&mt('Paste failed: an error occurred saving the folder or page.'));
+ }
}
}
}
- return 'ok';
+ return ('ok',\@msgs,$lockmsg);
}
sub copy_dependencies {
@@ -1677,34 +2152,105 @@ my %parameter_type = ( 'randompick'
my $valid_parameters_re = join('|',keys(%parameter_type));
# set parameters
sub update_parameter {
-
- return 0 if ($env{'form.changeparms'} !~ /^($valid_parameters_re)$/);
-
- my $which = $env{'form.changeparms'};
- my $idx = $env{'form.setparms'};
- if ($env{'form.'.$which.'_'.$idx}) {
- my $value = ($which eq 'randompick') ? $env{'form.'.$which.'_'.$idx}
- : 'yes';
- &LONCAPA::map::storeparameter($idx, 'parameter_'.$which, $value,
- $parameter_type{$which});
- &remember_parms($idx,$which,'set',$value);
+ if ($env{'form.changeparms'} eq 'all') {
+ my (@allidx,@allmapidx,%allchecked,%currchecked);
+ %allchecked = (
+ 'hiddenresource' => {},
+ 'encrypturl' => {},
+ 'randompick' => {},
+ 'randomorder' => {},
+ );
+ foreach my $which (keys(%allchecked)) {
+ $env{'form.all'.$which} =~ s/,$//;
+ if ($which eq 'randompick') {
+ foreach my $item (split(/,/,$env{'form.all'.$which})) {
+ my ($res,$value) = split(/:/,$item);
+ if ($value =~ /^\d+$/) {
+ $allchecked{$which}{$res} = $value;
+ }
+ }
+ } else {
+ map { $allchecked{$which}{$_} = 1; } split(/,/,$env{'form.all'.$which});
+ }
+ }
+ my $haschanges = 0;
+ foreach my $res (@LONCAPA::map::order) {
+ my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]);
+ $name=&LONCAPA::map::qtescape($name);
+ $url=&LONCAPA::map::qtescape($url);
+ next unless ($name && $url);
+ my $is_map;
+ if ($url =~ m{/uploaded/.+\.(page|sequence)$}) {
+ $is_map = 1;
+ }
+ foreach my $which (keys(%allchecked)) {
+ if (($which eq 'randompick' || $which eq 'randomorder')) {
+ next if (!$is_map);
+ }
+ my $oldvalue = 0;
+ my $newvalue = 0;
+ if ($allchecked{$which}{$res}) {
+ $newvalue = $allchecked{$which}{$res};
+ }
+ my $current = (&LONCAPA::map::getparameter($res,'parameter_'.$which))[0];
+ if ($which eq 'randompick') {
+ if ($current =~ /^(\d+)$/) {
+ $oldvalue = $1;
+ }
+ } else {
+ if ($current =~ /^yes$/i) {
+ $oldvalue = 1;
+ }
+ }
+ if ($oldvalue ne $newvalue) {
+ $haschanges = 1;
+ if ($newvalue) {
+ my $storeval = 'yes';
+ if ($which eq 'randompick') {
+ $storeval = $newvalue;
+ }
+ &LONCAPA::map::storeparameter($res,'parameter_'.$which,
+ $storeval,
+ $parameter_type{$which});
+ &remember_parms($res,$which,'set',$storeval);
+ } elsif ($oldvalue) {
+ &LONCAPA::map::delparameter($res,'parameter_'.$which);
+ &remember_parms($res,$which,'del');
+ }
+ }
+ }
+ }
+ return $haschanges;
} else {
- &LONCAPA::map::delparameter($idx,'parameter_'.$which);
+ return 0 if ($env{'form.changeparms'} !~ /^($valid_parameters_re)$/);
- &remember_parms($idx,$which,'del');
+ my $which = $env{'form.changeparms'};
+ my $idx = $env{'form.setparms'};
+ if ($env{'form.'.$which.'_'.$idx}) {
+ my $value = ($which eq 'randompick') ? $env{'form.rpicknum_'.$idx}
+ : 'yes';
+ &LONCAPA::map::storeparameter($idx, 'parameter_'.$which, $value,
+ $parameter_type{$which});
+ &remember_parms($idx,$which,'set',$value);
+ } else {
+ &LONCAPA::map::delparameter($idx,'parameter_'.$which);
+
+ &remember_parms($idx,$which,'del');
+ }
+ return 1;
}
- return 1;
}
sub handle_edit_cmd {
my ($coursenum,$coursedom) =@_;
+ return if ($env{'form.cmd'} eq '');
my ($cmd,$idx)=split('_',$env{'form.cmd'});
my $ratstr = $LONCAPA::map::resources[$LONCAPA::map::order[$idx]];
my ($title, $url, @rrest) = split(':', $ratstr);
- if ($cmd eq 'del') {
+ if ($cmd eq 'remove') {
if (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) &&
($url!~/$LONCAPA::assess_page_seq_re/)) {
&Apache::lonnet::removeuploadedurl($url);
@@ -1726,7 +2272,6 @@ sub handle_edit_cmd {
@LONCAPA::map::order[$idx+1,$idx] = @LONCAPA::map::order[$idx,$idx+1];
} elsif ($cmd eq 'rename') {
-
my $comment = &LONCAPA::map::qtunescape($env{'form.title'});
if ($comment=~/\S/) {
$LONCAPA::map::resources[$LONCAPA::map::order[$idx]]=
@@ -1735,6 +2280,7 @@ sub handle_edit_cmd {
# Devalidate title cache
my $renamed_url=&LONCAPA::map::qtescape($url);
&Apache::lonnet::devalidate_title_cache($renamed_url);
+
} else {
return 0;
}
@@ -1743,15 +2289,24 @@ sub handle_edit_cmd {
sub editor {
my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$crstype,
- $supplementalflag,$orderhash,$iconpath,$uploadtag)=@_;
- my $container= ($env{'form.pagepath'}) ? 'page'
- : 'sequence';
-
- my ($breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,$is_random_order) =
- &breadcrumbs($allowed,$crstype);
- $r->print($breadcrumbtrail);
+ $supplementalflag,$orderhash,$iconpath,$pathitem)=@_;
+ my ($randompick,$ishidden,$isencrypted,$plain,$is_random_order,$container);
+ if ($allowed) {
+ (my $breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,
+ $is_random_order,$container) =
+ &Apache::lonhtmlcommon::docs_breadcrumbs($allowed,$crstype,1);
+ $r->print($breadcrumbtrail);
+ } elsif ($env{'form.folderpath'} =~ /\:1$/) {
+ $container = 'page';
+ } else {
+ $container = 'sequence';
+ }
+
+ my $jumpto;
- my $jumpto = "uploaded/$coursedom/$coursenum/$folder.$container";
+ unless ($supplementalflag) {
+ $jumpto = "'uploaded/$coursedom/$coursenum/$folder.$container'";
+ }
unless ($allowed) {
$randompick = -1;
@@ -1791,17 +2346,30 @@ sub editor {
if ($env{'form.pastemarked'}) {
my %paste_errors;
- my ($paste_res,$save_error) =
+ my ($paste_res,$save_error,$pastemsgarray,$lockerror) =
&do_paste_from_buffer($coursenum,$coursedom,$folder,$container,
\%paste_errors);
+ if (ref($pastemsgarray) eq 'ARRAY') {
+ if (@{$pastemsgarray} > 0) {
+
+ $r->print(''.
+ join(' ',@{$pastemsgarray}).
+ '
');
+ }
+ }
+ if ($lockerror) {
+ $r->print(''.
+ $lockerror.
+ '
');
+ }
if ($save_error ne '') {
- return $save_error;
+ return $save_error;
}
if ($paste_res ne 'ok') {
- $r->print(''.$paste_res.'
');
+ $r->print(''.$paste_res.'
');
}
if (keys(%paste_errors) > 0) {
- $r->print(''."\n".
+ $r->print('
'."\n".
&mt('The following files are either dependencies of a web page or references within a folder and/or composite page which could not be copied during the paste operation:')."\n".
'
'."\n");
foreach my $key (sort(keys(%paste_errors))) {
@@ -1809,43 +2377,138 @@ sub editor {
}
$r->print(' '."\n");
}
- }
+ } elsif ($env{'form.clearmarked'}) {
+ my $output = &do_buffer_empty();
+ if ($output) {
+ $r->print(''.$output.'
');
+ }
+ }
$r->print($upload_output);
+# Rename, cut, copy or remove a single resource
if (&handle_edit_cmd()) {
my $contentchg;
- if ($env{'form.cmd'} =~ /^(del|cut)_/) {
+ if ($env{'form.cmd'} =~ m{^(del|cut)_}) {
$contentchg = 1;
}
($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container,$contentchg);
return $errtext if ($fatal);
}
+
+# Cut, copy and/or remove multiple resources
+ if ($env{'form.multichange'}) {
+ my %allchecked = (
+ cut => {},
+ remove => {},
+ );
+ my $needsupdate;
+ foreach my $which (keys(%allchecked)) {
+ $env{'form.multi'.$which} =~ s/,$//;
+ if ($env{'form.multi'.$which}) {
+ map { $allchecked{$which}{$_} = 1; } split(/,/,$env{'form.multi'.$which});
+ if (ref($allchecked{$which}) eq 'HASH') {
+ $needsupdate += scalar(keys(%{$allchecked{$which}}));
+ }
+ }
+ }
+ if ($needsupdate) {
+ my $haschanges = 0;
+ my %curr_groups = &Apache::longroup::coursegroups();
+ my $total = scalar(@LONCAPA::map::order) - 1;
+ for (my $i=$total; $i>=0; $i--) {
+ my $res = $LONCAPA::map::order[$i];
+ my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]);
+ $name=&LONCAPA::map::qtescape($name);
+ $url=&LONCAPA::map::qtescape($url);
+ next unless ($name && $url);
+ my %denied =
+ &action_restrictions($coursenum,$coursedom,$url,
+ $env{'form.folderpath'},\%curr_groups);
+ foreach my $which (keys(%allchecked)) {
+ next if ($denied{$which});
+ next unless ($allchecked{$which}{$res});
+ if ($which eq 'remove') {
+ if (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) &&
+ ($url!~/$LONCAPA::assess_page_seq_re/)) {
+ &Apache::lonnet::removeuploadedurl($url);
+ } else {
+ &LONCAPA::map::makezombie($res);
+ }
+ splice(@LONCAPA::map::order,$i,1);
+ $haschanges ++;
+ } elsif ($which eq 'cut') {
+ &LONCAPA::map::makezombie($res);
+ splice(@LONCAPA::map::order,$i,1);
+ $haschanges ++;
+ }
+ }
+ }
+ if ($haschanges) {
+ ($errtext,$fatal) =
+ &storemap($coursenum,$coursedom,$folder.'.'.$container,1);
+ return $errtext if ($fatal);
+ }
+ }
+ }
+
# Group import/search
if ($env{'form.importdetail'}) {
my @imports;
foreach my $item (split(/\&/,$env{'form.importdetail'})) {
if (defined($item)) {
my ($name,$url,$residx)=
- map {&unescape($_)} split(/\=/,$item);
- if ($url=~ m{^\Q/uploaded/$coursedom/$coursenum/\E(default|supplemental)_new\.(sequence|page)$}) {
+ map { &unescape($_); } split(/\=/,$item);
+ if ($url =~ m{^\Q/uploaded/$coursedom/$coursenum/\E(default|supplemental)_new\.(sequence|page)$}) {
+ my ($suffix,$errortxt,$locknotfreed) =
+ &new_timebased_suffix($coursedom,$coursenum,'map',$1,$2);
+ if ($locknotfreed) {
+ $r->print($locknotfreed);
+ }
+ if ($suffix) {
+ $url =~ s/_new\./_$suffix./;
+ } else {
+ return $errortxt;
+ }
+ } elsif ($url =~ m{^/adm/$match_domain/$match_username/new/(smppg|bulletinboard)$}) {
+ my $type = $1;
my ($suffix,$errortxt,$locknotfreed) =
- &newmap_suffix($1,$2,$coursedom,$coursenum);
+ &new_timebased_suffix($coursedom,$coursenum,$type);
if ($locknotfreed) {
$r->print($locknotfreed);
}
if ($suffix) {
- $url =~ s/_new\./_$suffix./;
+ $url =~ s{^(/adm/$match_domain/$match_username)/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');
+ if ($folder eq 'supplemental') {
+ next unless ($2 eq 'default');
+ } else {
+ next unless ($folder eq 'supplemental_'.$2);
+ }
+ } else {
+ next unless ($1 eq 'docs');
+ if ($folder eq 'default') {
+ next unless ($2 eq 'default');
+ } else {
+ next unless ($folder eq 'default_'.$2);
+ }
+ }
}
push(@imports, [$name, $url, $residx]);
}
}
- ($errtext,$fatal)=&group_import($coursenum, $coursedom, $folder,
- $container,'londocs',@imports);
+ ($errtext,$fatal,my $fixuperrors) =
+ &group_import($coursenum, $coursedom, $folder,$container,
+ 'londocs',@imports);
return $errtext if ($fatal);
+ if ($fixuperrors) {
+ $r->print($fixuperrors);
+ }
}
# Loading a complete map
if ($env{'form.loadmap'}) {
@@ -1901,8 +2564,13 @@ sub editor {
$r->print('');
}
- my ($to_show,$output);
-
+ my ($to_show,$output,@allidx,@allmapidx,%filters,%lists,%curr_groups);
+ %filters = (
+ canremove => [],
+ cancut => [],
+ cancopy => [],
+ );
+ %curr_groups = &Apache::longroup::coursegroups();
&Apache::loncommon::start_data_table_count(); #setup a row counter
foreach my $res (@LONCAPA::map::order) {
my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]);
@@ -1910,37 +2578,106 @@ sub editor {
$url=&LONCAPA::map::qtescape($url);
unless ($name) { $name=(split(/\//,$url))[-1]; }
unless ($name) { $idx++; next; }
+ push(@allidx,$res);
+ if ($url =~ m{/uploaded/.+\.(page|sequence)$}) {
+ push(@allmapidx,$res);
+ }
$output .= &entryline($idx,$name,$url,$folder,$allowed,$res,
$coursenum,$coursedom,$crstype,
- $uploadtag,$supplementalflag);
+ $pathitem,$supplementalflag,$container,
+ \%filters,\%curr_groups);
$idx++;
$shown++;
}
&Apache::loncommon::end_data_table_count();
-
- if ($shown) {
- $to_show = &Apache::loncommon::start_scrollbox('900px','880px','400px','contentscroll')
- .&Apache::loncommon::start_data_table(undef,'contentlist');
- if ($allowed) {
- $to_show .= &Apache::loncommon::start_data_table_header_row()
- .''.&mt('Move').' '
- .''.&mt('Actions').' '
- .''.&mt('Document').' ';
- if ($folder !~ /^supplemental/) {
- $to_show .= ''.&mt('Settings').' ';
+
+ my $need_save;
+ if (($allowed) || ($supplementalflag && $folder eq 'supplemental')) {
+ my $toolslink = ''
+ .&Apache::loncommon::help_open_menu('Navigation Screen',
+ 'Navigation_Screen',undef,'RAT')
+ .' '.&mt('Tools:').' '
+ .'
';
+ if ($shown) {
+ if ($allowed) {
+ $to_show = &Apache::loncommon::start_scrollbox('900px','880px','400px','contentscroll')
+ .&Apache::loncommon::start_data_table(undef,'contentlist')
+ .&Apache::loncommon::start_data_table_header_row()
+ .''.&mt('Move').' '
+ .''.&mt('Actions').' '
+ .''.&mt('Document').' ';
+ if ($folder !~ /^supplemental/) {
+ $to_show .= ''.&mt('Settings').' ';
+ }
+ $to_show .= &Apache::loncommon::end_data_table_header_row();
+ if ($folder !~ /^supplemental/) {
+ $lists{'canhide'} = join(',',@allidx);
+ $lists{'canrandomlyorder'} = join(',',@allmapidx);
+ foreach my $item ('canremove','cancut','cancopy') {
+ if (ref($filters{$item}) eq 'ARRAY') {
+ $lists{$item} = join(',',@{$filters{$item}});
+ }
+ }
+ if (@allidx > 0) {
+ my $path;
+ if ($env{'form.folderpath'}) {
+ $path =
+ &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
+ }
+ if (@allidx > 1) {
+ $to_show .=
+ &Apache::loncommon::continue_data_table_row().
+ ' '.
+ ''.
+ &multiple_check_form('actions',\%lists).
+ ' '.
+ ' '.
+ ' '.
+ ''.
+ &multiple_check_form('settings',\%lists).
+ ' '.
+ &Apache::loncommon::end_data_table_row();
+ $need_save = 1;
+ }
+ }
+ }
+ $to_show .= $output.' '
+ .&Apache::loncommon::end_data_table()
+ .' '
+ .&Apache::loncommon::end_scrollbox();
+ } else {
+ $to_show .= $toolslink
+ .&Apache::loncommon::start_data_table('LC_tableOfContent')
+ .$output.' '
+ .&Apache::loncommon::end_data_table();
}
- $to_show .= &Apache::loncommon::end_data_table_header_row();
+ } else {
+ if (!$allowed) {
+ $to_show .= $toolslink;
+ }
+ $to_show .= &Apache::loncommon::start_scrollbox('400px','380px','200px','contentscroll')
+ .''
+ .&mt('Currently no documents.')
+ .'
'
+ .&Apache::loncommon::end_scrollbox();
}
- $to_show .= $output.' '
- .&Apache::loncommon::end_data_table()
- .' '
- .&Apache::loncommon::end_scrollbox();
} else {
- $to_show .= &Apache::loncommon::start_scrollbox('400px','380px','200px','contentscroll')
- .''
- .&mt('Currently no documents.')
- .'
'
- .&Apache::loncommon::end_scrollbox();
+ if ($shown) {
+ $to_show = ''
+ .&Apache::loncommon::start_data_table('LC_tableOfContent')
+ .$output
+ .&Apache::loncommon::end_data_table()
+ .'
';
+ } else {
+ $to_show = ''
+ .&mt('Currently no documents.')
+ .'
'
+ }
}
my $tid = 1;
if ($supplementalflag) {
@@ -1948,28 +2685,76 @@ sub editor {
}
if ($allowed) {
my $readfile="/uploaded/$coursedom/$coursenum/$folder.$container";
- $r->print(&generate_edit_table($tid,$orderhash,$to_show,$iconpath,$jumpto,
- $readfile));
+ $r->print(&generate_edit_table($tid,$orderhash,$to_show,$iconpath,
+ $jumpto,$readfile,$need_save,"$folder.$container"));
&print_paste_buffer($r,$container,$folder,$coursedom,$coursenum);
} else {
- if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) {
- #Function Box for Supplemental Content for users with mdc priv.
- my $funcname = &mt('Folder Editor');
- $r->print(
- &Apache::loncommon::head_subbox(
- &Apache::lonhtmlcommon::start_funclist().
- &Apache::lonhtmlcommon::add_item_funclist(
- ''.
- ' '.
- ' ').
- &Apache::lonhtmlcommon::end_funclist()));
- }
$r->print($to_show);
}
return;
}
+sub multiple_check_form {
+ my ($caller,$listsref) = @_;
+ return unless (ref($listsref) eq 'HASH');
+ my $output =
+ ''.
+ '';
+ return $output;
+}
+
sub process_file_upload {
my ($upload_output,$coursenum,$coursedom,$allfiles,$codebase,$uploadcmd) = @_;
# upload a file, if present
@@ -1985,19 +2770,15 @@ sub process_file_upload {
my $errtext='';
my $fatal=0;
my $container='sequence';
- if ($env{'form.pagepath'}) {
+ if ($env{'form.folderpath'} =~ /:1$/) {
$container='page';
}
($errtext,$fatal)=
- &mapread($coursenum,$coursedom,$folder.'.'.$container);
+ &mapread($coursenum,$coursedom,$folder.'.'.$container);
if ($#LONCAPA::map::order<1) {
$LONCAPA::map::order[0]=1;
$LONCAPA::map::resources[1]='';
}
- if ($fatal) {
- $$upload_output = ''.&mt('The uploaded file has not been stored as an error occurred reading the contents of the current folder.').'
';
- return;
- }
my $destination = 'docs/';
if ($folder =~ /^supplemental/) {
$destination = 'supplemental/';
@@ -2007,6 +2788,10 @@ sub process_file_upload {
} elsif ($folder =~ /^(default|supplemental)_(\d+)$/) {
$destination .= $2.'/';
}
+ if ($fatal) {
+ $$upload_output = ''.&mt('The uploaded file has not been stored as an error occurred reading the contents of the current folder.').'
';
+ return;
+ }
# this is for a course, not a user, so set context to coursedoc.
my $newidx=&LONCAPA::map::getresidx();
$destination .= $newidx;
@@ -2075,7 +2860,6 @@ sub process_file_upload {
my $archiveurl = &HTML::Entities::encode($url,'<>&"');
my %archiveitems = (
folderpath => $env{'form.folderpath'},
- pagepath => $env{'form.pagepath'},
cmd => $nextphase,
newidx => $newidx,
position => $position,
@@ -2130,16 +2914,14 @@ sub is_supplemental_title {
sub entryline {
my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$coursedom,
- $crstype,$uploadtag,$supplementalflag)=@_;
- my ($foldertitle,$pagetitle,$renametitle);
+ $crstype,$pathitem,$supplementalflag,$container,$filtersref,$currgroups)=@_;
+ my ($foldertitle,$renametitle);
if (&is_supplemental_title($title)) {
($title,$foldertitle,$renametitle) = &Apache::loncommon::parse_supplemental_title($title);
- $pagetitle = $foldertitle;
} else {
$title=&HTML::Entities::encode($title,'"<>&\'');
$renametitle=$title;
$foldertitle=$title;
- $pagetitle=$title;
}
my $orderidx=$LONCAPA::map::order[$index];
@@ -2148,33 +2930,49 @@ sub entryline {
$renametitle=~s/\"\;/\\\"/g;
$renametitle=~s/ /%20/g;
my $line=&Apache::loncommon::start_data_table_row();
- my ($form_start,$form_end,$form_common);
+ my ($form_start,$form_end,$form_common,$form_param);
# Edit commands
- my ($container, $type, $esc_path, $path, $symb);
+ my ($esc_path, $path, $symb);
if ($env{'form.folderpath'}) {
- $type = 'folder';
- $container = 'sequence';
$esc_path=&escape($env{'form.folderpath'});
$path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
# $htmlfoldername=&HTML::Entities::encode($env{'form.foldername'},'<>&"');
}
- if ($env{'form.pagepath'}) {
- $type = $container = 'page';
- $esc_path=&escape($env{'form.pagepath'});
- $path = &HTML::Entities::encode($env{'form.pagepath'},'<>&"');
- }
- if (!$supplementalflag && $residx) {
+ my $isexternal;
+ if ($residx) {
my $currurl = $url;
$currurl =~ s{^http(|s)(:|:)//}{/adm/wrapper/ext/};
- my $path = 'uploaded/'.
- $env{'course.'.$env{'request.course.id'}.'.domain'}.'/'.
- $env{'course.'.$env{'request.course.id'}.'.num'}.'/';
- $symb = &Apache::lonnet::encode_symb($path.$folder.".$container",
- $residx,
- &Apache::lonnet::declutter($currurl));
+ if ($currurl =~ m{^/adm/wrapper/ext/}) {
+ $isexternal = 1;
+ }
+ if (!$supplementalflag) {
+ my $path = 'uploaded/'.
+ $env{'course.'.$env{'request.course.id'}.'.domain'}.'/'.
+ $env{'course.'.$env{'request.course.id'}.'.num'}.'/';
+ $symb = &Apache::lonnet::encode_symb($path.$folder.".$container",
+ $residx,
+ &Apache::lonnet::declutter($currurl));
+ }
+ }
+ my ($renamelink,%lt,$ishash);
+ if (ref($filtersref) eq 'HASH') {
+ $ishash = 1;
}
- my %lt;
+
if ($allowed) {
+ $form_start = '
+ ';
+
my $incindex=$index+1;
my $selectbox='';
if (($#LONCAPA::map::order>0) &&
@@ -2210,70 +3008,10 @@ sub entryline {
'ul' => 'URL',
'ti' => 'Title',
);
- my $nocopy=0;
- my $nocut=0;
- my $noremove=0;
- if ($url=~ m{^/res/.+\.(page|sequence)$}) {
- # no copy for published maps
- $nocopy=1;
- }
- if ($url=~/^\/res\/lib\/templates\//) {
- $nocopy=1;
- $nocut=1;
- }
- my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
- my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
- if ($url eq "/uploaded/$cdom/$cnum/group_allfolders.sequence") {
- if ($env{'form.folderpath'} =~ /^default&[^\&]+$/) {
- my %curr_groups = &Apache::longroup::coursegroups();
- if (keys(%curr_groups) > 0) {
- $noremove=1;
- }
- $nocut=1;
- $nocopy=1;
- }
- } elsif ($url =~ m{^\Q/uploaded/$cdom/$cnum/group_folder_\E(\w+)\.sequence$}) {
- my $group = $1;
- if ($env{'form.folderpath'} =~ /^default&[^\&]+\&group_allfolders\&[^\&]+$/) {
- my %curr_group = &Apache::longroup::coursegroups($cdom,$cnum,$group);
- if (keys(%curr_group) > 0) {
- $noremove=1;
- }
- }
- $nocut=1;
- $nocopy=1;
- } elsif ($url =~ m{^\Q/adm/$cdom/$cnum/\E(\w+)/smppg$}) {
- my $group = $1;
- if ($env{'form.folderpath'} =~ /^default&[^\&]+\&group_allfolders\&[^\&]+\&\Qgroup_folder_$group\E\&[^\&]+$/) {
- my %curr_group = &Apache::longroup::coursegroups($cdom,$cnum,$group);
- my %groupsettings = &Apache::longroup::get_group_settings($curr_group{$group});
- if (keys(%groupsettings) > 0) {
- $noremove=1;
- }
- $nocut=1;
- $nocopy=1;
- }
- } elsif ($env{'form.folderpath'} =~ /^default&[^\&]+\&group_allfolders\&[^\&]+\&group_folder_(\w+)\&/) {
- my $group = $1;
- my %curr_group = &Apache::longroup::coursegroups($cdom,$cnum,$group);
- if ($url =~ /group_boards_\Q$group\E/) {
- my %curr_group = &Apache::longroup::coursegroups($cdom,$cnum,$group);
- my %groupsettings = &Apache::longroup::get_group_settings($curr_group{$group});
- if (keys(%groupsettings) > 0) {
- if (ref($groupsettings{'functions'}) eq 'HASH') {
- if ($groupsettings{'functions'}{'discussion'} eq 'on') {
- $noremove=1;
- }
- }
- }
- $nocut=1;
- $nocopy=1;
- }
- }
- my $copylink=' ';
- my $cutlink=' ';
- my $removelink=' ';
-
+ my %denied = &action_restrictions($coursenum,$coursedom,$url,
+ $env{'form.folderpath'},
+ $currgroups);
+ my ($copylink,$cutlink,$removelink);
my $skip_confirm = 0;
if ( $folder =~ /^supplemental/
|| ($url =~ m{( /smppg$
@@ -2281,84 +3019,111 @@ sub entryline {
|/aboutme$
|/navmaps$
|/bulletinboard$
- |\.html$
- |^/adm/wrapper/ext)}x)) {
+ |\.html$)}x)
+ || $isexternal) {
$skip_confirm = 1;
}
- if (!$nocopy) {
+ if ($denied{'copy'}) {
+ $copylink=(<$lt{'cp'}
+ENDCOPY
+ } else {
+ my $formname = 'edit_copy_'.$orderidx;
+ my $js = "javascript:checkForSubmit(document.forms.renameform,'copy','actions','$orderidx','$esc_path','$index','$renametitle',$skip_confirm,'$container','$folder');";
$copylink=(<$lt{'cp'}
+
$form_start
+ $form_param
$form_common
$selectbox
$form_end
-
+
$removelink
$cutlink
- $lt{'rn'}
$copylink
+
END
-
}
# Figure out what kind of a resource this is
my ($extension)=($url=~/\.(\w+)$/);
my $uploaded=($url=~/^\/*uploaded\//);
my $icon=&Apache::loncommon::icon($url);
- my $isfolder=0;
- my $ispage=0;
- my $folderarg;
- my $pagearg;
- my $pagefile;
+ my $isfolder;
+ my $ispage;
+ my $containerarg;
if ($uploaded) {
if (($extension eq 'sequence') || ($extension eq 'page')) {
$url=~/\Q$coursenum\E\/([\/\w]+)\.\Q$extension\E$/;
- my $containerarg = $1;
+ $containerarg = $1;
if ($extension eq 'sequence') {
$icon=$iconpath.'navmap.folder.closed.gif';
- $folderarg=$containerarg;
$isfolder=1;
} else {
$icon=$iconpath.'page.gif';
- $pagearg=$containerarg;
$ispage=1;
}
if ($allowed) {
@@ -2371,15 +3136,11 @@ END
}
}
- my $editlink;
+ my ($editlink,$extresform);
my $orig_url = $url;
$orig_url=~s{http(:|:)//https(:|:)//}{https$2//};
- my $external = ($url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/});
+ $url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/};
if (!$supplementalflag && $residx && $symb) {
- if ($container eq 'page') {
- $url=&Apache::lonnet::clutter((&Apache::lonnet::decode_symb($symb))[2]);
- $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb);
- }
if ((!$isfolder) && (!$ispage)) {
(undef,undef,$url)=&Apache::lonnet::decode_symb($symb);
$url=&Apache::lonnet::clutter($url);
@@ -2395,112 +3156,107 @@ END
}
} elsif ($url=~m|^/ext/|) {
$url='/adm/wrapper'.$url;
- $external = 1;
- }
+ }
if (&Apache::lonnet::symbverify($symb,$url)) {
- $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb);
+ $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb);
} else {
$url='';
}
- }
+ }
}
my ($rand_pick_text,$rand_order_text);
- if ($isfolder || $extension eq 'sequence') {
+ if ($isfolder || $ispage || $extension eq 'sequence' || $extension eq 'page') {
my $foldername=&escape($foldertitle);
my $folderpath=$env{'form.folderpath'};
if ($folderpath) { $folderpath.='&' };
+ if (!$allowed && $supplementalflag) {
+ $folderpath.=$containerarg.'&'.$foldername;
+ $url.='folderpath='.&escape($folderpath);
+ } else {
# Append randompick number, hidden, and encrypted with ":" to foldername,
# so it gets transferred between levels
- $folderpath.=$folderarg.'&'.$foldername.':'.(&LONCAPA::map::getparameter($orderidx,
+ $folderpath.=$containerarg.'&'.$foldername.
+ ':'.(&LONCAPA::map::getparameter($orderidx,
'parameter_randompick'))[0]
.':'.((&LONCAPA::map::getparameter($orderidx,
'parameter_hiddenresource'))[0]=~/^yes$/i)
.':'.((&LONCAPA::map::getparameter($orderidx,
'parameter_encrypturl'))[0]=~/^yes$/i)
.':'.((&LONCAPA::map::getparameter($orderidx,
- 'parameter_randomorder'))[0]=~/^yes$/i);
- $url.='folderpath='.&escape($folderpath);
- my $rpicknum = (&LONCAPA::map::getparameter($orderidx,
- 'parameter_randompick'))[0];
- my $rpckchk;
- if ($rpicknum) {
- $rpckchk = ' checked="checked"';
- }
- my $formname = 'edit_rpick_'.$orderidx;
- $rand_pick_text =
+ 'parameter_randomorder'))[0]=~/^yes$/i)
+ .':'.$ispage;
+ $url.='folderpath='.&escape($folderpath);
+ my $rpicknum = (&LONCAPA::map::getparameter($orderidx,
+ 'parameter_randompick'))[0];
+ my $rpckchk;
+ if ($rpicknum) {
+ $rpckchk = ' checked="checked"';
+ }
+ my $formname = 'edit_randompick_'.$orderidx;
+ $rand_pick_text =
+''."\n".
+$form_param."\n".
+$form_common."\n".
+' '.&mt('Randomly Pick').'';
+ if ($rpicknum ne '') {
+ $rand_pick_text .= ': '.$rpicknum.' ';
+ }
+ $rand_pick_text .= ' '.
+ $form_end;
+ my $ro_set=
+ ((&LONCAPA::map::getparameter($orderidx,'parameter_randomorder'))[0]=~/^yes$/i?' checked="checked"':'');
+ my $formname = 'edit_rorder_'.$orderidx;
+ $rand_order_text =
' '."\n".
+$form_param."\n".
$form_common."\n".
-' '.&mt('Randomly Pick').' ';
- if ($rpicknum ne '') {
- $rand_pick_text .= ': '.$rpicknum.' ';
- }
- $rand_pick_text .= ' ';
- my $ro_set=
- ((&LONCAPA::map::getparameter($orderidx,'parameter_randomorder'))[0]=~/^yes$/i?' checked="checked"':'');
- $rand_order_text =
-$form_start.
-$form_common.'
- '.&mt('Random Order').' ';
- }
- if ($ispage) {
- my $pagename=&escape($pagetitle);
- my $pagepath;
- my $folderpath=$env{'form.folderpath'};
- if ($folderpath) { $pagepath = $folderpath.'&' };
- $pagepath.=$pagearg.'&'.$pagename;
- $url.='pagepath='.&escape($pagepath).
- '&pagesymb='.&escape($symb);
+' '.&mt('Random Order').' '.
+$form_end;
+ }
+ } elsif ($supplementalflag && !$allowed) {
+ $url .= ($url =~ /\?/) ? '&':'?';
+ $url .= 'folderpath='.&HTML::Entities::encode($esc_path,'<>&"');
+ if ($title) {
+ $url .= '&title='.&HTML::Entities::encode($renametitle,'<>&"');
+ }
+ if ($isexternal && $orderidx) {
+ $url .= '&idx='.$orderidx;
+ }
}
+ my ($tdalign,$tdwidth);
if ($allowed) {
- my $fileloc =
+ my $fileloc =
&Apache::lonnet::declutter(&Apache::lonnet::filelocation('',$orig_url));
-
- if ($external) {
- $editlink = <<"EXTLNK";
-
-
- $lt{'ed'}
-
-
-
-
- $lt{'ul'}
-
- $lt{'pr'}
-
-
- $lt{'ti'}
-
- $uploadtag
-
-
-
-
-
-EXTLNK
- } else {
- my ($cfile,$home,$switchserver,$forceedit,$forceview) =
+ if ($isexternal) {
+ ($editlink,$extresform) =
+ &Apache::lonextresedit::extedit_form(0,$residx,$orig_url,$title,$pathitem);
+ } elsif (!$isfolder && !$ispage) {
+ my ($cfile,$home,$switchserver,$forceedit,$forceview) =
&Apache::lonnet::can_edit_resource($fileloc,$coursenum,$coursedom,$orig_url);
- if (($cfile ne '') && ($symb ne '')) {
- my $jscall =
+ if (($cfile ne '') && ($symb ne '' || $supplementalflag)) {
+ my $jscall =
&Apache::lonhtmlcommon::jump_to_editres($cfile,$home,
$switchserver,
$forceedit,
- undef,$symb);
+ undef,$symb,
+ &escape($env{'form.folderpath'}),
+ $renametitle,'','',1);
if ($jscall) {
- $editlink = ' '.&mt('Edit').' ';
+ $editlink = ''.&mt('Edit').' '."\n";
}
}
}
+ $tdalign = ' align="right" valign="top"';
+ $tdwidth = ' width="80%"';
}
my $reinit;
if ($crstype eq 'Community') {
$reinit = &mt('(re-initialize community to access)');
} else {
$reinit = &mt('(re-initialize course to access)');
- }
- $line.='';
+ }
+ $line.=' '.$editlink.$renamelink;
if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) {
$line.=' ';
} elsif ($url) {
@@ -2509,7 +3265,7 @@ EXTLNK
} else {
$line.=' ';
}
- $line.=' ';
+ $line.=' ';
if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) {
$line.=''.$title.' ';
} elsif ($url) {
@@ -2518,7 +3274,7 @@ EXTLNK
} else {
$line.=$title.' '.$reinit.' ';
}
- $line.=$editlink." ";
+ $line.="$extresform";
$rand_pick_text = ' ' if ($rand_pick_text eq '');
$rand_order_text = ' ' if ($rand_order_text eq '');
if (($allowed) && ($folder!~/^supplemental/)) {
@@ -2529,16 +3285,20 @@ EXTLNK
((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i?' checked="checked"':'');
my $hidtext=
((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i?' checked="checked"':'');
+ my $formhidden = 'edit_hiddenresource_'.$orderidx;
+ my $formurlhidden = 'edit_encrypturl_'.$orderidx;
$line.=(<
- $form_start
+
+ $form_param
$form_common
- $lt{'hd'}
+ $lt{'hd'}
$form_end
- $form_start
+
+ $form_param
$form_common
- $lt{'ec'}
+ $lt{'ec'}
$form_end
$rand_pick_text
@@ -2549,26 +3309,122 @@ ENDPARMS
return $line;
}
-sub newmap_suffix {
- my ($area,$container,$coursedom,$coursenum) = @_;
- my ($prefix,$idtype,$errtext,$locknotfreed);
- $prefix = 'docs';
- if ($area eq 'supplemental') {
- $prefix = 'supp';
+sub action_restrictions {
+ my ($cnum,$cdom,$url,$folderpath,$currgroups) = @_;
+ my %denied = (
+ cut => 0,
+ copy => 0,
+ remove => 0,
+ );
+ if ($url=~ m{^/res/.+\.(page|sequence)$}) {
+ # no copy for published maps
+ $denied{'copy'} = 1;
+ } elsif ($url=~m{^/res/lib/templates/}) {
+ $denied{'copy'} = 1;
+ $denied{'cut'} = 1;
+ } elsif ($url eq "/uploaded/$cdom/$cnum/group_allfolders.sequence") {
+ if ($folderpath =~ /^default&[^\&]+$/) {
+ if ((ref($currgroups) eq 'HASH') && (keys(%{$currgroups}) > 0)) {
+ $denied{'remove'} = 1;
+ }
+ $denied{'cut'} = 1;
+ $denied{'copy'} = 1;
+ }
+ } elsif ($url =~ m{^\Q/uploaded/$cdom/$cnum/group_folder_\E(\w+)\.sequence$}) {
+ my $group = $1;
+ if ($folderpath =~ /^default&[^\&]+\&group_allfolders\&[^\&]+$/) {
+ if ((ref($currgroups) eq 'HASH') && (exists($currgroups->{$group}))) {
+ $denied{'remove'} = 1;
+ }
+ }
+ $denied{'cut'} = 1;
+ $denied{'copy'} = 1;
+ } elsif ($url =~ m{^\Q/adm/$cdom/$cnum/\E(\w+)/smppg$}) {
+ my $group = $1;
+ if ($folderpath =~ /^default&[^\&]+\&group_allfolders\&[^\&]+\&\Qgroup_folder_$group\E\&[^\&]+$/) {
+ if ((ref($currgroups) eq 'HASH') && (exists($currgroups->{$group}))) {
+ my %groupsettings = &Apache::longroup::get_group_settings($currgroups->{$group});
+ if (keys(%groupsettings) > 0) {
+ $denied{'remove'} = 1;
+ }
+ $denied{'cut'} = 1;
+ $denied{'copy'} = 1;
+ }
+ }
+ } elsif ($folderpath =~ /^default&[^\&]+\&group_allfolders\&[^\&]+\&group_folder_(\w+)\&/) {
+ my $group = $1;
+ if ($url =~ /group_boards_\Q$group\E/) {
+ if ((ref($currgroups) eq 'HASH') && (exists($currgroups->{$group}))) {
+ my %groupsettings = &Apache::longroup::get_group_settings($currgroups->{$group});
+ if (keys(%groupsettings) > 0) {
+ if (ref($groupsettings{'functions'}) eq 'HASH') {
+ if ($groupsettings{'functions'}{'discussion'} eq 'on') {
+ $denied{'remove'} = 1;
+ }
+ }
+ }
+ $denied{'cut'} = 1;
+ $denied{'copy'} = 1;
+ }
+ }
+ }
+ return %denied;
+}
+
+sub new_timebased_suffix {
+ my ($dom,$num,$type,$area,$container) = @_;
+ my ($prefix,$namespace,$idtype,$errtext,$locknotfreed);
+ if ($type eq 'paste') {
+ $prefix = $type;
+ $namespace = 'courseeditor';
+ } elsif ($type eq 'map') {
+ $prefix = 'docs';
+ if ($area eq 'supplemental') {
+ $prefix = 'supp';
+ }
+ $prefix .= $container;
+ $namespace = 'uploadedmaps';
+ } else {
+ $prefix = $type;
+ $namespace = 'templated';
}
- $prefix .= $container;
$idtype = 'concat';
my ($suffix,$freedlock,$error) =
- &Apache::lonnet::get_timebased_id($prefix,'num','uploadedmaps',
- $coursedom,$coursenum);
+ &Apache::lonnet::get_timebased_id($prefix,'num',$namespace,$dom,$num);
if (!$suffix) {
- $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new folder/page.');
+ if ($type eq 'paste') {
+ $errtext = &mt('Failed to acquire a unique timestamp-based suffix when adding to the paste buffer.');
+ } elsif ($type eq 'map') {
+ $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new folder/page.');
+ } elsif ($type eq 'smppg') {
+ $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new simple page.');
+ } else {
+ $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new bulletin board.');
+ }
if ($error) {
$errtext .= ' '.$error;
}
}
if ($freedlock ne 'ok') {
- $locknotfreed = ''.&mt('There was a problem removing a lockfile. This will prevent creation of additional folders or composite pages in this course. Please contact the domain coordinator for your LON-CAPA domain.').'
';
+ $locknotfreed =
+ ''.
+ &mt('There was a problem removing a lockfile.').' ';
+ if ($type eq 'paste') {
+ &mt('This will prevent use of the paste buffer until th next log-in.');
+ } elsif ($type eq 'map') {
+ &mt('This will prevent creation of additional folders or composite pages in this course.');
+ } elsif ($type eq 'smppg') {
+ $locknotfreed .=
+ &mt('This will prevent creation of additional simple pages in this course.');
+ } else {
+ $locknotfreed .=
+ &mt('This will prevent creation of additional bulletin boards in this course.');
+ }
+ unless ($type eq 'paste') {
+ $locknotfreed .=
+ ' '.&mt('Please contact the domain coordinator for your LON-CAPA domain.');
+ }
+ $locknotfreed .= '
';
}
return ($suffix,$errtext,$locknotfreed);
}
@@ -2668,7 +3524,7 @@ sub checkonthis {
$r->print(''.&mt('connection down').' ');
} elsif ($result eq 'not_found') {
unless ($url=~/\$/) {
- $r->print(''.&mt('not found').' ');
+ $r->print(''.&mt('not found').' ');
} else {
$r->print(''.&mt('unable to verify variable URL').' ');
}
@@ -2714,7 +3570,7 @@ sub list_symbs {
$r->print(&Apache::loncommon::start_data_table_row().
' '.$res->compTitle().' '.
''.$res->symb().' '.
- &Apache::loncommon::start_data_table_row());
+ &Apache::loncommon::end_data_table_row());
$count ++;
}
if (!$count) {
@@ -2724,6 +3580,7 @@ sub list_symbs {
}
$r->print(&Apache::loncommon::end_data_table());
}
+ $r->print(&endContentScreen());
}
@@ -2754,6 +3611,7 @@ sub verifycontent {
}
&untiehash();
$r->print(''.&mt('Done').'
');
+ $r->print(&endContentScreen());
}
@@ -2833,7 +3691,7 @@ sub checkversions {
if ($env{'form.timerange'} eq 'all') {
# show all documents
$header=&mt('All Documents in '.$crstype);
- $allsel=1;
+ $allsel=' selected="selected"';
foreach my $key (keys(%hash)) {
if ($key=~/^ids\_(\/res\/.+)$/) {
my $src=$1;
@@ -2854,19 +3712,19 @@ sub checkversions {
.&mt('seconds');
if ($env{'form.timerange'}==-1) {
$seltext='since start of course';
- $startsel='selected';
+ $startsel=' selected="selected"';
$env{'form.timerange'}=time;
}
$starttime=time-$env{'form.timerange'};
if ($env{'form.timerange'}==2592000) {
$seltext=&mt('during the last month').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
- $monthsel='selected';
+ $monthsel=' selected="selected"';
} elsif ($env{'form.timerange'}==604800) {
$seltext=&mt('during the last week').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
- $weeksel='selected';
+ $weeksel=' selected="selected"';
} elsif ($env{'form.timerange'}==86400) {
$seltext=&mt('since yesterday').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
- $daysel='selected';
+ $daysel=' selected="selected"';
}
$header=&mt('Content changed').' '.$seltext;
} else {
@@ -2904,11 +3762,11 @@ sub checkversions {
$lt{'cd'}
-$lt{'al'}
-$lt{'st'}
-$lt{'lm'}
-$lt{'lw'}
-$lt{'sy'}
+$lt{'al'}
+$lt{'st'}
+$lt{'lm'}
+$lt{'lw'}
+$lt{'sy'}
@@ -2924,111 +3782,93 @@ $lt{'sc'}:
-
ENDHEADERS
#number of columns for version history
- my $num_ver_col = 1;
$r->print(
- &Apache::loncommon::start_data_table().
- &Apache::loncommon::start_data_table_header_row().
- ''.&mt('Resources').' '.
- "$lt{'mr'} ".
- "$lt{'ve'} ".
- "$lt{'vu'} ".
- ''.&mt('History').' '.
- '');
+ &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ ''.&mt('Resources').' '.
+ "$lt{'mr'} ".
+ "$lt{'ve'} ".
+ "$lt{'vu'} ".
+ ''.&mt('History').' '.
+ &Apache::loncommon::end_data_table_header_row()
+ );
foreach my $key (sort(keys(%changes))) {
#excludes not versionable problems from resource version history:
next unless ($changes{$key}>$starttime && $key !~ /^\/res\/lib\/templates/);
- my ($root,$extension)=($key=~/^(.*)\.(\w+)$/);
- my $currentversion=&Apache::lonnet::getversion($key);
- if ($currentversion<0) {
- $currentversion=''.&mt('Could not be determined.').' ';
- }
- my $linkurl=&Apache::lonnet::clutter($key);
+ my ($root,$extension)=($key=~/^(.*)\.(\w+)$/);
+ my $currentversion=&Apache::lonnet::getversion($key);
+ if ($currentversion<0) {
+ $currentversion=''.&mt('Could not be determined.').' ';
+ }
+ my $linkurl=&Apache::lonnet::clutter($key);
$r->print(
- &Apache::loncommon::end_data_table_header_row().
&Apache::loncommon::start_data_table_row().
- ''.&Apache::lonnet::gettitle($linkurl).' '.
+ ''.&Apache::lonnet::gettitle($linkurl).' '.
''.$linkurl.' '.
- ''.$currentversion.' ('.
+ ' '.$currentversion.' ('.
&Apache::lonlocal::locallocaltime(&Apache::lonnet::metadata($root.'.'.$extension,'lastrevisiondate')).') '.
- '');
-# Used in course
- my $usedversion=$hash{'version_'.$linkurl};
- if (($usedversion) && ($usedversion ne 'mostrecent')) {
- if($usedversion != $currentversion){
+ ' '
+ );
+ # Used in course
+ my $usedversion=$hash{'version_'.$linkurl};
+ if (($usedversion) && ($usedversion ne 'mostrecent')) {
+ if ($usedversion != $currentversion) {
$r->print(''.$usedversion.' ');
- }else{
+ } else {
$r->print($usedversion);
}
- } else {
- $r->print($currentversion);
- }
- $r->print(' ');
-# Set version
- $r->print(&Apache::loncommon::select_form($setversions{$linkurl},
- 'set_version_'.$linkurl,
- {'select_form_order' =>
- ['',1..$currentversion,'mostrecent'],
- '' => '',
- 'mostrecent' => &mt('most recent'),
- map {$_,$_} (1..$currentversion)}));
- my $lastold=1;
- for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) {
- my $url=$root.'.'.$prevvers.'.'.$extension;
- if (&Apache::lonnet::metadata($url,'lastrevisiondate')<
- $starttime) {
- $lastold=$prevvers;
- }
- }
- #
- # Code to figure out how many version entries should go in
- # each of the four columns
- my $entries_per_col = 0;
- my $num_entries = ($currentversion-$lastold);
- if ($num_entries % $num_ver_col == 0) {
- $entries_per_col = $num_entries/$num_ver_col;
} else {
- $entries_per_col = $num_entries/$num_ver_col + 1;
+ $r->print($currentversion);
}
- my $entries_count = 0;
- $r->print(' ');
- my $cols_output = 1;
- for (my $prevvers=$lastold;$prevvers<$currentversion;$prevvers++) {
- my $url=$root.'.'.$prevvers.'.'.$extension;
- $r->print(''.&mt('Version').' '.$prevvers.' ('.
- &Apache::lonlocal::locallocaltime(
- &Apache::lonnet::metadata($url,
- 'lastrevisiondate')
- ).
- ')');
- if (&Apache::loncommon::fileembstyle($extension) eq 'ssi') {
- $r->print(' '.&mt('Diffs').' ');
- }
- $r->print(' ');
- if (++$entries_count % $entries_per_col == 0) {
- $r->print(' ');
- if ($cols_output != $num_ver_col) {
- $r->print('');
- $cols_output++;
- }
- }
- }
- while($cols_output++ < $num_ver_col) {
- $r->print(' ');
+ $r->print(' ');
+ # Set version
+ $r->print(&Apache::loncommon::select_form(
+ $setversions{$linkurl},
+ 'set_version_'.$linkurl,
+ {'select_form_order' => ['',1..$currentversion,'mostrecent'],
+ '' => '',
+ 'mostrecent' => &mt('most recent'),
+ map {$_,$_} (1..$currentversion)}));
+ my $lastold=1;
+ for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) {
+ my $url=$root.'.'.$prevvers.'.'.$extension;
+ if (&Apache::lonnet::metadata($url,'lastrevisiondate')<$starttime) {
+ $lastold=$prevvers;
+ }
+ }
+ $r->print(' ');
+ # List all available versions
+ $r->print('');
+ for (my $prevvers=$lastold;$prevvers<$currentversion;$prevvers++) {
+ my $url=$root.'.'.$prevvers.'.'.$extension;
+ $r->print(
+ ''
+ .''
+ .&mt('Version [_1]',$prevvers).' '
+ .' ('.&Apache::lonlocal::locallocaltime(
+ &Apache::lonnet::metadata($url,'lastrevisiondate'))
+ .')');
+ if (&Apache::loncommon::fileembstyle($extension) eq 'ssi') {
+ $r->print(
+ ' &').
+ '" target="diffs">'.&mt('Diffs').' ');
}
- }
+ $r->print(' ');
+ }
+ $r->print(' '.&Apache::loncommon::end_data_table_row());
}
- $r->print(''.&Apache::loncommon::end_data_table_row().
- &Apache::loncommon::end_data_table().
- ' ');
+ $r->print(
+ &Apache::loncommon::end_data_table().
+ ' '.
+ ''
+ );
&untiehash();
+ $r->print(&endContentScreen());
}
sub mark_hash_old {
@@ -3060,11 +3900,6 @@ sub changewarning {
my $pathvar='folderpath';
my $path=&escape($env{'form.folderpath'});
if (!defined($url)) {
- if (defined($env{'form.pagepath'})) {
- $pathvar='pagepath';
- $path=&escape($env{'form.pagepath'});
- $path.='&pagesymb='.&escape($env{'form.pagesymb'});
- }
$url='/adm/coursedocs?'.$pathvar.'='.$path;
}
my $course_type = &Apache::loncommon::course_type();
@@ -3130,6 +3965,7 @@ sub startContentScreen {
if (($mode eq 'navmaps') || ($mode eq 'supplemental')) {
$output .= ' '.&mt('Content Overview').' '."\n";
$output .= ' '.&mt('Content Search').' '."\n";
+ $output .= ' '.&mt('Content Index').' '."\n";
$output .= ''.&mt('Supplemental Content').' ';
} else {
$output .= ' '.&mt('Content Editor').' '."\n";
@@ -3176,7 +4012,7 @@ sub handler {
'Adding_External_Resource','Navigate_Content',
'Adding_Folders','Docs_Overview', 'Load_Map',
'Supplemental','Score_Upload_Form','Adding_Pages',
- 'Importing_LON-CAPA_Resource','Importing_IMS_Course',
+ 'Importing_LON-CAPA_Resource','Importing_IMS_Course',
'Uploading_From_Harddrive',
'Check_Resource_Versions','Verify_Content') {
$help{$topic}=&Apache::loncommon::help_open_topic('Docs_'.$topic);
@@ -3194,8 +4030,9 @@ sub handler {
'Docs_About_My_Personal_Info,Docs_Editing_Templated_Pages');
$help{'Group Portfolio'} = &Apache::loncommon::help_open_topic('Docs_About_Group_Files');
$help{'Caching'} = &Apache::loncommon::help_open_topic('Caching');
-
-
+ $help{'Course Roster'} = &Apache::loncommon::help_open_topic('Docs_Course_Roster');
+ $help{'Web Page'} = &Apache::loncommon::help_open_topic('Docs_Web_Page');
+
my $allowed;
# URI is /adm/supplemental when viewing supplemental docs in non-edit mode.
unless ($r->uri eq '/adm/supplemental') {
@@ -3237,9 +4074,9 @@ sub handler {
# Get the parameters that may be needed
#
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
- ['folderpath','pagepath',
- 'pagesymb','forcesupplement','forcestandard',
- 'tools','symb','command']);
+ ['folderpath',
+ 'forcesupplement','forcestandard',
+ 'tools','symb','command','supppath']);
# standard=1: this is a "new-style" course with an uploaded map as top level
# standard=2: this is a "old-style" course, and there is nothing we can do
@@ -3251,9 +4088,9 @@ sub handler {
# supplementalflag=0: show standard documents
# toolsflag=1: show utilities
-
+ $env{'form.folderpath'} = &unescape($env{'form.folderpath'});
my $supplementalflag=($env{'form.folderpath'}=~/^supplemental/);
- if (($env{'form.folderpath'}=~/^default/) || $env{'form.folderpath'} eq "" || ($env{'form.pagepath'})) {
+ if (($env{'form.folderpath'}=~/^default/) || ($env{'form.folderpath'} eq "")) {
$supplementalflag=0;
}
if ($env{'form.forcesupplement'}) { $supplementalflag=1; }
@@ -3268,106 +4105,57 @@ sub handler {
my $addentries = {};
my $container;
my $containertag;
- my $uploadtag;
+ my $pathitem;
# Do we directly jump somewhere?
- if ($env{'form.command'} eq 'direct') {
- my ($mapurl,$id,$resurl);
+ if (($env{'form.command'} eq 'direct') || ($env{'form.command'} eq 'directnav')) {
if ($env{'form.symb'} ne '') {
- ($mapurl,$id,$resurl) = &Apache::lonnet::decode_symb($env{'form.symb'});
- if ($resurl=~/\.(sequence|page)$/) {
- $mapurl=$resurl;
- } elsif ($resurl eq 'adm/navmaps') {
- $mapurl=$env{'course.'.$env{'request.course.id'}.'.url'};
- }
- my $mapresobj;
- my $navmap = Apache::lonnavmaps::navmap->new();
- if (ref($navmap)) {
- $mapresobj = $navmap->getResourceByUrl($mapurl);
- }
- $mapurl=~s{^.*/([^/]+)\.(\w+)$}{$1};
- my $type=$2;
- my $path;
- if (ref($mapresobj)) {
- my $pcslist = $mapresobj->map_hierarchy();
- if ($pcslist ne '') {
- foreach my $pc (split(/,/,$pcslist)) {
- next if ($pc <= 1);
- my $res = $navmap->getByMapPc($pc);
- if (ref($res)) {
- my $thisurl = $res->src();
- $thisurl=~s{^.*/([^/]+)\.\w+$}{$1};
- my $thistitle = $res->title();
- $path .= '&'.
- &Apache::lonhtmlcommon::entity_encode($thisurl).'&'.
- &Apache::lonhtmlcommon::entity_encode($thistitle).
- ':'.$res->randompick().
- ':'.$res->randomout().
- ':'.$res->encrypted().
- ':'.$res->randomorder();
- }
- }
- }
- $path .= '&'.&Apache::lonhtmlcommon::entity_encode($mapurl).'&'.
- &Apache::lonhtmlcommon::entity_encode($mapresobj->title()).
- ':'.$mapresobj->randompick().
- ':'.$mapresobj->randomout().
- ':'.$mapresobj->encrypted().
- ':'.$mapresobj->randomorder();
- } else {
- my $maptitle = &Apache::lonnet::gettitle($mapurl);
- $path = '&default&...::::'.
- '&'.&Apache::lonhtmlcommon::entity_encode($mapurl).'&'.
- &Apache::lonhtmlcommon::entity_encode($maptitle).'::::';
- }
- $path = 'default&'.
- &Apache::lonhtmlcommon::entity_encode('Main Course Documents').
- $path;
- if ($type eq 'sequence') {
- $env{'form.folderpath'}=$path;
- $env{'form.pagepath'}='';
- } else {
- $env{'form.pagepath'}=$path;
- $env{'form.folderpath'}='';
- }
+ $env{'form.folderpath'}=
+ &Apache::loncommon::symb_to_docspath($env{'form.symb'});
+ &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} =>
+ $env{'form.command'}.'_'.$env{'form.symb'}});
} elsif ($env{'form.supppath'} ne '') {
$env{'form.folderpath'}=$env{'form.supppath'};
+ &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} =>
+ $env{'form.command'}.'_'.$env{'form.supppath'}});
}
} elsif ($env{'form.command'} eq 'editdocs') {
- $env{'form.folderpath'} = 'default&'.
- &Apache::lonhtmlcommon::entity_encode('Main Course Content');
- $env{'form.pagepath'}='';
+ $env{'form.folderpath'} = 'default&'.
+ &escape(&mt('Main '.$crstype.' Content').':::::');
+ &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => $env{'form.command'}});
} elsif ($env{'form.command'} eq 'editsupp') {
- $env{'form.folderpath'} = 'default&'.
- &Apache::lonhtmlcommon::entity_encode('Supplemental Content');
- $env{'form.pagepath'}='';
+ $env{'form.folderpath'} = 'supplemental&'.
+ &escape('Supplemental Content');
+ &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/supplemental'});
+ } elsif ($env{'form.command'} eq 'contents') {
+ &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/navmaps'});
+ } elsif ($env{'form.command'} eq 'home') {
+ &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/menu'});
}
+
# Where do we store these for when we come back?
my $stored_folderpath='docs_folderpath';
if ($supplementalflag) {
$stored_folderpath='docs_sup_folderpath';
}
-# No folderpath, no pagepath, see if we have something stored
- if ((!$env{'form.folderpath'}) && (!$env{'form.pagepath'})) {
+# No folderpath, and in edit mode, see if we have something stored
+ if ((!$env{'form.folderpath'}) && $allowed) {
&Apache::loncommon::restore_course_settings($stored_folderpath,
- {'folderpath' => 'scalar'});
+ {'folderpath' => 'scalar'});
+ unless (&unescape($env{'form.folderpath'}) =~ m{^(default|supplemental)&}) {
+ undef($env{'form.folderpath'});
+ }
}
# If we are not allowed to make changes, all we can see are supplemental docs
if (!$allowed) {
- $env{'form.pagepath'}='';
unless ($env{'form.folderpath'} =~ /^supplemental/) {
$env{'form.folderpath'} = &supplemental_base();
}
}
-# If we still not have a folderpath, see if we can resurrect at pagepath
- if (!$env{'form.folderpath'} && $allowed) {
- &Apache::loncommon::restore_course_settings($stored_folderpath,
- {'pagepath' => 'scalar'});
- }
# Make the zeroth entry in supplemental docs page paths, so we can get to top level
if ($env{'form.folderpath'} =~ /^supplemental_\d+/) {
$env{'form.folderpath'} = &supplemental_base()
@@ -3375,48 +4163,41 @@ sub handler {
$env{'form.folderpath'};
}
# If after all of this, we still don't have any paths, make them
- unless (($env{'form.pagepath'}) || ($env{'form.folderpath'})) {
+ unless ($env{'form.folderpath'}) {
if ($supplementalflag) {
$env{'form.folderpath'}=&supplemental_base();
} else {
- $env{'form.folderpath'}='default';
+ $env{'form.folderpath'}='default'.&escape(&mt('Main '.$crstype.' Content').
+ ':::::');
}
}
# Store this
unless ($toolsflag) {
- &Apache::loncommon::store_course_settings($stored_folderpath,
- {'pagepath' => 'scalar',
- 'folderpath' => 'scalar'});
+ if ($allowed) {
+ &Apache::loncommon::store_course_settings($stored_folderpath,
+ {'folderpath' => 'scalar'});
+ }
+ my $folderpath;
if ($env{'form.folderpath'}) {
- my (@folderpath)=split('&',$env{'form.folderpath'});
- $env{'form.foldername'}=&unescape(pop(@folderpath));
- $env{'form.folder'}=pop(@folderpath);
- $container='sequence';
- }
- if ($env{'form.pagepath'}) {
- my (@pagepath)=split('&',$env{'form.pagepath'});
- $env{'form.pagename'}=&unescape(pop(@pagepath));
- $env{'form.folder'}=pop(@pagepath);
- $container='page';
- $containertag = ' '.
- ' ';
- $uploadtag =
- ' '.
- ' '.
- ' ';
+ $folderpath = $env{'form.folderpath'};
+ my (@folders)=split('&',$env{'form.folderpath'});
+ $env{'form.foldername'}=&unescape(pop(@folders));
+ if ($env{'form.foldername'} =~ /\:1$/) {
+ $container = 'page';
+ } else {
+ $container = 'sequence';
+ }
+ $env{'form.folder'}=pop(@folders);
} else {
- my $folderpath=$env{'form.folderpath'};
- if (!$folderpath) {
- if ($env{'form.folder'} eq '' ||
- $env{'form.folder'} eq 'supplemental') {
- $folderpath='default&'.
- &escape(&mt('Main '.$crstype.' Documents'));
- }
+ if ($env{'form.folder'} eq '' ||
+ $env{'form.folder'} eq 'supplemental') {
+ $folderpath='default&'.
+ &escape(&mt('Main '.$crstype.' Content').':::::');
}
- $containertag = ' ';
- $uploadtag = ' ';
}
+ $containertag = ' ';
+ $pathitem = ' ';
if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) {
$showdoc='/'.$1;
}
@@ -3454,7 +4235,7 @@ sub handler {
@tabids = ('002','ee2','ff2');
} else {
@tabids = ('aa1','bb1','cc1','ff1');
- unless ($env{'form.pagepath'}) {
+ unless ($env{'form.folderpath'} =~ /\:1$/) {
unshift(@tabids,'001');
push(@tabids,('dd1','ee1'));
}
@@ -3463,16 +4244,17 @@ sub handler {
$script .= &editing_js($udom,$uname,$supplementalflag).
&history_tab_js().
&inject_data_js().
- &Apache::lonhtmlcommon::resize_scrollbox_js('docs',$tabidstr);
+ &Apache::lonhtmlcommon::resize_scrollbox_js('docs',$tabidstr).
+ &Apache::lonextresedit::extedit_javascript();
$addentries = {
onload => "javascript:resize_scrollbox('contentscroll','1','1');",
};
}
- if ($env{'docs.markedcopy_url'}) {
- $script .= &paste_popup_js();
- }
+ $script .= &paste_popup_js();
my $confirm_switch = &mt("Editing requires switching to the resource's home server.").'\n'.
&mt('Switch server?');
+
+
}
# -------------------------------------------------------------------- Body tag
$script = '