--- loncom/interface/londocs.pm 2005/08/01 17:24:18 1.200 +++ loncom/interface/londocs.pm 2010/12/11 14:28:12 1.447 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.200 2005/08/01 17:24:18 raeburn Exp $ +# $Id: londocs.pm,v 1.447 2010/12/11 14:28:12 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -26,6 +26,8 @@ # http://www.lon-capa.org/ # + + package Apache::londocs; use strict; @@ -33,15 +35,17 @@ 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; @@ -52,53 +56,47 @@ 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)= - &Apache::lonratedt::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'. - $map,1); + &LONCAPA::map::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'. + $map,1); if ($errtext) { return ($errtext,2); } - + $hadchanges=1; return ($errtext,0); } -# ----------------------------------------- Return hash with valid author names + sub authorhosts { my %outhash=(); my $home=0; my $other=0; - foreach (keys %env) { - if ($_=~/^user\.role\.(au|ca)\.(.+)$/) { + foreach my $key (keys(%env)) { + if ($key=~/^user\.role\.(au|ca)\.(.+)$/) { my $role=$1; my $realm=$2; - my ($start,$end)=split(/\./,$env{$_}); + my ($start,$end)=split(/\./,$env{$key}); if (($start) && ($start>time)) { next; } if (($end) && (time>$end)) { next; } - my $ca; my $cd; + my ($ca,$cd); if ($1 eq 'au') { $ca=$env{'user.name'}; $cd=$env{'user.domain'}; } else { - ($cd,$ca)=($realm=~/^\/(\w+)\/(\w+)$/); + ($cd,$ca)=($realm=~/^\/($match_domain)\/($match_username)$/); } my $allowed=0; my $myhome=&Apache::lonnet::homeserver($ca,$cd); @@ -115,36 +113,43 @@ sub authorhosts { } return ($home,$other,%outhash); } -# ------------------------------------------------------ Generate "dump" button + sub dumpbutton { my ($home,$other,%outhash)=&authorhosts(); + my $crstype = &Apache::loncommon::course_type(); if ($home+$other==0) { return ''; } - my $output=''; if ($home) { - return ''. - ''. - &Apache::loncommon::help_open_topic('Docs_Dump_Course_Docs'); + my $link = + "" + .&mt('Dump '.$crstype.' Documents 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 '.$crstype.' Documents to Construction Space: available on other servers'); } } sub clean { my ($title)=@_; $title=~s/[^\w\/\!\$\%\^\*\-\_\=\+\;\:\,\\\|\`\~]+/\_/gs; - return $title; + return $title; } -# -------------------------------------------------------- Actually dump course + + sub dumpcourse { - my $r=shift; - my $html=&Apache::lonxml::xmlbegin(); - $r->print($html.'Dump DOCS'. - &Apache::loncommon::bodytag('Dump Course DOCS to Construction Space'). - '
'); + my ($r) = @_; + my $crstype = &Apache::loncommon::course_type(); + $r->print(&Apache::loncommon::start_page('Dump '.$crstype.' Documents to Construction Space'). + ''); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Dump '.$crstype.' Documents to Construction Space')); my ($home,$other,%outhash)=&authorhosts(); unless ($home) { return ''; } my $origcrsid=$env{'request.course.id'}; @@ -157,45 +162,48 @@ sub dumpcourse { my $title=$env{'form.authorfolder'}; $title=&clean($title); my %replacehash=(); - foreach (keys %env) { - if ($_=~/^form\.namefor\_(.+)/) { - $replacehash{$1}=$env{$_}; + foreach my $key (keys(%env)) { + if ($key=~/^form\.namefor\_(.+)/) { + $replacehash{$1}=$env{$key}; } } my $crs='/uploaded/'.$env{'request.course.id'}.'/'; $crs=~s/\_/\//g; - foreach (keys %replacehash) { - my $newfilename=$title.'/'.$replacehash{$_}; + foreach my $item (keys(%replacehash)) { + my $newfilename=$title.'/'.$replacehash{$item}; + $newfilename=~s/\.(\w+)$//; + my $ext=$1; $newfilename=&clean($newfilename); + $newfilename.='.'.$ext; my @dirs=split(/\//,$newfilename); my $path='/home/'.$ca.'/public_html'; my $makepath=$path; my $fail=0; for (my $i=0;$i<$#dirs;$i++) { $makepath.='/'.$dirs[$i]; - unless (-e $makepath) { - unless(mkdir($makepath,0777)) { $fail=1; } + unless (-e $makepath) { + unless(mkdir($makepath,0777)) { $fail=1; } } } - $r->print('
'.$_.' => '.$newfilename.': '); + $r->print('
'.$item.' => '.$newfilename.': '); if (my $fh=Apache::File->new('>'.$path.'/'.$newfilename)) { - if ($_=~/\.(sequence|page|html|htm|xml|xhtml)$/) { - print $fh &Apache::loncreatecourse::rewritefile( - &Apache::loncreatecourse::readfile($env{'request.course.id'},$_), + if ($item=~/\.(sequence|page|html|htm|xml|xhtml)$/) { + print $fh &Apache::lonclonecourse::rewritefile( + &Apache::lonclonecourse::readfile($env{'request.course.id'},$item), (%replacehash,$crs => '') ); } else { print $fh - &Apache::loncreatecourse::readfile($env{'request.course.id'},$_); + &Apache::lonclonecourse::readfile($env{'request.course.id'},$item); } $fh->close(); } else { $fail=1; } if ($fail) { - $r->print('fail'); + $r->print(''.&mt('fail').''); } else { - $r->print('ok'); + $r->print(''.&mt('ok').''); } } } else { @@ -204,8 +212,8 @@ sub dumpcourse { $r->print( '

'.&mt('Select the Construction Space').'

'); @@ -219,48 +227,79 @@ sub dumpcourse { $r->print(''); } my $title=$origcrsdata{'description'}; - $title=~s/\s+/\_/gs; + $title=~s/[\/\s]+/\_/gs; $title=&clean($title); - $r->print('

'.&mt('Folder in Construction Space').'


'); + $r->print('

'.&mt('Folder in Construction Space').'

' + .'
'); &tiehash(); - $r->print('

'.&mt('Filenames in Construction Space').'

'); - foreach (&Apache::loncreatecourse::crsdirlist($origcrsid,'userfiles')) { - $r->print(''); - my ($ext)=($_=~/\.(\w+)$/); + $r->print('

'.&mt('Filenames in Construction Space').'

' + .&Apache::loncommon::start_data_table() + .&Apache::loncommon::start_data_table_header_row() + .'' + .'' + .'' + .&Apache::loncommon::end_data_table_header_row()); + foreach my $file (&Apache::lonclonecourse::crsdirlist($origcrsid,'userfiles')) { + $r->print(&Apache::loncommon::start_data_table_row() + .''); + my ($ext)=($file=~/\.(\w+)$/); my $title=$hash{'title_'.$hash{ - 'ids_/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'.$_}}; - $title=~s/:/:/g; + 'ids_/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'.$file}}; $r->print(''); - unless ($title) { - $title=$_; + if (!$title) { + $title=$file; + } else { + $title=~s|/|_|g; } $title=~s/\.(\w+)$//; $title=&clean($title); $title.='.'.$ext; - $r->print("\n\n"); + $r->print("\n" + .&Apache::loncommon::end_data_table_row()); } - $r->print("
'.&mt('Internal Filename').''.&mt('Title').''.&mt('Save as ...').'
'.$_.''.&mt('Internal Filename').''.&mt('Title').''.&mt('Save as ...').''.$file.''.($title?$title:' ').'
\n"); + $r->print(&Apache::loncommon::end_data_table()); &untiehash(); $r->print( - '

'); + '

'); } } -# ------------------------------------------------------ Generate "export" button + sub exportbutton { - return ''. - ''. - &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs'); + my $crstype = &Apache::loncommon::course_type(); + return "".&mt('IMS Export')."". + &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs').'
'; } + + sub exportcourse { my $r=shift; + my $crstype = &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 $numdisc = keys(%discussiontime); my $navmap = Apache::lonnavmaps::navmap->new(); + if (!defined($navmap)) { + $r->print(&Apache::loncommon::start_page('Export '.$crstype.' to IMS Package'). + '

'.&mt('IMS Export Failed').'

'. + '
'); + if ($crstype eq 'Community') { + $r->print(&mt('Unable to retrieve information about community contents')); + } else { + $r->print(&mt('Unable to retrieve information about course contents')); + } + $r->print('
'); + if ($crstype eq 'Community') { + $r->print(&mt('Return to Community Editor')); + } else { + $r->print(&mt('Return to Course Editor')); + } + $r->print(''); + &Apache::lonnet::logthis('IMS export failed - could not create navmap object in '.lc($crstype).':'.$env{'request.course.id'}); + return; + } my $it=$navmap->getIterator(undef,undef,undef,1,undef,undef); my $curRes; my $outcome; @@ -274,7 +313,17 @@ sub exportcourse { my @exportitems = &Apache::loncommon::get_env_multiple('form.archive'); my @discussions = &Apache::loncommon::get_env_multiple('form.discussion'); if (@exportitems == 0 && @discussions == 0) { - $outcome = '
As you did not select any content items or discussions for export, an IMS package has not been created. Please go back to select either content items or discussions for export'; + $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; @@ -297,36 +346,53 @@ sub exportcourse { open(OUTPUT, "zip -r $imszip * 2> /dev/null |"); close(OUTPUT); chdir $cwd; - $outcome .= 'Download the zip file from IMS course archive
'; + $outcome .= '

' + .&mt('[_1]Your IMS package[_2] is ready for download.' + ,'','') + .'

'; if ($copyresult) { - $outcome .= 'The following errors occurred during export - '.$copyresult; + $outcome .= '

' + .&mt('The following errors occurred during export - [_1]' + ,$copyresult) + .'

'; } } else { - $outcome = '
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.
'; + $outcome = '

' + .&mt('Unfortunately you will not be able to retrieve' + .' an IMS archive of your course at this time,' + .' because there was a problem creating a' + .' manifest file.') + .'

' + .'

' + .&mt('Go Back') + .'

'; } } - my $html=&Apache::lonxml::xmlbegin(); - $r->print($html.'Export Course'. - &Apache::loncommon::bodytag('Export course to IMS content package')); + $r->print(&Apache::loncommon::start_page('Export '.$crstype.' to IMS Package')); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('IMS Export')); $r->print($outcome); - $r->print(''); + $r->print(&Apache::loncommon::end_page()); } else { - my $display; - $display = '
'."\n"; - $display .= 'Choose which items you wish to export from your course.

'; - $display .= ''. - ''. - ''. - ''. - '
 Content items'. - ''. + &mt('Choose which items you wish to export from your '.$crstype.'.'). + '

'. + '
'. + ''.&mt('Content items').''. + ''. - '  
  
 Discussion posts'. - ''. - '  
'; + '  '; + if ($numdisc > 0) { + $display .= '
'. + ''.&mt('Discussion posts').''. + ''. + '  '. + '
'; + } + $display .= ''; my $curRes; my $depth = 0; my $count = 0; @@ -335,13 +401,13 @@ sub exportcourse { my %parent = (); my %children = (); my $lastcontainer = $startcount; - my @bgcolors = ('#F6F6F6','#FFFFFF'); - $display .= ''. - ''; if ($numdisc > 0) { - $display.='Export discussion posts?'."\n"; + $display .= ''; } - $display.=' '; + $display .= &Apache::loncommon::end_data_table_header_row(); while ($curRes = $it->next()) { if (ref($curRes)) { $count ++; @@ -357,44 +423,47 @@ sub exportcourse { if (ref($curRes)) { my $symb = $curRes->symb(); my $ressymb = $symb; - if ($ressymb =~ m|adm/(\w+)/(\w+)/(\d+)/bulletinboard$|) { + 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'; } } - my $color = $count%2; - $display .=''; + $display .= ' '.$curRes->title().''."\n"; + + # Existing discussion posts? if ($discussiontime{$ressymb} > 0) { $boards ++; - $currelem = $count+$boards+$startcount; - $display .= ''."\n"; - } else { - $display .= ''."\n"; + $display .= ''."\n"; + } elsif ($numdisc > 0) { + $display .= ''."\n"; } + $display .= &Apache::loncommon::end_data_table_row(); } } + $display .= &Apache::loncommon::end_data_table(); my $scripttag = qq| - |; - my $html=&Apache::lonxml::xmlbegin(); - $r->print($html.'Export Course'.$scripttag.''. - &Apache::loncommon::bodytag('Export course to IMS content package' -)); - - $r->print($display.'
Export content item?
 '."\n"; + $display .= &Apache::loncommon::start_data_table() + .&Apache::loncommon::start_data_table_header_row() + .''.&mt('Export content item?').''.&mt('Export discussion posts?').'
'."\n". - ''."\n" + .'is_sequence()) || ($curRes->is_page())) { - my $checkitem = $count + $boards + $startcount; - $display .= 'onClick="javascript:propagateCheck('."'$checkitem'".')"'; + $lastcontainer = $currelem; + $display .= 'onclick="javascript:propagateCheck('."'$currelem'".')"'; } $display .= ' />'."\n"; for (my $i=0; $i<$depth; $i++) { - $display .= ''."\n"; + $display .= ('' x2)."\n"; } if ($curRes->is_sequence()) { - $display .= ' '."\n"; - $lastcontainer = $count + $startcount + $boards; + $display .= ' '."\n"; } elsif ($curRes->is_page()) { - $display .= ' '."\n"; - $lastcontainer = $count + $startcount + $boards; + $display .= ' '."\n"; } - my $currelem = $count+$boards+$startcount; $children{$parent{$depth}} .= $currelem.':'; - $display .= ' '.$curRes->title().'   ' + .'' + .' 
'. - '

'. + $r->print(&Apache::loncommon::start_page('Export '.$crstype.' to IMS Package', + $scripttag)); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('IMS Export')); + $r->print($display. + '

'. '

'); + &mt('Export').'" />

'); } } @@ -540,7 +607,7 @@ sub build_package { if ($curRes->is_sequence() || $curRes->is_page()) { $lastcontainer = $count; } - if (grep/^$count$/,@$exportitems) { + if (grep(/^$count$/,@$exportitems)) { &get_dependencies($exportitems,\%parent,$depth,\@dependencies); } } @@ -564,7 +631,7 @@ sub build_package { if (ref($curRes)) { $count ++; - if ((grep/^$count$/,@$exportitems) || (grep/^$count$/,@dependencies)) { + if ((grep(/^$count$/,@$exportitems)) || (grep(/^$count$/,@dependencies))) { my $symb = $curRes->symb(); my $isvisible = 'true'; my $resourceref; @@ -598,14 +665,14 @@ sub build_package { ' '."\n". ' '."\n"; - foreach (@hrefs) { + foreach my $item (@hrefs) { $imsresources .= - ' '."\n"; + ' '."\n"; } - if (grep/^$count$/,@$discussions) { + if (grep(/^$count$/,@$discussions)) { my $ressymb = $symb; my $mode; - if ($ressymb =~ m|adm/(\w+)/(\w+)/(\d+)/bulletinboard$|) { + 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'; } @@ -643,8 +710,8 @@ sub build_package { 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 ((!grep(/^$$parent{$depth}$/,@$exportitems)) && (!grep(/^$$parent{$depth}$/,@$dependencies))) { + push(@{$dependencies},$$parent{$depth}); if ($depth > 2) { &get_dependencies($exportitems,$parent,$depth-1,$dependencies); } @@ -690,7 +757,7 @@ sub process_content { } } elsif ($symb =~ m-lib/templates/examupload\.problem$-) { $content_type = 'examupload'; - } elsif ($symb =~ m-adm/(\w+)/(\w+)/(\d+)/bulletinboard$-) { + } 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) { @@ -738,7 +805,7 @@ sub replicate_content { if ($caller eq 'templateupload') { $url = $symb; $url =~ s#//#/#g; - } else { + } else { ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); } my $content; @@ -778,9 +845,9 @@ sub replicate_content { $$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. +# 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'; + $content = 'Not the owner of this resource'; } if ($repstatus eq 'ok') { print $copiedfile $content; @@ -810,7 +877,7 @@ sub extract_media { $dirpath = $url; $container = ''; } - &Apache::lonnet::extract_embedded_items(undef,undef,\%allfiles,\%codebase,$content); + &Apache::lonnet::extract_embedded_items(undef,\%allfiles,\%codebase,$content); foreach my $embed_file (keys(%allfiles)) { my $filename; if ($embed_file =~ m#([^/]+)$#) { @@ -831,14 +898,14 @@ sub extract_media { } } if ($caller eq 'resource') { - my $respath = $Apache::lonnet::perlvar{'lonDocRoot'}.'/res'; - my $embed_path = &Apache::lonnet::filelocation($respath,$embed_url); + 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') { @@ -850,7 +917,7 @@ sub extract_media { my $copiedfile; if ($copiedfile = Apache::File->new('>'.$destination)) { print $copiedfile $embed_content; - push @{$href}, 'resources/'.$count.'/res/'.$filename; + push(@{$href},'resources/'.$count.'/res/'.$filename); my $attrib_regexp = ''; if (@{$allfiles{$embed_file}} > 1) { $attrib_regexp = join('|',@{$allfiles{$embed_file}}); @@ -894,18 +961,16 @@ sub store_template { } } -# 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; - my $container = shift; - my $caller = shift; - while (@_) { - my $name = shift; - my $url = shift; - if (($url =~ m#^/uploaded/$coursedom/$coursenum/(default_\d+\.)(page|sequence)$#) && ($caller eq 'londocs')) { + 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". @@ -917,7 +982,7 @@ sub group_import { my $result=&Apache::lonnet::finishuserfileupload($coursenum,$coursedom, 'output',$1.$2); if ($result != m|^/uploaded/|) { - $errtext.='Map not saved: A network error occured when trying to save the new map. '; + $errtext.='Map not saved: A network error occurred when trying to save the new map. '; $fatal = 2; } if ($fatal) { @@ -925,21 +990,24 @@ sub group_import { } } if ($url) { - my $idx = &Apache::lonratedt::getresidx($url); - $Apache::lonratedt::order[$#Apache::lonratedt::order+1]=$idx; + if (!$residx + || defined($LONCAPA::map::zombies[$residx])) { + $residx = &LONCAPA::map::getresidx($url,$residx); + push(@LONCAPA::map::order, $residx); + } my $ext = 'false'; - if ($url=~/^http:\/\//) { $ext = 'true'; } - $url =~ s/:/\:/g; - $name =~ s/:/\:/g; - $Apache::lonratedt::resources[$idx] = - join ':', ($name, $url, $ext, 'normal', 'res'); + if ($url=~m{^http://} || $url=~m{^https://}) { $ext = 'true'; } + $url = &LONCAPA::map::qtunescape($url); + $name = &LONCAPA::map::qtunescape($name); + $LONCAPA::map::resources[$residx] = + join(':', ($name, $url, $ext, 'normal', 'res')); } } return &storemap($coursenum, $coursedom, $folder.'.'.$container); } sub breadcrumbs { - my ($where)=@_; + my ($allowed,$crstype)=@_; &Apache::lonhtmlcommon::clear_breadcrumbs(); my (@folders); if ($env{'form.pagepath'}) { @@ -949,313 +1017,674 @@ sub breadcrumbs { } my $folderpath; my $cpinfo=''; - if ($env{'form.markedcopy_url'}) { - &Apache::lonnet::logthis('Found '.$env{'form.markedcopy_url'}); - $cpinfo='&markedcopy_url='. - &Apache::lonnet::escape($env{'form.markedcopy_url'}). - '&markedcopy_title='. - &Apache::lonnet::escape($env{'form.markedcopy_title'}); + 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); + my $foldername=shift(@folders); if ($folderpath) {$folderpath.='&';} $folderpath.=$folder.'&'.$foldername; my $url='/adm/coursedocs?folderpath='. - &Apache::lonnet::escape($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 '.$crstype.' Documents'); + } &Apache::lonhtmlcommon::add_breadcrumb( {'href'=>$url.$cpinfo, - 'title'=>&Apache::lonnet::unescape($foldername), - 'text'=>''. - &Apache::lonnet::unescape($foldername).'' + '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); } } - return &Apache::lonhtmlcommon::breadcrumbs(undef,undef,undef,undef,undef, - 0,'nohelp'); } -sub editor { - my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output)=@_; - my $errtext=''; - my $fatal=0; - my $container='sequence'; - if ($env{'form.pagepath'}) { - $container='page'; - } - ($errtext,$fatal)= - &mapread($coursenum,$coursedom,$folder.'.'.$container); - if ($#Apache::lonratedt::order<1) { - my $idx=&Apache::lonratedt::getresidx(); - if ($idx<=0) { $idx=1; } - $Apache::lonratedt::order[0]=$idx; - $Apache::lonratedt::resources[$idx]=''; + + + + +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('
'. + ''); + + my %saveable_parameters = ('show' => 'scalar',); + &Apache::loncommon::store_course_settings('docs_log', + \%saveable_parameters); + &Apache::loncommon::restore_course_settings('docs_log', + \%saveable_parameters); + if (!$env{'form.show'}) { $env{'form.show'}=10; } + my %lt=('hiddenresource' => 'Resources hidden', + 'encrypturl' => 'URL hidden', + 'randompick' => 'Randomly pick', + 'randomorder' => 'Randomly ordered', + 'set' => 'set to', + 'del' => 'deleted'); + $r->print(&Apache::loncommon::display_filter(). + ''. + '
'); + $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; } } - if (defined($env{'form.markcopy'})) { + $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(':',$Apache::lonratedt::resources[$Apache::lonratedt::order[$env{'form.markcopy'}]]); - $env{'form.markedcopy_title'}=$title; - $env{'form.markedcopy_url'}=$url; - } - $r->print(&breadcrumbs($folder)); - if ($fatal) { - $r->print('

'.$errtext.'

'); + 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').'' + .'
' + .' ' + ); + + my $type; + if ($env{'docs.markedcopy_url'} =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//} ) { + $type = &mt('External Resource'); + $r->print($type.': '. + &LONCAPA::map::qtescape($env{'docs.markedcopy_title'}).' ('. + &LONCAPA::map::qtescape($env{'docs.markedcopy_url'}).')'); + } else { + my $extension = (split(/\./,$env{'docs.markedcopy_url'}))[-1]; + my $icon = &Apache::loncommon::icon($extension); + if ($extension eq 'sequence' && + $env{'docs.markedcopy_url'} =~ m{/default_\d+\.sequence$ }x) { + $icon = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL')); + $icon .= '/navmap.folder.closed.gif'; + } + $icon = ''; + $r->print($icon.$type.': '. &parse_supplemental_title(&LONCAPA::map::qtescape($env{'docs.markedcopy_title'}))); + } + if ($container eq 'page') { + $r->print(' + + +'); } else { + $r->print(' + +'); + } + $r->print('
'); +} + +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,$upload_output,$crstype)=@_; + 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]=''; + } + + my ($breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,$is_random_order) = + &breadcrumbs($allowed,$crstype); + $r->print($breadcrumbtrail); + + unless ($allowed) { + $randompick = -1; + } + # ------------------------------------------------------------ Process commands # ---------------- if they are for this folder and user allowed to make changes - if (($allowed) && ($env{'form.folder'} eq $folder)) { + if (($allowed) && ($env{'form.folder'} eq $folder)) { # set parameters and change order - if (defined($env{'form.setparms'})) { - my $idx=$env{'form.setparms'}; -# set parameters - if ($env{'form.randpick_'.$idx}) { - &Apache::lonratedt::storeparameter($idx,'parameter_randompick',$env{'form.randpick_'.$idx},'int_pos'); - } else { - &Apache::lonratedt::delparameter($idx,'parameter_randompick'); - } - if ($env{'form.hidprs_'.$idx}) { - &Apache::lonratedt::storeparameter($idx,'parameter_hiddenresource','yes','string_yesno'); - } else { - &Apache::lonratedt::delparameter($idx,'parameter_hiddenresource'); - } - if ($env{'form.encprs_'.$idx}) { - &Apache::lonratedt::storeparameter($idx,'parameter_encrypturl','yes','string_yesno'); - } else { - &Apache::lonratedt::delparameter($idx,'parameter_encrypturl'); - } + &snapshotbefore(); - if ($env{'form.newpos'}) { + 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); - my $newpos=$env{'form.newpos'}-1; - my $currentpos=$env{'form.currentpos'}-1; - my $i; - my @neworder=(); - if ($newpos>$currentpos) { -# moving stuff up - for ($i=0;$i<$currentpos;$i++) { - $neworder[$i]=$Apache::lonratedt::order[$i]; - } - for ($i=$currentpos;$i<$newpos;$i++) { - $neworder[$i]=$Apache::lonratedt::order[$i+1]; - } - $neworder[$newpos]=$Apache::lonratedt::order[$currentpos]; - for ($i=$newpos+1;$i<=$#Apache::lonratedt::order;$i++) { - $neworder[$i]=$Apache::lonratedt::order[$i]; - } - } else { -# moving stuff down - for ($i=0;$i<$newpos;$i++) { - $neworder[$i]=$Apache::lonratedt::order[$i]; - } - $neworder[$newpos]=$Apache::lonratedt::order[$currentpos]; - for ($i=$newpos+1;$i<$currentpos+1;$i++) { - $neworder[$i]=$Apache::lonratedt::order[$i-1]; - } - for ($i=$currentpos+1;$i<=$#Apache::lonratedt::order;$i++) { - $neworder[$i]=$Apache::lonratedt::order[$i]; - } - } - @Apache::lonratedt::order=@neworder; - } -# store the changed version + ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container); + return $errtext if ($fatal); + } - ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container); - if ($fatal) { - $r->print('

'.$errtext.'

'); - return; + 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 my $item (split(/\&/,$env{'form.importdetail'})) { + if (defined($item)) { + my ($name,$url,$residx)= + map {&unescape($_)} split(/\=/,$item); + push(@imports, [$name, $url, $residx]); } - } - if ($env{'form.pastemarked'}) { -# paste resource to end of list - my $url=$env{'form.markedcopy_url'}; - my $title=$env{'form.markedcopy_title'}; -# Maps need to be copied first - if (($url=~/\.(page|sequence)$/) || ($url=~/^\/uploaded\//)) { - $title=&mt('Copy of').' '.$title; - my $newid=$$.time; - $url=~/^(.+)\.(\w+)$/; - my $newurl=$1.$newid.'.'.$2; - my $storefn=$newurl; - $storefn=~s/^\/\w+\/\w+\/\w+\///; - &Apache::loncreatecourse::writefile - ($env{'request.course.id'},$storefn, - &Apache::lonnet::getfile($url)); - $url=$newurl; - } - $title=~s/\/\>\;/g; - $title=~s/\:/\:/g; - my $ext='false'; - if ($url=~/^http\:\/\//) { $ext='true'; } - $url=~s/\:/\:/g; -# Now insert the URL at the bottom - my $newidx=&Apache::lonratedt::getresidx($url); - $Apache::lonratedt::resources[$newidx]= - $title.':'.$url.':'.$ext.':normal:res'; - $Apache::lonratedt::order[1+$#Apache::lonratedt::order]=$newidx; -# Store the result - ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container); - if ($fatal) { - $r->print('

'.$errtext.'

'); - return; + ($errtext,$fatal)=&group_import($coursenum, $coursedom, $folder, + $container,'londocs',@imports); + return $errtext if ($fatal); + } +# Loading a complete map + 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; } - - } - $r->print($upload_output); - if ($env{'form.cmd'}) { - my ($cmd,$idx)=split(/\_/,$env{'form.cmd'}); - if ($cmd eq 'del') { - my (undef,$url)=split(':',$Apache::lonratedt::resources[$Apache::lonratedt::order[$idx]]); - if (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) && - ($url!~/\.(page|sequence|problem|exam|quiz|assess|survey|form|library)$/)) { - &Apache::lonnet::removeuploadedurl($url); - } else { - &Apache::lonratedt::makezombie($Apache::lonratedt::order[$idx]); - } - for (my $i=$idx;$i<$#Apache::lonratedt::order;$i++) { - $Apache::lonratedt::order[$i]= - $Apache::lonratedt::order[$i+1]; - } - $#Apache::lonratedt::order--; - } elsif ($cmd eq 'cut') { - my (undef,$url)=split(':',$Apache::lonratedt::resources[$Apache::lonratedt::order[$idx]]); - &Apache::lonratedt::makezombie($Apache::lonratedt::order[$idx]); - for (my $i=$idx;$i<$#Apache::lonratedt::order;$i++) { - $Apache::lonratedt::order[$i]= - $Apache::lonratedt::order[$i+1]; - } - $#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 $ratstr = $Apache::lonratedt::resources[$Apache::lonratedt::order[$idx]]; - 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; - if ($comment=~/\S/) { - $Apache::lonratedt::resources[ - $Apache::lonratedt::order[$idx]]= - $comment.':'.join(':',@rrest); - } - } -# Store the changed version ($errtext,$fatal)=&storemap($coursenum,$coursedom, $folder.'.'.$container); - if ($fatal) { - $r->print('

'.$errtext.'

'); - return; - } - } -# Group import/search - if ($env{'form.importdetail'}) { - my @imports; - foreach (split(/\&/,$env{'form.importdetail'})) { - if (defined($_)) { - my ($name,$url)=split(/\=/,$_); - $name=&Apache::lonnet::unescape($name); - $url=&Apache::lonnet::unescape($url); - push @imports, $name, $url; - } - } -# Store the changed version - ($errtext,$fatal)=group_import($coursenum, $coursedom, $folder, - $container,'londocs',@imports); - if ($fatal) { - $r->print('

'.$errtext.'

'); - return; - } - } -# Loading a complete map - if (($env{'form.importmap'}) && ($env{'form.loadmap'})) { - foreach (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$env{'form.importmap'}))) { - my ($title,$url,$ext,$type)=split(/\:/,$_); - my $idx=&Apache::lonratedt::getresidx($url); - $Apache::lonratedt::resources[$idx]=$_; - $Apache::lonratedt::order - [$#Apache::lonratedt::order+1]=$idx; - } - -# Store the changed version - ($errtext,$fatal)=&storemap($coursenum,$coursedom, - $folder.'.'.$container); - if ($fatal) { - $r->print('

'.$errtext.'

'); - return; - } - } - } -# ---------------------------------------------------------------- End commands -# ---------------------------------------------------------------- Print screen - my $idx=0; - my $shown=0; - $r->print(''); - foreach (@Apache::lonratedt::order) { - my ($name,$url)=split(/\:/,$Apache::lonratedt::resources[$_]); - unless ($name) { $name=(split(/\//,$url))[-1]; } - unless ($name) { $idx++; next; } - $r->print(&entryline($idx,$name,$url,$folder,$allowed,$_,$coursenum)); - $idx++; - $shown++; - } - unless ($shown) { - $r->print(''); - } - $r->print("\n
'.&mt('Currently no documents.').'
\n"); - if ($env{'form.markedcopy_url'}) { - $r->print(<
- - -ENDPASTE - $r->print( - ' '.&Apache::loncommon::filedescription( - (split(/\./,$env{'form.markedcopy_url'}))[-1]).': '. - $env{'form.markedcopy_title'}); - if ($container eq 'page') { - $r->print(< - -PAGEINFO - } else { - $r->print(< -FOLDERINFO + return $errtext if ($fatal); + } else { + $r->print('

'.&mt('No map selected.').'

'); + } - $r->print('

'); } + &log_differences($plain); + } +# ---------------------------------------------------------------- End commands +# ---------------------------------------------------------------- Print screen + my $idx=0; + my $shown=0; + if (($ishidden) || ($isencrypted) || ($randompick>=0) || ($is_random_order)) { + $r->print('
'. + '
  1. '.&mt('Parameters:').'
  2. '. + ($randompick>=0?'
  3. '.&mt('randomly pick [quant,_1,resource]',$randompick).'
  4. ':''). + ($ishidden?'
  5. '.&mt('contents hidden').'
  6. ':''). + ($isencrypted?'
  7. '.&mt('URLs hidden').'
  8. ':''). + ($is_random_order?'
  9. '.&mt('random order').'
  10. ':''). + '
'); + if ($randompick>=0) { + $r->print('

' + .&mt('Caution: this folder is set to randomly pick a subset' + .' of resources. Adding or removing resources from this' + .' folder will change the set of resources that the' + .' students see, resulting in spurious or missing credit' + .' for completed problems, not limited to ones you' + .' modify. Do not modify the contents of this folder if' + .' it is in active student use.') + .'

' + ); + } + if ($is_random_order) { + $r->print('

' + .&mt('Caution: this folder is set to randomly order its' + .' contents. Adding or removing resources from this folder' + .' will change the order of resources shown.') + .'

' + ); + } + $r->print('
'); + } + + my $output; + + &Apache::loncommon::start_data_table_count(); #setup a row counter + foreach my $res (@LONCAPA::map::order) { + my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]); + $name=&LONCAPA::map::qtescape($name); + $url=&LONCAPA::map::qtescape($url); + unless ($name) { $name=(split(/\//,$url))[-1]; } + unless ($name) { $idx++; next; } + $output .= &entryline($idx,$name,$url,$folder,$allowed,$res, + $coursenum,$crstype); + $idx++; + $shown++; + } + &Apache::loncommon::end_data_table_count(); + + if ($shown) { + $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'}) { + my ($parseaction,$showupload,$nextphase,$mimetype); + if ($env{'form.parserflag'}) { $parseaction = 'parse'; } - my $phase_status; my $folder=$env{'form.folder'}; if ($folder eq '') { $folder='default'; @@ -1269,12 +1698,13 @@ sub process_file_upload { } ($errtext,$fatal)= &mapread($coursenum,$coursedom,$folder.'.'.$container); - if ($#Apache::lonratedt::order<1) { - $Apache::lonratedt::order[0]=1; - $Apache::lonratedt::resources[1]=''; + if ($#LONCAPA::map::order<1) { + $LONCAPA::map::order[0]=1; + $LONCAPA::map::resources[1]=''; } if ($fatal) { - return 'failed'; + $$upload_output = '

'.&mt('The uploaded file has not been stored as an error occurred reading the contents of the current folder.').'

'; + return; } my $destination = 'docs/'; if ($folder =~ /^supplemental/) { @@ -1285,156 +1715,156 @@ sub process_file_upload { } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) { $destination .= $2.'/'; } -# this is for a course, not a user, so set coursedoc flag -# probably the only place in the system where this should be "1" - my $newidx=&Apache::lonratedt::getresidx(); +# this is for a course, not a user, so set context to coursedoc. + my $newidx=&LONCAPA::map::getresidx(); $destination .= $newidx; - my $url=&Apache::lonnet::userfileupload('uploaddoc',1,$destination, + my $url=&Apache::lonnet::userfileupload('uploaddoc','coursedoc',$destination, $parseaction,$allfiles, - $codebase); + $codebase,undef,undef,undef,undef, + undef,undef,\$mimetype); + if ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E.*/([^/]+)$}) { + my $stored = $1; + $showupload = '

'.&mt('Uploaded [_1]',''. + $stored.'').'

'; + } else { + my ($filename) = ($env{'form.uploaddoc.filename'} =~ m{([^/]+)$}); + + $$upload_output = '

'.&mt('Unable to save file [_1].',''.$filename.'').'

'; + return; + } my $ext='false'; - if ($url=~/^http\:\/\//) { $ext='true'; } - $url=~s/\:/\:/g; + if ($url=~m{^http://}) { $ext='true'; } + $url = &LONCAPA::map::qtunescape($url); my $comment=$env{'form.comment'}; - $comment=~s/\/\>\;/g; - $comment=~s/\:/\:/g; + $comment = &LONCAPA::map::qtunescape($comment); if ($folder=~/^supplemental/) { $comment=time.'___&&&___'.$env{'user.name'}.'___&&&___'. $env{'user.domain'}.'___&&&___'.$comment; } - $Apache::lonratedt::resources[$newidx]= - $comment.':'.$url.':'.$ext.':normal:res'; - $Apache::lonratedt::order[$#Apache::lonratedt::order+1]= $newidx; + $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'; + $$upload_output = '

'.$errtext.'

'; + return; } else { - if ($parseaction eq 'parse') { - my $total_embedded = keys(%{$allfiles}); + if ($parseaction eq 'parse' && $mimetype eq 'text/html') { + $$upload_output = $showupload; + my $total_embedded = scalar(keys(%{$allfiles})); if ($total_embedded > 0) { - my $num = 0; - $$upload_output .= 'This file contains embedded multimedia objects, which need to be uploaded to LON-CAPA.
-
- - - - '; - $$upload_output .= 'Upload embedded files:
- '; - foreach my $embed_file (keys(%{$allfiles})) { - $$upload_output .= ''; - $num ++; + } else { + $$upload_output .= &mt('Embedded item(s) already present, so no additional upload(s) required').'
'; } - $phase_status = 'phasetwo'; - $$upload_output .= '
'.$embed_file. - ' - '; - my $attrib; - if (@{$$allfiles{$embed_file}} > 1) { - $attrib = join(':',@{$$allfiles{$embed_file}}); + my $uploadphase = 'upload_embedded'; + my $primaryurl = &HTML::Entities::encode($url,'<>&"'); + my $state = &embedded_form_elems($uploadphase,$primaryurl,$newidx); + my ($embedded,$num) = + &Apache::loncommon::ask_for_embedded_content( + '/adm/coursedocs',$state,$allfiles,$codebase,{'docs_url' => $url}); + if ($embedded) { + if ($num) { + $$upload_output .= + '

'.&mt('This file contains embedded multimedia objects, which need to be uploaded.').'

'.$embedded; + $nextphase = $uploadphase; } else { - $attrib = $$allfiles{$embed_file}[0]; - } - $$upload_output .= - ''; - if (exists($$codebase{$embed_file})) { - $$upload_output .= - ''; + $$upload_output .= $embedded; } - $$upload_output .= '

- -
'; } else { - $$upload_output .= 'No embedded items identified
'; + $$upload_output .= &mt('No embedded items identified').'
'; } } } } - return $phase_status; + return $nextphase; } -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/'; +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 (($folder eq 'default') || ($folder eq 'supplemental')) { - $destination .= 'default/'; - } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) { - $destination .= $1.'/'; + 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,'"<>&\''); + $renametitle = &HTML::Entities::encode($renametitle,'"<>&\''); + $title=''.&Apache::lonlocal::locallocaltime($time).' '. + $name.':
'.$foldertitle; } - $destination .= $newidx; - my ($url,$filename); - $url=&Apache::lonnet::userfileupload($formname.$num,1,$destination); - ($filename) = ($url =~ m-^/uploaded/$coursedom/$coursenum/$destination/(.+)$-); - return $filename; + if (wantarray) { + return ($title,$foldertitle,$renametitle); + } + return $title; } # --------------------------------------------------------------- An entry line sub entryline { - my ($index,$title,$url,$folder,$allowed,$residx,$coursenum)=@_; - $title=~s/\&colon\;/\:/g; - $title=&HTML::Entities::encode(&HTML::Entities::decode( - &Apache::lonnet::unescape($title)),'"<>&\''); - my $renametitle=$title; - my $foldertitle=$title; - my $pagetitle=$title; - my $orderidx=$Apache::lonratedt::order[$index]; - if ($title=~ /^(\d+)___&&&___(\w+)___&&&___(\w+)___&&&___(.*)$/ ) { - $foldertitle=&Apache::lontexconvert::msgtexconverted($4); - $renametitle=$4; - $title=''.&Apache::lonlocal::locallocaltime($1).' '. - &Apache::loncommon::plainname($2,$3).':
'. - $foldertitle; + my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$crstype)=@_; + my ($foldertitle,$pagetitle,$renametitle); + if (&is_supplemental_title($title)) { + ($title,$foldertitle,$renametitle) = &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; - my $folderpath; + my ($container, $type, $esc_path, $path, $symb); if ($env{'form.folderpath'}) { + $type = 'folder'; $container = 'sequence'; - $folderpath=&Apache::lonnet::escape($env{'form.folderpath'}); + $esc_path=&escape($env{'form.folderpath'}); + $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); # $htmlfoldername=&HTML::Entities::encode($env{'form.foldername'},'<>&"'); } - my ($pagepath,$pagesymb); if ($env{'form.pagepath'}) { - $container = 'page'; - $pagepath=&Apache::lonnet::escape($env{'form.pagepath'}); - $pagesymb=&Apache::lonnet::escape($env{'form.pagesymb'}); + $type = $container = 'page'; + $esc_path=&escape($env{'form.pagepath'}); + $path = &HTML::Entities::encode($env{'form.pagepath'},'<>&"'); + $symb=&escape($env{'form.pagesymb'}); } my $cpinfo=''; - if ($env{'form.markedcopy_url'}) { - $cpinfo='&markedcopy_url='. - &Apache::lonnet::escape($env{'form.markedcopy_url'}). - '&markedcopy_title='. - &Apache::lonnet::escape($env{'form.markedcopy_title'}); - } if ($allowed) { my $incindex=$index+1; my $selectbox=''; if (($folder!~/^supplemental/) && - ($#Apache::lonratedt::order>0) && + ($#LONCAPA::map::order>0) && ((split(/\:/, - $Apache::lonratedt::resources[$Apache::lonratedt::order[0]]))[1] - ne '') && + $LONCAPA::map::resources[$LONCAPA::map::order[0]]))[1] + ne '') && ((split(/\:/, - $Apache::lonratedt::resources[$Apache::lonratedt::order[1]]))[1] + $LONCAPA::map::resources[$LONCAPA::map::order[1]]))[1] ne '')) { $selectbox= ''. - ''; + for (my $i=1;$i<=$#LONCAPA::map::order+1;$i++) { if ($i==$incindex) { - $selectbox.=''; + $selectbox.=''; } else { $selectbox.=''; } @@ -1448,60 +1878,85 @@ sub entryline { 'ct' => 'Cut', 'rn' => 'Rename', 'cp' => 'Copy'); - if ($env{'form.pagepath'}) { - $line.=(< - - - - - - - - -
- -$lt{
- -$lt{
-$selectbox - - -$lt{'rm'} - -$lt{'ct'} - -$lt{'rn'} - -$lt{'cp'} + 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 - } else { - $line.=(< - - - - - - - -
- -$lt{
- -$lt{
-$selectbox - - -$lt{'rm'} - -$lt{'ct'} - -$lt{'rn'} - -$lt{'cp'} + $form_end = ''; + $line.=(< +
+ + $lt{ + +
+
+ + $lt{ + +
+ + + $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+)$/); @@ -1514,14 +1969,14 @@ END my $pagefile; if ($uploaded) { if ($extension eq 'sequence') { - $icon=$iconpath.'/folder_closed.gif'; - $url=~/$coursenum\/([\/\w]+)\.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=~/$coursenum\/([\/\w]+)\.page$/; + $url=~/\Q$coursenum\E\/([\/\w]+)\.page$/; $pagearg=$1; $url='/adm/coursedocs?'; $ispage=1; @@ -1529,7 +1984,10 @@ END &Apache::lonnet::allowuploaded('/adm/coursedoc',$url); } } - $url=~s/^http\&colon\;\/\//\/adm\/wrapper\/ext\//; + + 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/'. @@ -1550,34 +2008,51 @@ END } elsif ($url!~/\.(sequence|page)$/) { $url='/adm/coursedocs/showdoc'.$url; } - } elsif ($url=~m|^/ext/|) { + } elsif ($url=~m|^/ext/|) { $url='/adm/wrapper'.$url; + $external = 1; } - $url.=(($url=~/\?/)?'&':'?').'symb='.&Apache::lonnet::escape($symb); + 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='.&Apache::lonnet::escape($symb); + $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb); } } - my $parameterset=' '; - if ($isfolder) { - my $foldername=&Apache::lonnet::escape($foldertitle); + my ($parameterset,$rand_order_text) = (' ', ' '); + if ($isfolder || $extension eq 'sequence') { + my $foldername=&escape($foldertitle); my $folderpath=$env{'form.folderpath'}; if ($folderpath) { $folderpath.='&' }; - $folderpath.=$folderarg.'&'.$foldername; - $url.='folderpath='.&Apache::lonnet::escape($folderpath).$cpinfo; +# 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('Save').''; + my $ro_set= + ((&LONCAPA::map::getparameter($orderidx,'parameter_randomorder'))[0]=~/^yes$/i?' checked="checked"':''); + $rand_order_text =' +'; } if ($ispage) { - my $pagename=&Apache::lonnet::escape($pagetitle); + my $pagename=&escape($pagetitle); my $pagepath; my $folderpath=$env{'form.folderpath'}; if ($folderpath) { $pagepath = $folderpath.'&' }; @@ -1591,33 +2066,62 @@ END $residx, $path.$pagearg.'.page'); } - $url.='pagepath='.&Apache::lonnet::escape($pagepath). - '&pagesymb='.&Apache::lonnet::escape($symb).$cpinfo; + $url.='pagepath='.&escape($pagepath). + '&pagesymb='.&escape($symb).$cpinfo; + } + if (($external) && ($allowed)) { + my $form = ($folder =~ /^default/)? 'newext' : 'supnewext'; + $external = ' '.&mt('Edit').''; + } else { + undef($external); } - $line.=''. - "$title"; + my $reinit; + if ($crstype eq 'Community') { + $reinit = &mt('(re-initialize community to access)'); + } else { + $reinit = &mt('(re-initialize course to access)'); + } + $line.=' + + '.($url?'':'').''.($url?'':'').' + + + '.($url?"":'').$title.($url?'':' '.$reinit.'').$external." + "; if (($allowed) && ($folder!~/^supplemental/)) { my %lt=&Apache::lonlocal::texthash( 'hd' => 'Hidden', 'ec' => 'URL hidden'); my $enctext= - ((&Apache::lonratedt::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i?' checked="1"':''); + ((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i?' checked="checked"':''); my $hidtext= - ((&Apache::lonratedt::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i?' checked="1"':''); + ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i?' checked="checked"':''); $line.=(< - - - -$parameterset + + $form_start + + $form_end + + + $form_start + + $form_end + + $form_start $rand_order_text $form_end + $form_start $parameterset $form_end ENDPARMS } - $line.=""; + $line.=&Apache::loncommon::end_data_table_row(); return $line; } -# ---------------------------------------------------------------- tie the hash +=pod + +=item tiehash() + +tie the hash + +=cut sub tiehash { my ($mode)=@_; @@ -1634,23 +2138,28 @@ sub tiehash { $hashtied=1; } } - } + } } sub untiehash { if ($hashtied) { untie %hash; } $hashtied=0; + return OK; } -# --------------------------------------------------------------- check on this + + sub checkonthis { my ($r,$url,$level,$title)=@_; - $url=&Apache::lonnet::unescape($url); + $url=&unescape($url); $alreadyseen{$url}=1; $r->rflush(); if (($url) && ($url!~/^\/uploaded\//) && ($url!~/\*$/)) { $r->print("\n
"); + if ($level==0) { + $r->print("
"); + } for (my $i=0;$i<=$level*5;$i++) { $r->print(' '); } @@ -1660,7 +2169,7 @@ sub checkonthis { my $result=&Apache::lonnet::repcopy( &Apache::lonnet::filelocation('',$url)); if ($result eq 'ok') { - $r->print(''.&mt('ok').''); + $r->print(''.&mt('ok').''); $r->rflush(); &Apache::lonnet::countacc($url); $url=~/\.(\w+)$/; @@ -1670,7 +2179,7 @@ sub checkonthis { for (my $i=0;$i<=$level*5;$i++) { $r->print(' '); } - $r->print('- '.&mt('Rendering').': '); + $r->print('- '.&mt('Rendering:').' '); my ($errorcount,$warningcount)=split(/:/, &Apache::lonnet::ssi_body($url, ('grade_target'=>'web', @@ -1678,78 +2187,102 @@ sub checkonthis { if (($errorcount) || ($warningcount)) { if ($errorcount) { - $r->print(''. - $errorcount.' '. - &mt('error(s)').' '); + $r->print(''.&mt('bomb').''. + &mt('[quant,_1,error]',$errorcount).''); } if ($warningcount) { - $r->print(''. - $warningcount.' '. - &mt('warning(s)').''); + $r->print(''. + &mt('[quant,_1,warning]',$warningcount).''); } } else { - $r->print(''.&mt('ok').''); + $r->print(''.&mt('ok').''); } $r->rflush(); } my $dependencies= &Apache::lonnet::metadata($url,'dependencies'); - foreach (split(/\,/,$dependencies)) { - if (($_=~/^\/res\//) && (!$alreadyseen{$_})) { - &checkonthis($r,$_,$level+1); + foreach my $dep (split(/\,/,$dependencies)) { + if (($dep=~/^\/res\//) && (!$alreadyseen{$dep})) { + &checkonthis($r,$dep,$level+1); } } } elsif ($result eq 'unavailable') { - $r->print(''.&mt('connection down').''); + $r->print(''.&mt('connection down').''); } elsif ($result eq 'not_found') { unless ($url=~/\$/) { - $r->print(''.&mt('not found').''); + $r->print(''.&mt('not found').''); } else { - $r->print(''.&mt('unable to verify variable URL').''); + $r->print(''.&mt('unable to verify variable URL').''); } } else { - $r->print(''.&mt('access denied').''); + $r->print(''.&mt('access denied').''); } - } - } + } + } +} + + + +=pod + +=item list_symbs() + +List Symbs + +=cut + +sub list_symbs { + my ($r) = @_; + + my $crstype = &Apache::loncommon::course_type(); + $r->print(&Apache::loncommon::start_page('Symb List')); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Symb List')); + &startContentScreen($r,'tools'); + my $navmap = Apache::lonnavmaps::navmap->new(); + if (!defined($navmap)) { + $r->print('

'.&mt('Retrieval of List Failed').'

'. + '
'. + &mt('Unable to retrieve information about course contents'). + '
'); + &Apache::lonnet::logthis('Symb list failed - could not create navmap object in '.lc($crstype).':'.$env{'request.course.id'}); + } else { + $r->print("
\n");
+        foreach my $res ($navmap->retrieveResources()) {
+            $r->print($res->compTitle()."\t".$res->symb()."\n");
+        }
+        $r->print("\n
\n"); + } } -# -# -------------------------------------------------------------- Verify Content -# sub verifycontent { - my $r=shift; - my $loaderror=&Apache::lonnet::overloaderror($r); - if ($loaderror) { return $loaderror; } - my $html=&Apache::lonxml::xmlbegin(); - $r->print($html.'Verify Content'. - &Apache::loncommon::bodytag('Verify Course Documents')); + my ($r) = @_; + my $crstype = &Apache::loncommon::course_type(); + $r->print(&Apache::loncommon::start_page('Verify '.$crstype.' Documents')); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$crstype.' Documents')); + &startContentScreen($r,'tools'); $hashtied=0; undef %alreadyseen; %alreadyseen=(); &tiehash(); - foreach (keys %hash) { - if ($hash{$_}=~/\.(page|sequence)$/) { - if (($_=~/^src_/) && ($alreadyseen{&Apache::lonnet::unescape($hash{$_})})) { - $r->print('
'. - &mt('The following sequence or page is included more than once in your course: '). - &Apache::lonnet::unescape($hash{$_}).'
'. - &mt('Note that grading records for problems included in this sequence or folder will overlap.
')); + foreach my $key (keys(%hash)) { + if ($hash{$key}=~/\.(page|sequence)$/) { + if (($key=~/^src_/) && ($alreadyseen{&unescape($hash{$key})})) { + $r->print('
'. + &mt('The following sequence or page is included more than once in your '.$crstype.':').' '. + &unescape($hash{$key}).'
'. + &mt('Note that grading records for problems included in this sequence or folder will overlap.').'
'); } } - if (($_=~/^src\_(.+)$/) && (!$alreadyseen{&Apache::lonnet::unescape($hash{$_})})) { - &checkonthis($r,$hash{$_},0,$hash{'title_'.$1}); + if (($key=~/^src\_(.+)$/) && (!$alreadyseen{&unescape($hash{$key})})) { + &checkonthis($r,$hash{$key},0,$hash{'title_'.$1}); } } &untiehash(); - $r->print('

'.&mt('Done').'.

'.''. - &mt('Return to DOCS').''); + $r->print('

'.&mt('Done').'

'); } -# -------------------------------------------------------------- Check Versions - sub devalidateversioncache { my $src=shift; &Apache::lonnet::devalidate_cache_new('courseresversion',$env{'request.course.id'}.'_'. @@ -1757,10 +2290,12 @@ sub devalidateversioncache { } sub checkversions { - my $r=shift; - my $html=&Apache::lonxml::xmlbegin(); - $r->print($html.'Check Versions'. - &Apache::loncommon::bodytag('Check Course Document Versions')); + my ($r) = @_; + my $crstype = &Apache::loncommon::course_type(); + $r->print(&Apache::loncommon::start_page("Check $crstype Document Versions")); + $r->print(&Apache::lonhtmlcommon::breadcrumbs("Check $crstype Document Versions")); + &startContentScreen($r,'tools'); + my $header=''; my $startsel=''; my $monthsel=''; @@ -1779,16 +2314,16 @@ sub checkversions { my %newsetversions=(); if ($env{'form.setmostrecent'}) { $haschanged=1; - foreach (keys %hash) { - if ($_=~/^ids\_(\/res\/.+)$/) { + foreach my $key (keys(%hash)) { + if ($key=~/^ids\_(\/res\/.+)$/) { $newsetversions{$1}='mostrecent'; &devalidateversioncache($1); } } } elsif ($env{'form.setcurrent'}) { $haschanged=1; - foreach (keys %hash) { - if ($_=~/^ids\_(\/res\/.+)$/) { + foreach my $key (keys(%hash)) { + if ($key=~/^ids\_(\/res\/.+)$/) { my $getvers=&Apache::lonnet::getversion($1); if ($getvers>0) { $newsetversions{$1}=$getvers; @@ -1798,11 +2333,11 @@ sub checkversions { } } elsif ($env{'form.setversions'}) { $haschanged=1; - foreach (keys %env) { - if ($_=~/^form\.set_version_(.+)$/) { + foreach my $key (keys(%env)) { + if ($key=~/^form\.set_version_(.+)$/) { my $src=$1; - if (($env{$_}) && ($env{$_} ne $setversions{$src})) { - $newsetversions{$src}=$env{$_}; + if (($env{$key}) && ($env{$key} ne $setversions{$src})) { + $newsetversions{$src}=$env{$key}; &devalidateversioncache($src); } } @@ -1811,20 +2346,20 @@ sub checkversions { if ($haschanged) { if (&Apache::lonnet::put('resourceversions',\%newsetversions, $env{'course.'.$env{'request.course.id'}.'.domain'}, - $env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') { - $r->print('

'.&mt('Your Version Settings have been Stored').'

'); + $env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') { + $r->print('

'.&mt('Your Version Settings have been Saved').'

'); } else { - $r->print('

'.&mt('An Error Occured while Attempting to Store your Version Settings').'

'); + $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 Course'); + $header=&mt('All Documents in '.$crstype); $allsel=1; - foreach (keys %hash) { - if ($_=~/^ids\_(\/res\/.+)$/) { + foreach my $key (keys(%hash)) { + if ($key=~/^ids\_(\/res\/.+)$/) { my $src=$1; $changes{$src}=1; } @@ -1834,7 +2369,7 @@ sub checkversions { %changes=&Apache::lonnet::dump ('versionupdate',$env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'}); - my $firstkey=(keys %changes)[0]; + my $firstkey=(keys(%changes))[0]; unless ($firstkey=~/^error\:/) { unless ($env{'form.timerange'}) { $env{'form.timerange'}=604800; @@ -1866,7 +2401,7 @@ sub checkversions { $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'}); my %lt=&Apache::lonlocal::texthash - ('st' => 'Version changes since start of Course', + ('st' => 'Version changes since start of '.$crstype, 'lm' => 'Version changes since last Month', 'lw' => 'Version changes since last Week', 'sy' => 'Version changes since Yesterday', @@ -1875,9 +2410,9 @@ sub checkversions { 'fi' => 'File', 'md' => 'Modification Date', 'mr' => 'Most recently published Version', - 've' => 'Version used in Course', - 'vu' => 'Set Version to be used in Course', -'sv' => 'Set Versions to be used in Course according to Selections below', + 've' => 'Version used in '.$crstype, + 'vu' => 'Set Version to be used in '.$crstype, +'sv' => 'Set Versions to be used in '.$crstype.' according to Selections below', 'sm' => 'Keep all Resources up-to-date with most recent Versions (default)', 'sc' => 'Set all Resource Versions to current Version (Fix Versions)', 'di' => 'Differences'); @@ -1898,14 +2433,14 @@ sub checkversions { ENDHEADERS - foreach (sort keys %changes) { - if ($changes{$_}>$starttime) { - my ($root,$extension)=($_=~/^(.*)\.(\w+)$/); - my $currentversion=&Apache::lonnet::getversion($_); + 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($_); + my $linkurl=&Apache::lonnet::clutter($key); $r->print( ''. - ''. - ''. + ''); + 'mostrecent' => &mt('most recent'), + map {$_,$_} (1..$currentversion)})); + $r->print(''); my $lastold=1; for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) { my $url=$root.'.'.$prevvers.'.'.$extension; @@ -1952,7 +2487,7 @@ ENDHEADERS $lastold=$prevvers; } } - # + # # Code to figure out how many version entries should go in # each of the four columns my $entries_per_col = 0; @@ -1963,11 +2498,11 @@ ENDHEADERS $entries_per_col = $num_entries/4 + 1; } my $entries_count = 0; - $r->print(''); if ($cols_output != 4) { @@ -1996,7 +2531,7 @@ ENDHEADERS } } $r->print('


'. &Apache::lonnet::gettitle($linkurl). @@ -1921,10 +2456,10 @@ ENDHEADERS 'lastrevisiondate') ). '
Most Recent: '. + 'Most Recent: '. ''.$currentversion.''. - 'In Course: '. + 'In '.$crstype.': '. ''); # Used in course my $usedversion=$hash{'version_'.$linkurl}; @@ -1933,17 +2468,17 @@ ENDHEADERS } else { $r->print($currentversion); } - $r->print(''. - 'Use: '); + $r->print(''. + 'Use: '); # Set version $r->print(&Apache::loncommon::select_form($setversions{$linkurl}, 'set_version_'.$linkurl, - ('select_form_order' => + {'select_form_order' => ['',1..$currentversion,'mostrecent'], '' => '', - 'mostrecent' => 'most recent', - map {$_,$_} (1..$currentversion)))); - $r->print('
'); + $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, @@ -1980,7 +2515,7 @@ ENDHEADERS '&versionone='.$prevvers. '">'.&mt('Diffs').''); } - $r->print('
'); + $r->print('
'); if (++$entries_count % $entries_per_col == 0) { $r->print('
'); - $r->print('

'.&mt('Done').'.

'); + $r->print('

'.&mt('Done').'

'); &untiehash(); } @@ -2028,45 +2563,126 @@ sub changewarning { my ($r,$postexec,$message,$url)=@_; if (!&is_hash_old()) { return; } my $pathvar='folderpath'; - my $path=&Apache::lonnet::escape($env{'form.folderpath'}); + my $path=&escape($env{'form.folderpath'}); if (!defined($url)) { if (defined($env{'form.pagepath'})) { $pathvar='pagepath'; - $path=&Apache::lonnet::escape($env{'form.pagepath'}); - $path.='&pagesymb='.&Apache::lonnet::escape($env{'form.pagesymb'}); + $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". '
'. '

'. +'" />

'. &mt($message,' '). -$help{'Caching'}.'

'."\n\n"); + &mt('re-initializing '.$course_type).'" onclick="reinit(this.form)" />'). +$help{'Caching'}.'

'."\n\n"); +} + + +sub init_breadcrumbs { + my ($form,$text)=@_; + &Apache::lonhtmlcommon::clear_breadcrumbs(); + &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs", + text=>&Apache::loncommon::course_type().' Editor', + faq=>273, + bug=>'Instructor Interface', + help => 'Docs_Adding_Course_Doc'}); + &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?".$form.'=1', + text=>$text, + faq=>273, + bug=>'Instructor Interface'}); +} + +# subroutine to list form elements +sub create_list_elements { + my @formarr = @_; + my $list = ''; + for my $button (@formarr){ + for my $picture(keys %$button) { + $list .= &Apache::lonhtmlcommon::htmltag('li', $picture.' '.$button->{$picture}, {class => 'LC_menubuttons_inline_text'}); + } + } + return $list; +} + +# subroutine to create ul from list elements +sub create_form_ul { + my $list = shift; + my $ul = &Apache::lonhtmlcommon::htmltag('ul',$list, {class => 'LC_ListStyleNormal'}); + return $ul; +} + +# +# Start tabs +# + +sub startContentScreen { + my ($r,$mode)=@_; + $r->print(''); + $r->print('
' + .'
'); + $r->print('
'); +} + +# +# End tabs +# + +sub endContentScreen { + my ($r)=@_; + $r->print('
'); +} + +sub supplemental_base { + return 'supplemental&'.&escape(&mt('Supplemental '.&Apache::loncommon::course_type().' Documents')); } -# ================================================================ 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 $crstype = &Apache::loncommon::course_type(); +# # --------------------------------------------- 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','Adding_Pages', - 'Importing_LON-CAPA_Resource','Uploading_From_Harddrive', - 'Check_Resource_Versions','Verify_Content') { - $help{$_}=&Apache::loncommon::help_open_topic('Docs_'.$_); - } + foreach my $topic ('Adding_Course_Doc','Main_Course_Documents', + 'Adding_External_Resource','Navigate_Content', + 'Adding_Folders','Docs_Overview', 'Load_Map', + 'Supplemental','Score_Upload_Form','Adding_Pages', + 'Importing_LON-CAPA_Resource','Uploading_From_Harddrive', + 'Check_Resource_Versions','Verify_Content') { + $help{$topic}=&Apache::loncommon::help_open_topic('Docs_'.$topic); + } # Composite help files $help{'Syllabus'} = &Apache::loncommon::help_open_topic( 'Docs_About_Syllabus,Docs_Editing_Templated_Pages'); @@ -2076,67 +2692,146 @@ 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().' Documents to Construction Space'); &dumpcourse($r); - } elsif ($env{'form.exportcourse'}) { + } elsif ($allowed && $env{'form.exportcourse'}) { + &init_breadcrumbs('exportcourse','IMS Export'); &exportcourse($r); } else { -# is this a standard course? +# +# Done catching special calls +# The whole rest is for course and supplemental documents +# Get the parameters that may be needed +# + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, + ['folderpath','pagepath', + 'pagesymb','forcesupplement','forcestandard']); + +# standard=1: this is a "new-style" course with an uploaded map as top level +# standard=2: this is a "old-style" course, and there is nothing we can do my $standard=($env{'request.course.uri'}=~/^\/uploaded\//); - my $forcestandard = 0; - my $forcesupplement; + +# Decide whether this should display supplemental or main content +# supplementalflag=1: show supplemental documents +# supplementalflag=0: show standard documents + + + my $supplementalflag=($env{'form.folderpath'}=~/^supplemental/); + if (($env{'form.folderpath'}=~/^default/) || $env{'form.folderpath'} eq "" || ($env{'form.pagepath'})) { + $supplementalflag=0; + } + if ($env{'form.forcesupplement'}) { $supplementalflag=1; } + if ($env{'form.forcestandard'}) { $supplementalflag=0; } + unless ($allowed) { $supplementalflag=1; } + unless ($standard) { $supplementalflag=1; } + my $script=''; - my $allowed; - my $events=''; my $showdoc=0; my $containertag; my $uploadtag; - &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['folderpath','pagepath','pagesymb','markedcopy_url','markedcopy_title']); + +# Where do we store these for when we come back? + my $stored_folderpath='docs_folderpath'; + if ($supplementalflag) { + $stored_folderpath='docs_sup_folderpath'; + } + +# No folderpath, no pagepath, see if we have something stored + if ((!$env{'form.folderpath'}) && (!$env{'form.pagepath'})) { + &Apache::loncommon::restore_course_settings($stored_folderpath, + {'folderpath' => 'scalar'}); + } + +# If we are not allowed to make changes, all we can see are supplemental docs + if (!$allowed) { + $env{'form.pagepath'}=''; + unless ($env{'form.folderpath'} =~ /^supplemental/) { + $env{'form.folderpath'} = &supplemental_base(); + } + } +# If we still not have a folderpath, see if we can resurrect at pagepath + if (!$env{'form.folderpath'} && $allowed) { + &Apache::loncommon::restore_course_settings($stored_folderpath, + {'pagepath' => 'scalar'}); + } +# Make the zeroth entry in supplemental docs page paths, so we can get to top level + if ($env{'form.folderpath'} =~ /^supplemental_\d+/) { + $env{'form.folderpath'} = &supplemental_base() + .'&'. + $env{'form.folderpath'}; + } +# If after all of this, we still don't have any paths, make them + unless (($env{'form.pagepath'}) || ($env{'form.folderpath'})) { + if ($supplementalflag) { + $env{'form.folderpath'}=&supplemental_base(); + } else { + $env{'form.folderpath'}='default'; + } + } + +# Store this + &Apache::loncommon::store_course_settings($stored_folderpath, + {'pagepath' => 'scalar', + 'folderpath' => 'scalar'}); + if ($env{'form.folderpath'}) { my (@folderpath)=split('&',$env{'form.folderpath'}); - $env{'form.foldername'}=&Apache::lonnet::unescape(pop(@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'}=&Apache::lonnet::unescape(pop(@pagepath)); + $env{'form.pagename'}=&unescape(pop(@pagepath)); $env{'form.folder'}=pop(@pagepath); $containertag = ''. - ''; - $uploadtag = ''. - ''; + ''; + $uploadtag = + ''. + ''. + ''; + } else { + my $folderpath=$env{'form.folderpath'}; + if (!$folderpath) { + if ($env{'form.folder'} eq '' || + $env{'form.folder'} eq 'supplemental') { + $folderpath='default&'. + &escape(&mt('Main '.$crstype.' Documents')); + } + } + $containertag = ''; + $uploadtag = ''; } if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) { $showdoc='/'.$1; } - unless ($showdoc) { # got called from remote - if (($env{'form.folder'}=~/^default_/) || - ($env{'form.folder'} =~ m#^\d+/(pages|sequences)/#)) { - $forcestandard = 1; - } - $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 ($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"; -# print screen - my $html=&Apache::lonxml::xmlbegin(); - $r->print(< -The LearningOnline Network with CAPA - -ENDDOCUMENT - if ($allowed) { - $r->print(< + # Breadcrumbs + &Apache::lonhtmlcommon::clear_breadcrumbs(); + unless ($showdoc) { + &Apache::lonhtmlcommon::add_breadcrumb({ + href=>"/adm/coursedocs",text=>"$crstype Contents"}); + + $r->print(&Apache::loncommon::start_page("$crstype Contents", $script, + {'force_register' => $showdoc,}) + .&Apache::loncommon::help_open_menu('','',273,'RAT') + .&Apache::lonhtmlcommon::breadcrumbs( + 'Editing the Table of Contents for your '.$crstype, + 'Docs_Adding_Course_Doc') + ); + } else { + $r->print(&Apache::loncommon::start_page("$crstype documents",undef, + {'force_register' => $showdoc,})); + } + + my %allfiles = (); + my %codebase = (); + my ($upload_result,$upload_output,$uploadphase); + if ($allowed) { + if (($env{'form.uploaddoc.filename'}) && + ($env{'form.cmd'}=~/^upload_(\w+)/)) { + my $context = $1; + # Process file upload - phase one - upload and parse primary file. + undef($hadchanges); + $uploadphase = &process_file_upload(\$upload_output,$coursenum,$coursedom, + \%allfiles,\%codebase,$context); + if ($hadchanges) { + &mark_hash_old(); + } + $r->print($upload_output); + } elsif ($env{'form.phase'} eq 'upload_embedded') { + # Process file upload - phase two - upload embedded objects + $uploadphase = 'check_embedded'; + my $primaryurl = &HTML::Entities::encode($env{'form.primaryurl'},'<>&"'); + my $state = &embedded_form_elems($uploadphase,$primaryurl, + $env{'form.newidx'}); + my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'}; + my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'}; + my ($destination,$dir_root) = &embedded_destination(); + my $url_root = '/uploaded/'.$docudom.'/'.$docuname; + my $actionurl = '/adm/coursedocs'; + my ($result,$flag) = + &Apache::loncommon::upload_embedded('coursedoc',$destination, + $docuname,$docudom,$dir_root,$url_root,undef,undef,undef,$state, + $actionurl); + $r->print($result.&return_to_editor()); + } elsif ($env{'form.phase'} eq 'check_embedded') { + # Process file upload - phase three - modify references in HTML file + $uploadphase = 'modified_orightml'; + my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'}; + my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'}; + my ($destination,$dir_root) = &embedded_destination(); + $r->print(&Apache::loncommon::modify_html_refs('coursedoc',$destination, + $docuname,$docudom,undef, + $dir_root). + &return_to_editor()); + } + } + + unless ($showdoc || $uploadphase) { +# ----------------------------------------------------------------------------- + my %lt=&Apache::lonlocal::texthash( + 'uplm' => 'Upload a new main '.lc($crstype).' document', + 'upls' => 'Upload a new supplemental '.lc($crstype).' document', + 'impp' => 'Import a document', + 'copm' => 'All documents out of a published map into this folder', + 'upld' => 'Import Document', + 'srch' => 'Search', + 'impo' => 'Import', + 'wish' => 'Import from Wishlist', + 'selm' => 'Select Map', + 'load' => 'Load Map', + 'reco' => 'Recover Deleted Documents', + 'newf' => 'New Folder', + 'newp' => 'New Composite Page', + 'extr' => 'External Resource', + 'syll' => 'Syllabus', + 'navc' => 'Table of Contents', + 'sipa' => 'Simple Course Page', + 'sipr' => 'Simple Problem', + 'drbx' => 'Drop Box', + 'scuf' => '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'}? + + --> + +CHBO + + my $fileuploada = " $help{'Uploading_From_Harddrive'}"; + my $fileuploadform=(< + + $fileupload +
+ $lt{'title'}:
+ + $uploadtag + +
+ + $checkbox + +FUFORM + $fileuploadform .= &create_form_ul(&Apache::lonhtmlcommon::htmltag('li',$fileuploada,{class => 'LC_menubuttons_inline_text'})).''; + + my $simpleeditdefaultform=(< + +SEDFFORM + my @simpleeditdefaultforma = ( + { ''.$lt{srch}.'' => "$uploadtag$lt{'srch'}" }, + { ''.$lt{impo}.'' => "$lt{'impo'}$help{'Importing_LON-CAPA_Resource'}" }, + { ''.$lt{wish}.'' => "$lt{'wish'}" }, + ); + $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' + ); + + $r->print(< + + + + + $containertag + +
+ + $uploadtag +
+HIDDENFORM + } + +# Generate the tabs + &startContentScreen($r,($supplementalflag?'supdocs':'docs')); + + +# + + my $savefolderpath; + + if ($allowed) { + my $folder=$env{'form.folder'}; + if ($folder eq '' || $supplementalflag) { + $folder='default'; + $savefolderpath = $env{'form.folderpath'}; + $env{'form.folderpath'}='default&'.&escape(&mt('Content')); + $uploadtag = ''; + } + my $postexec=''; + if ($folder eq 'default') { + $r->print(''."\n" + ); + } else { + #$postexec='self.close();'; + } + my $folderseq='/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time. + '.sequence'; + my $pageseq = '/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time. + '.page'; + my $container='sequence'; + if ($env{'form.pagepath'}) { + $container='page'; + } + my $readfile='/uploaded/'.$coursedom.'/'.$coursenum.'/'.$folder.'.'.$container; + + + + my $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=( + {''.$lt{newp}.''=>$newpageform}, + {''.$lt{syll}.''=>$newsylform}, + {''.$lt{grpo}.''=>$newgroupfileform}, + ); + + my @importdoc = ( + {''.$lt{extr}.''=>$extresourcesform}, + {''.$lt{imsf}.''=>$imspform},); + $fileuploadform = &create_form_ul(&create_list_elements(@importdoc)) . '
' . $fileuploadform; + + push @specialdocumentsforma, ({''.$lt{navc}.''=>$newnavform}, + {''.$lt{sipa}.''=>$newsmppageform}, + {''.$lt{sipr}.''=>$newsmpproblemform}, + {''.$lt{drbx}.''=>$newdropboxform}, + {''.$lt{scuf}.''=>$newexuploadform}, + {''.$lt{bull}.''=>$newbulform}, + {''.$lt{mypi}.''=>$newaboutmeform}, + {''.$lt{abou}.''=>$newaboutsomeoneform}, + {''.$lt{rost}.''=>$newrosterform},); + + $specialdocumentsform = &create_form_ul(&create_list_elements(@specialdocumentsforma)); + } + +if($env{'form.pagepath'}) { + + @specialdocumentsforma=( + {''.&mt('Simple Problem').''=>$newsmpproblemform}, + {''.&mt('Score Upload Form').''=>$newexuploadform} + ); + $specialdocumentsform= &create_form_ul(&create_list_elements(@specialdocumentsforma)); +} + +my @tools = ( +# {''.$lt{extr}.''=>$extresourcesform}, +# {''.$lt{imsf}.''=>$imspform}, + {''.$lt{reco}.''=>$recoverform}, + ); + +my %orderhash = ( + 'aa' => ['Import Documents',$fileuploadform], + 'bb' => ['Published Resources',$simpleeditdefaultform], + 'cc' => ['Special Documents',$specialdocumentsform], + 'dd' => ['Tools', &create_form_ul(&create_list_elements(@tools)).&generate_admin_options(\%help,\%env)], + ); +unless($env{'form.pagepath'}) { + $orderhash{'00'} = ['Newfolder',$newfolderform]; +} + + $hadchanges=0; + unless ($supplementalflag) { + my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype); + if ($error) { + $r->print('

'.$error.'

'); + } + if ($hadchanges) { + &mark_hash_old(); + } + + &changewarning($r,''); + $r->print(&generate_edit_table('1',\%orderhash)); + } + + } + +# Supplemental documents start here + + my $folder=$env{'form.folder'}; + unless ($supplementalflag) { + $folder='supplemental'; + } + if ($folder =~ /^supplemental$/ && + (($env{'form.folderpath'} =~ /^default\&/) || ($env{'form.folderpath'} eq ''))) { + $env{'form.folderpath'} = &supplemental_base(); + } elsif ($allowed) { + $env{'form.folderpath'} = $savefolderpath; + } + $env{'form.pagepath'} = ''; + if ($allowed) { + my $folderseq= + '/uploaded/'.$coursedom.'/'.$coursenum.'/supplemental_'.time. + '.sequence'; + + my $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); + + my $supupdocformbtn = "$help{'Uploading_From_Harddrive'}"; + my $supupdocform=(< + + $fileupload +
+
+ + $checkbox + +

+ $lt{'comment'}:
+ +
+ + +SUPDOCFORM + $supupdocform .= &create_form_ul(&Apache::lonhtmlcommon::htmltag('li',$supupdocformbtn,{class => 'LC_menubuttons_inline_text'})).""; + + my $supnewfolderform=(< + + + + $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 = ( + {''.$lt{syll}.'' + =>$supnewsylform}, + {''.$lt{mypi}.'' + =>$supnewaboutmeform}, + ); +my @supimportdoc = ( + {''.$lt{extr}.'' + =>$supnewextform}, + ); +$supupdocform = &create_form_ul(&create_list_elements(@supimportdoc)) . '
' . $supupdocform; +my %suporderhash = ( + '00' => ['Supnewfolder', $supnewfolderform], + 'ee' => ['Import Documents',$supupdocform], + 'ff' => ['Special Documents',&create_form_ul(&create_list_elements(@specialdocs))] + ); + if ($supplementalflag) { + my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype); + if ($error) { + $r->print('

'.$error.'

'); + } + $r->print(&generate_edit_table('2',\%suporderhash)); + } + } elsif ($supplementalflag) { + my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype); + if ($error) { + $r->print('

'.$error.'

'); + } + } + + &endContentScreen($r); + + if ($allowed) { + $r->print(' +
+ + + + +
'); + } + } else { + unless ($uploadphase) { +# -------------------------------------------------------- This is showdoc mode + $r->print("

".&mt('Uploaded Document').' - '. + &Apache::lonnet::gettitle($r->uri).'

'. +&mt('It is recommended that you use an up-to-date virus scanner before handling this file.')."

". + &entryline(0,&mt("Click to download or use your browser's Save Link function"),$showdoc).'
'); + } + } + } + $r->print(&Apache::loncommon::end_page()); + return OK; +} + +sub embedded_form_elems { + my ($phase,$primaryurl,$newidx) = @_; + my $folderpath = &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); + return < + + + + +STATE +} + +sub embedded_destination { + my $folder=$env{'form.folder'}; + my $destination = 'docs/'; + if ($folder =~ /^supplemental/) { + $destination = 'supplemental/'; + } + if (($folder eq 'default') || ($folder eq 'supplemental')) { + $destination .= 'default/'; + } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) { + $destination .= $2.'/'; + } + $destination .= $env{'form.newidx'}; + my $dir_root = '/userfiles'; + return ($destination,$dir_root); +} + +sub return_to_editor { + my $actionurl = '/adm/coursedocs'; + return '

'."\n". + '
'."\n". + ''.&mt('Return to Editor'). + '

'; +} + +sub generate_admin_options { + my ($help_ref,$env_ref) = @_; + my %lt=&Apache::lonlocal::texthash( + 'vc' => 'Verify Content', + 'cv' => 'Check/Set Resource Versions', + 'ls' => 'List Symbs', + 'sl' => 'Show Log', + 'imse' => 'IMS Export', + 'dcd' => 'Dump Course Documents to Construction Space: available on other servers' + ); + my %help = %{$help_ref}; + my %env = %{$env_ref}; + my $dumpbut=&dumpbutton(); + my $exportbut=&exportbutton(); + my @list = ( + {''.$lt{vc}.'' + => "$lt{'vc'}$help{'Verify_Content'}"}, + {''.$lt{cv}.'' + =>"$lt{'cv'}$help{'Check_Resource_Versions'}"}, + ); + if($dumpbut ne ''){ + push @list, {''.$lt{dcd}.''=>$dumpbut}; + } + push @list, ({''.$lt{imse}.'' + =>$exportbut}, + {''.$lt{ls}.'' + =>"$lt{'ls'}"}, + {''.$lt{sl}.'' + =>"$lt{'sl'}"}, + ); + return '
'.&create_form_ul(&create_list_elements(@list)).'
'; + +} + + +sub generate_edit_table { + my ($tid,$orderhash_ref) = @_; + return unless(ref($orderhash_ref) eq 'HASH'); + my %orderhash = %{$orderhash_ref}; + my $form; + my $activetab; + my $active; + if($env{'form.active'} ne ''){ + $activetab = $env{'form.active'}; + } + $form = '
'; + $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]' + ); + + my $crstype = &Apache::loncommon::course_type(); + my $docs_folderpath = &HTML::Entities::encode($env{'environment.internal.'.$env{'request.course.id'}.'.docs_folderpath.folderpath'},'<>&"'); + my $docs_pagepath = &HTML::Entities::encode($env{'environment.internal.'.$env{'request.course.id'}.'.docs_folderpath.pagepath'},'<>&"'); + my $main_container_page; + if ($docs_folderpath eq '') { + if ($docs_pagepath ne '') { + $main_container_page = 1; + } + } + my $toplevelmain = 'default&Main%20'.$crstype.'%20Documents'; + my $toplevelsupp = &supplemental_base(); + + return < +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(); +} +} -ENDNEWSCRIPT - } -# -------------------------------------------------------------------- Body tag - $r->print(''. - &Apache::loncommon::bodytag('Course Documents','',$events, - '','',$showdoc). - &Apache::loncommon::help_open_menu('','','','',273,'RAT')); - my %allfiles = (); - my %codebase = (); - my ($upload_result,$upload_output); - if ($allowed) { - if (($env{'form.uploaddoc.filename'}) && ($env{'form.cmd'}=~/^upload_(\w+)/)) { -# Process file upload - phase one - upload and parse primary file. - $upload_result = &process_file_upload(\$upload_output,$coursenum, - $coursedom,\%allfiles, - \%codebase,$1); - if ($upload_result eq 'phasetwo') { - $r->print($upload_output); - } - } elsif ($env{'form.phasetwo'}) { - my %newname = (); - my %origname = (); - my %attribs = (); - my $updateflag = 0; - my $residx = $env{'form.newidx'}; - my $primary_url = &Apache::lonnet::unescape($env{'form.primaryurl'}); -# Process file upload - phase two - gather secondary files. - for (my $i=0; $i<$env{'form.phasetwo'}; $i++) { - if ($env{'form.embedded_item_'.$i.'.filename'}) { - my $javacodebase; - $newname{$i} = &process_secondary_uploads(\$upload_output,$coursedom,$coursenum,'embedded_item_',$i,$residx); - $origname{$i} = &Apache::lonnet::unescape($env{'form.embedded_orig_'.$i}); - if (exists($env{'form.embedded_codebase_'.$i})) { - $javacodebase = &Apache::lonnet::unescape($env{'form.embedded_codebase_'.$i}); - $origname{$i} =~ s#^\Q$javacodebase\E/##; - } - my @attributes = (); - if ($env{'form.embedded_attrib_'.$i} =~ /:/) { - @attributes = split/:/,$env{'form.embedded_attrib_'.$i}; - } else { - @attributes = ($env{'form.embedded_attrib_'.$i}); - } - foreach (@attributes) { - push(@{$attribs{$i}},&Apache::lonnet::unescape($_)); - } - if ($javacodebase) { - $codebase{$i} = $javacodebase; - $codebase{$i} =~ s#/$##; - $updateflag = 1; - } - } - unless ($newname{$i} eq $origname{$i}) { - $updateflag = 1; - } - } -# Process file upload - phase three - modify primary file - if ($updateflag) { - my ($content,$rtncode); - my $updateflag = 0; - my $getstatus = &Apache::lonnet::getuploaded('GET',$primary_url,$coursedom,$coursenum,\$content,\$rtncode); - if ($getstatus eq 'ok') { - foreach my $item (keys %newname) { - if ($newname{$item} ne $origname{$item}) { - my $attrib_regexp = ''; - if (@{$attribs{$item}} > 1) { - $attrib_regexp = join('|',@{$attribs{$item}}); - } else { - $attrib_regexp = $attribs{$item}[0]; - } - if ($content =~ m#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#) { - } - $content =~ s#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#$1$newname{$item}$2#gi; - } - if (exists($codebase{$item})) { - $content =~ s/(codebase\s*=\s*["']?)\Q$codebase{$item}\E(["']?)/$1.$2/i; - } - } -# Save edited file. - my $saveresult; - my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'}; - my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'}; - my $url = &Apache::lonnet::store_edited_file($primary_url,$content,$docudom,$docuname,\$saveresult); - } else { - &Apache::lonnet::logthis('retrieval of uploaded file - '.$primary_url.' - for editing, failed: '.$getstatus); - } - } - } - } +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(); +} - unless ($showdoc || $upload_result eq 'phasetwo') { -# ----------------------------------------------------------------------------- - my %lt=&Apache::lonlocal::texthash( - 'uplm' => 'Upload a new main course document', - 'upls' => 'Upload a new supplemental course document', - 'impp' => 'Import a document', - 'pubd' => 'Published documents', - 'copm' => 'All documents out of a published map into this folder', - 'spec' => 'Special documents', - 'upld' => 'Upload Document', - 'srch' => 'Search', - 'impo' => 'Import', - 'selm' => 'Select Map', - 'load' => 'Load Map', - 'reco' => 'Recover Deleted Resources', - 'newf' => 'New Folder', - 'newp' => 'New Composite Page', - 'extr' => 'External Resource', - 'syll' => 'Syllabus', - 'navc' => 'Navigate Contents', - 'sipa' => 'Simple Page', - 'sipr' => 'Simple Problem', - 'scuf' => 'Score Upload Form', - 'bull' => 'Bulletin Board', - 'mypi' => 'My Personal Info', - 'abou' => 'About User', - 'imsf' => 'Import IMS package', - 'file' => 'File', - 'title' => 'Title', - 'comment' => 'Comment', - 'parse' => 'If HTML file, upload embedded images/multimedia files' - ); -# ----------------------------------------------------------------------------- - if ($allowed) { - my $dumpbut=&dumpbutton(); - my $exportbut=&exportbutton(); - my %lt=&Apache::lonlocal::texthash( - 'vc' => 'Verify Content', - 'cv' => 'Check/Set Resource Versions', - ); +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'; + } +} +} - my $folderpath=$env{'form.folderpath'}; - if (!$folderpath) { - if ($env{'form.folder'} eq '' || - $env{'form.folder'} eq 'supplemental') { - $folderpath='default&'. - &Apache::lonnet::escape(&mt('Main Course Documents')); - } - } - unless ($env{'form.pagepath'}) { - $containertag = ''; - $uploadtag = ''; - } +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'; + } +} +} - $r->print(< - - - -$containertag - -
- -$uploadtag -
-
- -
-$help{'Verify_Content'} - - $help{'Check_Resource_Versions'} -$dumpbut -$exportbut -
-
-ENDCOURSEVERIFY - $r->print(&Apache::loncommon::help_open_topic('Docs_Adding_Course_Doc', - &mt('Editing the Table of Contents for your Course'))); - } -# --------------------------------------------------------- Standard documents - $r->print(''); - if (($standard) && ($allowed) && (!$forcesupplement)) { - $r->print(' - - - - - -'."\n". -'
'); -# '

'.&mt('Main Course Documents'). -# ($allowed?' '.$help{'Main_Course_Documents'}:'').'

'); - my $folder=$env{'form.folder'}; - if ($folder eq '' || $folder eq 'supplemental') { - $folder='default'; - $env{'form.folderpath'}='default&'.&Apache::lonnet::escape(&mt('Main Course Documents')); - } - my $postexec=''; - if ($folder eq 'default') { - $r->print(''); - } else { - #$postexec='self.close();'; - } - $hadchanges=0; - &editor($r,$coursenum,$coursedom,$folder,$allowed,$upload_output); - if ($hadchanges) { - &mark_hash_old() - } - &changewarning($r,$postexec); - 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'; +function openTabs(pageId) { + tabnav = document.getElementById(pageId).getElementsByTagName('UL'); + if(tabnav.length > 2 ){ + currentNav = document.getElementById(tabnav[1].id); + currentLis = currentNav.getElementsByTagName('LI'); + for(i = 0; i< currentLis.length; i++){ + if(currentLis[i].className == 'active') { + funcString = currentLis[i].onclick.toString(); + tab = funcString.split('"'); + if(tab.length < 2) { + tab = funcString.split("'"); + } + currentData = document.getElementById(tab[1]); + currentData.style.display = 'block'; + } + } } - my $readfile='/uploaded/'.$coursedom.'/'.$coursenum.'/'.$folder.'.'.$container; - $r->print(<
$lt{'uplm'}$lt{'impp'}$lt{'spec'}
-$lt{'file'}:
-
- -
-$lt{'title'}:
- -$uploadtag - -
- - - -
-
- - - $help{'Uploading_From_Harddrive'} - -
-
-
-$lt{'pubd'}
-$uploadtag - - - -$help{'Importing_LON-CAPA_Resource'} - -

-


-$lt{'copm'}
-
- -$help{'Load_Map'} -

-
-
-
- -
-ENDFORM - unless ($env{'form.pagepath'}) { - $r->print(< -
-$uploadtag - - - $help{'Adding_External_Resource'} - -
-
- - - -
-ENDFORM - } - $r->print('
'); - unless ($env{'form.pagepath'}) { - $r->print(< - - - -$help{'Adding_Folders'} - - -
- - - -$help{'Adding_Pages'} - -
-
-$uploadtag - - - - $help{'Syllabus'} - -
-
-$uploadtag - - - -$help{'Navigate_Content'} - -
-
-$uploadtag - - - $help{'Simple Page'} - -
-
-$uploadtag - - -$help{'Simple Problem'} - -
-
-$uploadtag - - - -$help{'Score_Upload_Form'} - -
-
-$uploadtag - - - -$help{'Bulletin Board'} - -
-
-$uploadtag - - - -$help{'My Personal Info'} - -
-
-$uploadtag - - - - -
-ENDFORM - } - if ($env{'form.pagepath'}) { - $r->print(< -$uploadtag - - -$help{'Simple Problem'} - - -
-$uploadtag - - - -$help{'Score_Upload_Form'} - -
-ENDBLOCK - } - $r->print('
'); - $r->print(''); - } -# ----------------------------------------------------- Supplemental documents - if (!$forcestandard) { - $r->print(''); -# '

'.&mt('Supplemental Course Documents'). -# ($allowed?' '.$help{'Supplemental'}:'').'

'); - my $folder=$env{'form.folder'}; - unless ($folder=~/^supplemental/) { - $folder='supplemental'; - } - if ($folder =~ /^supplemental$/ && - $env{'form.folderpath'} =~ /^default\&/) { - $env{'form.folderpath'}='supplemental&'. - &Apache::lonnet::escape(&mt('Supplemental Course Documents')); - } - &editor($r,$coursenum,$coursedom,$folder,$allowed); - if ($allowed) { - my $folderseq= - '/uploaded/'.$coursedom.'/'.$coursenum.'/supplemental_'.time. - '.sequence'; +} - $r->print(< -$lt{'upls'} -$lt{'spec'} - - -
- -
-
- - - -

-$lt{'comment'}:
- -
- - - - - $help{'Uploading_From_Harddrive'} - -
- - -
- - - - $help{'Adding_Folders'} - -
-
- - - - $help{'Adding_External_Resource'} - -
-
- - - - -$help{'Syllabus'} - -
-
- - - - -$help{'My Personal Info'} - -
- - -ENDSUPFORM - } - } - if ($allowed) { - $r->print('
'); - } - $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(''); - return OK; -} +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'; + if (nav == 'mainnav') { + var storedpath = "$docs_folderpath"; + if (storedpath == '') { + storedpath = "$docs_pagepath"; + } + var storedpage = "$main_container_page"; + var reg = new RegExp("^supplemental"); + if (pageId == 'mainCourseDocuments') { + if (storedpage == 1) { + document.simpleedit.folderpath.value = ''; + document.uploaddocument.folderpath.value = ''; + } else { + if (reg.test(storedpath)) { + document.simpleedit.folderpath.value = '$toplevelmain'; + document.uploaddocument.folderpath.value = '$toplevelmain'; + document.newext.folderpath.value = '$toplevelmain'; + } else { + document.simpleedit.folderpath.value = storedpath; + document.uploaddocument.folderpath.value = storedpath; + document.newext.folderpath.value = storedpath; + } + } + } else { + if (reg.test(storedpath)) { + document.simpleedit.folderpath.value = storedpath; + document.supuploaddocument.folderpath.value = storedpath; + document.supnewext.folderpath.value = storedpath; + } else { + document.simpleedit.folderpath.value = '$toplevelsupp'; + document.supuploaddocument.folderpath.value = '$toplevelsupp'; + document.supnewext.folderpath.value = '$toplevelsupp'; + } + } + } + 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