--- loncom/interface/londocs.pm 2004/06/15 15:50:03 1.130
+++ loncom/interface/londocs.pm 2012/08/27 15:58:05 1.484.2.8
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Documents
#
-# $Id: londocs.pm,v 1.130 2004/06/15 15:50:03 www Exp $
+# $Id: londocs.pm,v 1.484.2.8 2012/08/27 15:58:05 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -30,15 +30,23 @@ package Apache::londocs;
use strict;
use Apache::Constants qw(:common :http);
+use Apache::imsexport;
use Apache::lonnet;
use Apache::loncommon;
-use Apache::lonratedt;
-use Apache::lonratsrv;
+use Apache::lonhtmlcommon;
+use LONCAPA::map();
+use Apache::lonratedt();
use Apache::lonxml;
-use Apache::loncreatecourse;
+use Apache::lonclonecourse;
+use Apache::lonnavmaps;
+use Apache::lonnavdisplay();
+use Apache::lonuserstate();
use HTML::Entities;
+use HTML::TokeParser;
use GDBM_File;
use Apache::lonlocal;
+use Cwd;
+use LONCAPA qw(:DEFAULT :match);
my $iconpath;
@@ -49,490 +57,2118 @@ my %alreadyseen=();
my $hadchanges;
-# Available help topics
my %help=();
-# Mapread read maps into lonratedt::global arrays
-# @order and @resources, determines status
-# sets @order - pointer to resources in right order
-# sets @resources - array with the resources with correct idx
-#
sub mapread {
my ($coursenum,$coursedom,$map)=@_;
return
- &Apache::lonratedt::mapread('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
- $map);
+ &LONCAPA::map::mapread('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
+ $map);
}
sub storemap {
- my ($coursenum,$coursedom,$map)=@_;
+ my ($coursenum,$coursedom,$map,$contentchg)=@_;
+ my $report;
+ if (($contentchg) && ($map =~ /^default/)) {
+ $report = 1;
+ }
my ($outtext,$errtext)=
- &Apache::lonratedt::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
- $map,1);
+ &LONCAPA::map::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
+ $map,1,$report);
if ($errtext) { return ($errtext,2); }
-
+
$hadchanges=1;
return ($errtext,0);
}
-# ----------------------------------------- Return hash with valid author names
+
sub authorhosts {
my %outhash=();
my $home=0;
my $other=0;
- foreach (keys %ENV) {
- if ($_=~/^user\.role\.(au|ca)\.(.+)$/) {
+ foreach my $key (keys(%env)) {
+ if ($key=~/^user\.role\.(au|ca)\.(.+)$/) {
my $role=$1;
my $realm=$2;
- my ($start,$end)=split(/\./,$ENV{$_});
+ my ($start,$end)=split(/\./,$env{$key});
if (($start) && ($start>time)) { next; }
if (($end) && (time>$end)) { next; }
- my $ca; my $cd;
+ my ($ca,$cd);
if ($1 eq 'au') {
- $ca=$ENV{'user.name'};
- $cd=$ENV{'user.domain'};
+ $ca=$env{'user.name'};
+ $cd=$env{'user.domain'};
} else {
- ($cd,$ca)=($realm=~/^\/(\w+)\/(\w+)$/);
+ ($cd,$ca)=($realm=~/^\/($match_domain)\/($match_username)$/);
}
my $allowed=0;
my $myhome=&Apache::lonnet::homeserver($ca,$cd);
my @ids=&Apache::lonnet::current_machine_ids();
- foreach my $id (@ids) { if ($id eq $myhome) { $allowed=1; } }
+ foreach my $id (@ids) {
+ if ($id eq $myhome) {
+ $allowed=1;
+ last;
+ }
+ }
if ($allowed) {
$home++;
- $outhash{'home_'.$ca.'@'.$cd}=1;
+ $outhash{'home_'.$ca.':'.$cd}=1;
} else {
- $outhash{'otherhome_'.$ca.'@'.$cd}=$myhome;
+ $outhash{'otherhome_'.$ca.':'.$cd}=$myhome;
$other++;
}
}
}
return ($home,$other,%outhash);
}
-# ------------------------------------------------------ Generate "dump" button
-sub dumpbutton {
- my ($home,$other,%outhash)=&authorhosts();
- if ($home+$other==0) { return ''; }
- my $output='
';
- if ($home) {
- return ' '.
- ' '.
- &Apache::loncommon::help_open_topic('Docs_Dump_Course_Docs');
- } else {
- return' '.
- &mt('Dump Course DOCS to Construction Space: available on other servers');
- }
+
+sub clean {
+ my ($title)=@_;
+ $title=~s/[^\w\/\!\$\%\^\*\-\_\=\+\;\:\,\\\|\`\~]+/\_/gs;
+ return $title;
}
-# -------------------------------------------------------- Actually dump course
+
sub dumpcourse {
- my $r=shift;
- $r->print('Dump DOCS '.
- &Apache::loncommon::bodytag('Dump Course DOCS to Construction Space').
- '');
+ '
');
}
+ $r->print(&endContentScreen());
}
-
-# Imports the given (name, url) resources into the course
-# coursenum, coursedom, and folder must precede the list
sub group_import {
- my $coursenum = shift;
- my $coursedom = shift;
- my $folder = shift;
- while (@_) {
- my $name = shift;
- my $url = shift;
+ my ($coursenum, $coursedom, $folder, $container, $caller, @files) = @_;
+
+ while (@files) {
+ my ($name, $url, $residx) = @{ shift(@files) };
+ if (($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$})
+ && ($caller eq 'londocs')
+ && (!&Apache::lonnet::stat_file($url))) {
+
+ my $errtext = '';
+ my $fatal = 0;
+ my $newmapstr = ''."\n".
+ ' '."\n".
+ ' '."\n".
+ ' '."\n".
+ ' ';
+ $env{'form.output'}=$newmapstr;
+ my $result=&Apache::lonnet::finishuserfileupload($coursenum,$coursedom,
+ 'output',$1.$2);
+ if ($result != m|^/uploaded/|) {
+ $errtext.='Map not saved: A network error occurred when trying to save the new map. ';
+ $fatal = 2;
+ }
+ if ($fatal) {
+ return ($errtext,$fatal);
+ }
+ }
if ($url) {
- my $idx = $#Apache::lonratedt::resources + 1;
- $Apache::lonratedt::order[$#Apache::lonratedt::order+1]=$idx;
+ if (!$residx
+ || defined($LONCAPA::map::zombies[$residx])) {
+ $residx = &LONCAPA::map::getresidx($url,$residx);
+ push(@LONCAPA::map::order, $residx);
+ }
my $ext = 'false';
- if ($url=~/^http:\/\//) { $ext = 'true'; }
- $url =~ s/:/\:/g;
- $name =~ s/:/\:/g;
- $Apache::lonratedt::resources[$idx] =
- join ':', ($name, $url, $ext, 'normal', 'res');
+ if ($url=~m{^http://} || $url=~m{^https://}) { $ext = 'true'; }
+ $url = &LONCAPA::map::qtunescape($url);
+ $name = &LONCAPA::map::qtunescape($name);
+ $LONCAPA::map::resources[$residx] =
+ join(':', ($name, $url, $ext, 'normal', 'res'));
}
}
- return &storemap($coursenum, $coursedom, $folder.'.sequence');
+ return &storemap($coursenum, $coursedom, $folder.'.'.$container,1);
}
sub breadcrumbs {
- my ($where)=@_;
+ my ($allowed,$crstype)=@_;
&Apache::lonhtmlcommon::clear_breadcrumbs();
- my (@folders)=split('&',$ENV{'form.folderpath'});
+ my (@folders);
+ if ($env{'form.pagepath'}) {
+ @folders = split('&',$env{'form.pagepath'});
+ } else {
+ @folders=split('&',$env{'form.folderpath'});
+ }
my $folderpath;
+ my $cpinfo='';
+ 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);
+ my $foldername=shift(@folders);
if ($folderpath) {$folderpath.='&';}
$folderpath.=$folder.'&'.$foldername;
- my $url='/adm/coursedocs?folderpath='.
- &Apache::lonnet::escape($folderpath);
- &Apache::lonhtmlcommon::add_breadcrumb(
- {'href'=>$url,
- 'title'=>&Apache::lonnet::unescape($foldername),
- 'text'=>''.
- &Apache::lonnet::unescape($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.$cpinfo,
+ 'title'=>$name,
+ 'text'=>$name,
+ 'no_mt'=>1,
});
-
-
+ $plain.=$name.' > ';
}
- return &Apache::lonhtmlcommon::breadcrumbs(undef,undef,undef,undef,undef,0);
+ $plain=~s/\>\;\s*$//;
+ return (&Apache::lonhtmlcommon::breadcrumbs(undef,undef,0,'nohelp',
+ undef, undef, 1 ),$randompick,$ishidden,
+ $isencrypted,$plain,$is_random_order);
}
-sub editor {
- my ($r,$coursenum,$coursedom,$folder,$allowed)=@_;
+sub log_docs {
+ return &Apache::lonnet::write_log('course','docslog',@_);
+}
- $r->print(&breadcrumbs($folder));
- my $errtext='';
- my $fatal=0;
- ($errtext,$fatal)=
- &mapread($coursenum,$coursedom,$folder.'.sequence');
- if ($#Apache::lonratedt::order<1) {
- $Apache::lonratedt::order[0]=1;
- $Apache::lonratedt::resources[1]='';
+{
+ my @oldresources=();
+ my @oldorder=();
+ my $parmidx;
+ my %parmaction=();
+ my %parmvalue=();
+ my $changedflag;
+
+ sub snapshotbefore {
+ @oldresources=@LONCAPA::map::resources;
+ @oldorder=@LONCAPA::map::order;
+ $parmidx=undef;
+ %parmaction=();
+ %parmvalue=();
+ $changedflag=0;
}
- if ($fatal) {
- $r->print(''.$errtext.'
');
+
+ sub remember_parms {
+ my ($idx,$parameter,$action,$value)=@_;
+ $parmidx=$idx;
+ $parmaction{$parameter}=$action;
+ $parmvalue{$parameter}=$value;
+ $changedflag=1;
+ }
+
+ sub log_differences {
+ my ($plain)=@_;
+ my %storehash=('folder' => $plain,
+ 'currentfolder' => $env{'form.folder'});
+ if ($parmidx) {
+ $storehash{'parameter_res'}=$oldresources[$parmidx];
+ foreach my $parm (keys(%parmaction)) {
+ $storehash{'parameter_action_'.$parm}=$parmaction{$parm};
+ $storehash{'parameter_value_'.$parm}=$parmvalue{$parm};
+ }
+ }
+ my $maxidx=$#oldresources;
+ if ($#LONCAPA::map::resources>$#oldresources) {
+ $maxidx=$#LONCAPA::map::resources;
+ }
+ for (my $idx=0; $idx<=$maxidx; $idx++) {
+ if ($LONCAPA::map::resources[$idx] ne $oldresources[$idx]) {
+ $storehash{'before_resources_'.$idx}=$oldresources[$idx];
+ $storehash{'after_resources_'.$idx}=$LONCAPA::map::resources[$idx];
+ $changedflag=1;
+ }
+ if ($LONCAPA::map::order[$idx] ne $oldorder[$idx]) {
+ $storehash{'before_order_res_'.$idx}=$oldresources[$oldorder[$idx]];
+ $storehash{'after_order_res_'.$idx}=$LONCAPA::map::resources[$LONCAPA::map::order[$idx]];
+ $changedflag=1;
+ }
+ }
+ $storehash{'maxidx'}=$maxidx;
+ if ($changedflag) { &log_docs(\%storehash); }
+ }
+}
+
+sub docs_change_log {
+ my ($r,$coursenum,$coursedom,$folder,$allowed,$crstype,$iconpath)=@_;
+ my $supplementalflag=($env{'form.folderpath'}=~/^supplemental/);
+ my $js = ''."\n";
+ $r->print(&Apache::loncommon::start_page('Content Change Log',$js));
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs('Content Change Log'));
+ $r->print(&startContentScreen(($supplementalflag?'suppdocs':'docs')));
+ my %orderhash;
+ my $container='sequence';
+ my $pathitem;
+ if ($env{'form.pagepath'}) {
+ $container='page';
+ $pathitem = ' ';
+ } else {
+ my $folderpath=$env{'form.folderpath'};
+ if ($folderpath eq '') {
+ $folderpath = 'default&'.&escape(&mt('Main '.$crstype.' Documents'));
+ }
+ $pathitem = ' ';
+ }
+ my $readfile="/uploaded/$coursedom/$coursenum/$folder.$container";
+ my $jumpto = $readfile;
+ $jumpto =~ s{^/}{};
+ my $tid = 1;
+ if ($supplementalflag) {
+ $tid = 2;
+ }
+ my ($breadcrumbtrail) = &breadcrumbs($allowed,$crstype);
+ $r->print($breadcrumbtrail.
+ &generate_edit_table($tid,\%orderhash,undef,$iconpath,$jumpto,
+ $readfile));
+ my %docslog=&Apache::lonnet::dump('nohist_docslog',
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
+
+ if ((keys(%docslog))[0]=~/^error\:/) { undef(%docslog); }
+
+ my %saveable_parameters = ('show' => 'scalar',);
+ &Apache::loncommon::store_course_settings('docs_log',
+ \%saveable_parameters);
+ &Apache::loncommon::restore_course_settings('docs_log',
+ \%saveable_parameters);
+ if (!$env{'form.show'}) { $env{'form.show'}=10; }
+# FIXME: internationalization seems wrong here
+ my %lt=('hiddenresource' => 'Resources hidden',
+ 'encrypturl' => 'URL hidden',
+ 'randompick' => 'Randomly pick',
+ 'randomorder' => 'Randomly ordered',
+ 'set' => 'set to',
+ 'del' => 'deleted');
+ my $filter = &Apache::loncommon::display_filter('docslog')."\n".
+ $pathitem."\n".
+ ' '.
+ (' 'x2).' ';
+ $r->print(''.
+ '
'.&mt('Display of Content Changes').' '."\n".
+ &makedocslogform($filter,1).
+ ' ');
+ $r->print(&Apache::loncommon::start_data_table().&Apache::loncommon::start_data_table_header_row().
+ ' '.&mt('Time').' '.&mt('User').' '.&mt('Folder').' '.&mt('Before').' '.
+ &mt('After').' '.
+ &Apache::loncommon::end_data_table_header_row());
+ my $shown=0;
+ foreach my $id (sort { $docslog{$b}{'exe_time'}<=>$docslog{$a}{'exe_time'} } (keys(%docslog))) {
+ if ($env{'form.displayfilter'} eq 'currentfolder') {
+ if ($docslog{$id}{'logentry'}{'currentfolder'} ne $folder) { next; }
+ }
+ my @changes=keys(%{$docslog{$id}{'logentry'}});
+ if ($env{'form.displayfilter'} eq 'containing') {
+ my $wholeentry=$docslog{$id}{'exe_uname'}.':'.$docslog{$id}{'exe_udom'}.':'.
+ &Apache::loncommon::plainname($docslog{$id}{'exe_uname'},$docslog{$id}{'exe_udom'});
+ foreach my $key (@changes) {
+ $wholeentry.=':'.$docslog{$id}{'logentry'}{$key};
+ }
+ if ($wholeentry!~/\Q$env{'form.containingphrase'}\E/i) { next; }
+ }
+ my $count = 0;
+ my $time =
+ &Apache::lonlocal::locallocaltime($docslog{$id}{'exe_time'});
+ my $plainname =
+ &Apache::loncommon::plainname($docslog{$id}{'exe_uname'},
+ $docslog{$id}{'exe_udom'});
+ my $about_me_link =
+ &Apache::loncommon::aboutmewrapper($plainname,
+ $docslog{$id}{'exe_uname'},
+ $docslog{$id}{'exe_udom'});
+ my $send_msg_link='';
+ if ((($docslog{$id}{'exe_uname'} ne $env{'user.name'})
+ || ($docslog{$id}{'exe_udom'} ne $env{'user.domain'}))) {
+ $send_msg_link =' '.
+ &Apache::loncommon::messagewrapper(&mt('Send message'),
+ $docslog{$id}{'exe_uname'},
+ $docslog{$id}{'exe_udom'});
+ }
+ $r->print(&Apache::loncommon::start_data_table_row());
+ $r->print(''.$time.'
+ '.$about_me_link.
+ ''.$docslog{$id}{'exe_uname'}.
+ ':'.$docslog{$id}{'exe_udom'}.' '.
+ $send_msg_link.' '.
+ $docslog{$id}{'logentry'}{'folder'}.' ');
+ my $is_supp = 0;
+ if ($docslog{$id}{'logentry'}{'currentfolder'} =~ /^supplemental/) {
+ $is_supp = 1;
+ }
+# Before
+ for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
+ my $oldname=(split(/\:/,$docslog{$id}{'logentry'}{'before_resources_'.$idx}))[0];
+ my $newname=(split(/\:/,$docslog{$id}{'logentry'}{'after_resources_'.$idx}))[0];
+ if ($oldname ne $newname) {
+ my $shown = &LONCAPA::map::qtescape($oldname);
+ if ($is_supp) {
+ $shown = &Apache::loncommon::parse_supplemental_title($shown);
+ }
+ $r->print($shown);
+ }
+ }
+ $r->print('');
+ for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
+ if ($docslog{$id}{'logentry'}{'before_order_res_'.$idx}) {
+ my $shown = &LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'before_order_res_'.$idx}))[0]);
+ if ($is_supp) {
+ $shown = &Apache::loncommon::parse_supplemental_title($shown);
+ }
+ $r->print(''.$shown.' ');
+ }
+ }
+ $r->print(' ');
+# After
+ $r->print(' ');
+
+ for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
+ my $oldname=(split(/\:/,$docslog{$id}{'logentry'}{'before_resources_'.$idx}))[0];
+ my $newname=(split(/\:/,$docslog{$id}{'logentry'}{'after_resources_'.$idx}))[0];
+ if ($oldname ne '' && $oldname ne $newname) {
+ my $shown = &LONCAPA::map::qtescape($newname);
+ if ($is_supp) {
+ $shown = &Apache::loncommon::parse_supplemental_title(&LONCAPA::map::qtescape($newname));
+ }
+ $r->print($shown);
+ }
+ }
+ $r->print('');
+ for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
+ if ($docslog{$id}{'logentry'}{'after_order_res_'.$idx}) {
+ my $shown = &LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'after_order_res_'.$idx}))[0]);
+ if ($is_supp) {
+ $shown = &Apache::loncommon::parse_supplemental_title($shown);
+ }
+ $r->print(''.$shown.' ');
+ }
+ }
+ $r->print(' ');
+ if ($docslog{$id}{'logentry'}{'parameter_res'}) {
+ $r->print(&LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'parameter_res'}))[0]).':');
+ foreach my $parameter ('randompick','hiddenresource','encrypturl','randomorder') {
+ if ($docslog{$id}{'logentry'}{'parameter_action_'.$parameter}) {
+# FIXME: internationalization seems wrong here
+ $r->print(''.
+ &mt($lt{$parameter}.' '.$lt{$docslog{$id}{'logentry'}{'parameter_action_'.$parameter}}.' [_1]',
+ $docslog{$id}{'logentry'}{'parameter_value_'.$parameter})
+ .' ');
+ }
+ }
+ $r->print(' ');
+ }
+# End
+ $r->print(' '.&Apache::loncommon::end_data_table_row());
+ $shown++;
+ if (!($env{'form.show'} eq &mt('all')
+ || $shown<=$env{'form.show'})) { last; }
+ }
+ $r->print(&Apache::loncommon::end_data_table()."\n".
+ &makesimpleeditform($pathitem)."\n".
+ '');
+ $r->print(&endContentScreen());
+}
+
+sub update_paste_buffer {
+ my ($coursenum,$coursedom,$folder) = @_;
+
+ return if (!defined($env{'form.markcopy'}));
+ 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;
+ }
+ }
+ }
+ &Apache::lonnet::appenv(\%addtoenv);
+ delete($env{'form.markcopy'});
+}
+
+sub recurse_uploaded_maps {
+ my ($url,$dir,$hierarchy,$titlesref,$nestref,$namesref) = @_;
+ if (ref($hierarchy->{$url}) eq 'HASH') {
+ my @maps = map { $hierarchy->{$url}{$_}; } sort { $a <=> $b } (keys(%{$hierarchy->{$url}}));
+ my @titles = map { $titlesref->{$url}{$_}; } sort { $a <=> $b } (keys(%{$titlesref->{$url}}));
+ my (@uploaded,@names,%shorter);
+ for (my $i=0; $i<@maps; $i++) {
+ my ($inner) = ($maps[$i] =~ m{^/uploaded/$match_domain/$match_courseid/(?:default|supplemental)_(\d+)\.(?:page|sequence)$});
+ if ($inner ne '') {
+ push(@uploaded,$inner);
+ push(@names,&escape($titles[$i]));
+ $shorter{$maps[$i]} = $inner;
+ }
+ }
+ $$nestref .= "$dir:".join(',',@uploaded).'&';
+ $$namesref .= "$dir:".(join(',',@names)).'___&&&___';
+ foreach my $map (@maps) {
+ if ($shorter{$map} ne '') {
+ &recurse_uploaded_maps($map,$shorter{$map},$hierarchy,$titlesref,$nestref,$namesref);
+ }
+ }
+ }
+ return;
+}
+
+sub print_paste_buffer {
+ my ($r,$container,$folder,$coursedom,$coursenum) = @_;
+ return if (!defined($env{'docs.markedcopy_url'}));
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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.')
+ }
+ }
+ if ($rem =~ m{^(default|supplemental)_?(\d*)\.(?:page|sequence)$}) {
+ my $prefix = $1;
+ $parent = $2;
+ if ($folder !~ /^\Q$prefix\E/) {
+ $areachange = 1;
+ }
+ $is_uploaded_map = 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('');
+ } else {
+ $r->print(&mt('Paste buffer contains:').' '.$buffer.
+ ''.$nopaste.'
');
+ }
+ $r->print(' ');
+}
+
+sub recurse_print {
+ my ($r,$dir,$deps,$display) = @_;
+ $r->print($display->{$dir}."\n");
+ if (ref($deps->{$dir}) eq 'ARRAY') {
+ foreach my $subdir (@{$deps->{$dir}}) {
+ &recurse_print($r,$subdir,$deps,$display);
+ }
+ }
+}
+
+sub supp_pasteable {
+ my ($url) = @_;
+ if (($url =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//}) ||
+ (($url =~ /\.sequence$/) && ($url =~ m{^/uploaded/})) ||
+ ($url =~ m{^/uploaded/$match_domain/$match_courseid/(docs|supplemental)/(default|\d+)/\d+/}) ||
+ ($url =~ m{^/adm/$match_domain/$match_username/aboutme}) ||
+ ($url =~ m{^/public/$match_domain/$match_courseid/syllabus})) {
+ return 1;
+ }
+ return;
+}
+
+sub paste_popup_js {
+ my %lt = &Apache::lonlocal::texthash(
+ show => 'Show Paste Options',
+ hide => 'Hide Paste 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 =' ';
+ return;
+}
+
+function hidePasteOptions() {
+ document.getElementById('pasteoptions').style.display='none';
+ document.getElementById('pasteoptionstext').innerHTML ='';
+ return;
+}
+
+END
+
+}
+
+
+sub do_paste_from_buffer {
+ my ($coursenum,$coursedom,$folder,$container,$errors) = @_;
+
+# Early out if paste buffer is empty
+ if (!$env{'form.pastemarked'}) {
+ return ();
+ }
+
+# 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'));
+ }
+ }
+
+# 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 ($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;
+# 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.'));
+ }
+ }
+# 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');
+ }
+
+# 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);
+ }
+ }
+ foreach my $item (@nested) {
+ if ($env{'form.docs.markedcopy_'.$item} eq 'move') {
+ $tomove{$type.'_'.$item} = 1;
+ }
+ }
+ }
+ }
+
+# 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"});
+ }
+ }
+# 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;
+ }
+ $mapchanges{$url} = 1;
+ }
+ }
+ }
+ 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{/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'; }
+ $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) {
+# 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;
+ }
+ }
+ }
+ }
+ }
+# 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.':'.$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;
+ }
+ }
+
+ 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');
+ }
+ return ($result,$save_err);
+}
+
+sub get_newmap_url {
+ my ($url,$folder,$prefixchg,$coursedom,$coursenum,$srcdom,$srcnum,
+ $titleref,$allmaps,$newurls) = @_;
+ my $newurl;
+ if ($url=~ m{^/uploaded/}) {
+ $$titleref=&mt('Copy of').' '.$$titleref;
+ }
+ my $now = time;
+ my $suffix=$$.int(rand(100)).$now;
+ my ($oldid,$ext) = ($url=~/^(.+)\.(\w+)$/);
+ if ($oldid =~ m{^(/uploaded/$match_domain/$match_courseid/)(\D+)(\d+)$}) {
+ my $path = $1;
+ my $prefix = $2;
+ my $ancestor = $3;
+ if (length($ancestor) > 10) {
+ $ancestor = substr($ancestor,-10,10);
+ }
+ my $newid;
+ if ($prefixchg) {
+ if ($folder =~ /^supplemental/) {
+ $prefix =~ s/^default/supplemental/;
+ } else {
+ $prefix =~ s/^supplemental/default/;
+ }
+ }
+ if (($srcdom eq $coursedom) && ($srcnum eq $coursenum)) {
+ $newurl = $path.$prefix.$ancestor.$suffix.'.'.$ext;
+ } else {
+ $newurl = "/uploaded/$coursedom/$coursenum/$prefix".$now.'.'.$ext;
+ }
+ my $counter = 0;
+ my $is_unique = &uniqueness_check($newurl);
+ if ($folder =~ /^default/) {
+ if ($allmaps->{$newurl}) {
+ $is_unique = 0;
+ }
+ }
+ while ((!$is_unique || $allmaps->{$newurl} || $newurls->{$newurl}) && ($counter < 100)) {
+ $counter ++;
+ $suffix ++;
+ if (($srcdom eq $coursedom) && ($srcnum eq $coursenum)) {
+ $newurl = $path.$prefix.$ancestor.$suffix.'.'.$ext;
+ } else {
+ $newurl = "/uploaded/$coursedom/$coursenum/$prefix".$ancestor.$suffix.'.'.$ext;
+ }
+ $is_unique = &uniqueness_check($newurl);
+ }
+ if ($is_unique) {
+ $newurls->{$newurl} = 1;
+ } else {
+ if ($url=~/\.page$/) {
+ return (undef,&mt('Paste failed: an error occurred creating a unique URL for the composite page'));
+ } else {
+ return (undef,&mt('Paste failed: an error occurred creating a unique URL for the folder'));
+ }
+ }
+ }
+ return ($newurl);
+}
+
+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;
+ }
+ }
+ return $url;
+}
+
+sub uniqueness_check {
+ my ($newurl) = @_;
+ my $unique = 1;
+ foreach my $res (@LONCAPA::map::order) {
+ my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]);
+ $url=&LONCAPA::map::qtescape($url);
+ if ($newurl eq $url) {
+ $unique = 0;
+ last;
+ }
+ }
+ return $unique;
+}
+
+sub contained_map_check {
+ my ($url,$folder,$removefrommap,$removeparam,$addedmaps,$hierarchy,$titles,
+ $allmaps) = @_;
+ my $content = &Apache::lonnet::getfile($url);
+ unless ($content eq '-1') {
+ my $parser = HTML::TokeParser->new(\$content);
+ $parser->attr_encoded(1);
+ while (my $token = $parser->get_token) {
+ next if ($token->[0] ne 'S');
+ if ($token->[1] eq 'resource') {
+ next if ($token->[2]->{'type'} eq 'zombie');
+ my $ressrc = $token->[2]->{'src'};
+ if ($folder =~ /^supplemental/) {
+ unless (&supp_pasteable($ressrc)) {
+ $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;
+ next;
+ }
+ }
+ if ($ressrc =~ m{^/(res|uploaded)/.+\.(sequence|page)$}) {
+ if ($1 eq 'uploaded') {
+ $hierarchy->{$url}{$token->[2]->{'id'}} = $ressrc;
+ $titles->{$url}{$token->[2]->{'id'}} = $token->[2]->{'title'};
+ } else {
+ if ($allmaps->{$ressrc}) {
+ $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;
+ } elsif (ref($addedmaps->{$ressrc}) eq 'ARRAY') {
+ $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;
+ } else {
+ $addedmaps->{$ressrc} = [$url];
+ }
+ }
+ &contained_map_check($ressrc,$folder,$removefrommap,$removeparam,
+ $addedmaps,$hierarchy,$titles,$allmaps);
+ }
+ } elsif ($token->[1] eq 'param') {
+ if ($folder =~ /^supplemental/) {
+ 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'}];
+ }
+ }
+ }
+ }
+ }
+ 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 $checktitle;
+ if (($prefixchg) &&
+ ($oldurl =~ m{^/uploaded/$match_domain/$match_courseid/supplemental})) {
+ $checktitle = 1;
+ }
+ my $skip;
+ if ($oldurl =~ m{^\Q/uploaded/$cdom/$cnum/\E(default|supplemental)(_?\d*)\.(?:page|sequence)$}) {
+ my $mapid = $1.$2;
+ if ($tomove->{$mapid}) {
+ $skip = 1;
+ }
+ }
+ my $file = &Apache::lonnet::getfile($oldurl);
+ return if ($file eq '-1');
+ my $parser = HTML::TokeParser->new(\$file);
+ $parser->attr_encoded(1);
+ my $changed = 0;
+ while (my $token = $parser->get_token) {
+ next if ($token->[0] ne 'S');
+ if ($token->[1] eq 'resource') {
+ my $ressrc = $token->[2]->{'src'};
+ next if ($ressrc eq '');
+ my $id = $token->[2]->{'id'};
+ 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;
+ }
+ }
+ next if ($token->[2]->{'type'} eq 'external');
+ if ($token->[2]->{'type'} eq 'zombie') {
+ next if ($skip);
+ $zombies->{$oldurl}{$ressrc} = $id;
+ $changed = 1;
+ } elsif ($ressrc =~ m{^/uploaded/($match_domain)/($match_courseid)/(.+)$}) {
+ my $srcdom = $1;
+ my $srcnum = $2;
+ my $rem = $3;
+ my $newurl;
+ my $mapname;
+ if ($rem =~ /^(default|supplemental)(_?\d*).(sequence|page)$/) {
+ 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);
+ next;
+ } else {
+ ($newurl,my $error) =
+ &get_newmap_url($ressrc,$folder,$prefixchg,$cdom,$cnum,
+ $srcdom,$srcnum,\$title,$allmaps,$newurls);
+ if ($newurl =~ /(?:default|supplemental)_(\d+)\.(?:sequence|page)$/) {
+ $newsubdir->{$ressrc} = $1;
+ }
+ if ($error) {
+ next;
+ }
+ }
+ }
+ 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;
+ $mapchanges->{$ressrc} = 1;
+ unless (&url_paste_fixups($ressrc,$folder,$prefixchg,$cdom,$cnum,$allmaps,
+ $rewrites,$retitles,$copies,$dbcopies,$zombies,
+ $params,$mapmoves,$mapchanges,$tomove,$newsubdir,
+ $newurls)) {
+ $mapmoves->{$ressrc} = 1;
+ }
+ $changed = 1;
+ } else {
+ $rewrites->{$oldurl}{$ressrc} = $id;
+ $copies->{$oldurl}{$ressrc} = $id;
+ $changed = 1;
+ }
+ }
+ } 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;
+ $changed = 1;
+ }
+ } elsif ($ressrc =~ m{^/public/($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;
+ $changed = 1;
+ }
+ }
+ } elsif ($token->[1] eq 'param') {
+ next if ($skip);
+ my $to = $token->[2]->{'to'};
+ if ($to ne '') {
+ if (ref($params->{$oldurl}{$to}) eq 'ARRAY') {
+ push(@{$params->{$oldurl}{$to}},$token->[2]->{'name'});
+ } else {
+ @{$params->{$oldurl}{$to}} = ($token->[2]->{'name'});
+ }
+ }
+ }
+ }
+ return $changed;
+}
+
+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 @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;
+ }
+ }
+ undef(%added);
+ }
+ if ($key eq $oldurl) {
+ if ((exists($docmoves->{$key}))) {
+ unless (grep(/^\Q$oldurl\E/,@allcopies)) {
+ push(@allcopies,$oldurl);
+ }
+ }
+ }
+ if (@allcopies > 0) {
+ foreach my $item (@allcopies) {
+ 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};
+ } else {
+ $storefn = $relpath;
+ $storefn =~s{^/uploaded/$match_domain/$match_courseid/}{};
+ if ($prefixchg) {
+ $storefn =~ s/^\Q$before->{'doc'}\E/$after->{'doc'}/;
+ }
+ if ($newsubdir->{$key}) {
+ $storefn =~ s#^(docs|supplemental)/\Q$oldsubdir\E/#$1/$newsubdir->{$key}#;
+ }
+ }
+ ©_dependencies($item,$storefn,$relpath,$errors,\$content);
+ 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}))) {
+ return &mt('Paste failed: an error occurred copying the file.');
+ } elsif (ref($errors) eq 'HASH') {
+ $errors->{$item} = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ 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 ($newsubdir->{$key}) {
+ $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir->{$key}/;
+ }
+ my $mapcontent = &Apache::lonnet::getfile($key);
+ if ($mapcontent eq '-1') {
+ if (ref($errors) eq 'HASH') {
+ $errors->{$key} = 1;
+ }
+ } else {
+ my $newmap =
+ &Apache::lonclonecourse::writefile($env{'request.course.id'},$storefn,
+ $mapcontent);
+ if ($newmap eq '/adm/notfound.html') {
+ if (ref($errors) eq 'HASH') {
+ $errors->{$key} = 1;
+ }
+ }
+ }
+ }
+ 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;
+ }
+ foreach my $key (keys(%updates)) {
+ my (%torewrite,%toretitle,%toremove,%remparam,%currparam,%zombie,%newdb);
+ if (ref($rewrites->{$key}) eq 'HASH') {
+ %torewrite = %{$rewrites->{$key}};
+ }
+ if (ref($retitles->{$key}) eq 'HASH') {
+ %toretitle = %{$retitles->{$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($params->{$key}) eq 'HASH') {
+ %currparam = %{$params->{$key}};
+ }
+ my ($errtext,$fatal) = &LONCAPA::map::mapread($key);
+ if ($fatal) {
+ 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) {
+ undef($LONCAPA::map::zombies[$i]);
+ }
+ }
+ }
+ for (my $i=0; $i<@LONCAPA::map::resources; $i++) {
+ if (defined($LONCAPA::map::resources[$i])) {
+ my $changed;
+ my ($title,$src,$ext,$type)=split(/\:/,$LONCAPA::map::resources[$i]);
+ if ($toremove{$src} eq $i) {
+ splice(@LONCAPA::map::order,$i,1);
+ if (ref($currparam{$i}) eq 'ARRAY') {
+ foreach my $name (@{$currparam{$i}}) {
+ &LONCAPA::map::delparameter($i,'parameter_'.$name);
+ }
+ }
+ next;
+ }
+ my $origsrc = $src;
+ if ((exists($toretitle{$src})) && ($toretitle{$src} eq $i)) {
+ if ($title =~ m{^\d+\Q___&&&___\E$match_username\Q___&&&___\E$match_domain\Q___&&&___\E(.+)$}) {
+ $changed = 1;
+ }
+ }
+ if ((exists($torewrite{$src})) && ($torewrite{$src} eq $i)) {
+ $src =~ s{^/(uploaded|adm|public)/$match_domain/$match_courseid/}{/$1/$cdom/$cnum/};
+ if ($origsrc =~ m{^/uploaded/}) {
+ if ($prefixchg) {
+ if ($src =~ /\.(page|sequence)$/) {
+ $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'}#;
+ }
+ }
+ 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}#;
+ }
+ }
+ }
+ $changed = 1;
+ } elsif ($newdb{$src} ne '') {
+ $src = $newdb{$src};
+ $changed = 1;
+ }
+ if ($changed) {
+ $LONCAPA::map::resources[$i] = join(':',($title,$src,$ext,$type));
+ }
+ }
+ }
+ foreach my $idx (keys(%remparam)) {
+ if (ref($remparam{$idx}) eq 'ARRAY') {
+ foreach my $name (@{$remparam{$idx}}) {
+ &LONCAPA::map::delparameter($idx,'parameter_'.$name);
+ }
+ }
+ }
+ my $storefn;
+ if ($key eq $oldurl) {
+ $storefn = $url;
+ $storefn=~s{^/uploaded/$match_domain/$match_courseid/}{};
+ } else {
+ $storefn = $key;
+ $storefn=~s{^/uploaded/$match_domain/$match_courseid/}{};
+ if ($prefixchg) {
+ $storefn =~ s/^\Q$before->{'map'}\E/$after->{'map'}/;
+ }
+ if ($newsubdir->{$key}) {
+ $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir->{$key}/;
+ }
+ }
+ my $report;
+ if ($folder !~ /^supplemental/) {
+ $report = 1;
+ }
+ 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.');
+ }
+ }
+ }
+ return 'ok';
+}
+
+sub copy_dependencies {
+ my ($item,$storefn,$relpath,$errors,$contentref) = @_;
+ my $content;
+ if (ref($contentref)) {
+ $content = $$contentref;
+ } else {
+ $content = &Apache::lonnet::getfile($item);
+ }
+ unless ($content eq '-1') {
+ my $mm = new File::MMagic;
+ my $mimetype = $mm->checktype_contents($content);
+ if ($mimetype eq 'text/html') {
+ my (%allfiles,%codebase,$state);
+ my $res = &Apache::lonnet::extract_embedded_items(undef,\%allfiles,\%codebase,\$content);
+ if ($res eq 'ok') {
+ my ($numexisting,$numpathchanges,$existing);
+ (undef,$numexisting,$numpathchanges,$existing) =
+ &Apache::loncommon::ask_for_embedded_content(
+ '/adm/coursedocs',$state,\%allfiles,\%codebase,
+ {'error_on_invalid_names' => 1,
+ 'ignore_remote_references' => 1,
+ 'docs_url' => $item,
+ 'context' => 'paste'});
+ if ($numexisting > 0) {
+ if (ref($existing) eq 'HASH') {
+ foreach my $dep (keys(%{$existing})) {
+ my $depfile = $dep;
+ unless ($depfile =~ m{^\Q$relpath\E}) {
+ $depfile = $relpath.$dep;
+ }
+ my $depcontent = &Apache::lonnet::getfile($depfile);
+ unless ($depcontent eq '-1') {
+ my $storedep = $dep;
+ $storedep =~ s{^\Q$relpath\E}{};
+ my $dep_url =
+ &Apache::lonclonecourse::writefile(
+ $env{'request.course.id'},
+ $storefn.$storedep,$depcontent);
+ if ($dep_url eq '/adm/notfound.html') {
+ if (ref($errors) eq 'HASH') {
+ $errors->{$depfile} = 1;
+ }
+ } else {
+ ©_dependencies($depfile,$storefn,$relpath,$errors,\$depcontent);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return;
+}
+
+my %parameter_type = ( 'randompick' => 'int_pos',
+ 'hiddenresource' => 'string_yesno',
+ 'encrypturl' => 'string_yesno',
+ 'randomorder' => 'string_yesno',);
+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);
+ } else {
+ &LONCAPA::map::delparameter($idx,'parameter_'.$which);
+
+ &remember_parms($idx,$which,'del');
+ }
+ return 1;
+}
+
+
+sub handle_edit_cmd {
+ my ($coursenum,$coursedom) =@_;
+ 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 (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) &&
+ ($url!~/$LONCAPA::assess_page_seq_re/)) {
+ &Apache::lonnet::removeuploadedurl($url);
+ } else {
+ &LONCAPA::map::makezombie($LONCAPA::map::order[$idx]);
+ }
+ splice(@LONCAPA::map::order, $idx, 1);
+
+ } elsif ($cmd eq 'cut') {
+ &LONCAPA::map::makezombie($LONCAPA::map::order[$idx]);
+ splice(@LONCAPA::map::order, $idx, 1);
+
+ } elsif ($cmd eq 'up'
+ && ($idx) && (defined($LONCAPA::map::order[$idx-1]))) {
+ @LONCAPA::map::order[$idx-1,$idx] = @LONCAPA::map::order[$idx,$idx-1];
+
+ } elsif ($cmd eq 'down'
+ && defined($LONCAPA::map::order[$idx+1])) {
+ @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]]=
+ $comment.':'.join(':', $url, @rrest);
+ }
+# Devalidate title cache
+ my $renamed_url=&LONCAPA::map::qtescape($url);
+ &Apache::lonnet::devalidate_title_cache($renamed_url);
+ } else {
+ return 0;
+ }
+ return 1;
+}
+
+sub editor {
+ my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$crstype,
+ $supplementalflag,$orderhash,$iconpath)=@_;
+ my $container= ($env{'form.pagepath'}) ? 'page'
+ : 'sequence';
+
+ my ($breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,$is_random_order) =
+ &breadcrumbs($allowed,$crstype);
+ $r->print($breadcrumbtrail);
+
+ my $jumpto = "uploaded/$coursedom/$coursenum/$folder.$container";
+
+ unless ($allowed) {
+ $randompick = -1;
+ }
+
+ 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]='';
+ }
+
# ------------------------------------------------------------ Process commands
# ---------------- if they are for this folder and user allowed to make changes
- if (($allowed) && ($ENV{'form.folder'} eq $folder)) {
+ if (($allowed) && ($env{'form.folder'} eq $folder)) {
# set parameters and change order
- if (defined($ENV{'form.setparms'})) {
- my $idx=$ENV{'form.setparms'};
-# set parameters
- if ($ENV{'form.randpick_'.$idx}) {
- &Apache::lonratedt::storeparameter($idx,'parameter_randompick',$ENV{'form.randpick_'.$idx},'int_pos');
- } else {
- &Apache::lonratedt::delparameter($idx,'parameter_randompick');
- }
- if ($ENV{'form.hidprs_'.$idx}) {
- &Apache::lonratedt::storeparameter($idx,'parameter_hiddenresource','yes','string_yesno');
- } else {
- &Apache::lonratedt::delparameter($idx,'parameter_hiddenresource');
- }
- if ($ENV{'form.encprs_'.$idx}) {
- &Apache::lonratedt::storeparameter($idx,'parameter_encrypturl','yes','string_yesno');
- } else {
- &Apache::lonratedt::delparameter($idx,'parameter_encrypturl');
- }
+ &snapshotbefore();
- if ($ENV{'form.newpos'}) {
-# change order
+ if (&update_parameter()) {
+ ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container);
+ return $errtext if ($fatal);
+ }
- my $newpos=$ENV{'form.newpos'}-1;
- my $currentpos=$ENV{'form.currentpos'}-1;
- my $i;
- my @neworder=();
- if ($newpos>$currentpos) {
-# moving stuff up
- for ($i=0;$i<$currentpos;$i++) {
- $neworder[$i]=$Apache::lonratedt::order[$i];
- }
- for ($i=$currentpos;$i<$newpos;$i++) {
- $neworder[$i]=$Apache::lonratedt::order[$i+1];
- }
- $neworder[$newpos]=$Apache::lonratedt::order[$currentpos];
- for ($i=$newpos+1;$i<=$#Apache::lonratedt::order;$i++) {
- $neworder[$i]=$Apache::lonratedt::order[$i];
- }
- } else {
-# moving stuff down
- for ($i=0;$i<$newpos;$i++) {
- $neworder[$i]=$Apache::lonratedt::order[$i];
- }
- $neworder[$newpos]=$Apache::lonratedt::order[$currentpos];
- for ($i=$newpos+1;$i<$currentpos+1;$i++) {
- $neworder[$i]=$Apache::lonratedt::order[$i-1];
- }
- for ($i=$currentpos+1;$i<=$#Apache::lonratedt::order;$i++) {
- $neworder[$i]=$Apache::lonratedt::order[$i];
- }
- }
- @Apache::lonratedt::order=@neworder;
- }
-# store the changed version
+ if ($env{'form.newpos'} && $env{'form.currentpos'}) {
+# change order
+ my $res = splice(@LONCAPA::map::order,$env{'form.currentpos'}-1,1);
+ splice(@LONCAPA::map::order,$env{'form.newpos'}-1,0,$res);
- ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.sequence');
- if ($fatal) {
- $r->print(''.$errtext.'
');
- return;
- }
-
- }
+ ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container);
+ return $errtext if ($fatal);
+ }
-# upload a file, if present
- if (($ENV{'form.uploaddoc.filename'}) &&
- ($ENV{'form.cmd'}=~/^upload_(\w+)/)) {
- if ( ($folder=~/^$1/) || ($1 eq 'default') ) {
-# this is for a course, not a user, so set coursedoc flag
-# probably the only place in the system where this should be "1"
- my $url=&Apache::lonnet::userfileupload('uploaddoc',1,'docs');
- my $ext='false';
- if ($url=~/^http\:\/\//) { $ext='true'; }
- $url=~s/\:/\:/g;
- my $comment=$ENV{'form.comment'};
- $comment=~s/\\<\;/g;
- $comment=~s/\>/\>\;/g;
- $comment=~s/\:/\:/g;
- if ($folder=~/^supplemental/) {
- $comment=time.'___&&&___'.$ENV{'user.name'}.'___&&&___'.
- $ENV{'user.domain'}.'___&&&___'.$comment;
- }
- my $newidx=$#Apache::lonratedt::resources+1;
- $Apache::lonratedt::resources[$newidx]=
- $comment.':'.$url.':'.$ext.':normal:res';
- $Apache::lonratedt::order[$#Apache::lonratedt::order+1]=
- $newidx;
-
- ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.sequence');
- if ($fatal) {
- $r->print(''.$errtext.'
');
- return;
- }
- }
+ if ($env{'form.pastemarked'}) {
+ my %paste_errors;
+ my ($paste_res,$save_error) =
+ &do_paste_from_buffer($coursenum,$coursedom,$folder,$container,
+ \%paste_errors);
+ if ($save_error ne '') {
+ return $save_error;
+ }
+ if ($paste_res ne 'ok') {
+ $r->print(''.$paste_res.'
');
}
- if ($ENV{'form.cmd'}) {
- my ($cmd,$idx)=split(/\_/,$ENV{'form.cmd'});
- if ($cmd eq 'del') {
- my (undef,$url)=split(':',$Apache::lonratedt::resources[$Apache::lonratedt::order[$idx]]);
- if ($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) {
- &Apache::lonnet::removeuploadedurl($url);
- }
- for (my $i=$idx;$i<$#Apache::lonratedt::order;$i++) {
- $Apache::lonratedt::order[$i]=
- $Apache::lonratedt::order[$i+1];
- }
- $#Apache::lonratedt::order--;
- } elsif ($cmd eq 'up') {
- if (($idx) && (defined($Apache::lonratedt::order[$idx-1]))) {
- my $i=$Apache::lonratedt::order[$idx-1];
- $Apache::lonratedt::order[$idx-1]=
- $Apache::lonratedt::order[$idx];
- $Apache::lonratedt::order[$idx]=$i;
- }
- } elsif ($cmd eq 'down') {
- if (defined($Apache::lonratedt::order[$idx+1])) {
- my $i=$Apache::lonratedt::order[$idx+1];
- $Apache::lonratedt::order[$idx+1]=
- $Apache::lonratedt::order[$idx];
- $Apache::lonratedt::order[$idx]=$i;
- }
- } elsif ($cmd eq 'rename') {
- my ($rtitle,@rrest)=split(/\:/,
- $Apache::lonratedt::resources[
- $Apache::lonratedt::order[$idx]]);
- my $comment=
- &HTML::Entities::decode($ENV{'form.title'});
- $comment=~s/\\<\;/g;
- $comment=~s/\>/\>\;/g;
- $comment=~s/\:/\:/g;
- $Apache::lonratedt::resources[
- $Apache::lonratedt::order[$idx]]=
- $comment.':'.join(':',@rrest);
-
+ if (keys(%paste_errors) > 0) {
+ $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))) {
+ $r->print(''.$key.' '."\n");
}
-# Store the changed version
- ($errtext,$fatal)=&storemap($coursenum,$coursedom,
- $folder.'.sequence');
- if ($fatal) {
- $r->print(''.$errtext.'
');
- return;
- }
+ $r->print(' '."\n");
}
+ }
+
+ $r->print($upload_output);
+
+ if (&handle_edit_cmd()) {
+ my $contentchg;
+ if ($env{'form.cmd'} =~ /^(del|cut)_/) {
+ $contentchg = 1;
+ }
+ ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container,$contentchg);
+ return $errtext if ($fatal);
+ }
# Group import/search
- if ($ENV{'form.importdetail'}) {
- my @imports;
- foreach (split(/\&/,$ENV{'form.importdetail'})) {
- if (defined($_)) {
- my ($name,$url)=split(/\=/,$_);
- $name=&Apache::lonnet::unescape($name);
- $url=&Apache::lonnet::unescape($url);
- push @imports, $name, $url;
- }
- }
-# Store the changed version
- ($errtext,$fatal)=group_import($coursenum, $coursedom, $folder,
- @imports);
- if ($fatal) {
- $r->print(''.$errtext.'
');
- return;
+ if ($env{'form.importdetail'}) {
+ my @imports;
+ foreach my $item (split(/\&/,$env{'form.importdetail'})) {
+ if (defined($item)) {
+ my ($name,$url,$residx)=
+ map {&unescape($_)} split(/\=/,$item);
+ push(@imports, [$name, $url, $residx]);
}
- }
+ }
+ ($errtext,$fatal)=&group_import($coursenum, $coursedom, $folder,
+ $container,'londocs',@imports);
+ return $errtext if ($fatal);
+ }
# Loading a complete map
- if (($ENV{'form.importmap'}) && ($ENV{'form.loadmap'})) {
- foreach (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$ENV{'form.importmap'}))) {
- my $idx=$#Apache::lonratedt::resources;
- $idx++;
- $Apache::lonratedt::resources[$idx]=$_;
- $Apache::lonratedt::order
- [$#Apache::lonratedt::order+1]=$idx;
- }
-
-# Store the changed version
- ($errtext,$fatal)=&storemap($coursenum,$coursedom,
- $folder.'.sequence');
- if ($fatal) {
- $r->print(''.$errtext.'
');
- return;
- }
- }
- }
+ if ($env{'form.loadmap'}) {
+ if ($env{'form.importmap'}=~/\w/) {
+ foreach my $res (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$env{'form.importmap'}))) {
+ my ($title,$url,$ext,$type)=split(/\:/,$res);
+ my $idx=&LONCAPA::map::getresidx($url);
+ $LONCAPA::map::resources[$idx]=$res;
+ $LONCAPA::map::order[$#LONCAPA::map::order+1]=$idx;
+ }
+ ($errtext,$fatal)=&storemap($coursenum,$coursedom,
+ $folder.'.'.$container,1);
+ return $errtext if ($fatal);
+ } else {
+ $r->print(''.&mt('No map selected.').'
');
+
+ }
+ }
+ &log_differences($plain);
+ }
# ---------------------------------------------------------------- End commands
# ---------------------------------------------------------------- Print screen
- my $idx=0;
- $r->print('');
- foreach (@Apache::lonratedt::order) {
- my ($name,$url)=split(/\:/,$Apache::lonratedt::resources[$_]);
- unless ($name) { $name=(split(/\//,$url))[-1]; }
- unless ($name) { next; }
- $r->print(&entryline($idx,$name,$url,$folder,$allowed,$_,$coursenum));
- $idx++;
+ my $idx=0;
+ my $shown=0;
+ if (($ishidden) || ($isencrypted) || ($randompick>=0) || ($is_random_order)) {
+ $r->print(''.
+ '
'.&mt('Parameters:').' '.
+ ($randompick>=0?''.&mt('randomly pick [quant,_1,resource]',$randompick).' ':'').
+ ($ishidden?''.&mt('contents hidden').' ':'').
+ ($isencrypted?''.&mt('URLs hidden').' ':'').
+ ($is_random_order?''.&mt('random order').' ':'').
+ '');
+ if ($randompick>=0) {
+ $r->print('
'
+ .&mt('Caution: this folder is set to randomly pick a subset'
+ .' of resources. Adding or removing resources from this'
+ .' folder will change the set of resources that the'
+ .' students see, resulting in spurious or missing credit'
+ .' for completed problems, not limited to ones you'
+ .' modify. Do not modify the contents of this folder if'
+ .' it is in active student use.')
+ .'
'
+ );
+ }
+ if ($is_random_order) {
+ $r->print('
'
+ .&mt('Caution: this folder is set to randomly order its'
+ .' contents. Adding or removing resources from this folder'
+ .' will change the order of resources shown.')
+ .'
'
+ );
+ }
+ $r->print('
');
+ }
+
+ my ($to_show,$output);
+
+ &Apache::loncommon::start_data_table_count(); #setup a row counter
+ foreach my $res (@LONCAPA::map::order) {
+ my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]);
+ $name=&LONCAPA::map::qtescape($name);
+ $url=&LONCAPA::map::qtescape($url);
+ unless ($name) { $name=(split(/\//,$url))[-1]; }
+ unless ($name) { $idx++; next; }
+ $output .= &entryline($idx,$name,$url,$folder,$allowed,$res,
+ $coursenum,$crstype);
+ $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').' ';
+ }
+ $to_show .= &Apache::loncommon::end_data_table_header_row();
}
- $r->print('
');
+ $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();
}
+ my $tid = 1;
+ if ($supplementalflag) {
+ $tid = 2;
+ }
+ if ($allowed) {
+ my $readfile="/uploaded/$coursedom/$coursenum/$folder.$container";
+ $r->print(&generate_edit_table($tid,$orderhash,$to_show,$iconpath,$jumpto,
+ $readfile));
+ &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 process_file_upload {
+ my ($upload_output,$coursenum,$coursedom,$allfiles,$codebase,$uploadcmd) = @_;
+# upload a file, if present
+ my ($parseaction,$showupload,$nextphase,$mimetype);
+ if ($env{'form.parserflag'}) {
+ $parseaction = 'parse';
+ }
+ my $folder=$env{'form.folder'};
+ if ($folder eq '') {
+ $folder='default';
+ }
+ if ( ($folder=~/^$uploadcmd/) || ($uploadcmd eq 'default') ) {
+ my $errtext='';
+ my $fatal=0;
+ my $container='sequence';
+ if ($env{'form.pagepath'}) {
+ $container='page';
+ }
+ ($errtext,$fatal)=
+ &mapread($coursenum,$coursedom,$folder.'.'.$container);
+ if ($#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/';
+ }
+ if (($folder eq 'default') || ($folder eq 'supplemental')) {
+ $destination .= 'default/';
+ } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) {
+ $destination .= $2.'/';
+ }
+# this is for a course, not a user, so set context to coursedoc.
+ my $newidx=&LONCAPA::map::getresidx();
+ $destination .= $newidx;
+ my $url=&Apache::lonnet::userfileupload('uploaddoc','coursedoc',$destination,
+ $parseaction,$allfiles,
+ $codebase,undef,undef,undef,undef,
+ undef,undef,\$mimetype);
+ if ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E.*/([^/]+)$}) {
+ my $stored = $1;
+ $showupload = ''.&mt('Uploaded [_1]',''.
+ $stored.' ').'
';
+ } else {
+ my ($filename) = ($env{'form.uploaddoc.filename'} =~ m{([^/]+)$});
+
+ $$upload_output = ''.&mt('Unable to save file [_1].',''.$filename.' ').'
';
+ return;
+ }
+ my $ext='false';
+ if ($url=~m{^http://}) { $ext='true'; }
+ $url = &LONCAPA::map::qtunescape($url);
+ my $comment=$env{'form.comment'};
+ $comment = &LONCAPA::map::qtunescape($comment);
+ if ($folder=~/^supplemental/) {
+ $comment=time.'___&&&___'.$env{'user.name'}.'___&&&___'.
+ $env{'user.domain'}.'___&&&___'.$comment;
+ }
+
+ $LONCAPA::map::resources[$newidx]=
+ $comment.':'.$url.':'.$ext.':normal:res';
+ $LONCAPA::map::order[$#LONCAPA::map::order+1]= $newidx;
+ ($errtext,$fatal)=&storemap($coursenum,$coursedom,
+ $folder.'.'.$container,1);
+ if ($fatal) {
+ $$upload_output = ''.$errtext.'
';
+ return;
+ } else {
+ if ($parseaction eq 'parse' && $mimetype eq 'text/html') {
+ $$upload_output = $showupload;
+ my $total_embedded = scalar(keys(%{$allfiles}));
+ if ($total_embedded > 0) {
+ my $uploadphase = 'upload_embedded';
+ my $primaryurl = &HTML::Entities::encode($url,'<>&"');
+ my $state = &embedded_form_elems($uploadphase,$primaryurl,$newidx);
+ my ($embedded,$num) =
+ &Apache::loncommon::ask_for_embedded_content(
+ '/adm/coursedocs',$state,$allfiles,$codebase,{'docs_url' => $url});
+ if ($embedded) {
+ if ($num) {
+ $$upload_output .=
+ ''.&mt('This file contains embedded multimedia objects, which need to be uploaded.').'
'.$embedded;
+ $nextphase = $uploadphase;
+ } else {
+ $$upload_output .= $embedded;
+ }
+ } else {
+ $$upload_output .= &mt('Embedded item(s) already present, so no additional upload(s) required').' ';
+ }
+ } else {
+ $$upload_output .= &mt('No embedded items identified').' ';
+ }
+ $$upload_output = ''.$$upload_output.'
';
+ } elsif (&Apache::loncommon::is_archive_file($mimetype)) {
+ $nextphase = 'decompress_uploaded';
+ my $position = scalar(@LONCAPA::map::order)-1;
+ my $noextract = &return_to_editor();
+ my $archiveurl = &HTML::Entities::encode($url,'<>&"');
+ my %archiveitems = (
+ folderpath => $env{'form.folderpath'},
+ pagepath => $env{'form.pagepath'},
+ cmd => $nextphase,
+ newidx => $newidx,
+ position => $position,
+ phase => $nextphase,
+ comment => $comment,
+ );
+ my ($destination,$dir_root) = &embedded_destination($coursenum,$coursedom);
+ my @current = &get_dir_list($url,$coursenum,$coursedom,$newidx);
+ $$upload_output = $showupload.
+ &Apache::loncommon::decompress_form($mimetype,
+ $archiveurl,'/adm/coursedocs',$noextract,
+ \%archiveitems,\@current);
+ }
+ }
+ }
+ return $nextphase;
+}
+
+sub get_dir_list {
+ my ($url,$coursenum,$coursedom,$newidx) = @_;
+ my ($destination,$dir_root) = &embedded_destination();
+ my ($dirlistref,$listerror) =
+ &Apache::lonnet::dirlist("$dir_root/$destination/$newidx",$coursedom,$coursenum,1);
+ my @dir_lines;
+ my $dirptr=16384;
+ if (ref($dirlistref) eq 'ARRAY') {
+ foreach my $dir_line (sort
+ {
+ my ($afile)=split('&',$a,2);
+ my ($bfile)=split('&',$b,2);
+ return (lc($afile) cmp lc($bfile));
+ } (@{$dirlistref})) {
+ my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$dir_line,16);
+ $filename =~ s/\s+$//;
+ next if ($filename =~ /^\.\.?$/);
+ my $isdir = 0;
+ if ($dirptr&$testdir) {
+ $isdir = 1;
+ }
+ push(@dir_lines, [$filename,$dom,$isdir,$size,$mtime,$obs]);
+ }
+ }
+ return @dir_lines;
+}
+
+sub is_supplemental_title {
+ my ($title) = @_;
+ return scalar($title =~ m/^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/);
}
# --------------------------------------------------------------- An entry line
sub entryline {
- my ($index,$title,$url,$folder,$allowed,$residx,$coursenum)=@_;
- $title=~s/\&colon\;/\:/g;
- $title=&HTML::Entities::encode(&HTML::Entities::decode(
- &Apache::lonnet::unescape($title)),'"<>&\'');
- my $renametitle=$title;
- my $foldertitle=$title;
- my $orderidx=$Apache::lonratedt::order[$index];
- if ($title=~ /^(\d+)___&&&___(\w+)___&&&___(\w+)___&&&___(.*)$/ ) {
- $foldertitle=&Apache::lontexconvert::msgtexconverted($4);
- $renametitle=$4;
- $title=''.&Apache::lonlocal::locallocaltime($1).' '.
- &Apache::loncommon::plainname($2,$3).': '.
- $foldertitle;
+ my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$crstype)=@_;
+ my ($foldertitle,$pagetitle,$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];
+
+
+ $renametitle=~s/\\/\\\\/g;
$renametitle=~s/\"\;/\\\"/g;
- my $line='';
+ $renametitle=~s/ /%20/g;
+ my $line=&Apache::loncommon::start_data_table_row();
+ my ($form_start,$form_end,$form_common);
# Edit commands
- my $folderpath;
- if ($ENV{'form.folderpath'}) {
- $folderpath=&Apache::lonnet::escape($ENV{'form.folderpath'});
- # $htmlfoldername=&HTML::Entities::encode($ENV{'form.foldername'},'<>&"');
+ my ($container, $type, $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'},'<>&"');
+ $symb=&escape($env{'form.pagesymb'});
+ }
+ my $cpinfo='';
if ($allowed) {
my $incindex=$index+1;
my $selectbox='';
- if ($folder!~/^supplemental/) {
+ if (($#LONCAPA::map::order>0) &&
+ ((split(/\:/,
+ $LONCAPA::map::resources[$LONCAPA::map::order[0]]))[1]
+ ne '') &&
+ ((split(/\:/,
+ $LONCAPA::map::resources[$LONCAPA::map::order[1]]))[1]
+ ne '')) {
$selectbox=
' '.
- '';
- for (my $i=1;$i<=$#Apache::lonratedt::order+1;$i++) {
+ '';
+ for (my $i=1;$i<=$#LONCAPA::map::order+1;$i++) {
if ($i==$incindex) {
- $selectbox.='('.$i.') ';
+ $selectbox.='('.$i.') ';
} else {
$selectbox.=''.$i.' ';
}
@@ -543,48 +2179,122 @@ sub entryline {
'up' => 'Move Up',
'dw' => 'Move Down',
'rm' => 'Remove',
- 'rn' => 'Rename');
+ 'ct' => 'Cut',
+ 'rn' => 'Rename',
+ 'cp' => 'Copy');
+ my $nocopy=0;
+ my $nocut=0;
+ if ($url=~ m{^/res/.+\.(page|sequence)$}) {
+ # no copy for published maps
+ $nocopy=1;
+ }
+ if ($url=~/^\/res\/lib\/templates\//) {
+ $nocopy=1;
+ $nocut=1;
+ }
+ my $copylink=' ';
+ my $cutlink=' ';
+
+ my $skip_confirm = 0;
+ if ( $folder =~ /^supplemental/
+ || ($url =~ m{( /smppg$
+ |/syllabus$
+ |/aboutme$
+ |/navmaps$
+ |/bulletinboard$
+ |\.html$
+ |^/adm/wrapper/ext)}x)) {
+ $skip_confirm = 1;
+ }
+
+ if (!$nocopy) {
+ $copylink=(<$lt{'cp'}
+ENDCOPY
+ }
+ if (!$nocut) {
+ $cutlink=(<$lt{'ct'}
+ENDCUT
+ }
+ $form_start = '
+ ';
$line.=(<
-
-
-
-
-
-
-
-
-
-
-$selectbox
-
-
-$lt{'rm'}
-
-$lt{'rn'}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $form_start
+ $form_common
+ $selectbox
+ $form_end
+
+
+ $lt{'rm'}
+$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;
if ($uploaded) {
- if ($extension eq 'sequence') {
- $icon=$iconpath.'/folder_closed.gif';
- $url=~/$coursenum\/([\/\w]+)\.sequence$/;
- $url='/adm/coursedocs?';
- $folderarg=$1;
- $isfolder=1;
- }
+ if (($extension eq 'sequence') || ($extension eq 'page')) {
+ $url=~/\Q$coursenum\E\/([\/\w]+)\.\Q$extension\E$/;
+ my $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) {
+ $url='/adm/coursedocs?';
+ } else {
+ $url='/adm/supplemental?';
+ }
+ } else {
+ &Apache::lonnet::allowuploaded('/adm/coursedoc',$url);
+ }
}
- $url=~s/^http\&colon\;\/\//\/adm\/wrapper\/ext\//;
- if ((!$isfolder) && ($residx) && ($folder!~/supplemental/)) {
+
+ my $orig_url = $url;
+ $orig_url=~s{http(:|:)//https(:|:)//}{https$2//};
+ my $external = ($url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/});
+ if ((!$isfolder) && ($residx) && ($folder!~/supplemental/) && (!$ispage)) {
my $symb=&Apache::lonnet::symbclean(
&Apache::lonnet::declutter('uploaded/'.
- $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}.'/'.
- $ENV{'course.'.$ENV{'request.course.id'}.'.num'}.'/'.$folder.
+ $env{'course.'.$env{'request.course.id'}.'.domain'}.'/'.
+ $env{'course.'.$env{'request.course.id'}.'.num'}.'/'.$folder.
'.sequence').
'___'.$residx.'___'.
&Apache::lonnet::declutter($url));
@@ -600,72 +2310,184 @@ END
} elsif ($url!~/\.(sequence|page)$/) {
$url='/adm/coursedocs/showdoc'.$url;
}
+ } elsif ($url=~m|^/ext/|) {
+ $url='/adm/wrapper'.$url;
+ $external = 1;
+ }
+ if (&Apache::lonnet::symbverify($symb,$url)) {
+ $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb);
+ } else {
+ $url='';
+ }
+ if ($container eq 'page') {
+ my $symb=$env{'form.pagesymb'};
+
+ $url=&Apache::lonnet::clutter((&Apache::lonnet::decode_symb($symb))[2]);
+ $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb);
}
- $url.=(($url=~/\?/)?'&':'?').'symb='.&Apache::lonnet::escape($symb);
}
- my $parameterset=' ';
- if ($isfolder) {
- my $foldername=&Apache::lonnet::escape($foldertitle);
- my $folderpath=$ENV{'form.folderpath'};
+ my ($rand_pick_text,$rand_order_text);
+ if ($isfolder || $extension eq 'sequence') {
+ my $foldername=&escape($foldertitle);
+ my $folderpath=$env{'form.folderpath'};
if ($folderpath) { $folderpath.='&' };
- $folderpath.=$folderarg.'&'.$foldername;
- $url.='folderpath='.&Apache::lonnet::escape($folderpath);
- $parameterset=&mt('Randomly Pick: ').
- ' ';
- }
- $line.=' '.
- "$title ";
+# Append randompick number, hidden, and encrypted with ":" to foldername,
+# so it gets transferred between levels
+ $folderpath.=$folderarg.'&'.$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).$cpinfo;
+ my $rpicknum = (&LONCAPA::map::getparameter($orderidx,
+ 'parameter_randompick'))[0];
+ my $rpckchk;
+ if ($rpicknum) {
+ $rpckchk = ' checked="checked"';
+ }
+ my $formname = 'edit_rpick_'.$orderidx;
+ $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;
+ my $symb=$env{'form.pagesymb'};
+ if (!$symb) {
+ my $path='uploaded/'.
+ $env{'course.'.$env{'request.course.id'}.'.domain'}.'/'.
+ $env{'course.'.$env{'request.course.id'}.'.num'}.'/';
+ $symb=&Apache::lonnet::encode_symb($path.$folder.'.sequence',
+ $residx,
+ $path.$pagearg.'.page');
+ }
+ $url.='pagepath='.&escape($pagepath).
+ '&pagesymb='.&escape($symb).$cpinfo;
+ }
+ if (($external) && ($allowed)) {
+ my $form = ($folder =~ /^default/)? 'newext' : 'supnewext';
+ $external = ' '.&mt('Edit').' ';
+ } else {
+ undef($external);
+ }
+ my $reinit;
+ if ($crstype eq 'Community') {
+ $reinit = &mt('(re-initialize community to access)');
+ } else {
+ $reinit = &mt('(re-initialize course to access)');
+ }
+ $line.='';
+ if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) {
+ $line.=' ';
+ } elsif ($url) {
+ $line.=&Apache::loncommon::modal_link($url.(($url=~/\?/)?'&':'?').'inhibitmenu=yes',
+ ' ',600,500);
+ } else {
+ $line.=' ';
+ }
+ $line.=' ';
+ if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) {
+ $line.=''.$title.' ';
+ } elsif ($url) {
+ $line.=&Apache::loncommon::modal_link($url.(($url=~/\?/)?'&':'?').'inhibitmenu=yes',
+ $title,600,500);
+ } else {
+ $line.=$title.' '.$reinit.' ';
+ }
+ $line.=$external." ";
+ $rand_pick_text = ' ' if ($rand_pick_text eq '');
+ $rand_order_text = ' ' if ($rand_order_text eq '');
if (($allowed) && ($folder!~/^supplemental/)) {
my %lt=&Apache::lonlocal::texthash(
'hd' => 'Hidden',
- 'ec' => 'URL hidden',
- 'sp' => 'Store Parameters');
+ 'ec' => 'URL hidden');
my $enctext=
- ((&Apache::lonratedt::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i?' checked="1"':'');
+ ((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i?' checked="checked"':'');
my $hidtext=
- ((&Apache::lonratedt::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i?' checked="1"':'');
+ ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i?' checked="checked"':'');
$line.=(<
- $lt{'hd'}
-
- $lt{'ec'}
-$parameterset
-
-
-
+
+ $form_start
+ $form_common
+ $lt{'hd'}
+ $form_end
+
+ $form_start
+ $form_common
+ $lt{'ec'}
+ $form_end
+
+ $rand_pick_text
+ $rand_order_text
ENDPARMS
}
- $line.=" ";
+ $line.=&Apache::loncommon::end_data_table_row();
return $line;
}
-# ---------------------------------------------------------------- tie the hash
+=pod
+
+=item tiehash()
+
+tie the hash
+
+=cut
sub tiehash {
+ my ($mode)=@_;
$hashtied=0;
- if ($ENV{'request.course.fn'}) {
- if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.".db",
- &GDBM_READER(),0640)) {
+ if ($env{'request.course.fn'}) {
+ if ($mode eq 'write') {
+ if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db",
+ &GDBM_WRCREAT(),0640)) {
+ $hashtied=2;
+ }
+ } else {
+ if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db",
+ &GDBM_READER(),0640)) {
$hashtied=1;
- }
- }
+ }
+ }
+ }
}
sub untiehash {
if ($hashtied) { untie %hash; }
$hashtied=0;
+ return OK;
}
-# --------------------------------------------------------------- check on this
+
+
sub checkonthis {
my ($r,$url,$level,$title)=@_;
+ $url=&unescape($url);
$alreadyseen{$url}=1;
$r->rflush();
if (($url) && ($url!~/^\/uploaded\//) && ($url!~/\*$/)) {
$r->print("\n ");
+ if ($level==0) {
+ $r->print(" ");
+ }
for (my $i=0;$i<=$level*5;$i++) {
$r->print(' ');
}
@@ -674,8 +2496,8 @@ sub checkonthis {
if ($url=~/^\/res\//) {
my $result=&Apache::lonnet::repcopy(
&Apache::lonnet::filelocation('',$url));
- if ($result==OK) {
- $r->print(''.&mt('ok').' ');
+ if ($result eq 'ok') {
+ $r->print(''.&mt('ok').' ');
$r->rflush();
&Apache::lonnet::countacc($url);
$url=~/\.(\w+)$/;
@@ -685,84 +2507,139 @@ sub checkonthis {
for (my $i=0;$i<=$level*5;$i++) {
$r->print(' ');
}
- $r->print('- '.&mt('Rendering').': ');
- my $oldpath=$ENV{'request.filename'};
- $ENV{'request.filename'}=&Apache::lonnet::filelocation('',$url);
- &Apache::lonxml::xmlparse($r,'web',
- &Apache::lonnet::getfile(
- &Apache::lonnet::filelocation('',$url)));
- undef($Apache::lonhomework::parsing_a_problem);
- $ENV{'request.filename'}=$oldpath;
- if (($Apache::lonxml::errorcount) ||
- ($Apache::lonxml::warningcount)) {
- if ($Apache::lonxml::errorcount) {
- $r->print(''.
- $Apache::lonxml::errorcount.' '.
- &mt('error(s)').' ');
+ $r->print('- '.&mt('Rendering:').' ');
+ my ($errorcount,$warningcount)=split(/:/,
+ &Apache::lonnet::ssi_body($url,
+ ('grade_target'=>'web',
+ 'return_only_error_and_warning_counts' => 1)));
+ if (($errorcount) ||
+ ($warningcount)) {
+ if ($errorcount) {
+ $r->print(''.
+ &mt('[quant,_1,error]',$errorcount).' ');
}
- if ($Apache::lonxml::warningcount) {
- $r->print(''.
- $Apache::lonxml::warningcount.' '.
- &mt('warning(s)').' ');
+ if ($warningcount) {
+ $r->print(''.
+ &mt('[quant,_1,warning]',$warningcount).' ');
}
} else {
- $r->print(''.&mt('ok').' ');
+ $r->print(''.&mt('ok').' ');
}
$r->rflush();
}
my $dependencies=
&Apache::lonnet::metadata($url,'dependencies');
- foreach (split(/\,/,$dependencies)) {
- if (($_=~/^\/res\//) && (!$alreadyseen{$_})) {
- &checkonthis($r,$_,$level+1);
+ foreach my $dep (split(/\,/,$dependencies)) {
+ if (($dep=~/^\/res\//) && (!$alreadyseen{$dep})) {
+ &checkonthis($r,$dep,$level+1);
}
}
- } elsif ($result==HTTP_SERVICE_UNAVAILABLE) {
- $r->print(''.&mt('connection down').' ');
- } elsif ($result==HTTP_NOT_FOUND) {
+ } elsif ($result eq 'unavailable') {
+ $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').' ');
+ $r->print(''.&mt('unable to verify variable URL').' ');
}
} else {
- $r->print(''.&mt('access denied').' ');
+ $r->print(''.&mt('access denied').' ');
}
- }
- }
+ }
+ }
}
-#
-# -------------------------------------------------------------- Verify Content
-#
-sub verifycontent {
- my $r=shift;
- my $loaderror=&Apache::lonnet::overloaderror($r);
- if ($loaderror) { return $loaderror; }
- $r->print('Verify Content '.
- &Apache::loncommon::bodytag('Verify Course Documents'));
+=pod
+
+=item list_symbs()
+
+List Content Identifiers
+
+=cut
+
+sub list_symbs {
+ my ($r) = @_;
+
+ my $crstype = &Apache::loncommon::course_type();
+ $r->print(&Apache::loncommon::start_page('List of Content Identifiers'));
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs('Content Identifiers'));
+ $r->print(&startContentScreen('tools'));
+ my $navmap = Apache::lonnavmaps::navmap->new();
+ if (!defined($navmap)) {
+ $r->print(''.&mt('Retrieval of List Failed').' '.
+ ''.
+ &mt('Unable to retrieve information about course contents').
+ '
');
+ &Apache::lonnet::logthis('Symb list failed - could not create navmap object in '.lc($crstype).':'.$env{'request.course.id'});
+ } else {
+ $r->print(''.&mt("$crstype Content Identifiers").' '.
+ &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ ''.&mt('Title').' '.&mt('Identifier').' '.
+ &Apache::loncommon::end_data_table_header_row()."\n");
+ my $count;
+ foreach my $res ($navmap->retrieveResources()) {
+ $r->print(&Apache::loncommon::start_data_table_row().
+ ''.$res->compTitle().' '.
+ ''.$res->symb().' '.
+ &Apache::loncommon::start_data_table_row());
+ $count ++;
+ }
+ if (!$count) {
+ $r->print(&Apache::loncommon::start_data_table_row().
+ ''.&mt("$crstype is empty").' '.
+ &Apache::loncommon::end_data_table_row());
+ }
+ $r->print(&Apache::loncommon::end_data_table());
+ }
+}
+
+
+sub verifycontent {
+ my ($r) = @_;
+ my $crstype = &Apache::loncommon::course_type();
+ $r->print(&Apache::loncommon::start_page('Verify '.$crstype.' Documents'));
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$crstype.' Documents'));
+ $r->print(&startContentScreen('tools'));
+ $r->print(''.&mt($crstype.' content verification').' ');
$hashtied=0;
undef %alreadyseen;
%alreadyseen=();
&tiehash();
- foreach (keys %hash) {
- if (($_=~/^src\_(.+)$/) && (!$alreadyseen{$hash{$_}})) {
- &checkonthis($r,$hash{$_},0,$hash{'title_'.$1});
+
+ foreach my $key (keys(%hash)) {
+ if ($hash{$key}=~/\.(page|sequence)$/) {
+ if (($key=~/^src_/) && ($alreadyseen{&unescape($hash{$key})})) {
+ $r->print(''.
+ &mt('The following sequence or page is included more than once in your '.$crstype.':').' '.
+ &unescape($hash{$key}).' '.
+ &mt('Note that grading records for problems included in this sequence or folder will overlap.').' ');
+ }
+ }
+ if (($key=~/^src\_(.+)$/) && (!$alreadyseen{&unescape($hash{$key})})) {
+ &checkonthis($r,$hash{$key},0,$hash{'title_'.$1});
}
}
&untiehash();
- $r->print(''.&mt('Done').'. '.''.
- &mt('Return to DOCS').' ');
+ $r->print(''.&mt('Done').'
');
}
-# -------------------------------------------------------------- Check Versions
+
+sub devalidateversioncache {
+ my $src=shift;
+ &Apache::lonnet::devalidate_cache_new('courseresversion',$env{'request.course.id'}.'_'.
+ &Apache::lonnet::clutter($src));
+}
sub checkversions {
- my $r=shift;
- $r->print('Check Versions '.
- &Apache::loncommon::bodytag('Check Course Document Versions'));
+ my ($r) = @_;
+ my $crstype = &Apache::loncommon::course_type();
+ $r->print(&Apache::loncommon::start_page("Check $crstype Document Versions"));
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs("Check $crstype Document Versions"));
+ $r->print(&startContentScreen('tools'));
+
my $header='';
my $startsel='';
my $monthsel='';
@@ -773,56 +2650,62 @@ sub checkversions {
my $starttime=0;
my $haschanged=0;
my %setversions=&Apache::lonnet::dump('resourceversions',
- $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
$hashtied=0;
&tiehash();
my %newsetversions=();
- if ($ENV{'form.setmostrecent'}) {
+ if ($env{'form.setmostrecent'}) {
$haschanged=1;
- foreach (keys %hash) {
- if ($_=~/^ids\_(\/res\/.+)$/) {
+ foreach my $key (keys(%hash)) {
+ if ($key=~/^ids\_(\/res\/.+)$/) {
$newsetversions{$1}='mostrecent';
+ &devalidateversioncache($1);
}
}
- } elsif ($ENV{'form.setcurrent'}) {
+ } elsif ($env{'form.setcurrent'}) {
$haschanged=1;
- foreach (keys %hash) {
- if ($_=~/^ids\_(\/res\/.+)$/) {
+ foreach my $key (keys(%hash)) {
+ if ($key=~/^ids\_(\/res\/.+)$/) {
my $getvers=&Apache::lonnet::getversion($1);
if ($getvers>0) {
$newsetversions{$1}=$getvers;
+ &devalidateversioncache($1);
}
}
}
- } elsif ($ENV{'form.setversions'}) {
+ } elsif ($env{'form.setversions'}) {
$haschanged=1;
- foreach (keys %ENV) {
- if ($_=~/^form\.set_version_(.+)$/) {
+ foreach my $key (keys(%env)) {
+ if ($key=~/^form\.set_version_(.+)$/) {
my $src=$1;
- if (($ENV{$_}) && ($ENV{$_} ne $setversions{$src})) {
- $newsetversions{$src}=$ENV{$_};
+ if (($env{$key}) && ($env{$key} ne $setversions{$src})) {
+ $newsetversions{$src}=$env{$key};
+ &devalidateversioncache($src);
}
}
}
}
if ($haschanged) {
if (&Apache::lonnet::put('resourceversions',\%newsetversions,
- $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.num'}) eq 'ok') {
- $r->print(''.&mt('Your Version Settings have been Stored').' ');
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') {
+ $r->print(&Apache::loncommon::confirmwrapper(
+ &Apache::lonhtmlcommon::confirm_success(&mt('Your Version Settings have been Saved'))));
} else {
- $r->print(''.&mt('An Error Occured while Attempting to Store your Version Settings').' ');
+ $r->print(&Apache::loncommon::confirmwrapper(
+ &Apache::lonhtmlcommon::confirm_success(&mt('An Error Occured while Attempting to Save your Version Settings'),1)));
}
- &changewarning($r,'');
+ &mark_hash_old();
}
- if ($ENV{'form.timerange'} eq 'all') {
+ &changewarning($r,'');
+ if ($env{'form.timerange'} eq 'all') {
# show all documents
- $header=&mt('All Documents in Course');
+ $header=&mt('All Documents in '.$crstype);
$allsel=1;
- foreach (keys %hash) {
- if ($_=~/^ids\_(\/res\/.+)$/) {
+ foreach my $key (keys(%hash)) {
+ if ($key=~/^ids\_(\/res\/.+)$/) {
my $src=$1;
$changes{$src}=1;
}
@@ -830,28 +2713,28 @@ sub checkversions {
} else {
# show documents which changed
%changes=&Apache::lonnet::dump
- ('versionupdate',$ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
- my $firstkey=(keys %changes)[0];
+ ('versionupdate',$env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
+ my $firstkey=(keys(%changes))[0];
unless ($firstkey=~/^error\:/) {
- unless ($ENV{'form.timerange'}) {
- $ENV{'form.timerange'}=604800;
+ unless ($env{'form.timerange'}) {
+ $env{'form.timerange'}=604800;
}
- my $seltext=&mt('during the last').' '.$ENV{'form.timerange'}.' '
+ my $seltext=&mt('during the last').' '.$env{'form.timerange'}.' '
.&mt('seconds');
- if ($ENV{'form.timerange'}==-1) {
+ if ($env{'form.timerange'}==-1) {
$seltext='since start of course';
$startsel='selected';
- $ENV{'form.timerange'}=time;
+ $env{'form.timerange'}=time;
}
- $starttime=time-$ENV{'form.timerange'};
- if ($ENV{'form.timerange'}==2592000) {
+ $starttime=time-$env{'form.timerange'};
+ if ($env{'form.timerange'}==2592000) {
$seltext=&mt('during the last month').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
$monthsel='selected';
- } elsif ($ENV{'form.timerange'}==604800) {
+ } elsif ($env{'form.timerange'}==604800) {
$seltext=&mt('during the last week').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
$weeksel='selected';
- } elsif ($ENV{'form.timerange'}==86400) {
+ } elsif ($env{'form.timerange'}==86400) {
$seltext=&mt('since yesterday').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
$daysel='selected';
}
@@ -861,29 +2744,35 @@ sub checkversions {
}
}
%setversions=&Apache::lonnet::dump('resourceversions',
- $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
my %lt=&Apache::lonlocal::texthash
- ('st' => 'Version changes since start of Course',
+ ('st' => 'Version changes since start of '.$crstype,
'lm' => 'Version changes since last Month',
'lw' => 'Version changes since last Week',
'sy' => 'Version changes since Yesterday',
'al' => 'All Resources (possibly large output)',
+ 'cd' => 'Change display',
'sd' => 'Display',
'fi' => 'File',
'md' => 'Modification Date',
'mr' => 'Most recently published Version',
- 've' => 'Version used in Course',
- 'vu' => 'Set Version to be used in Course',
-'sv' => 'Set Versions to be used in Course according to Selections below',
+ 've' => 'Version used in '.$crstype,
+ 'vu' => 'Set Version to be used in '.$crstype,
+'sv' => 'Set Versions to be used in '.$crstype.' according to Selections below',
'sm' => 'Keep all Resources up-to-date with most recent Versions (default)',
'sc' => 'Set all Resource Versions to current Version (Fix Versions)',
- 'di' => 'Differences');
+ 'di' => 'Differences',
+ 'save' => 'Save changes',
+ 'vers' => 'Version choice(s) for specific resources',
+ 'act' => 'Actions');
$r->print(<$header
');
- $r->print(''.&mt('Done').'. ');
+ $r->print(''.&Apache::loncommon::end_data_table_row().
+ &Apache::loncommon::end_data_table().
+ ' ');
+
+ &untiehash();
+}
+sub mark_hash_old {
+ my $retie_hash=0;
+ if ($hashtied) {
+ $retie_hash=1;
+ &untiehash();
+ }
+ &tiehash('write');
+ $hash{'old'}=1;
&untiehash();
+ if ($retie_hash) { &tiehash(); }
+}
+
+sub is_hash_old {
+ my $untie_hash=0;
+ if (!$hashtied) {
+ $untie_hash=1;
+ &tiehash();
+ }
+ my $return=$hash{'old'};
+ if ($untie_hash) { &untiehash(); }
+ return $return;
}
sub changewarning {
- my ($r,$postexec)=@_;
- $r->print(
-''.
-'');
+ my ($r,$postexec,$message,$url)=@_;
+ if (!&is_hash_old()) { return; }
+ 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();
+ if (!defined($message)) {
+ $message='Changes will become active for your current session after [_1], or the next time you log in.';
+ }
+ $r->print("\n\n".
+''."\n".
+''."\n\n");
+}
+
+
+sub init_breadcrumbs {
+ my ($form,$text)=@_;
+ &Apache::lonhtmlcommon::clear_breadcrumbs();
+ &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?tools=1",
+ text=>&Apache::loncommon::course_type().' Editor',
+ faq=>273,
+ bug=>'Instructor Interface',
+ help => 'Docs_Adding_Course_Doc'});
+ &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?".$form.'=1',
+ text=>$text,
+ faq=>273,
+ bug=>'Instructor Interface'});
+}
+
+# subroutine to list form elements
+sub create_list_elements {
+ my @formarr = @_;
+ my $list = '';
+ for my $button (@formarr){
+ for my $picture(keys %$button) {
+ $list .= &Apache::lonhtmlcommon::htmltag('li', $picture.' '.$button->{$picture}, {class => 'LC_menubuttons_inline_text'});
+ }
+ }
+ return $list;
+}
+
+# subroutine to create ul from list elements
+sub create_form_ul {
+ my $list = shift;
+ my $ul = &Apache::lonhtmlcommon::htmltag('ul',$list, {class => 'LC_ListStyleNormal'});
+ return $ul;
+}
+
+#
+# Start tabs
+#
+
+sub startContentScreen {
+ my ($mode) = @_;
+ my $output = '';
+ if (($mode eq 'navmaps') || ($mode eq 'supplemental')) {
+ $output .= ' '.&mt('Content Overview').' '."\n";
+ $output .= ' '.&mt('Content Search').' '."\n";
+ $output .= ''.&mt('Supplemental Content').' ';
+ } else {
+ $output .= ' '.&mt('Content Editor').' '."\n";
+ $output .= ''.&mt('Supplemental Content Editor').' '."\n";
+ $output .= ' '.&mt('Content Utilities').' '."\n";
+ '> '.&mt('Content Utilities').' ';
+ }
+ $output .= "\n".' '."\n";
+ $output .= ''.
+ '
'.
+ '
';
+ return $output;
+}
+
+#
+# End tabs
+#
+
+sub endContentScreen {
+ return '
';
+}
+
+sub supplemental_base {
+ return 'supplemental&'.&escape(&mt('Supplemental '.&Apache::loncommon::course_type().' Content'));
}
-# ================================================================ Main Handler
sub handler {
my $r = shift;
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
return OK if $r->header_only;
+# get course data
+ my $crstype = &Apache::loncommon::course_type();
+ my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'};
+ my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'};
+
+# graphics settings
+ $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL').'/');
+
+#
# --------------------------------------------- Initialize help topics for this
- foreach ('Adding_Course_Doc','Main_Course_Documents',
- 'Adding_External_Resource','Navigate_Content',
- 'Adding_Folders','Docs_Overview', 'Load_Map',
- 'Supplemental', 'Score_Upload_Form',
- 'Importing_LON-CAPA_Resource','Uploading_From_Harddrive',
- 'Check_Resource_Versions','Verify_Content') {
- $help{$_}=&Apache::loncommon::help_open_topic('Docs_'.$_);
- }
+ foreach my $topic ('Adding_Course_Doc','Main_Course_Documents',
+ 'Adding_External_Resource','Navigate_Content',
+ 'Adding_Folders','Docs_Overview', 'Load_Map',
+ 'Supplemental','Score_Upload_Form','Adding_Pages',
+ 'Importing_LON-CAPA_Resource','Uploading_From_Harddrive',
+ 'Check_Resource_Versions','Verify_Content') {
+ $help{$topic}=&Apache::loncommon::help_open_topic('Docs_'.$topic);
+ }
# Composite help files
$help{'Syllabus'} = &Apache::loncommon::help_open_topic(
'Docs_About_Syllabus,Docs_Editing_Templated_Pages');
@@ -1037,512 +3058,1816 @@ sub handler {
'Option_Response_Simple');
$help{'Bulletin Board'} = &Apache::loncommon::help_open_topic(
'Docs_About_Bulletin_Board,Docs_Editing_Templated_Pages');
- $help{'My Personal Info'} = &Apache::loncommon::help_open_topic(
+ $help{'My Personal Information Page'} = &Apache::loncommon::help_open_topic(
'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');
-
- if ($ENV{'form.verify'}) {
+
+
+ my $allowed;
+# URI is /adm/supplemental when viewing supplemental docs in non-edit mode.
+ unless ($r->uri eq '/adm/supplemental') {
+ # does this user have privileges to modify content.
+ $allowed = &Apache::lonnet::allowed('mdc',$env{'request.course.id'});
+ }
+
+ &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['chooseserver',
+ 'inhibitmenu']);
+ if ($allowed && $env{'form.chooseserver'}) {
+ &choose_dump_server($r);
+ return OK;
+ } elsif ($allowed && $env{'form.verify'}) {
+ &init_breadcrumbs('verify','Verify Content');
&verifycontent($r);
- } elsif ($ENV{'form.versions'}) {
+ } elsif ($allowed && $env{'form.listsymbs'}) {
+ &init_breadcrumbs('listsymbs','List Content IDs');
+ &list_symbs($r);
+ } elsif ($allowed && $env{'form.docslog'}) {
+ &init_breadcrumbs('docslog','Show Log');
+ my $folder = $env{'form.folder'};
+ if ($folder eq '') {
+ $folder='default';
+ }
+ &docs_change_log($r,$coursenum,$coursedom,$folder,$allowed,$crstype,$iconpath);
+ } elsif ($allowed && $env{'form.versions'}) {
+ &init_breadcrumbs('versions','Check/Set Resource Versions');
&checkversions($r);
- } elsif ($ENV{'form.dumpcourse'}) {
+ } elsif ($allowed && $env{'form.dumpcourse'}) {
+ &init_breadcrumbs('dumpcourse','Dump '.&Apache::loncommon::course_type().' Content to Authoring Space');
&dumpcourse($r);
+ } elsif ($allowed && $env{'form.exportcourse'}) {
+ &init_breadcrumbs('exportcourse','IMS Export');
+ &Apache::imsexport::exportcourse($r);
} else {
-# is this a standard course?
+#
+# Done catching special calls
+# The whole rest is for course and supplemental documents and utilities menu
+# Get the parameters that may be needed
+#
+ &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
+ ['folderpath','pagepath',
+ 'pagesymb','forcesupplement','forcestandard',
+ 'tools','symb','command']);
+
+# 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
+
+ my $standard=($env{'request.course.uri'}=~/^\/uploaded\//);
+
+# Decide whether this should display supplemental or main content or utilities
+# supplementalflag=1: show supplemental documents
+# supplementalflag=0: show standard documents
+# toolsflag=1: show utilities
+
+
+ my $supplementalflag=($env{'form.folderpath'}=~/^supplemental/);
+ if (($env{'form.folderpath'}=~/^default/) || $env{'form.folderpath'} eq "" || ($env{'form.pagepath'})) {
+ $supplementalflag=0;
+ }
+ if ($env{'form.forcesupplement'}) { $supplementalflag=1; }
+ if ($env{'form.forcestandard'}) { $supplementalflag=0; }
+ unless ($allowed) { $supplementalflag=1; }
+ unless ($standard) { $supplementalflag=1; }
+ my $toolsflag=0;
+ if ($env{'form.tools'}) { $toolsflag=1; }
- my $standard=($ENV{'request.course.uri'}=~/^\/uploaded\//);
- my $forcestandard;
- my $forcesupplement;
my $script='';
- my $allowed;
- my $events='';
my $showdoc=0;
- &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
- ['folderpath']);
- if ($ENV{'form.folderpath'}) {
- my (@folderpath)=split('&',$ENV{'form.folderpath'});
- $ENV{'form.foldername'}=&Apache::lonnet::unescape(pop(@folderpath));
- $ENV{'form.folder'}=pop(@folderpath);
- }
- if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) {
- $showdoc='/'.$1;
- }
- unless ($showdoc) { # got called from remote
- $forcestandard=($ENV{'form.folder'}=~/^default_/);
- $forcesupplement=($ENV{'form.folder'}=~/^supplemental_/);
-
-# does this user have privileges to post, etc?
- $allowed=&Apache::lonnet::allowed('mdc',$ENV{'request.course.id'});
- if ($allowed) {
- &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['cmd']);
- $script=&Apache::lonratedt::editscript('simple');
+ my $addentries = {};
+ my $container;
+ my $containertag;
+ my $uploadtag;
+
+# Do we directly jump somewhere?
+
+ if ($env{'form.command'} eq 'direct') {
+ my ($mapurl,$id,$resurl);
+ 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'}='';
+ }
+ } elsif ($env{'form.supppath'} ne '') {
+ $env{'form.folderpath'}=$env{'form.supppath'};
}
- } else { # got called in sequence from course
- $allowed=0;
- $script=''.&Apache::lonmenu::registerurl(1,undef).''."\n";
- $iconpath = $r->dir_config('lonIconsURL') . "/";
+ # Breadcrumbs
+ &Apache::lonhtmlcommon::clear_breadcrumbs();
+ unless ($showdoc) {
+ &Apache::lonhtmlcommon::add_breadcrumb({
+ href=>"/adm/coursedocs",text=>"$crstype Contents"});
+
+ $r->print(&Apache::loncommon::start_page("$crstype Contents", $script,
+ {'force_register' => $showdoc,
+ 'add_entries' => $addentries,
+ })
+ .&Apache::loncommon::help_open_menu('','',273,'RAT')
+ .&Apache::lonhtmlcommon::breadcrumbs(
+ 'Editing '.$crstype.' Contents',
+ 'Docs_Adding_Course_Doc')
+ );
+ } else {
+ $r->print(&Apache::loncommon::start_page("$crstype documents",undef,
+ {'force_register' => $showdoc,}));
+ }
- my $now=time;
+ my %allfiles = ();
+ my %codebase = ();
+ my ($upload_result,$upload_output,$uploadphase);
+ if ($allowed) {
+ if (($env{'form.uploaddoc.filename'}) &&
+ ($env{'form.cmd'}=~/^upload_(\w+)/)) {
+ my $context = $1;
+ # Process file upload - phase one - upload and parse primary file.
+ undef($hadchanges);
+ $uploadphase = &process_file_upload(\$upload_output,$coursenum,$coursedom,
+ \%allfiles,\%codebase,$context);
+ if ($hadchanges) {
+ &mark_hash_old();
+ }
+ $r->print($upload_output);
+ } elsif ($env{'form.phase'} eq 'upload_embedded') {
+ # Process file upload - phase two - upload embedded objects
+ $uploadphase = 'check_embedded';
+ my $primaryurl = &HTML::Entities::encode($env{'form.primaryurl'},'<>&"');
+ my $state = &embedded_form_elems($uploadphase,$primaryurl,
+ $env{'form.newidx'});
+ my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
+ my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
+ my ($destination,$dir_root) = &embedded_destination();
+ my $url_root = '/uploaded/'.$docudom.'/'.$docuname;
+ my $actionurl = '/adm/coursedocs';
+ my ($result,$flag) =
+ &Apache::loncommon::upload_embedded('coursedoc',$destination,
+ $docuname,$docudom,$dir_root,$url_root,undef,undef,undef,$state,
+ $actionurl);
+ $r->print($result.&return_to_editor());
+ } elsif ($env{'form.phase'} eq 'check_embedded') {
+ # Process file upload - phase three - modify references in HTML file
+ $uploadphase = 'modified_orightml';
+ my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
+ my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
+ my ($destination,$dir_root) = &embedded_destination();
+ my $result =
+ &Apache::loncommon::modify_html_refs('coursedoc',$destination,
+ $docuname,$docudom,undef,
+ $dir_root);
+ $r->print($result.&return_to_editor());
+ } elsif ($env{'form.phase'} eq 'decompress_uploaded') {
+ $uploadphase = 'decompress_phase_one';
+ $r->print(&decompression_phase_one().
+ &return_to_editor());
+ } elsif ($env{'form.phase'} eq 'decompress_cleanup') {
+ $uploadphase = 'decompress_phase_two';
+ $r->print(&decompression_phase_two().
+ &return_to_editor());
+ }
+ }
-# print screen
- $r->print(<
-
-The LearningOnline Network with CAPA
-
-ENDDOCUMENT
- if ($allowed) {
- $r->print(<
+ if ($allowed && $toolsflag) {
+ $r->print(&startContentScreen('tools'));
+ $r->print(&generate_admin_menu($crstype));
+ $r->print(&endContentScreen());
+ } elsif ((!$showdoc) && (!$uploadphase)) {
+# -----------------------------------------------------------------------------
+ my %lt=&Apache::lonlocal::texthash(
+ 'uplm' => 'Upload a new main '.lc($crstype).' document',
+ 'upls' => 'Upload a new supplemental '.lc($crstype).' document',
+ 'impp' => 'Import a document',
+ 'copm' => 'All documents out of a published map into this folder',
+ 'upld' => 'Import Document',
+ 'srch' => 'Search',
+ 'impo' => 'Import',
+ 'lnks' => 'Import from Stored Links',
+ 'selm' => 'Select Map',
+ 'load' => 'Load Map',
+ 'reco' => 'Recover Deleted Documents',
+ 'newf' => 'New Folder',
+ 'newp' => 'New Composite Page',
+ 'extr' => 'External Resource',
+ 'syll' => 'Syllabus',
+ 'navc' => 'Table of Contents',
+ 'sipa' => 'Simple Course Page',
+ 'sipr' => 'Simple Problem',
+ 'drbx' => 'Drop Box',
+ 'scuf' => 'External Scores (handgrade, upload, clicker)',
+ 'bull' => 'Discussion Board',
+ 'mypi' => 'My Personal Information Page',
+ 'grpo' => 'Group Portfolio',
+ 'rost' => 'Course Roster',
+ 'abou' => 'Personal Information Page for a User',
+ 'imsf' => 'IMS Import',
+ 'imsl' => 'Import IMS package',
+ 'file' => 'File',
+ 'title' => 'Title',
+ 'comment' => 'Comment',
+ 'parse' => 'Upload embedded images/multimedia files if HTML file',
+ 'nd' => 'Upload Document',
+ 'pm' => 'Published Map',
+ 'sd' => 'Special Document',
+ 'mo' => 'More Options',
+ );
+# -----------------------------------------------------------------------------
+ my $fileupload=(<
+
+FIUP
+
+ my $checkbox=(<$lt{'parse'}?
+
+ -->
+
+ $lt{'parse'}
+
+CHBO
+
+ my $fileuploada = " $help{'Uploading_From_Harddrive'}";
+ my $fileuploadform=(<
+
+ $fileupload
+
+ $lt{'title'}:
+
+ $uploadtag
+
+
+
+ $checkbox
+
+FUFORM
+ $fileuploadform .= $fileuploada.'';
+
+ my $simpleeditdefaultform=(<
+
+SEDFFORM
+ my @simpleeditdefaultforma = (
+ { ' ' => "$uploadtag" },
+ { ' ' => "$help{'Importing_LON-CAPA_Resource'}" },
+ { ' ' => "" },
+ );
+ $simpleeditdefaultform .= &create_form_ul(&create_list_elements(@simpleeditdefaultforma));
+ $simpleeditdefaultform .=(<
+ $lt{'copm'}
+
+
+ $help{'Load_Map'}
+
+SEDFFORM
+
+ my $extresourcesform=(<
+ $uploadtag
+
+ $help{'Adding_External_Resource'}
+
+ERFORM
+
+
+ if ($allowed) {
+ my $folder = $env{'form.folder'};
+ if ($folder eq '') {
+ $folder='default';
+ }
+ &update_paste_buffer($coursenum,$coursedom,$folder);
+ $r->print(<
+
+
+
+
+ $containertag
+
+
+HIDDENFORM
+ $r->print(&makesimpleeditform($uploadtag)."\n".
+ &makedocslogform($uploadtag."\n".
+ ' '."\n"));
+ }
+
+# Generate the tabs
+ my $mode;
+ if (($supplementalflag) && (!$allowed)) {
+ &Apache::lonnavdisplay::startContentScreen($r,'supplemental');
+ } else {
+ $r->print(&startContentScreen(($supplementalflag?'suppdocs':'docs')));
+ }
+
+#
+
+ my $savefolderpath;
+
+ if ($allowed) {
+ my $folder=$env{'form.folder'};
+ if ($folder eq '' || $supplementalflag) {
+ $folder='default';
+ $savefolderpath = $env{'form.folderpath'};
+ $env{'form.folderpath'}='default&'.&escape(&mt('Content'));
+ $uploadtag = ' ';
+ }
+ my $postexec='';
+ if ($folder eq 'default') {
+ $r->print(''."\n"
+ );
+ } else {
+ #$postexec='self.close();';
+ }
+ my $folderseq='/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time.
+ '.sequence';
+ my $pageseq = '/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time.
+ '.page';
+ my $container='sequence';
+ if ($env{'form.pagepath'}) {
+ $container='page';
+ }
+ my $readfile='/uploaded/'.$coursedom.'/'.$coursenum.'/'.$folder.'.'.$container;
+
+ my $imspform=(<
+
+
+
+IMSPFORM
+
+ my $newnavform=(<
+
+ $uploadtag
+
+
+ $help{'Navigate_Content'}
+
+NNFORM
+ my $newsmppageform=(<
+
+ $uploadtag
+
+
+ $help{'Simple Page'}
+
+NSPFORM
+
+ my $newsmpproblemform=(<
+
+ $uploadtag
+
+
+ $help{'Simple Problem'}
+
+
+NSPROBFORM
+
+ my $newdropboxform=(<
+
+ $uploadtag
+
+
+
+NDBFORM
+
+ my $newexuploadform=(<
+
+ $uploadtag
+
+
+ $help{'Score_Upload_Form'}
+
+NEXUFORM
+
+ my $newbulform=(<
+
+ $uploadtag
+
+
+ $help{'Bulletin Board'}
+
+NBFORM
+
+ my $newaboutmeform=(<
+
+ $uploadtag
+
+
+ $help{'My Personal Information Page'}
+
+NAMFORM
+
+ my $newaboutsomeoneform=(<
+
+ $uploadtag
+
+
+
+NASOFORM
+
+
+ my $newrosterform=(<
+
+ $uploadtag
+
+
+ $help{'Course Roster'}
+
+NROSTFORM
+
+my $specialdocumentsform;
+my @specialdocumentsforma;
+my $gradingform;
+my @gradingforma;
+my $communityform;
+my @communityforma;
+my $newfolderform;
+my $newfolderb;
+
+ my $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
+
+ my $newpageform=(<
+
+
+
+
+ $help{'Adding_Pages'}
+
+NPFORM
+
+
+ $newfolderform=(<
+
+
+
+ $lt{'newf'} $help{'Adding_Folders'}
+
+NFFORM
+
+ my $newsylform=(<
+
+ $uploadtag
+
+
+ $help{'Syllabus'}
+
+
+NSYLFORM
+
+ my $newgroupfileform=(<
+
+ $uploadtag
+
+
+ $help{'Group Portfolio'}
+
+NGFFORM
+ @specialdocumentsforma=(
+ {' '=>$newpageform},
+ {' '=>$newsylform},
+ {' '=>$newnavform},
+ {' '=>$newsmppageform},
+ );
+ $specialdocumentsform = &create_form_ul(&create_list_elements(@specialdocumentsforma));
+
+
+ my @importdoc = (
+ {' '=>$extresourcesform},
+ {' '=>$imspform},);
+ $fileuploadform = &create_form_ul(&create_list_elements(@importdoc)) . ' ' . $fileuploadform;
+
+ @gradingforma=(
+ {' '=>$newsmpproblemform},
+ {' '=>$newdropboxform},
+ {' '=>$newexuploadform},
+
+ );
+ $gradingform = &create_form_ul(&create_list_elements(@gradingforma));
+
+ @communityforma=(
+ {' '=>$newbulform},
+ {' '=>$newaboutmeform},
+ {' '=>$newaboutsomeoneform},
+ {' '=>$newrosterform},
+ {' '=>$newgroupfileform},
+ );
+ $communityform = &create_form_ul(&create_list_elements(@communityforma));
+
+my %orderhash = (
+ 'aa' => ['Import Content',$fileuploadform],
+ 'bb' => ['Published Content',$simpleeditdefaultform],
+ 'cc' => ['Grading Resources',$gradingform],
+ );
+unless ($env{'form.pagepath'}) {
+ $orderhash{'00'} = ['Newfolder',$newfolderform];
+ $orderhash{'dd'} = ['Collaboration',$communityform];
+ $orderhash{'ee'} = ['Special Documents',$specialdocumentsform];
+}
+
+ $hadchanges=0;
+ unless (($supplementalflag || $toolsflag)) {
+ my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,
+ $supplementalflag,\%orderhash,$iconpath);
+ if ($error) {
+ $r->print(''.$error.'
');
+ }
+ if ($hadchanges) {
+ &mark_hash_old();
+ }
+
+ &changewarning($r,'');
+ }
+ }
+
+# Supplemental documents start here
+
+ my $folder=$env{'form.folder'};
+ unless ($supplementalflag) {
+ $folder='supplemental';
+ }
+ if ($folder =~ /^supplemental$/ &&
+ (($env{'form.folderpath'} =~ /^default\&/) || ($env{'form.folderpath'} eq ''))) {
+ $env{'form.folderpath'} = &supplemental_base();
+ } elsif ($allowed) {
+ $env{'form.folderpath'} = $savefolderpath;
+ }
+ $env{'form.pagepath'} = '';
+ if ($allowed) {
+ my $folderseq=
+ '/uploaded/'.$coursedom.'/'.$coursenum.'/supplemental_'.time.
+ '.sequence';
+
+ my $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
+
+ my $supupdocformbtn = " $help{'Uploading_From_Harddrive'}";
+ my $supupdocform=(<
+
+ $fileupload
+
+
+
+ $checkbox
+
+
+ $lt{'comment'}:
+
+
+
+
+SUPDOCFORM
+ $supupdocform .= &create_form_ul(&Apache::lonhtmlcommon::htmltag('li',$supupdocformbtn,{class => 'LC_menubuttons_inline_text'}))."";
+
+ my $supnewfolderform=(<
+
+
+
+
+ $help{'Adding_Folders'}
+
+SNFFORM
+
+
+ my $supnewextform=(<
+
+
+
+ $help{'Adding_External_Resource'}
+
+SNEFORM
+
+ my $supnewsylform=(<
+
+
+
+
+ $help{'Syllabus'}
+
+SNSFORM
+
+ my $supnewaboutmeform=(<
+
+
+
+
+ $help{'My Personal Information Page'}
+
+SNAMFORM
+
+
+my @specialdocs = (
+ {' '
+ =>$supnewsylform},
+ {' '
+ =>$supnewaboutmeform},
+ );
+my @supimportdoc = (
+ {' '
+ =>$supnewextform},
+ );
+$supupdocform = &create_form_ul(&create_list_elements(@supimportdoc)) . ' ' . $supupdocform;
+my %suporderhash = (
+ '00' => ['Supnewfolder', $supnewfolderform],
+ 'ee' => ['Import Content',$supupdocform],
+ 'ff' => ['Special Documents',&create_form_ul(&create_list_elements(@specialdocs))]
+ );
+ if ($supplementalflag) {
+ my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,
+ $supplementalflag,\%suporderhash,$iconpath);
+ if ($error) {
+ $r->print(''.$error.'
');
+ }
+ }
+ } elsif ($supplementalflag) {
+ my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,
+ $supplementalflag,'',$iconpath);
+ if ($error) {
+ $r->print(''.$error.'
');
+ }
+ }
+
+ $r->print(&endContentScreen());
+
+ if ($allowed) {
+ $r->print('
+');
+ }
+ } elsif ($showdoc) {
+# -------------------------------------------------------- This is showdoc mode
+ $r->print("".&mt('Uploaded Document').' - '.
+ &Apache::lonnet::gettitle($r->uri).' '.
+&mt('It is recommended that you use an up-to-date virus scanner before handling this file.')."
".
+ &entryline(0,&mt("Click to download or use your browser's Save Link function"),$showdoc).'
');
+ }
+ }
+ $r->print(&Apache::loncommon::end_page());
+ return OK;
+}
+
+sub embedded_form_elems {
+ my ($phase,$primaryurl,$newidx) = @_;
+ my $folderpath = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
+ return <
+
+
+
+
+STATE
+}
+
+sub embedded_destination {
+ my $folder=$env{'form.folder'};
+ my $destination = 'docs/';
+ if ($folder =~ /^supplemental/) {
+ $destination = 'supplemental/';
+ }
+ if (($folder eq 'default') || ($folder eq 'supplemental')) {
+ $destination .= 'default/';
+ } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) {
+ $destination .= $2.'/';
+ }
+ $destination .= $env{'form.newidx'};
+ my $dir_root = '/userfiles';
+ return ($destination,$dir_root);
+}
+
+sub return_to_editor {
+ my $actionurl = '/adm/coursedocs';
+ return '
'."\n".
+ ' '."\n".
+ ''.&mt('Return to Editor').
+ ' ';
+}
+
+sub decompression_info {
+ my ($destination,$dir_root) = &embedded_destination();
+ my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
+ my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
+ my $container='sequence';
+ my ($pathitem,$hiddenelem);
+ my @hiddens = ('newidx','comment','position');
+ if ($env{'form.pagepath'}) {
+ $container='page';
+ $pathitem = 'pagepath';
+ } else {
+ $pathitem = 'folderpath';
+ }
+ unshift(@hiddens,$pathitem);
+ foreach my $item (@hiddens) {
+ if ($env{'form.'.$item}) {
+ $hiddenelem .= ' '."\n";
+ }
+ }
+ return ($destination,$dir_root,$londocroot,$docudom,$docuname,$container,
+ $hiddenelem);
+}
+
+sub decompression_phase_one {
+ my ($dir,$file,$warning,$error,$output);
+ my ($destination,$dir_root,$londocroot,$docudom,$docuname,$container,$hiddenelem)=
+ &decompression_info();
+ if ($env{'form.archiveurl'} !~ m{^/uploaded/\Q$docudom/$docuname/\E(?:docs|supplemental)/(?:default|\d+).*/([^/]+)$}) {
+ $error = &mt('Archive file "[_1]" not in the expected location.',$env{'form.archiveurl'});
+ } else {
+ my $file = $1;
+ $output =
+ &Apache::loncommon::process_decompression($docudom,$docuname,$file,
+ $destination,$dir_root,
+ $hiddenelem);
+ if ($env{'form.autoextract_camtasia'}) {
+ $output .= &remove_archive($docudom,$docuname,$container);
+ }
+ }
+ if ($error) {
+ $output .= ''.&mt('Not extracted.').' '.
+ $error.'
'."\n";
+ }
+ if ($warning) {
+ $output .= ''.$warning.'
'."\n";
+ }
+ return $output;
+}
+
+sub decompression_phase_two {
+ my ($destination,$dir_root,$londocroot,$docudom,$docuname,$container,$hiddenelem)=
+ &decompression_info();
+ my $output;
+ if ($env{'form.archivedelete'}) {
+ $output = &remove_archive($docudom,$docuname,$container);
+ }
+ $output .=
+ &Apache::loncommon::process_extracted_files('coursedocs',$docudom,$docuname,
+ $destination,$dir_root,$hiddenelem);
+ return $output;
+}
+
+sub remove_archive {
+ my ($docudom,$docuname,$container) = @_;
+ my $map = $env{'form.folder'}.'.'.$container;
+ my ($output,$delwarning,$delresult,$url);
+ my ($errtext,$fatal) = &mapread($docuname,$docudom,$map);
+ if ($fatal) {
+ if ($container eq 'page') {
+ $delwarning = &mt('An error occurred retrieving the contents of the current page.');
+ } else {
+ $delwarning = &mt('An error occurred retrieving the contents of the current folder.');
+ }
+ $delwarning .= &mt('As a result the archive file has not been removed.');
+ } else {
+ my $currcmd = $env{'form.cmd'};
+ my $position = $env{'form.position'};
+ if ($position > 0) {
+ $env{'form.cmd'} = 'del_'.$position;
+ my ($title,$url,@rrest) =
+ split(/:/,$LONCAPA::map::resources[$LONCAPA::map::order[$position]]);
+ if (&handle_edit_cmd($docuname,$docudom)) {
+ ($errtext,$fatal) = &storemap($docuname,$docudom,$map,1);
+ if ($fatal) {
+ if ($container eq 'page') {
+ $delwarning = &mt('An error occurred updating the contents of the current page.');
+ } else {
+ $delwarning = &mt('An error occurred updating the contents of the current folder.');
+ }
+ } else {
+ $delresult = &mt('Archive file removed.');
+ }
+ }
+ }
+ $env{'form.cmd'} = $currcmd;
+ }
+ if ($delwarning) {
+ $output = ''.
+ $delwarning.
+ '
';
+ }
+ if ($delresult) {
+ $output .= ''.
+ $delresult.
+ '
';
+ }
+ return $output;
+}
+
+sub generate_admin_menu {
+ my ($crstype) = @_;
+ my $lc_crstype = lc($crstype);
+ my ($home,$other,%outhash)=&authorhosts();
+ my %lt=&Apache::lonlocal::texthash (
+ 'vc' => 'Verify Content',
+ 'cv' => 'Check/Set Resource Versions',
+ 'ls' => 'List Resource Identifiers',
+ 'imse' => 'Export contents to IMS Archive',
+ 'dcd' => "Dump $crstype Content to Authoring Space",
+ );
+ my ($candump,$dumpurl);
+ if ($home + $other > 0) {
+ $candump = 'F';
+ if ($home) {
+ $dumpurl = "javascript:injectData(document.courseverify,'dummy','dumpcourse','$lt{'dcd'}')";
+ } else {
+ my @hosts;
+ foreach my $aurole (keys(%outhash)) {
+ unless(grep(/^\Q$outhash{$aurole}\E/,@hosts)) {
+ push(@hosts,$outhash{$aurole});
+ }
+ }
+ if (@hosts == 1) {
+ my $switchto = '/adm/switchserver?otherserver='.$hosts[0].
+ '&role='.
+ &HTML::Entities::encode($env{'request.role'},'"<>&').'&origurl='.
+ &HTML::Entities::encode('/adm/coursedocs?dumpcourse=1','"<>&');
+ $dumpurl = "javascript:dump_needs_switchserver('$switchto')";
+ } else {
+ $dumpurl = "javascript:choose_switchserver_window()";
+ }
+ }
+ }
+ my @menu=
+ ({ categorytitle=>'Administration',
+ items =>[
+ { linktext => $lt{'vc'},
+ url => "javascript:injectData(document.courseverify,'dummy','verify','$lt{'vc'}')",
+ permission => 'F',
+ help => 'Verify_Content',
+ icon => 'verify.png',
+ linktitle => 'Verify contents can be retrieved/rendered',
+ },
+ { linktext => $lt{'cv'},
+ url => "javascript:injectData(document.courseverify,'dummy','versions','$lt{'cv'}')",
+ permission => 'F',
+ help => 'Check_Resource_Versions',
+ icon => 'resversion.png',
+ linktitle => "View version information for resources in your $lc_crstype, and fix/unfix use of specific versions",
+ },
+ { linktext => $lt{'ls'},
+ url => "javascript:injectData(document.courseverify,'dummy','listsymbs','$lt{'ls'}')",
+ permission => 'F',
+ #help => '',
+ icon => 'symbs.png',
+ linktitle => "List the unique identifier used for each resource instance in your $lc_crstype"
+ },
+ ]
+ },
+ { categorytitle=>'Export',
+ items =>[
+ { linktext => $lt{'imse'},
+ url => "javascript:injectData(document.courseverify,'dummy','exportcourse','$lt{'imse'}')",
+ permission => 'F',
+ help => 'Docs_Export_Course_Docs',
+ icon => 'imsexport.png',
+ linktitle => $lt{'imse'},
+ },
+ { linktext => $lt{'dcd'},
+ url => $dumpurl,
+ permission => $candump,
+ #help => '',
+ icon => 'dump.png',
+ linktitle => $lt{'dcd'},
+ },
+ ]
+ });
+ return '';
+}
+
+sub generate_edit_table {
+ my ($tid,$orderhash_ref,$to_show,$iconpath,$jumpto,$readfile) = @_;
+ return unless(ref($orderhash_ref) eq 'HASH');
+ my %orderhash = %{$orderhash_ref};
+ my $form;
+ my $activetab;
+ my $active;
+ if($env{'form.active'} ne ''){
+ $activetab = $env{'form.active'};
+ }
+ my $backicon = $iconpath.'clickhere.gif';
+ my $backtext = &mt('To Overview');
+ $form = ''.
+ '
'."\n".
+ ''.
+ ''.
+ ' '.$backtext.' '."\n".
+ ''.
+ ''.
+ &mt('Undo Delete').' '."\n";
+ if ($env{'form.docslog'}) {
+ $form .= '';
+ } else {
+ $form .= ' ';
+ }
+ $form .= ''.
+ &mt('History').' '."\n";
+ if ($env{'form.docslog'}) {
+ $form .= ''.
+ &mt('Edit').' '."\n";
+ }
+ foreach my $name (reverse(sort(keys(%orderhash)))) {
+ if($name ne '00'){
+ if($activetab eq '' || $activetab ne $name){
+ $active = '';
+ }elsif($activetab eq $name){
+ $active = 'class="active"';
+ }
+ $form .= ''.&mt(${$orderhash{$name}}[0]).' '."\n";
+ } else {
+ $form .= ''.${$orderhash{$name}}[1].' '."\n";
+
+ }
+ }
+ $form .= ' '."\n";
+ $form .= '
'."\n";
+
+ if ($to_show ne '') {
+ $form .= '
'.$to_show.'
'."\n";
+ }
+ foreach my $field (keys(%orderhash)){
+ if($field ne '00'){
+ if($activetab eq '' || $activetab ne $field){
+ $active = 'style="display: none;float:left"';
+ }elsif($activetab eq $field){
+ $active = 'style="display:block;float:left"';
+ }
+ $form .= '
'.${$orderhash{$field}}[1]
+ .'
'."\n";
+ }
+ }
+ unless ($env{'form.docslog'}) {
+ $form .= '
'."\n";
+ }
+ return $form;
+}
+
+sub editing_js {
+ my ($udom,$uname,$supplementalflag) = @_;
+ my $now = time();
+ my %lt = &Apache::lonlocal::texthash(
+ p_mnf => 'Name of New Folder',
+ t_mnf => 'New Folder',
+ p_mnp => 'Name of New Page',
+ t_mnp => 'New Page',
+ p_mxu => 'Title for the External Score',
+ p_msp => 'Name of Simple Course Page',
+ p_msb => 'Title for the Problem',
+ p_mdb => 'Title for the Drop Box',
+ p_mbb => 'Title for the Discussion Board',
+ p_mab => "Enter user:domain for User's Personal Information Page",
+ p_mab2 => 'Personal Information Page of ',
+ p_mab_alrt1 => 'Not a valid user:domain',
+ p_mab_alrt2 => 'Please enter both user and domain in the format user:domain',
+ p_chn => 'New Title',
+ p_rmr1 => 'WARNING: Removing a resource makes associated grades and scores inaccessible!',
+ p_rmr2a => 'Remove[_99]',
+ p_rmr2b => '?[_99]',
+ p_ctr1a => 'WARNING: Cutting a resource makes associated grades and scores inaccessible!',
+ p_ctr1b => 'Grades remain inaccessible if resource is pasted into another folder.',
+ p_ctr2a => 'Cut[_98]',
+ p_ctr2b => '?[_98]',
+ rpck => 'Enter number to pick (e.g., 3)',
+ );
+
+ my $crstype = &Apache::loncommon::course_type();
+ my $docs_folderpath = &HTML::Entities::encode($env{'environment.internal.'.$env{'request.course.id'}.'.docs_folderpath.folderpath'},'<>&"');
+ my $docs_pagepath = &HTML::Entities::encode($env{'environment.internal.'.$env{'request.course.id'}.'.docs_folderpath.pagepath'},'<>&"');
+ my $main_container_page;
+ if ($docs_folderpath eq '') {
+ if ($docs_pagepath ne '') {
+ $main_container_page = 1;
+ }
+ }
+ my $toplevelmain = 'default&Main%20'.$crstype.'%20Documents';
+ my $toplevelsupp = &supplemental_base();
+
+ my $backtourl = '/adm/navmaps';
+ if ($supplementalflag) {
+ $backtourl = '/adm/supplemental';
+ }
+
+ return <
+function unselectInactive(nav) {
+currentNav = document.getElementById(nav);
+currentLis = currentNav.getElementsByTagName('LI');
+for (i = 0; i < currentLis.length; i++) {
+ if (currentLis[i].className == 'goback') {
+ currentLis[i].className = 'goback';
+ } else {
+ if (currentLis[i].className == 'right active' || currentLis[i].className == 'right') {
+ currentLis[i].className = 'right';
+ } else {
+ currentLis[i].className = 'i';
+ }
+ }
+}
+}
+
+function hideAll(current, nav, data) {
+unselectInactive(nav);
+if(current.className == 'right'){
+ current.className = 'right active'
+ }else{
+ current.className = 'active';
+}
+currentData = document.getElementById(data);
+currentDivs = currentData.getElementsByTagName('DIV');
+for (i = 0; i < currentDivs.length; i++) {
+ if(currentDivs[i].className == 'LC_ContentBox'){
+ currentDivs[i].style.display = 'none';
+ }
+}
+}
+
+function openTabs(pageId) {
+ tabnav = document.getElementById(pageId).getElementsByTagName('UL');
+ if(tabnav.length > 2 ){
+ currentNav = document.getElementById(tabnav[1].id);
+ currentLis = currentNav.getElementsByTagName('LI');
+ for(i = 0; i< currentLis.length; i++){
+ if(currentLis[i].className == 'active') {
+ funcString = currentLis[i].onclick.toString();
+ tab = funcString.split('"');
+ if(tab.length < 2) {
+ tab = funcString.split("'");
+ }
+ currentData = document.getElementById(tab[1]);
+ currentData.style.display = 'block';
+ }
+ }
+ }
+}
+
+function showPage(current, pageId, nav, data) {
+ hideAll(current, nav, data);
+ openTabs(pageId);
+ unselectInactive(nav);
+ current.className = 'active';
+ currentData = document.getElementById(pageId);
+ currentData.style.display = 'block';
+ activeTab = pageId;
+ if (nav == 'mainnav') {
+ var storedpath = "$docs_folderpath";
+ if (storedpath == '') {
+ storedpath = "$docs_pagepath";
+ }
+ var storedpage = "$main_container_page";
+ var reg = new RegExp("^supplemental");
+ if (pageId == 'mainCourseDocuments') {
+ if (storedpage == 1) {
+ document.simpleedit.folderpath.value = '';
+ document.uploaddocument.folderpath.value = '';
+ } else {
+ if (reg.test(storedpath)) {
+ document.simpleedit.folderpath.value = '$toplevelmain';
+ document.uploaddocument.folderpath.value = '$toplevelmain';
+ document.newext.folderpath.value = '$toplevelmain';
+ } else {
+ document.simpleedit.folderpath.value = storedpath;
+ document.uploaddocument.folderpath.value = storedpath;
+ document.newext.folderpath.value = storedpath;
+ }
+ }
+ } else {
+ if (reg.test(storedpath)) {
+ document.simpleedit.folderpath.value = storedpath;
+ document.supuploaddocument.folderpath.value = storedpath;
+ document.supnewext.folderpath.value = storedpath;
+ } else {
+ document.simpleedit.folderpath.value = '$toplevelsupp';
+ document.supuploaddocument.folderpath.value = '$toplevelsupp';
+ document.supnewext.folderpath.value = '$toplevelsupp';
+ }
+ }
+ }
+ resize_scrollbox('contentscroll','1','0');
+ return false;
+}
+
+function toContents(jumpto) {
+ var newurl = '$backtourl';
+ if (jumpto != '') {
+ newurl = newurl+'?postdata='+jumpto;
+;
+ }
+ location.href=newurl;
+}
ENDNEWSCRIPT
- }
-# -------------------------------------------------------------------- Body tag
- $r->print(''.
- &Apache::loncommon::bodytag('Course Documents','',$events,
- '','',$showdoc).
- &Apache::loncommon::help_open_faq(273).
- &Apache::loncommon::help_open_bug('RAT'));
- unless ($showdoc) {
-# -----------------------------------------------------------------------------
- my %lt=&Apache::lonlocal::texthash(
- 'uplm' => 'Upload a new main course document',
- 'upls' => 'Upload a new supplemental course document',
- 'impp' => 'Import a published document',
- 'spec' => 'Special documents',
- 'upld' => 'Upload Document',
- 'srch' => 'Search',
- 'impo' => 'Import',
- 'selm' => 'Select Map',
- 'load' => 'Load Map',
- 'newf' => 'New Folder',
- 'extr' => 'External Resource',
- 'syll' => 'Syllabus',
- 'navc' => 'Navigate Contents',
- 'sipa' => 'Simple Page',
- 'sipr' => 'Simple Problem',
- 'scuf' => 'Score Upload Form',
- 'bull' => 'Bulletin Board',
- 'mypi' => 'My Personal Info',
- 'abou' => 'About User',
- 'imsf' => 'Import IMS package',
- 'file' => 'File',
- 'title' => 'Title',
- 'comment' => 'Comment'
- );
-# -----------------------------------------------------------------------------
- if ($allowed) {
- my $dumpbut=&dumpbutton();
- my %lt=&Apache::lonlocal::texthash(
- 'vc' => 'Verify Content',
- 'cv' => 'Check/Set Resource Versions',
- );
+}
- my $folderpath=$ENV{'form.folderpath'};
- if (!$folderpath) {
- if ($ENV{'form.folder'} eq '' ||
- $ENV{'form.folder'} eq 'supplemental') {
- $folderpath='default&'.
- &Apache::lonnet::escape(&mt('Main Course Documents'));
- }
- }
- $r->print(<
-
-
-
-
-
-
-ENDCOURSEVERIFY
- $r->print(&Apache::loncommon::help_open_topic('Docs_Adding_Course_Doc',
- &mt('Editing the Table of Contents for your Course')));
- }
-# --------------------------------------------------------- Standard documents
- $r->print('');
- if (($standard) && ($allowed) && (!$forcesupplement)) {
- $r->print('');
-# ''.&mt('Main Course Documents').
-# ($allowed?' '.$help{'Main_Course_Documents'}:'').' ');
- my $folder=$ENV{'form.folder'};
- if ($folder eq '' || $folder eq 'supplemental') {
- $folder='default';
- $ENV{'form.folderpath'}='default&'.&Apache::lonnet::escape(&mt('Main Course Documents'));
- }
- my $postexec='';
- if ($folder eq 'default') {
- $r->print('');
- } else {
- #$postexec='self.close();';
- }
- $hadchanges=0;
- &editor($r,$coursenum,$coursedom,$folder,$allowed);
- if ($hadchanges) {
- &changewarning($r,$postexec);
- }
- my $folderseq='/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time.
- '.sequence';
- $r->print(<
-$lt{'uplm'}
-$lt{'impp'}
-$lt{'spec'}
-
-
-$lt{'file'}:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-ENDFORM
- $r->print('');
- }
-# ----------------------------------------------------- Supplemental documents
- if (!$forcestandard) {
- $r->print('');
-# ''.&mt('Supplemental Course Documents').
-# ($allowed?' '.$help{'Supplemental'}:'').' ');
- my $folder=$ENV{'form.folder'};
- unless ($folder=~/^supplemental/) {
- $folder='supplemental';
- }
- if ($folder =~ /^supplemental$/ &&
- $ENV{'form.folderpath'} =~ /^default\&/) {
- $ENV{'form.folderpath'}='supplemental&'.
- &Apache::lonnet::escape(&mt('Supplemental Course Documents'));
- }
- &editor($r,$coursenum,$coursedom,$folder,$allowed);
- if ($allowed) {
- my $folderseq=
- '/uploaded/'.$coursedom.'/'.$coursenum.'/supplemental_'.time.
- '.sequence';
+sub history_tab_js {
+ return <<"ENDHIST";
+function toggleHistoryDisp(choice) {
+ document.docslogform.docslog.value = choice;
+ document.docslogform.submit();
+ return;
+}
- $r->print(<
-$lt{'upls'}
-$lt{'spec'}
-
-
-
-
-
-
-
-
-
- $help{'Adding_Folders'}
-
-
-
-
-
-
- $help{'Adding_External_Resource'}
-
-
-
-
-
-
-
-$help{'Syllabus'}
-
-
-
-
-
-
-
-$help{'My Personal Info'}
-
-
-
-
-ENDSUPFORM
+ENDHIST
+}
+
+sub inject_data_js {
+ return < 'Dumping to Authoring Space requires switching server.',
+ swit => 'Switch server?',
+ duco => 'Dump content to Authoring Space',
+ yone => 'You need to switch to a server housing an Authoring Space for which you are author or co-author.',
+ chos => 'Choose server',
+ );
+ my $role = $env{'request.role'};
+ my $js = <<"ENDSWJS";
+
+
+ENDSWJS
+
+ my $startpage = &Apache::loncommon::start_page('Choose server',$js,
+ {'only_body' => 1,
+ 'js_ready' => 1,});
+ my $endpage = &Apache::loncommon::end_page({'js_ready' => 1});
+
+ my $hostpicker;
+ my $count = 0;
+ foreach my $host (sort(@hosts)) {
+ my $checked;
+ if ($count == 0) {
+ $checked = ' checked="checked"';
+ }
+ $hostpicker .= ' '.$host.' ';
+ $count++;
}
- $r->print('');
- } else {
-# -------------------------------------------------------- This is showdoc mode
- $r->print("".&mt('Uploaded Document').' '.
-&mt('It is recommended that you use an up-to-date virus scanner before handling this file.')."
".
- &entryline(0,&mt("Click to download or use your browser's Save Link function"),$showdoc).'
');
- }
- }
- $r->print('');
- return OK;
-}
+
+ return <<"ENDSWITCHJS";
+
+function dump_needs_switchserver(url) {
+ if (url!='' && url!= null) {
+ if (confirm("$lt{'dump'}\\n$lt{'swit'}")) {
+ go(url);
+ }
+ }
+ return;
+}
+
+function choose_switchserver_window() {
+ newWindow = window.open('','ChooseServer','height=400,width=500,scrollbars=yes')
+ newWindow.document.open();
+ newWindow.document.writeln('$startpage');
+ newWindow.document.write('$lt{'duco'}<\\/h3>\\n'+
+ ' $lt{'yone'}<\\/p>\\n'+
+ '
$lt{'chos'}<\\/legend>\\n'+
+ ' \\n'+
+ '$hostpicker\\n'+
+ ' \\n'+
+ ' \\n'+
+ '<\\/form><\\/fieldset><\\/div> \\n');
+ newWindow.document.writeln('$endpage');
+ newWindow.document.close();
+ newWindow.focus();
+}
+
+ENDSWITCHJS
+}
+
+sub makedocslogform {
+ my ($formelems,$docslog) = @_;
+ return <<"LOGSFORM";
+
+
+ $formelems
+
+LOGSFORM
+}
+
+sub makesimpleeditform {
+ my ($formelems) = @_;
+ return <<"SIMPFORM";
+
+
+ $formelems
+
+SIMPFORM
+}
1;
__END__
+
+
+=head1 NAME
+
+Apache::londocs.pm
+
+=head1 SYNOPSIS
+
+This is part of the LearningOnline Network with CAPA project
+described at http://www.lon-capa.org.
+
+=head1 SUBROUTINES
+
+=over
+
+=item %help=()
+
+Available help topics
+
+=item mapread()
+
+Mapread read maps into LONCAPA::map:: global arrays
+@order and @resources, determines status
+sets @order - pointer to resources in right order
+sets @resources - array with the resources with correct idx
+
+=item authorhosts()
+
+Return hash with valid author names
+
+=item clean()
+
+=item dumpcourse()
+
+ Actually dump course
+
+=item group_import()
+
+ Imports the given (name, url) resources into the course
+ coursenum, coursedom, and folder must precede the list
+
+=item breadcrumbs()
+
+=item log_docs()
+
+=item docs_change_log()
+
+=item update_paste_buffer()
+
+=item print_paste_buffer()
+
+=item do_paste_from_buffer()
+
+=item get_newmap_url()
+
+=item dbcopy()
+
+=item uniqueness_check()
+
+=item contained_map_check()
+
+=item reinit_role()
+
+=item url_paste_fixups()
+
+=item apply_fixups()
+
+=item copy_dependencies()
+
+=item update_parameter()
+
+=item handle_edit_cmd()
+
+=item editor()
+
+=item process_file_upload()
+
+=item process_secondary_uploads()
+
+=item is_supplemental_title()
+
+=item entryline()
+
+=item tiehash()
+
+=item untiehash()
+
+=item checkonthis()
+
+check on this
+
+=item verifycontent()
+
+Verify Content
+
+=item devalidateversioncache() & checkversions()
+
+Check Versions
+
+=item mark_hash_old()
+
+=item is_hash_old()
+
+=item changewarning()
+
+=item init_breadcrumbs()
+
+Breadcrumbs for special functions
+
+=item create_list_elements()
+
+=item create_form_ul()
+
+=item startContentScreen()
+
+=item endContentScreen()
+
+=item supplemental_base()
+
+=item embedded_form_elems()
+
+=item embedded_destination()
+
+=item return_to_editor()
+
+=item decompression_info()
+
+=item decompression_phase_one()
+
+=item decompression_phase_two()
+
+=item remove_archive()
+
+=item generate_admin_menu()
+
+=item generate_edit_table()
+
+=item editing_js()
+
+=item history_tab_js()
+
+=item inject_data_js()
+
+=item dump_switchserver_js()
+
+=item resize_scrollbox_js()
+
+=item makedocslogform()
+
+=item makesimpleeditform()
+
+=back
+
+=cut