--- loncom/interface/londocs.pm 2003/10/08 17:34:33 1.86
+++ loncom/interface/londocs.pm 2009/10/23 17:21:03 1.403
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Documents
#
-# $Id: londocs.pm,v 1.86 2003/10/08 17:34:33 albertel Exp $
+# $Id: londocs.pm,v 1.403 2009/10/23 17:21:03 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -26,19 +26,26 @@
# http://www.lon-capa.org/
#
+
+
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 HTML::Entities;
use GDBM_File;
use Apache::lonlocal;
+use Cwd;
+use LONCAPA qw(:DEFAULT :match);
my $iconpath;
@@ -49,138 +56,149 @@ 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 ($outtext,$errtext)=
+ &LONCAPA::map::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
+ $map,1);
+ if ($errtext) { return ($errtext,2); }
+
$hadchanges=1;
- return
- &Apache::lonratedt::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
- $map,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)$/);
}
- if (&Apache::lonnet::homeserver($ca,$cd) eq
- $Apache::lonnet::perlvar{'lonHostID'}) {
+ 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; } }
+ if ($allowed) {
$home++;
$outhash{'home_'.$ca.'@'.$cd}=1;
} else {
- $outhash{'otherhome_'.$ca.'@'.$cd}=
- &Apache::lonnet::homeserver($ca,$cd);
+ $outhash{'otherhome_'.$ca.'@'.$cd}=$myhome;
$other++;
}
}
}
return ($home,$other,%outhash);
}
-# ------------------------------------------------------ Generate "dump" button
+
sub dumpbutton {
my ($home,$other,%outhash)=&authorhosts();
+ my $type = &Apache::loncommon::course_type();
if ($home+$other==0) { return ''; }
- my $output='
';
if ($home) {
- return ' '.
- ' ';
+ my $link = "".&mt('Dump '.$type.' DOCS to Construction Space')." ";
+ return $link.' '.
+ &Apache::loncommon::help_open_topic('Docs_Dump_Course_Docs').' ';
} else {
- return' '.
- &mt('Dump Course DOCS to Construction Space: available on other servers');
+ return ''.
+ &mt('Dump '.$type.
+ ' DOCS to Construction Space: available on other servers').
+ '
';
}
}
-# -------------------------------------------------------- Actually dump course
+sub clean {
+ my ($title)=@_;
+ $title=~s/[^\w\/\!\$\%\^\*\-\_\=\+\;\:\,\\\|\`\~]+/\_/gs;
+ return $title;
+}
+
+
sub dumpcourse {
- my $r=shift;
- $r->print('Dump DOCS '.
- &Apache::loncommon::bodytag('Dump Course DOCS to Construction Space').
- '');
+ '
');
+ }
+}
+
+
+
+sub exportbutton {
+ my $type = &Apache::loncommon::course_type();
+ return "".&mt('IMS Export')." ".
+ &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs').' ';
+}
+
+
+
+sub exportcourse {
+ my $r=shift;
+ my $type = &Apache::loncommon::course_type();
+ my %discussiontime = &Apache::lonnet::dump('discussiontimes',
+ $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'});
+ my $numdisc = keys(%discussiontime);
+ my $navmap = Apache::lonnavmaps::navmap->new();
+ if (!defined($navmap)) {
+ $r->print(&Apache::loncommon::start_page('Export '.$type.' to IMS Package').
+ ''.&mt('IMS Export Failed').' '.
+ ''.
+ &mt('Unable to retrieve information about course contents').
+ '
'.&mt('Return to Course Editor').' ');
+ &Apache::lonnet::logthis('IMS export failed - could not create navmap object in '.lc($type).':'.$env{'request.course.id'});
+ return;
+ }
+ my $it=$navmap->getIterator(undef,undef,undef,1,undef,undef);
+ my $curRes;
+ my $outcome;
+
+ &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
+ ['finishexport']);
+ if ($env{'form.finishexport'}) {
+ &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
+ ['archive','discussion']);
+
+ my @exportitems = &Apache::loncommon::get_env_multiple('form.archive');
+ my @discussions = &Apache::loncommon::get_env_multiple('form.discussion');
+ if (@exportitems == 0 && @discussions == 0) {
+ $outcome =
+ ''
+ .&mt('As you did not select any content items or discussions'
+ .' for export, an IMS package has not been created.')
+ .'
'
+ .''
+ .&mt('Please [_1]go back[_2] to select either content items'
+ .' or discussions for export.'
+ ,''
+ ,' ')
+ .'
';
+ } else {
+ my $now = time;
+ my %symbs;
+ my $manifestok = 0;
+ my $imsresources;
+ my $tempexport;
+ my $copyresult;
+ my $ims_manifest = &create_ims_store($now,\$manifestok,\$outcome,\$tempexport);
+ if ($manifestok) {
+ &build_package($now,$navmap,\@exportitems,\@discussions,\$outcome,$tempexport,\$copyresult,$ims_manifest);
+ close($ims_manifest);
+
+#Create zip file in prtspool
+ my $imszipfile = '/prtspool/'.
+ $env{'user.name'}.'_'.$env{'user.domain'}.'_'.
+ time.'_'.rand(1000000000).'.zip';
+ my $cwd = &Cwd::getcwd();
+ my $imszip = '/home/httpd/'.$imszipfile;
+ chdir $tempexport;
+ open(OUTPUT, "zip -r $imszip * 2> /dev/null |");
+ close(OUTPUT);
+ chdir $cwd;
+ if ($copyresult) {
+ $outcome .= ''
+ .&mt('The following errors occurred during export - [_1]'
+ ,$copyresult)
+ .'
';
+ }
+ $outcome .= ''
+ .&mt('[_1]Your IMS package[_2] is ready for download.'
+ ,'',' ')
+ .'
';
+ } else {
+ $outcome = ''
+ .&mt('Unfortunately you will not be able to retrieve'
+ .' an IMS archive of this posts at this time,'
+ .' because there was a problem creating a'
+ .' manifest file.')
+ .'
'
+ .''
+ .&mt('Go Back')
+ .'
';
+ }
+ }
+ $r->print(&Apache::loncommon::start_page('Export '.$type.' to IMS Package'));
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs('IMS Export'));
+ $r->print($outcome);
+ $r->print(&Apache::loncommon::end_page());
+ } else {
+ my $display;
+ $display = '');
+ }
+}
+
+sub create_ims_store {
+ my ($now,$manifestok,$outcome,$tempexport) = @_;
+ $$tempexport = $Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/ims_exports';
+ my $ims_manifest;
+ if (!-e $$tempexport) {
+ mkdir($$tempexport,0700);
+ }
+ $$tempexport .= '/'.$now;
+ if (!-e $$tempexport) {
+ mkdir($$tempexport,0700);
+ }
+ $$tempexport .= '/'.$env{'user.domain'}.'_'.$env{'user.name'};
+ if (!-e $$tempexport) {
+ mkdir($$tempexport,0700);
+ }
+ if (!-e "$$tempexport/resources") {
+ mkdir("$$tempexport/resources",0700);
+ }
+# open manifest file
+ my $manifest = '/imsmanifest.xml';
+ my $manifestfilename = $$tempexport.$manifest;
+ if ($ims_manifest = Apache::File->new('>'.$manifestfilename)) {
+ $$manifestok=1;
+ print $ims_manifest
+''."\n".
+''."\n".
+'
+
+
+
+ '.$env{'request.course.id'}.'
+
+ '.$env{'course.'.$env{'request.course.id'}.'.description'}.'
+
+
+
+ '."\n".
+' '."\n".
+' '."\n".
+' '.$env{'course.'.$env{'request.course.id'}.'.description'}.' '
+ } else {
+ $$outcome .= 'An error occurred opening the IMS manifest file. '
+;
+ }
+ return $ims_manifest;
+}
+
+sub build_package {
+ my ($now,$navmap,$exportitems,$discussions,$outcome,$tempexport,$copyresult,$ims_manifest) = @_;
+# first iterator to look for dependencies
+ my $it = $navmap->getIterator(undef,undef,undef,1,undef,undef);
+ my $curRes;
+ my $count = 0;
+ my $depth = 0;
+ my $lastcontainer = 0;
+ my %parent = ();
+ my @dependencies = ();
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ while ($curRes = $it->next()) {
+ if (ref($curRes)) {
+ $count ++;
+ }
+ if ($curRes == $it->BEGIN_MAP()) {
+ $depth++;
+ $parent{$depth} = $lastcontainer;
+ }
+ if ($curRes == $it->END_MAP()) {
+ $depth--;
+ $lastcontainer = $parent{$depth};
+ }
+ if (ref($curRes)) {
+ if ($curRes->is_sequence() || $curRes->is_page()) {
+ $lastcontainer = $count;
+ }
+ if (grep(/^$count$/,@$exportitems)) {
+ &get_dependencies($exportitems,\%parent,$depth,\@dependencies);
+ }
+ }
+ }
+# second iterator to build manifest and store resources
+ $it = $navmap->getIterator(undef,undef,undef,1,undef,undef);
+ $depth = 0;
+ my $prevdepth;
+ $count = 0;
+ my $imsresources;
+ my $pkgdepth;
+ while ($curRes = $it->next()) {
+ if ($curRes == $it->BEGIN_MAP()) {
+ $prevdepth = $depth;
+ $depth++;
+ }
+ if ($curRes == $it->END_MAP()) {
+ $prevdepth = $depth;
+ $depth--;
+ }
+
+ if (ref($curRes)) {
+ $count ++;
+ if ((grep(/^$count$/,@$exportitems)) || (grep(/^$count$/,@dependencies))) {
+ my $symb = $curRes->symb();
+ my $isvisible = 'true';
+ my $resourceref;
+ if ($curRes->randomout()) {
+ $isvisible = 'false';
+ }
+ unless ($curRes->is_sequence()) {
+ $resourceref = 'identifierref="RES-'.$env{'request.course.id'}.'-'.$count.'"';
+ }
+ my $step = $prevdepth - $depth;
+ if (($step >= 0) && ($count > 1)) {
+ while ($step >= 0) {
+ print $ims_manifest "\n".' '."\n";
+ $step --;
+ }
+ }
+ $prevdepth = $depth;
+
+ my $itementry =
+ '- '.
+ '
'.$curRes->title().' ';
+ print $ims_manifest "\n".$itementry;
+
+ unless ($curRes->is_sequence()) {
+ my $content_file;
+ my @hrefs = ();
+ &process_content($count,$curRes,$cdom,$cnum,$symb,\$content_file,\@hrefs,$copyresult,$tempexport);
+ if ($content_file) {
+ $imsresources .= "\n".
+ ' '."\n".
+ ' '."\n";
+ foreach my $item (@hrefs) {
+ $imsresources .=
+ ' '."\n";
+ }
+ if (grep(/^$count$/,@$discussions)) {
+ my $ressymb = $symb;
+ my $mode;
+ if ($ressymb =~ m|adm/($match_domain)/($match_username)/(\d+)/bulletinboard$|) {
+ unless ($ressymb =~ m|adm/wrapper/adm|) {
+ $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard';
+ }
+ $mode = 'board';
+ }
+ my %extras = (
+ caller => 'imsexport',
+ tempexport => $tempexport.'/resources',
+ count => $count
+ );
+ my $discresult = &Apache::lonfeedback::list_discussion($mode,undef,$ressymb,\%extras);
+ }
+ $imsresources .= ' '."\n";
+ }
+ }
+ $pkgdepth = $depth;
+ }
+ }
+ }
+ while ($pkgdepth > 0) {
+ print $ims_manifest " \n";
+ $pkgdepth --;
+ }
+ my $resource_text = qq|
+
+
+
+ $imsresources
+
+
+ |;
+ print $ims_manifest $resource_text;
+}
+
+sub get_dependencies {
+ my ($exportitems,$parent,$depth,$dependencies) = @_;
+ if ($depth > 1) {
+ if ((!grep(/^$$parent{$depth}$/,@$exportitems)) && (!grep(/^$$parent{$depth}$/,@$dependencies))) {
+ push(@{$dependencies},$$parent{$depth});
+ if ($depth > 2) {
+ &get_dependencies($exportitems,$parent,$depth-1,$dependencies);
+ }
+ }
+ }
+}
+
+sub process_content {
+ my ($count,$curRes,$cdom,$cnum,$symb,$content_file,$href,$copyresult,$tempexport) = @_;
+ my $content_type;
+ my $message;
+ my @uploads = ();
+ if ($curRes->is_sequence()) {
+ $content_type = 'sequence';
+ } elsif ($curRes->is_page()) {
+ $content_type = 'page'; # need to handle individual items in pages.
+ } elsif ($symb =~ m-public/$cdom/$cnum/syllabus$-) {
+ $content_type = 'syllabus';
+ my $contents = &Apache::imsexport::templatedpage($content_type);
+ if ($contents) {
+ $$content_file = &store_template($contents,$tempexport,$count,$content_type);
+ }
+ } elsif ($symb =~ m-\.sequence___\d+___ext-) {
+ $content_type = 'external';
+ my $title = $curRes->title;
+ my $contents = &Apache::imsexport::external($symb,$title);
+ if ($contents) {
+ $$content_file = &store_template($contents,$tempexport,$count,$content_type);
+ }
+ } elsif ($symb =~ m-adm/navmaps$-) {
+ $content_type = 'navmap';
+ } elsif ($symb =~ m-adm/[^/]+/[^/]+/(\d+)/smppg$-) {
+ $content_type = 'simplepage';
+ my $contents = &Apache::imsexport::templatedpage($content_type,$1,$count,\@uploads);
+ if ($contents) {
+ $$content_file = &store_template($contents,$tempexport,$count,$content_type);
+ }
+ } elsif ($symb =~ m-lib/templates/simpleproblem\.problem$-) {
+ $content_type = 'simpleproblem';
+ my $contents = &Apache::imsexport::simpleproblem($symb);
+ if ($contents) {
+ $$content_file = &store_template($contents,$tempexport,$count,$content_type);
+ }
+ } elsif ($symb =~ m-lib/templates/examupload\.problem$-) {
+ $content_type = 'examupload';
+ } elsif ($symb =~ m-adm/($match_domain)/($match_username)/(\d+)/bulletinboard$-) {
+ $content_type = 'bulletinboard';
+ my $contents = &Apache::imsexport::templatedpage($content_type,$3,$count,\@uploads,$1,$2);
+ if ($contents) {
+ $$content_file = &store_template($contents,$tempexport,$count,$content_type);
+ }
+ } elsif ($symb =~ m-adm/([^/]+)/([^/]+)/aboutme$-) {
+ $content_type = 'aboutme';
+ my $contents = &Apache::imsexport::templatedpage($content_type,undef,$count,\@uploads,$1,$2);
+ if ($contents) {
+ $$content_file = &store_template($contents,$tempexport,$count,$content_type);
+ }
+ } elsif ($symb =~ m-\.(sequence|page)___\d+___uploaded/$cdom/$cnum/-) {
+ $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'uploaded');
+ } elsif ($symb =~ m-\.(sequence|page)___\d+___([^/]+)/([^/]+)-) {
+ my $canedit = 0;
+ if ($2 eq $env{'user.domain'} && $3 eq $env{'user.name'}) {
+ $canedit= 1;
+ }
+# only include problem code where current user is author
+ if ($canedit) {
+ $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'resource');
+ } else {
+ $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'noedit');
+ }
+ } elsif ($symb =~ m-uploaded/$cdom/$cnum-) {
+ $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'uploaded');
+ }
+ if (@uploads > 0) {
+ foreach my $item (@uploads) {
+ my $uploadmsg = '';
+ &replicate_content($cdom,$cnum,$tempexport,$item,$count,\$uploadmsg,$href,'templateupload');
+ if ($uploadmsg) {
+ $$copyresult .= $uploadmsg."\n";
+ }
+ }
+ }
+ if ($message) {
+ $$copyresult .= $message."\n";
+ }
+}
+
+sub replicate_content {
+ my ($cdom,$cnum,$tempexport,$symb,$count,$message,$href,$caller) = @_;
+ my ($map,$ind,$url);
+ if ($caller eq 'templateupload') {
+ $url = $symb;
+ $url =~ s#//#/#g;
+ } else {
+ ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
+ }
+ my $content;
+ my $filename;
+ my $repstatus;
+ my $content_name;
+ if ($url =~ m-/([^/]+)$-) {
+ $filename = $1;
+ if (!-e $tempexport.'/resources') {
+ mkdir($tempexport.'/resources',0700);
+ }
+ if (!-e $tempexport.'/resources/'.$count) {
+ mkdir($tempexport.'/resources/'.$count,0700);
+ }
+ my $destination = $tempexport.'/resources/'.$count.'/'.$filename;
+ my $copiedfile;
+ if ($copiedfile = Apache::File->new('>'.$destination)) {
+ my $content;
+ if ($caller eq 'resource') {
+ my $respath = $Apache::lonnet::perlvar{'lonDocRoot'}.'/res';
+ my $filepath = &Apache::lonnet::filelocation($respath,$url);
+ $content = &Apache::lonnet::getfile($filepath);
+ if ($content eq -1) {
+ $$message = 'Could not copy file '.$filename;
+ } else {
+ &extract_media($url,$cdom,$cnum,\$content,$count,$tempexport,$href,$message,'resource');
+ $repstatus = 'ok';
+ }
+ } elsif ($caller eq 'uploaded' || $caller eq 'templateupload') {
+ my $rtncode;
+ $repstatus = &Apache::lonnet::getuploaded('GET',$url,$cdom,$cnum,\$content,$rtncode);
+ if ($repstatus eq 'ok') {
+ if ($url =~ /\.html?$/i) {
+ &extract_media($url,$cdom,$cnum,\$content,$count,$tempexport,$href,$message,'uploaded');
+ }
+ } else {
+ $$message = 'Could not render '.$url.' server message - '.$rtncode." \n";
+ }
+ } elsif ($caller eq 'noedit') {
+# Need to render the resource without the LON-CAPA Internal header and the Post discussion footer, and then set $content equal to this.
+ $repstatus = 'ok';
+ $content = 'Not the owner of this resource';
+ }
+ if ($repstatus eq 'ok') {
+ print $copiedfile $content;
+ }
+ close($copiedfile);
+ } else {
+ $$message = 'Could not open destination file for '.$filename." \n";
+ }
+ } else {
+ $$message = 'Could not determine name of file for '.$symb." \n";
+ }
+ if ($repstatus eq 'ok') {
+ $content_name = 'resources/'.$count.'/'.$filename;
+ }
+ return $content_name;
+}
+
+sub extract_media {
+ my ($url,$cdom,$cnum,$content,$count,$tempexport,$href,$message,$caller) = @_;
+ my ($dirpath,$container);
+ my %allfiles = ();
+ my %codebase = ();
+ if ($url =~ m-(.*/)([^/]+)$-) {
+ $dirpath = $1;
+ $container = $2;
+ } else {
+ $dirpath = $url;
+ $container = '';
+ }
+ &Apache::lonnet::extract_embedded_items(undef,\%allfiles,\%codebase,$content);
+ foreach my $embed_file (keys(%allfiles)) {
+ my $filename;
+ if ($embed_file =~ m#([^/]+)$#) {
+ $filename = $1;
+ } else {
+ $filename = $embed_file;
+ }
+ my $newname = 'res/'.$filename;
+ my ($rtncode,$embed_content,$repstatus);
+ my $embed_url;
+ if ($embed_file =~ m-^/-) {
+ $embed_url = $embed_file; # points to absolute path
+ } else {
+ if ($embed_file =~ m-https?://-) {
+ next; # points to url
+ } else {
+ $embed_url = $dirpath.$embed_file; # points to relative path
+ }
+ }
+ if ($caller eq 'resource') {
+ my $respath = $Apache::lonnet::perlvar{'lonDocRoot'}.'/res';
+ my $embed_path = &Apache::lonnet::filelocation($respath,$embed_url);
+ $embed_content = &Apache::lonnet::getfile($embed_path);
+ unless ($embed_content eq -1) {
+ $repstatus = 'ok';
+ }
+ } elsif ($caller eq 'uploaded') {
+
+ $repstatus = &Apache::lonnet::getuploaded('GET',$embed_url,$cdom,$cnum,\$embed_content,$rtncode);
+ }
+ if ($repstatus eq 'ok') {
+ my $destination = $tempexport.'/resources/'.$count.'/res';
+ if (!-e "$destination") {
+ mkdir($destination,0755);
+ }
+ $destination .= '/'.$filename;
+ my $copiedfile;
+ if ($copiedfile = Apache::File->new('>'.$destination)) {
+ print $copiedfile $embed_content;
+ push(@{$href},'resources/'.$count.'/res/'.$filename);
+ my $attrib_regexp = '';
+ if (@{$allfiles{$embed_file}} > 1) {
+ $attrib_regexp = join('|',@{$allfiles{$embed_file}});
+ } else {
+ $attrib_regexp = $allfiles{$embed_file}[0];
+ }
+ $$content =~ s#($attrib_regexp\s*=\s*['"]?)\Q$embed_file\E(['"]?)#$1$newname$2#gi;
+ if ($caller eq 'resource' && $container =~ /\.(problem|library)$/) {
+ $$content =~ s#\Q$embed_file\E#$newname#gi;
+ }
+ }
+ } else {
+ $$message .= 'replication of embedded file - '.$embed_file.' in '.$url.' failed, reason -'.$rtncode." \n";
+ }
+ }
+ return;
+}
+
+sub store_template {
+ my ($contents,$tempexport,$count,$content_type) = @_;
+ if ($contents) {
+ if ($tempexport) {
+ if (!-e $tempexport.'/resources') {
+ mkdir($tempexport.'/resources',0700);
+ }
+ if (!-e $tempexport.'/resources/'.$count) {
+ mkdir($tempexport.'/resources/'.$count,0700);
+ }
+ my $destination = $tempexport.'/resources/'.$count.'/'.$content_type.'.xml';
+ my $storetemplate;
+ if ($storetemplate = Apache::File->new('>'.$destination)) {
+ print $storetemplate $contents;
+ close($storetemplate);
+ }
+ if ($content_type eq 'external') {
+ return 'resources/'.$count.'/'.$content_type.'.html';
+ } else {
+ return 'resources/'.$count.'/'.$content_type.'.xml';
+ }
+ }
}
}
-# 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'));
}
}
- &storemap($coursenum, $coursedom, $folder.'.sequence');
+ return &storemap($coursenum, $coursedom, $folder.'.'.$container);
+}
+
+sub breadcrumbs {
+ my ($allowed,$type)=@_;
+ &Apache::lonhtmlcommon::clear_breadcrumbs();
+ 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;
+ if (!$allowed) {
+ my $description = $env{'course.'.$env{'request.course.id'}.'.description'};
+ &Apache::lonhtmlcommon::add_breadcrumb(
+ {'href' => '/adm/menu',
+ 'title'=> 'Go to main menu',
+ 'text' => $description,
+ });
+ $plain .= $description.' >';
+ }
+ while (@folders) {
+ my $folder=shift(@folders);
+ my $foldername=shift(@folders);
+ if ($folderpath) {$folderpath.='&';}
+ $folderpath.=$folder.'&'.$foldername;
+ my $url='/adm/coursedocs?folderpath='.
+ &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 '.$type.' Documents');
+ }
+ &Apache::lonhtmlcommon::add_breadcrumb(
+ {'href'=>$url.$cpinfo,
+ 'title'=>$name,
+ 'text'=>$name,
+ 'no_mt'=>1,
+ });
+ $plain.=$name.' > ';
+ }
+ $plain=~s/\>\;\s*$//;
+ return (&Apache::lonhtmlcommon::breadcrumbs(undef,undef,0,'nohelp',
+ undef, undef, 1 ),$randompick,$ishidden,$isencrypted,$plain,$is_random_order);
+}
+
+sub log_docs {
+ return &Apache::lonnet::instructor_log('docslog',@_);
+}
+
+{
+ 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;
+ }
+
+ 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)=@_;
+ my $folder=$env{'form.folder'};
+ $r->print(&Apache::loncommon::start_page('Course Document Change Log'));
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course Document Change Log'));
+ 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); }
+
+ $r->print('');
+ $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'}.' ');
+# 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) {
+ $r->print(&LONCAPA::map::qtescape($oldname));
+ }
+ }
+ $r->print('');
+ for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
+ if ($docslog{$id}{'logentry'}{'before_order_res_'.$idx}) {
+ $r->print(''.&LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'before_order_res_'.$idx}))[0]).' ');
+ }
+ }
+ $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) {
+ $r->print(&LONCAPA::map::qtescape($newname));
+ }
+ }
+ $r->print('');
+ for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
+ if ($docslog{$id}{'logentry'}{'after_order_res_'.$idx}) {
+ $r->print(''.&LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'after_order_res_'.$idx}))[0]).' ');
+ }
+ }
+ $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}) {
+ $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());
+}
+
+sub update_paste_buffer {
+ my ($coursenum,$coursedom) = @_;
+
+ 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) = &parse_supplemental_title($title);
+ } elsif ($env{'docs.markedcopy_supplemental'}) {
+ &Apache::lonnet::delenv('docs.markedcopy_supplemental');
+ }
+ $url=~s{http(:|:)//https(:|:)//}{https$2//};
+
+ &Apache::lonnet::appenv({'docs.markedcopy_title' => $title,
+ 'docs.markedcopy_url' => $url});
+ delete($env{'form.markcopy'});
+}
+
+sub print_paste_buffer {
+ my ($r,$container) = @_;
+ return if (!defined($env{'docs.markedcopy_url'}));
+
+ $r->print(''
+ .''.&mt('Clipboard').' '
+ .' ');
+}
+
+sub do_paste_from_buffer {
+ my ($coursenum,$coursedom,$folder) = @_;
+
+ if (!$env{'form.pastemarked'}) {
+ return;
+ }
+
+# paste resource to end of list
+ my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url'});
+ my $title=&LONCAPA::map::qtescape($env{'docs.markedcopy_title'});
+# Maps need to be copied first
+ if (($url=~/\.(page|sequence)$/) && ($url=~/^\/uploaded\//)) {
+ $title=&mt('Copy of').' '.$title;
+ my $newid=$$.int(rand(100)).time;
+ my ($oldid,$ext) = ($url=~/^(.+)\.(\w+)$/);
+ if ($oldid =~ m{^(/uploaded/\Q$coursedom\E/\Q$coursenum\E/)(\D+)(\d+)$}) {
+ my $path = $1;
+ my $prefix = $2;
+ my $ancestor = $3;
+ if (length($ancestor) > 10) {
+ $ancestor = substr($ancestor,-10,10);
+ }
+ $oldid = $path.$prefix.$ancestor;
+ }
+ my $counter = 0;
+ my $newurl=$oldid.$newid.'.'.$ext;
+ my $is_unique = &uniqueness_check($newurl);
+ while (!$is_unique && $counter < 100) {
+ $counter ++;
+ $newid ++;
+ $newurl = $oldid.$newid;
+ $is_unique = &uniqueness_check($newurl);
+ }
+ if (!$is_unique) {
+ if ($url=~/\.page$/) {
+ return &mt('Paste failed: an error occurred creating a unique URL for the composite page');
+ } else {
+ return &mt('Paste failed: an error occurred creating a unique URL for the folder');
+ }
+ }
+ my $storefn=$newurl;
+ $storefn=~s{^/\w+/$match_domain/$match_username/}{};
+ my $paste_map_result =
+ &Apache::lonclonecourse::writefile($env{'request.course.id'},$storefn,
+ &Apache::lonnet::getfile($url));
+ if ($paste_map_result eq '/adm/notfound.html') {
+ if ($url=~/\.page$/) {
+ return &mt('Paste failed: an error occurred saving the composite page');
+ } else {
+ return &mt('Paste failed: an error occurred saving the folder');
+ }
+ }
+ $url = $newurl;
+ }
+# published maps can only exists once, so remove it from paste buffer when done
+ if (($url=~/\.(page|sequence)$/) && ($url=~m {^/res/})) {
+ &Apache::lonnet::delenv('docs.markedcopy');
+ }
+ 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;
+ $title=&mt('Copy of').' '.$title;
+ }
+ }
+ $title = &LONCAPA::map::qtunescape($title);
+ my $ext='false';
+ if ($url=~m{^http(|s)://}) { $ext='true'; }
+ $url = &LONCAPA::map::qtunescape($url);
+# Now insert the URL at the bottom
+ my $newidx = &LONCAPA::map::getresidx($url);
+ if ($env{'docs.markedcopy_supplemental'}) {
+ if ($folder =~ /^supplemental/) {
+ $title = $env{'docs.markedcopy_supplemental'};
+ } else {
+ (undef,undef,$title) =
+ &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);
+ return 'ok';
+# Store the result
+}
+
+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;
+}
+
+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!~/\.(page|sequence|problem|exam|quiz|assess|survey|form|library|task)$/)) {
+ &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)=@_;
- if ($ENV{'form.foldername'}) {
- $r->print('Folder: '.$ENV{'form.foldername'}.' ');
- }
- 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 ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$type)=@_;
+ my $container= ($env{'form.pagepath'}) ? 'page'
+ : 'sequence';
+
+ 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]='';
}
- if ($fatal) {
- $r->print(''.$errtext.'
');
+
+ my ($breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,$is_random_order);
+ if ($allowed) {
+ ($breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,$is_random_order) =
+ &breadcrumbs($allowed,$type);
+ $r->print($breadcrumbtrail);
} else {
+ $randompick = -1;
+ }
+
# ------------------------------------------------------------ Process commands
+
# ---------------- if they are for this folder and user allowed to make changes
- if (($allowed) && ($ENV{'form.folder'} eq $folder)) {
-# upload a file, if present
- if (($ENV{'form.uploaddoc.filename'}) &&
- ($ENV{'form.cmd'}=~/^upload_(\w+)/)) {
- if ($folder=~/^$1/) {
-# 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);
- 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;
- &storemap($coursenum,$coursedom,$folder.'.sequence');
- }
- }
- if ($ENV{'form.cmd'}) {
- my ($cmd,$idx)=split(/\_/,$ENV{'form.cmd'});
- if ($cmd eq 'del') {
- 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);
-
- }
-# Store the changed version
- &storemap($coursenum,$coursedom,$folder.'.sequence');
+ if (($allowed) && ($env{'form.folder'} eq $folder)) {
+# set parameters and change order
+ &snapshotbefore();
+
+ if (&update_parameter()) {
+ ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container);
+ return $errtext if ($fatal);
+ }
+
+ 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.'.'.$container);
+ return $errtext if ($fatal);
+ }
+
+ if ($env{'form.pastemarked'}) {
+ my $paste_res =
+ &do_paste_from_buffer($coursenum,$coursedom,$folder);
+ if ($paste_res eq 'ok') {
+ ($errtext,$fatal) = &storemap($coursenum,$coursedom,$folder.'.'.$container);
+ return $errtext if ($fatal);
+ } elsif ($paste_res ne '') {
+ $r->print(''.$paste_res.'
');
}
+ }
+
+ $r->print($upload_output);
+
+ if (&handle_edit_cmd()) {
+ ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container);
+ 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;
- }
+ 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]);
}
-# Store the changed version
- group_import($coursenum, $coursedom, $folder, @imports);
- }
+ }
+ ($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;
- }
+ 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);
+ return $errtext if ($fatal);
+ } else {
+ $r->print(''.&mt('No map selected.').'
');
-# Store the changed version
- &storemap($coursenum,$coursedom,$folder.'.sequence');
- }
- }
+ }
+ }
+ &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) { $name='NO RESOURCE'; $url='/adm/notfound.html'; }
- $r->print(&entryline($idx,$name,$url,$folder,$allowed,$_));
- $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('
');
+ $r->print('');
+ }
+
+ my $output;
+ 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);
+ $idx++;
+ $shown++;
+ }
+ if ($shown) {
+ $r->print(&Apache::loncommon::start_data_table());
+ if ($allowed) {
+ $r->print(&Apache::loncommon::start_data_table_header_row()
+ .''.&mt('Move').' '
+ .''.&mt('Actions').' '
+ .''.&mt('Document').' ');
+ if ($folder !~ /^supplemental/) {
+ $->print(''.&mt('Settings').' ');
+ }
+ $r->print(&Apache::loncommon::end_data_table_header_row());
+ }
+ $r->print($output
+ .&Apache::loncommon::end_data_table()
+ );
+ } else {
+ $r->print(''
+ .&mt('Currently no documents.')
+ .'
'
+ );
}
+ if ($allowed) {
+ &print_paste_buffer($r,$container);
+ }
+ return;
+}
+
+sub process_file_upload {
+ my ($upload_output,$coursenum,$coursedom,$allfiles,$codebase,$uploadcmd) = @_;
+# upload a file, if present
+ my $parseaction;
+ if ($env{'form.parserflag'}) {
+ $parseaction = 'parse';
+ }
+ my $phase_status;
+ my $folder=$env{'form.folder'};
+ if ($folder eq '') {
+ $folder='default';
+ }
+ if ( ($folder=~/^$uploadcmd/) || ($uploadcmd eq 'default') ) {
+ my $errtext='';
+ my $fatal=0;
+ my $container='sequence';
+ if ($env{'form.pagepath'}) {
+ $container='page';
+ }
+ ($errtext,$fatal)=
+ &mapread($coursenum,$coursedom,$folder.'.'.$container);
+ if ($#LONCAPA::map::order<1) {
+ $LONCAPA::map::order[0]=1;
+ $LONCAPA::map::resources[1]='';
+ }
+ if ($fatal) {
+ return 'failed';
+ }
+ my $destination = 'docs/';
+ if ($folder =~ /^supplemental/) {
+ $destination = 'supplemental/';
+ }
+ if (($folder eq 'default') || ($folder eq 'supplemental')) {
+ $destination .= 'default/';
+ } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) {
+ $destination .= $2.'/';
+ }
+# this is for a course, not a user, so set coursedoc flag
+# probably the only place in the system where this should be "1"
+ my $newidx=&LONCAPA::map::getresidx();
+ $destination .= $newidx;
+ my $url=&Apache::lonnet::userfileupload('uploaddoc',1,$destination,
+ $parseaction,$allfiles,
+ $codebase);
+ 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);
+ if ($fatal) {
+ $$upload_output .= ''.$errtext.'
';
+ return 'failed';
+ } else {
+ if ($parseaction eq 'parse') {
+ my $total_embedded = scalar(keys(%{$allfiles}));
+ if ($total_embedded > 0) {
+ my $num = 0;
+ my $state = '
+
+
+
+
+ ';
+ $phase_status = 'phasetwo';
+
+ $$upload_output .=
+ 'This file contains embedded multimedia objects, which need to be uploaded to LON-CAPA. '.
+ &Apache::loncommon::ask_for_embedded_content(
+ '/adm/coursedocs',$state,$allfiles,$codebase);
+ } else {
+ $$upload_output .= 'No embedded items identified ';
+ }
+ }
+ }
+ }
+ return $phase_status;
+}
+
+sub process_secondary_uploads {
+ my ($upload_output,$coursedom,$coursenum,$formname,$num,$newidx) = @_;
+ my $folder=$env{'form.folder'};
+ my $destination = 'docs/';
+ if ($folder =~ /^supplemental/) {
+ $destination = 'supplemental/';
+ }
+ if (($folder eq 'default') || ($folder eq 'supplemental')) {
+ $destination .= 'default/';
+ } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) {
+ $destination .= $2.'/';
+ }
+ $destination .= $newidx;
+ my ($url,$filename);
+ $url=&Apache::lonnet::userfileupload($formname.$num,1,$destination);
+ ($filename) = ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/\Q$destination\E/(.+)$});
+ return $filename;
+}
+
+sub is_supplemental_title {
+ my ($title) = @_;
+ return scalar($title =~ m/^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/);
+}
+
+sub parse_supplemental_title {
+ my ($title) = @_;
+
+ my ($foldertitle,$renametitle);
+ if ($title =~ /&&&/) {
+ $title = &HTML::Entites::decode($title);
+ }
+ if ($title =~ m/^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/) {
+ $renametitle=$4;
+ my ($time,$uname,$udom) = ($1,$2,$3);
+ $foldertitle=&Apache::lontexconvert::msgtexconverted($4);
+ my $name = &Apache::loncommon::plainname($uname,$udom);
+ $name = &HTML::Entities::encode($name,'"<>&\'');
+ $title=''.&Apache::lonlocal::locallocaltime($time).' '.
+ $name.': '.$foldertitle;
+ }
+ if (wantarray) {
+ return ($title,$foldertitle,$renametitle);
+ }
+ return $title;
}
# --------------------------------------------------------------- An entry line
sub entryline {
- my ($index,$title,$url,$folder,$allowed,$residx)=@_;
- $title=~s/\&colon\;/\:/g;
- $title=&HTML::Entities::encode(&HTML::Entities::decode(
- &Apache::lonnet::unescape($title)),'\"\<\>\&\'');
- my $renametitle=$title;
- my $foldertitle=$title;
- 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)=@_;
+ my ($foldertitle,$pagetitle,$renametitle);
+ if (&is_supplemental_title($title)) {
+ ($title,$foldertitle,$renametitle) = &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);
# Edit commands
+ 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($path = $env{'form.pagepath'});
+ $path = &HTML::Entities::encode($env{'form.pagepath'},'<>&"');
+ $symb=&escape($env{'form.pagesymb'});
+ }
+ my $cpinfo='';
if ($allowed) {
- $line.=(<
-
-
-
-
-
-
-
-
-Remove
-
-Rename
+ my $incindex=$index+1;
+ my $selectbox='';
+ if (($folder!~/^supplemental/) &&
+ ($#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<=$#LONCAPA::map::order+1;$i++) {
+ if ($i==$incindex) {
+ $selectbox.='('.$i.') ';
+ } else {
+ $selectbox.=''.$i.' ';
+ }
+ }
+ $selectbox.=' ';
+ }
+ my %lt=&Apache::lonlocal::texthash(
+ 'up' => 'Move Up',
+ 'dw' => 'Move Down',
+ 'rm' => 'Remove',
+ 'ct' => 'Cut',
+ 'rn' => 'Rename',
+ 'cp' => 'Copy');
+ my $nocopy=0;
+ my $nocut=0;
+ if ($url=~/\.(page|sequence)$/) {
+ if ($url =~ m{/res/}) {
+ # no copy for published maps
+ $nocopy = 1;
+ } else {
+ foreach my $item (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$url),1)) {
+ my ($title,$url,$ext,$type)=split(/\:/,$item);
+ if (($url=~/\.(page|sequence)/) && ($type ne 'zombie')) {
+ $nocopy=1;
+ last;
+ }
+ }
+ }
+ }
+ 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 = (<
+
+
+
+
+END
+ $form_end = '';
+ $line.=(<
+
+
+
+
+
+
+
+
+
+
+
+
+ $form_start
+ $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='unknown';
- if (-e "/home/httpd/html/adm/lonIcons/$extension.gif") {
- $icon=$extension;
- }
+ 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='folder_closed';
- $url=~/\/(\w+)\.sequence/;
- $url='/adm/coursedocs?folder='.$1;
- $isfolder=1;
- } else {
- $url=&Apache::lonnet::tokenwrapper($url);
- }
+ if ($extension eq 'sequence') {
+ $icon=$iconpath.'/navmap.folder.closed.gif';
+ $url=~/\Q$coursenum\E\/([\/\w]+)\.sequence$/;
+ $url='/adm/coursedocs?';
+ $folderarg=$1;
+ $isfolder=1;
+ } elsif ($extension eq 'page') {
+ $icon=$iconpath.'/page.gif';
+ $url=~/\Q$coursenum\E\/([\/\w]+)\.page$/;
+ $pagearg=$1;
+ $url='/adm/coursedocs?';
+ $ispage=1;
+ } else {
+ &Apache::lonnet::allowuploaded('/adm/coursedoc',$url);
+ }
}
- $url=~s/^http\&colon\;\/\//\/adm\/wrapper\/ext\//;
- if (($residx) && ($folder!~/supplemental/)) {
- $url.=(($url=~/\?/)?'&':'?').'symb='.
- &Apache::lonnet::escape(&Apache::lonnet::symbclean(
+
+ 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)));
+ &Apache::lonnet::declutter($url));
+ (undef,undef,$url)=&Apache::lonnet::decode_symb($symb);
+ $url=&Apache::lonnet::clutter($url);
+ if ($url=~/^\/*uploaded\//) {
+ $url=~/\.(\w+)$/;
+ my $embstyle=&Apache::loncommon::fileembstyle($1);
+ if (($embstyle eq 'img') || ($embstyle eq 'emb')) {
+ $url='/adm/wrapper'.$url;
+ } elsif ($embstyle eq 'ssi') {
+ #do nothing with these
+ } 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);
+ }
+ }
+ my ($parameterset,$rand_order_text) = (' ', ' ');
+ if ($isfolder || $extension eq 'sequence') {
+ my $foldername=&escape($foldertitle);
+ my $folderpath=$env{'form.folderpath'};
+ if ($folderpath) { $folderpath.='&' };
+# 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;
+ $parameterset=''.&mt('Randomly Pick: ').
+ ' '.
+''.&mt('Save').' ';
+ my $ro_set=
+ ((&LONCAPA::map::getparameter($orderidx,'parameter_randomorder'))[0]=~/^yes$/i?' checked="checked"':'');
+ $rand_order_text ='
+ '.&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 ($isfolder) { $url.='&foldername='.
- &Apache::lonnet::escape($foldertitle); }
- $line.=' '.
- "$title ";
+ if (($external) && ($allowed)) {
+ my $form = ($folder =~ /^default/)? 'newext' : 'supnewext';
+ $external = ' '.&mt('Edit').' ';
+ } else {
+ undef($external);
+ }
+ $line.='
+
+ '.($url?'':'').' '.($url?' ':'').'
+
+
+ '.($url?"":'').$title.($url?' ':' '.&mt('(re-initialize course to access)').' ').$external."
+ ";
+ if (($allowed) && ($folder!~/^supplemental/)) {
+ my %lt=&Apache::lonlocal::texthash(
+ 'hd' => 'Hidden',
+ 'ec' => 'URL hidden');
+ my $enctext=
+ ((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i?' checked="checked"':'');
+ my $hidtext=
+ ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i?' checked="checked"':'');
+ $line.=(<
+ $form_start
+ $lt{'hd'}
+ $form_end
+
+
+ $form_start
+ $lt{'ec'}
+ $form_end
+
+ $form_start $rand_order_text $form_end
+ $form_start $parameterset $form_end
+ENDPARMS
+ }
+ $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(' ');
+ $r->print("\n ");
+ if ($level==0) {
+ $r->print(" ");
+ }
for (my $i=0;$i<=$level*5;$i++) {
$r->print(' ');
}
@@ -489,8 +2154,8 @@ sub checkonthis {
if ($url=~/^\/res\//) {
my $result=&Apache::lonnet::repcopy(
&Apache::lonnet::filelocation('',$url));
- if ($result==OK) {
- $r->print('ok ');
+ if ($result eq 'ok') {
+ $r->print(''.&mt('ok').' ');
$r->rflush();
&Apache::lonnet::countacc($url);
$url=~/\.(\w+)$/;
@@ -500,195 +2165,453 @@ 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)));
- $ENV{'request.filename'}=$oldpath;
- if (($Apache::lonxml::errorcount) ||
- ($Apache::lonxml::warningcount)) {
- if ($Apache::lonxml::errorcount) {
- $r->print(''.
- $Apache::lonxml::errorcount.' 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('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) {
- $r->print(''.&mt('not found').' ');
+ } elsif ($result eq 'unavailable') {
+ $r->print(''.&mt('connection down').' ');
+ } elsif ($result eq 'not_found') {
+ unless ($url=~/\$/) {
+ $r->print(''.&mt('not found').' ');
+ } else {
+ $r->print(''.&mt('unable to verify variable URL').' ');
+ }
} else {
- $r->print(''.&mt('access denied').' ');
+ $r->print(''.&mt('access denied').' ');
}
- }
- }
+ }
+ }
+}
+
+
+
+=pod
+
+=item list_symbs()
+
+List Symbs
+
+=cut
+
+sub list_symbs {
+ my ($r) = @_;
+
+ my $type = &Apache::loncommon::course_type();
+ $r->print(&Apache::loncommon::start_page('Symb List'));
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs('Symb List'));
+ 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($type).':'.$env{'request.course.id'});
+ } else {
+ $r->print("\n");
+ foreach my $res ($navmap->retrieveResources()) {
+ $r->print($res->compTitle()."\t".$res->symb()."\n");
+ }
+ $r->print("\n \n");
+ }
+ $r->print(''.&mt('Return to DOCS').' ');
}
-#
-# -------------------------------------------------------------- Verify Content
-#
sub verifycontent {
- my $r=shift;
+ my ($r) = @_;
+ my $type = &Apache::loncommon::course_type();
my $loaderror=&Apache::lonnet::overloaderror($r);
if ($loaderror) { return $loaderror; }
-
- $r->print('Verify Content '.
- &Apache::loncommon::bodytag('Verify Course Documents'));
+ $r->print(&Apache::loncommon::start_page('Verify '.$type.' Documents'));
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$type.' Documents'));
$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 '.$type.': ').
+ &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').'. ');
+ $r->print(''.&mt('Done').'. '.''.
+ &mt('Return to DOCS').' ');
}
-# -------------------------------------------------------------- Check Versions
+
+sub devalidateversioncache {
+ my $src=shift;
+ &Apache::lonnet::devalidate_cache_new('courseresversion',$env{'request.course.id'}.'_'.
+ &Apache::lonnet::clutter($src));
+}
sub checkversions {
- my $r=shift;
- $r->print('Check Versions '.
- &Apache::loncommon::bodytag('Check Course Document Versions'));
- $hashtied=0;
- &tiehash();
- my %changes=&Apache::lonnet::dump
- ('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;
- }
- my $seltext=&mt('during the last').' '.$ENV{'form.timerange'}.' '
- .&mt('seconds');
- my $startsel='';
- my $monthsel='';
- my $weeksel='';
- my $daysel='';
- if ($ENV{'form.timerange'}==-1) {
- $seltext='since start of course';
- $startsel='selected';
- $ENV{'form.timerange'}=time;
- }
- my $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) {
- $seltext=&mt('during the last week').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
- $weeksel='selected';
- } elsif ($ENV{'form.timerange'}==86400) {
- $seltext=&mt('since yesterday').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
- $daysel='selected';
- }
- my %lt=&Apache::lonlocal::texthash
- ('st' => 'Since Start of Course',
- 'lm' => 'Last Month',
- 'lw' => 'Last Week',
- 'sy' => 'Since Yesterday',
- 'di' => 'Display',
- 'cc' => 'Content changed',
+ my ($r) = @_;
+ my $type = &Apache::loncommon::course_type();
+ $r->print(&Apache::loncommon::start_page("Check $type Document Versions"));
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs("Check $type Document Versions"));
+ my $header='';
+ my $startsel='';
+ my $monthsel='';
+ my $weeksel='';
+ my $daysel='';
+ my $allsel='';
+ my %changes=();
+ 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'});
+
+ $hashtied=0;
+ &tiehash();
+ my %newsetversions=();
+ if ($env{'form.setmostrecent'}) {
+ $haschanged=1;
+ foreach my $key (keys(%hash)) {
+ if ($key=~/^ids\_(\/res\/.+)$/) {
+ $newsetversions{$1}='mostrecent';
+ &devalidateversioncache($1);
+ }
+ }
+ } elsif ($env{'form.setcurrent'}) {
+ $haschanged=1;
+ 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'}) {
+ $haschanged=1;
+ foreach my $key (keys(%env)) {
+ if ($key=~/^form\.set_version_(.+)$/) {
+ my $src=$1;
+ 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 Saved').' ');
+ } else {
+ $r->print(''.&mt('An Error Occured while Attempting to Save your Version Settings').' ');
+ }
+ &mark_hash_old();
+ }
+ &changewarning($r,'');
+ if ($env{'form.timerange'} eq 'all') {
+# show all documents
+ $header=&mt('All Documents in '.$type);
+ $allsel=1;
+ foreach my $key (keys(%hash)) {
+ if ($key=~/^ids\_(\/res\/.+)$/) {
+ my $src=$1;
+ $changes{$src}=1;
+ }
+ }
+ } 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];
+ unless ($firstkey=~/^error\:/) {
+ unless ($env{'form.timerange'}) {
+ $env{'form.timerange'}=604800;
+ }
+ my $seltext=&mt('during the last').' '.$env{'form.timerange'}.' '
+ .&mt('seconds');
+ if ($env{'form.timerange'}==-1) {
+ $seltext='since start of course';
+ $startsel='selected';
+ $env{'form.timerange'}=time;
+ }
+ $starttime=time-$env{'form.timerange'};
+ if ($env{'form.timerange'}==2592000) {
+ $seltext=&mt('during the last month').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
+ $monthsel='selected';
+ } elsif ($env{'form.timerange'}==604800) {
+ $seltext=&mt('during the last week').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
+ $weeksel='selected';
+ } elsif ($env{'form.timerange'}==86400) {
+ $seltext=&mt('since yesterday').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
+ $daysel='selected';
+ }
+ $header=&mt('Content changed').' '.$seltext;
+ } else {
+ $header=&mt('No content modifications yet.');
+ }
+ }
+ %setversions=&Apache::lonnet::dump('resourceversions',
+ $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 '.$type,
+ 'lm' => 'Version changes since last Month',
+ 'lw' => 'Version changes since last Week',
+ 'sy' => 'Version changes since Yesterday',
+ 'al' => 'All Resources (possibly large output)',
+ 'sd' => 'Display',
'fi' => 'File',
'md' => 'Modification Date',
- 've' => 'Version',
+ 'mr' => 'Most recently published Version',
+ 've' => 'Version used in '.$type,
+ 'vu' => 'Set Version to be used in '.$type,
+'sv' => 'Set Versions to be used in '.$type.' 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');
- $r->print(<print(<
+
+
+
+$lt{'al'}
$lt{'st'}
$lt{'lm'}
$lt{'lw'}
$lt{'sy'}
-
-
-$lt{'cc'} $seltext
-
-
-$lt{'fi'} $lt{'md'}
-$lt{'ve'} $lt{'di'}
+
+$header
+
+
ENDHEADERS
- foreach (keys %changes) {
- if ($changes{$_}>$starttime) {
- my ($root,$extension)=($_=~/^(.*)\.(\w+)$/);
- my $currentversion=&Apache::lonnet::getversion($_);
- my $linkurl=&Apache::lonnet::clutter($_);
- $r->print(
- ''.$linkurl.
- ' '.
- &Apache::lonlocal::locallocaltime($changes{$_}).' '.$currentversion.' '.
- '');
- my $lastold=1;
- for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) {
- my $url=$root.'.'.$prevvers.'.'.$extension;
- if (&Apache::lonnet::metadata($url,'lastrevisiondate')<
- $starttime) {
- $lastold=$prevvers;
- }
- }
+ foreach my $key (sort(keys(%changes))) {
+ if ($changes{$key}>$starttime) {
+ my ($root,$extension)=($key=~/^(.*)\.(\w+)$/);
+ my $currentversion=&Apache::lonnet::getversion($key);
+ if ($currentversion<0) {
+ $currentversion=&mt('Could not be determined.');
+ }
+ my $linkurl=&Apache::lonnet::clutter($key);
+ $r->print(
+ ' '.
+ &Apache::lonnet::gettitle($linkurl).
+ ' '.
+ ' '.
+ ''.
+ ''.$linkurl.
+ ' '.
+ ' '.
+ ''.
+ &Apache::lonlocal::locallocaltime(
+ &Apache::lonnet::metadata($root.'.'.$extension,
+ 'lastrevisiondate')
+ ).
+ ' '.
+ 'Most Recent: '.
+ ''.$currentversion.' '.
+ ' '.
+ 'In '.$type.': '.
+ '');
+# Used in course
+ my $usedversion=$hash{'version_'.$linkurl};
+ if (($usedversion) && ($usedversion ne 'mostrecent')) {
+ $r->print($usedversion);
+ } else {
+ $r->print($currentversion);
+ }
+ $r->print(' '.
+ 'Use: ');
+# Set version
+ $r->print(&Apache::loncommon::select_form($setversions{$linkurl},
+ 'set_version_'.$linkurl,
+ ('select_form_order' =>
+ ['',1..$currentversion,'mostrecent'],
+ '' => '',
+ 'mostrecent' => 'most recent',
+ map {$_,$_} (1..$currentversion))));
+ $r->print(' ');
+ my $lastold=1;
+ for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) {
+ my $url=$root.'.'.$prevvers.'.'.$extension;
+ if (&Apache::lonnet::metadata($url,'lastrevisiondate')<
+ $starttime) {
+ $lastold=$prevvers;
+ }
+ }
+ #
+ # Code to figure out how many version entries should go in
+ # each of the four columns
+ my $entries_per_col = 0;
+ my $num_entries = ($currentversion-$lastold);
+ if ($num_entries % 4 == 0) {
+ $entries_per_col = $num_entries/4;
+ } else {
+ $entries_per_col = $num_entries/4 + 1;
+ }
+ my $entries_count = 0;
+ $r->print('');
+ my $cols_output = 1;
for (my $prevvers=$lastold;$prevvers<$currentversion;$prevvers++) {
- my $url=$root.'.'.$prevvers.'.'.$extension;
- $r->print(''.&mt('Version').' '.$prevvers.' ('.
- &Apache::lonlocal::locallocaltime(&Apache::lonnet::metadata($url,'lastrevisiondate')).
- ') ');
- if (&Apache::loncommon::fileembstyle($extension) eq 'ssi') {
+ my $url=$root.'.'.$prevvers.'.'.$extension;
+ $r->print(''.&mt('Version').' '.$prevvers.' ('.
+ &Apache::lonlocal::locallocaltime(
+ &Apache::lonnet::metadata($url,
+ 'lastrevisiondate')
+ ).
+ ')');
+ if (&Apache::loncommon::fileembstyle($extension) eq 'ssi') {
$r->print(' Diffs ');
- }
- $r->print(' ');
- }
- $r->print(' ');
- }
- }
- $r->print('
');
- $r->print(''.&mt('Done').'. ');
- } else {
- $r->print(''.&mt('No content modifications yet.').'
');
- }
- &untiehash();
+ &Apache::lonnet::clutter($root.'.'.$extension).
+ '&versionone='.$prevvers.
+ '">'.&mt('Diffs').'');
+ }
+ $r->print(' ');
+ if (++$entries_count % $entries_per_col == 0) {
+ $r->print('');
+ if ($cols_output != 4) {
+ $r->print('');
+ $cols_output++;
+ }
+ }
+ }
+ while($cols_output++ < 4) {
+ $r->print(' ')
+ }
+ $r->print(' '."\n");
+ }
+ }
+ $r->print('
');
+ $r->print(''.&mt('Done').'. ');
+
+ &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,$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",
+ text=>"Edit ".&Apache::loncommon::course_type(),
+ 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'});
}
-# ================================================================ Main Handler
+
+
+
sub handler {
my $r = shift;
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
return OK if $r->header_only;
+ my $type = &Apache::loncommon::course_type();
+
- &Apache::lonlocal::clearreroutetrans();
# --------------------------------------------- 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') {
- $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');
@@ -698,482 +2621,1274 @@ 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'}) {
+
+# does this user have privileges to modify docs
+ my $allowed=&Apache::lonnet::allowed('mdc',$env{'request.course.id'});
+ if ($allowed && $env{'form.verify'}) {
+ &init_breadcrumbs('verify','Verify Content');
&verifycontent($r);
- } elsif ($ENV{'form.versions'}) {
+ } elsif ($allowed && $env{'form.listsymbs'}) {
+ &init_breadcrumbs('listsymbs','List Symbs');
+ &list_symbs($r);
+ } elsif ($allowed && $env{'form.docslog'}) {
+ &init_breadcrumbs('docslog','Show Log');
+ &docs_change_log($r);
+ } 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().' DOCS to Construction Space');
&dumpcourse($r);
+ } elsif ($allowed && $env{'form.exportcourse'}) {
+ &init_breadcrumbs('exportcourse','IMS Export');
+ &exportcourse($r);
} else {
# is this a standard course?
- my $standard=($ENV{'request.course.uri'}=~/^\/uploaded\//);
- my $forcestandard;
+ my $standard=($env{'request.course.uri'}=~/^\/uploaded\//);
+ my $forcestandard = 0;
my $forcesupplement;
my $script='';
- my $allowed;
- my $events='';
my $showdoc=0;
+ my $containertag;
+ my $uploadtag;
+
+
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
- ['folder','foldername']);
+ ['folderpath','pagepath',
+ 'pagesymb']);
+# No folderpath, no pagepath, see if we have something stored
+ if ((!$env{'form.folderpath'}) && (!$env{'form.pagepath'})) {
+ &Apache::loncommon::restore_course_settings('docs_folderpath',
+ {'folderpath' => 'scalar'});
+ }
+ if (!$env{'form.folderpath'}) {
+ &Apache::loncommon::restore_course_settings('docs_folderpath',
+ {'pagepath' => 'scalar'});
+ }
+ if ($env{'form.pagepath'}) {
+ $env{'form.folderpath'}='';
+ }
+ if ($env{'form.folderpath'} =~ /^supplemental_\d+/) {
+ $env{'form.folderpath'} = 'supplemental&'.
+ &escape(&mt('Supplemental '.$type.' Documents')).'&'.
+ $env{'form.folderpath'};
+ }
+ &Apache::loncommon::store_course_settings('docs_folderpath',
+ {'pagepath' => 'scalar',
+ 'folderpath' => 'scalar'});
+ if ($env{'form.folderpath'}) {
+ my (@folderpath)=split('&',$env{'form.folderpath'});
+ $env{'form.foldername'}=&unescape(pop(@folderpath));
+ $env{'form.folder'}=pop(@folderpath);
+ }
+ if ($env{'form.pagepath'}) {
+ my (@pagepath)=split('&',$env{'form.pagepath'});
+ $env{'form.pagename'}=&unescape(pop(@pagepath));
+ $env{'form.folder'}=pop(@pagepath);
+ $containertag = ' '.
+ ' ';
+ $uploadtag = ' '.
+ ' ';
+ }
if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) {
- $showdoc=$1;
+ $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) {
+ if ($showdoc) { # got called in sequence from course
+ $allowed=0;
+ } else {
+ if (($env{'form.folder'}=~/^(?:group|default)_/) ||
+ ($env{'form.folder'} =~ m:^\d+/(pages|sequences)/:)) {
+ $forcestandard = 1;
+ }
+ $forcesupplement=($env{'form.folder'}=~/^supplemental_/);
+
+ if ($allowed) {
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['cmd']);
- $script=&Apache::lonratedt::editscript('simple');
+ $script=&Apache::lonratedt::editscript('simple');
}
- } else { # got called in sequence from course
- $allowed=0;
- $script=''.&Apache::lonmenu::registerurl(1,undef).''."\n";
+
+ # Breadcrumbs
+ &Apache::lonhtmlcommon::clear_breadcrumbs();
+ if ($allowed) {
+ &Apache::lonhtmlcommon::add_breadcrumb({
+ href=>"/adm/coursedocs",text=>"$type Editor"});
- my $now=time;
+ $r->print(&Apache::loncommon::start_page("$type Editor", $script,
+ {'force_register' => $showdoc,})
+ .&Apache::loncommon::help_open_menu('','',273,'RAT')
+ .&Apache::lonhtmlcommon::breadcrumbs(
+ 'Editing the Table of Contents for your '.$type,
+ 'Docs_Adding_Course_Doc')
+ );
+ } elsif ($showdoc) {
+ $r->print(&Apache::loncommon::start_page("$type documents",undef,
+ {'force_register' => $showdoc,}));
+ } else {
+ my $folder=$env{'form.folder'};
+ if ($folder eq '' || $folder eq 'supplemental') {
+ $env{'form.folderpath'} = 'supplemental&'.
+ &escape(&mt('Supplemental '.$type.' Documents'));
+ }
+ my ($breadcrumbtrail) = &breadcrumbs($allowed,$type);
+ $r->print(&Apache::loncommon::start_page("Supplemental documents").
+ $breadcrumbtrail);
+ }
-# print screen
- $r->print(<
-
-The LearningOnline Network with CAPA
-
-ENDDOCUMENT
- if ($allowed) {
- $r->print(<
+ my %allfiles = ();
+ my %codebase = ();
+ my ($upload_result,$upload_output);
+ if ($allowed) {
+ if (($env{'form.uploaddoc.filename'}) &&
+ ($env{'form.cmd'}=~/^upload_(\w+)/)) {
+# Process file upload - phase one - upload and parse primary file.
+ undef($hadchanges);
+ $upload_result = &process_file_upload(\$upload_output,$coursenum,
+ $coursedom,\%allfiles,
+ \%codebase,$1);
+ if ($hadchanges) {
+ &mark_hash_old();
+ }
+ if ($upload_result eq 'phasetwo') {
+ $r->print($upload_output);
+ }
+ } elsif ($env{'form.phasetwo'}) {
+ my %newname = ();
+ my %origname = ();
+ my %attribs = ();
+ my $updateflag = 0;
+ my $residx = $env{'form.newidx'};
+ my $primary_url = &unescape($env{'form.primaryurl'});
+# Process file upload - phase two - gather secondary files.
+ for (my $i=0; $i<$env{'form.phasetwo'}; $i++) {
+ if ($env{'form.embedded_item_'.$i.'.filename'}) {
+ my $javacodebase;
+ $newname{$i} = &process_secondary_uploads(\$upload_output,$coursedom,$coursenum,'embedded_item_',$i,$residx);
+ $origname{$i} = &unescape($env{'form.embedded_orig_'.$i});
+ if (exists($env{'form.embedded_codebase_'.$i})) {
+ $javacodebase = &unescape($env{'form.embedded_codebase_'.$i});
+ $origname{$i} =~ s#^\Q$javacodebase\E/##;
+ }
+ my @attributes = ();
+ if ($env{'form.embedded_attrib_'.$i} =~ /:/) {
+ @attributes = split(/:/,$env{'form.embedded_attrib_'.$i});
+ } else {
+ @attributes = ($env{'form.embedded_attrib_'.$i});
+ }
+ foreach my $attr (@attributes) {
+ push(@{$attribs{$i}},&unescape($attr));
+ }
+ if ($javacodebase) {
+ $codebase{$i} = $javacodebase;
+ $codebase{$i} =~ s#/$##;
+ $updateflag = 1;
+ }
+ }
+ unless ($newname{$i} eq $origname{$i}) {
+ $updateflag = 1;
+ }
+ }
+# Process file upload - phase three - modify primary file
+ if ($updateflag) {
+ my ($content,$rtncode);
+ my $updateflag = 0;
+ my $getstatus = &Apache::lonnet::getuploaded('GET',$primary_url,$coursedom,$coursenum,\$content,\$rtncode);
+ if ($getstatus eq 'ok') {
+ foreach my $item (keys(%newname)) {
+ if ($newname{$item} ne $origname{$item}) {
+ my $attrib_regexp = '';
+ if (@{$attribs{$item}} > 1) {
+ $attrib_regexp = join('|',@{$attribs{$item}});
+ } else {
+ $attrib_regexp = $attribs{$item}[0];
+ }
+ if ($content =~ m#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#) {
+ }
+ $content =~ s#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#$1$newname{$item}$2#gi;
+ }
+ if (exists($codebase{$item})) {
+ $content =~ s/(codebase\s*=\s*["']?)\Q$codebase{$item}\E(["']?)/$1.$2/i; #' stupid emacs
+ }
+ }
+# Save edited file.
+ my $saveresult;
+ my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
+ my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $url = &Apache::lonnet::store_edited_file($primary_url,$content,$docudom,$docuname,\$saveresult);
+ } else {
+ &Apache::lonnet::logthis('retrieval of uploaded file - '.$primary_url.' - for editing, failed: '.$getstatus);
+ }
+ }
+ }
+ }
+
+ unless ($showdoc || $upload_result eq 'phasetwo') {
+# -----------------------------------------------------------------------------
+ my %lt=&Apache::lonlocal::texthash(
+ 'uplm' => 'Upload a new main '.lc($type).' document',
+ 'upls' => 'Upload a new supplemental '.lc($type).' document',
+ 'impp' => 'Import a document',
+ 'copm' => 'All documents out of a published map into this folder',
+ 'upld' => 'Upload Document',
+ 'srch' => 'Search',
+ 'impo' => 'Import',
+ 'book' => 'Import Bookmarks',
+ 'selm' => 'Select Map',
+ 'load' => 'Load Map',
+ 'reco' => 'Recover Deleted Resources',
+ 'newf' => 'New Folder',
+ 'newp' => 'New Composite Page',
+ 'extr' => 'External Resource',
+ 'syll' => 'Syllabus',
+ 'navc' => 'Navigate Contents',
+ 'sipa' => 'Simple Course Page',
+ 'sipr' => 'Simple Problem',
+ 'drbx' => 'Drop Box',
+ 'scuf' => 'Score Upload Form',
+ '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
+ #$list .= Apache::lonhtmlcommon::htmltag('li', $picture.' '.$button->{$picture}, {class => 'LC_menubuttons_inline_text'});
+ #$fileuploadform .= create_form_ul(create_list_elements(@fileuploada));
+ $fileuploadform .= create_form_ul(Apache::lonhtmlcommon::htmltag('li',$fileuploada,{class => 'LC_menubuttons_inline_text'}));
+ $fileuploadform .= (<
+FUFORM
+
+ my $simpleeditdefaultform=(<
+
+SEDFFORM
+ my @simpleeditdefaultforma = (
+ { ' ' => "$uploadtag$lt{'srch'} " },
+ { ' ' => "$lt{'impo'} $help{'Importing_LON-CAPA_Resource'}" },
+ { ' ' => "$lt{'book'} " },
+ );
+ $simpleeditdefaultform .= create_form_ul(create_list_elements(@simpleeditdefaultforma));
+ $simpleeditdefaultform .=(<
+
+ $lt{'copm'}
+
+
+ $help{'Load_Map'}
+
+
+SEDFFORM
+
+ my $extresourcesform=(<
+ $uploadtag
+
+ $lt{'extr'} $help{'Adding_External_Resource'}
+
+ERFORM
+
+ if ($allowed) {
+ &update_paste_buffer($coursenum,$coursedom);
+ my %lt=&Apache::lonlocal::texthash(
+ 'vc' => 'Verify Content',
+ 'cv' => 'Check/Set Resource Versions',
+ 'ls' => 'List Symbs',
+ 'sl' => 'Show Log'
+ );
+
+ my $folderpath=$env{'form.folderpath'};
+ if (!$folderpath) {
+ if ($env{'form.folder'} eq '' ||
+ $env{'form.folder'} eq 'supplemental') {
+ $folderpath='default&'.
+ &escape(&mt('Main '.$type.' Documents'));
+ }
+ }
+ unless ($env{'form.pagepath'}) {
+ $containertag = ' ';
+ $uploadtag = ' ';
+ }
+ $r->print(<
+
+
+
+
+ $containertag
+
+
+HIDDENFORM
+ }
+# --------------------------------------------------------- Main tab structure
+
+ my $activeClass = 1;
+ my $active = '';
+
+ if ($allowed) {
+ $r->print('');
+ if (($standard) && ($allowed) && (!$forcesupplement) && (($env{'form.folderpath'}=~/^default/) || $env{'form.folderpath'}eq"" || ($env{'form.pagepath'}))) {
+ if($activeClass == 1){
+ $active = 'class="active"';
+ $activeClass = 0;
+ }
+ }
+ $r->print(''.&mt('Main Course Documents').' ');
+ $active = '';
+ if (!$forcestandard || ($env{'form.folderpath'}=~/^supplemental/)) {
+ if($activeClass == 1){
+ $active = 'class="active"';
+ }
+ }
+ $r->print(''.&mt('Supplemental Course Documents').' ');
+ $r->print(' ');
+ } else {
+ $r->print(' ');
+ }
+ $r->print(''
+ .'
');
+# --------------------------------------------------------- Standard documents
+ my $savefolderpath;
+ $active = 'style="display: none;"';
+ if($activeClass == 0){
+ $active = 'style="display: block;"';
+ }
+ if ($allowed) {
+ $r->print('
');
+ my $folder=$env{'form.folder'};
+ if ($folder eq '' || $folder=~/^supplemental/) {
+ $folder='default';
+ $savefolderpath = $env{'form.folderpath'};
+ $env{'form.folderpath'}='default&'.&escape(&mt('Main '.$type.' Documents'));
+ $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 $recoverform=(<
+ $lt{'reco'}
+
+RFORM
+
+ my $imspform=(<
+
+ $lt{'imsf'}
+
+IMSPFORM
+
+ my $newnavform=(<
+
+ $uploadtag
+
+ $lt{'navc'}
+ $help{'Navigate_Content'}
+
+NNFORM
+ my $newsmppageform=(<
+
+ $uploadtag
+
+ $lt{'sipa'}
+ $help{'Simple Page'}
+
+NSPFORM
+
+ my $newsmpproblemform=(<
+
+ $uploadtag
+
+ $lt{'sipr'}
+ $help{'Simple Problem'}
+
+
+NSPROBFORM
+
+ my $newdropboxform=(<
+
+ $uploadtag
+
+ $lt{'drbx'}
+
+NDBFORM
+
+ my $newexuploadform=(<
+
+ $uploadtag
+
+ $lt{'scuf'}
+ $help{'Score_Upload_Form'}
+
+NEXUFORM
+
+ my $newbulform=(<
+
+ $uploadtag
+
+ $lt{'bull'}
+ $help{'Bulletin Board'}
+
+NBFORM
+
+ my $newaboutmeform=(<
+
+ $uploadtag
+
+ $lt{'mypi'}
+ $help{'My Personal Information Page'}
+
+NAMFORM
+
+ my $newaboutsomeoneform=(<
+
+ $uploadtag
+
+ $lt{'abou'}
+
+NASOFORM
+
+
+ my $newrosterform=(<
+
+ $uploadtag
+
+ $lt{'rost'}
+ $help{'Course Roster'}
+
+NROSTFORM
+
+my $specialdocumentsform;
+my @specialdocumentsforma;
+my $newfolderform;
+my $newfolderb;
+
+ unless ($env{'form.pagepath'}) {
+ my $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
+
+ my $newpageform=(<
+
+
+
+ $lt{'newp'}
+ $help{'Adding_Pages'}
+
+NPFORM
+
+
+ $newfolderform=(<
+
+
+
+ $lt{'newf'} $help{'Adding_Folders'}
+
+NFFORM
+
+ my $newsylform=(<
+
+ $uploadtag
+
+ $lt{'syll'}
+ $help{'Syllabus'}
+
+
+NSYLFORM
+
+ my $newgroupfileform=(<
+
+ $uploadtag
+
+ $lt{'grpo'}
+ $help{'Group Portfolio'}
+
+NGFFORM
+ @specialdocumentsforma=(
+ {' '=>$newpageform},
+ {' '=>$newsylform},
+ {' '=>$newgroupfileform},
+ );
+
+ }
+ push @specialdocumentsforma, ({' '=>$newnavform},
+ {' '=>$newsmppageform},
+ {' '=>$newsmpproblemform},
+ {' '=>$newdropboxform},
+ {' '=>$newexuploadform},
+ {' '=>$newbulform},
+ {' '=>$newaboutmeform},
+ {' '=>$newaboutsomeoneform},
+ {' '=>$newrosterform},);
+
+ $specialdocumentsform = create_form_ul(create_list_elements(@specialdocumentsforma));
+
+if($env{'form.pagepath'}) {
+
+ @specialdocumentsforma=(
+ {' '=>$newsmpproblemform},
+ {' '=>$newexuploadform}
+ );
+ $specialdocumentsform= create_form_ul(create_list_elements(@specialdocumentsforma));
+}
+
+my @tools = (
+ {' '=>$extresourcesform},
+ {' '=>$imspform},
+ {' '=>$recoverform},
+ );
+
+my %orderhash = (
+ '00' => ['Newfolder',$newfolderform],
+ 'aa' => ['Upload Document',$fileuploadform],
+ 'bb' => ['Published Resources',$simpleeditdefaultform],
+ 'cc' => ['Special Documents',$specialdocumentsform],
+ 'dd' => ['Tools', create_form_ul(create_list_elements(@tools)).&generate_admin_options($containertag,$uploadtag,\%help,\%env)],
+ );
+my $tid='1';
+my $varcd = 'Main Course Documents';
+ $hadchanges=0;
+ my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$type);
+ if ($error) {
+ $r->print(''.$error.'
');
+ }
+ if ($hadchanges) {
+ &mark_hash_old();
+ }
+
+ &changewarning($r,'');
+$r->print(&generate_edit_table($tid,$varcd,\%orderhash));
+
+$r->print(' ');
+ }
+ if ($env{'form.pagepath'}) {
+ }
+# ----------------------------------------------------- Supplemental documents
+ $active = 'style="display: none;"';
+ if($activeClass == 1){
+ $active = 'style="display: block;"';
+ }
+ $r->print('
');
+ my $folder=$env{'form.folder'};
+ unless ($folder=~/^supplemental/) {
+ $folder='supplemental';
+ }
+ if ($folder =~ /^supplemental$/ &&
+ (($env{'form.folderpath'} =~ /^default\&/) || ($env{'form.folderpath'} eq ''))) {
+ $env{'form.folderpath'} = 'supplemental&'.
+ &escape(&mt('Supplemental '.$type.' Documents'));
+ } 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=(<
+
+
+
+ $lt{'newf'}
+ $help{'Adding_Folders'}
+
+SNFFORM
+
+
+ my $supnewextform=(<
+
+
+
+ $lt{'extr'} $help{'Adding_External_Resource'}
+
+SNEFORM
+
+ my $supnewsylform=(<
+
+
+
+ $lt{'syll'}
+ $help{'Syllabus'}
+
+SNSFORM
+
+ my $supnewaboutmeform=(<
+
+
+
+ $lt{'mypi'}
+ $help{'My Personal Information Page'}
+
+SNAMFORM
+
+
+my @specialdocs = (
+ {' '=>$supnewextform},
+ {' '=>$supnewsylform},
+ {' '=>$supnewaboutmeform},
+ );
+my %suporderhash = (
+ '00' => ['Supnewfolder', $supnewfolderform],
+ 'ee' => ['Upload Document',$supupdocform],
+ 'ff' => ['Special Documents',create_form_ul(create_list_elements(@specialdocs))]
+ );
+
+ my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$type);
+ if ($error) {
+ $r->print(''.$error.'
');
+ }
+ my $tid='2';
+ my $varscd = 'Supplemental Course Documents';
+ $r->print(&generate_edit_table($tid,$varscd,\%suporderhash));
+ } else {
+ my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$type);
+ if ($error) {
+ $r->print(''.$error.'
');
+ }
+ }
+
+
+$r->print(' ');
+$r->print('
');
+
+
+ if ($allowed) {
+ $r->print('
+');
+ }
+ } else {
+ unless ($upload_result eq 'phasetwo') {
+# -------------------------------------------------------- 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 generate_admin_options {
+ my ($containertag,$uploadtag,$help_ref,$env_ref) = @_;
+ my %lt=&Apache::lonlocal::texthash(
+ 'vc' => 'Verify Content',
+ 'cv' => 'Check/Set Resource Versions',
+ 'ls' => 'List Symbs',
+ 'sl' => 'Show Log'
+ );
+ my %help = %{$help_ref};
+ my %env = %{$env_ref};
+ my $dumpbut=&dumpbutton();
+ my $exportbut=&exportbutton();
+ my @list = (
+ {' '=>"$lt{'vc'} $help{'Verify_Content'}"},
+ {' '=>"$lt{'cv'} $help{'Check_Resource_Versions'}"},
+ );
+ if($dumpbut ne ''){
+ push @list, {' '=>$dumpbut};
+ }
+ push @list, ({' '=>$exportbut},
+ {' '=>"$lt{'ls'} "},
+ {' '=>"$lt{'sl'} "},
+ );
+ return '';
+
+}
+
+
+sub generate_edit_table {
+ my ($tid,$varcd,$orderhash_ref) = @_;
+ my %orderhash = %{$orderhash_ref};
+ my $form;
+ my $activetab;
+ my $active;
+ if($env{'form.active'} ne ''){
+ $activetab = $env{'form.active'};
+ }
+ $form = '';
+ $form .= '
';
+ foreach my $name (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]).' ';
+ } else {
+ $form .= ''.${$orderhash{$name}}[1].' ';
+
+ }
+ }
+ $form .= ' ';
+ $form .= '
';
+ foreach my $field (keys(%orderhash)){
+ if($field ne '00'){
+ if($activetab eq '' || $activetab ne $field){
+ $active = 'style="display: none;"';
+ }elsif($activetab eq $field){
+ $active = 'style="display:block;"';
+ }
+ $form .= '
'.${$orderhash{$field}}[1]
+ .'
';
+ }
+ }
+ $form .= '
';
+
+ return $form;
+}
+
+sub editing_js {
+ my ($udom,$uname) = @_;
+ 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 Uploaded 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]'
+ );
+
+ return <
-ENDNEWSCRIPT
- }
-# -------------------------------------------------------------------- Body tag
- $r->print(''.
- &Apache::loncommon::bodytag('Course Documents','',$events,
- '','',$showdoc));
- 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'
- );
-# -----------------------------------------------------------------------------
- if ($allowed) {
- my $dumpbut=&dumpbutton();
- $r->print(<
-
-
-
-
-
-
-ENDCOURSEVERIFY
- $r->print(&Apache::loncommon::help_open_topic('Docs_Adding_Course_Doc',
- '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'};
- unless ($folder=~/^default/) { $folder='default'; }
- my $postexec='';
- if ($folder eq 'default') {
- $r->print('');
- } else {
- $postexec='self.close();';
- }
- $hadchanges=0;
- &editor($r,$coursenum,$coursedom,$folder,$allowed);
- if ($hadchanges) {
- $r->print(
-''.
-'');
- }
- my $folderseq='/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time.
- '.sequence';
- $r->print(<
-$lt{'uplm'}
-$lt{'impp'}
-$lt{'spec'}
-
-
-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'; }
- &editor($r,$coursenum,$coursedom,$folder,$allowed);
- if ($allowed) {
- my $folderseq=
- '/uploaded/'.$coursedom.'/'.$coursenum.'/supplemental_'.time.
- '.sequence';
+function removeres(folderpath,index,oldtitle,container,pagesymb,skip_confirm) {
+if (skip_confirm || confirm('$lt{"p_rmr1"}\\n\\n$lt{"p_rmr2a"} "'+oldtitle+'" $lt{"p_rmr2b"}')) {
+this.document.forms.renameform.markcopy.value=-1;
+this.document.forms.renameform.cmd.value='del_'+index;
+if (container == 'sequence') {
+ this.document.forms.renameform.folderpath.value=folderpath;
+}
+if (container == 'page') {
+ this.document.forms.renameform.pagepath.value=folderpath;
+ this.document.forms.renameform.pagesymb.value=pagesymb;
+}
+this.document.forms.renameform.submit();
+}
+}
- $r->print(<
-$lt{'upls'}
-$lt{'impp'}
-$lt{'spec'}
-
-
-
-
-
-
-
-
-
-
- $help{'Importing_LON-CAPA_Resource'}
-
-
-
- $help{'Load_Map'}
-
-
-
-
-
-
-
-
- $help{'Adding_Folders'}
-
-
-
-
-
-
-
- $help{'Adding_External_Resource'}
-
-
-
-
-
-
-
-
-$help{'Syllabus'}
-
-
-
-
-
-
-
-
-$help{'My Personal Info'}
-
-
-
-
-ENDSUPFORM
- }
- }
- if ($allowed) {
- $r->print(' ');
- }
- $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(&Apache::lonlocal::endreroutetrans().'');
- return OK;
-}
+function cutres(folderpath,index,oldtitle,container,pagesymb,folder,skip_confirm) {
+if (skip_confirm || confirm('$lt{"p_ctr1a"}\\n$lt{"p_ctr1b"}\\n\\n$lt{"p_ctr2a"} "'+oldtitle+'" $lt{"p_ctr2b"}')) {
+this.document.forms.renameform.cmd.value='cut_'+index;
+this.document.forms.renameform.markcopy.value=index;
+this.document.forms.renameform.copyfolder.value=folder+'.'+container;
+if (container == 'sequence') {
+ this.document.forms.renameform.folderpath.value=folderpath;
+}
+if (container == 'page') {
+ this.document.forms.renameform.pagepath.value=folderpath;
+ this.document.forms.renameform.pagesymb.value=pagesymb;
+}
+this.document.forms.renameform.submit();
+}
+}
+
+function markcopy(folderpath,index,oldtitle,container,pagesymb,folder) {
+this.document.forms.renameform.markcopy.value=index;
+this.document.forms.renameform.copyfolder.value=folder+'.'+container;
+if (container == 'sequence') {
+this.document.forms.renameform.folderpath.value=folderpath;
+}
+if (container == 'page') {
+this.document.forms.renameform.pagepath.value=folderpath;
+this.document.forms.renameform.pagesymb.value=pagesymb;
+}
+this.document.forms.renameform.submit();
+}
+
+function unselectInactive(nav) {
+currentNav = document.getElementById(nav);
+currentLis = currentNav.getElementsByTagName('LI');
+for (i = 0; i < currentLis.length; i++) {
+ 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('"');
+ 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';
+ return false;
+}
+
+function injectData(current, hiddenField, name, value) {
+ currentElement = document.getElementById(hiddenField);
+ currentElement.name = name;
+ currentElement.value = value;
+ current.submit();
+}
+ENDNEWSCRIPT
+}
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 dumpbutton()
+
+Generate "dump" button
+
+=item clean()
+
+=item dumpcourse()
+
+ Actually dump course
+
+
+=item exportbutton()
+
+ Generate "export" button
+
+=item exportcourse()
+
+=item create_ims_store()
+
+=item build_package()
+
+=item get_dependencies()
+
+=item process_content()
+
+=item replicate_content()
+
+=item extract_media()
+
+=item store_template()
+
+=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 update_parameter()
+
+=item handle_edit_cmd()
+
+=item editor()
+
+=item process_file_upload()
+
+=item process_secondary_uploads()
+
+=item is_supplemental_title()
+
+=item parse_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
+
+=back
+
+=cut