--- loncom/interface/londocs.pm 2012/11/01 01:01:13 1.502 +++ loncom/interface/londocs.pm 2013/03/13 00:29:09 1.536 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.502 2012/11/01 01:01:13 raeburn Exp $ +# $Id: londocs.pm,v 1.536 2013/03/13 00:29:09 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -40,7 +40,7 @@ use Apache::lonxml; use Apache::lonclonecourse; use Apache::lonnavmaps; use Apache::lonnavdisplay(); -use Apache::lonuserstate(); +use Apache::lonextresedit(); use HTML::Entities; use HTML::TokeParser; use GDBM_File; @@ -152,7 +152,7 @@ sub dumpcourse { $r->print(&endContentScreen()); return ''; } - my ($ca,$cd)=split(/\@/,$env{'form.authorspace'}); + my ($ca,$cd)=split(/\:/,$env{'form.authorspace'}); $r->print('

'.&mt('Copying Files').'

'); my $title=$env{'form.authorfolder'}; $title=&clean($title); @@ -270,7 +270,9 @@ sub dumpcourse { sub group_import { my ($coursenum, $coursedom, $folder, $container, $caller, @files) = @_; - + my ($donechk,$allmaps,%hierarchy,%titles,%addedmaps,%removefrommap, + %removeparam,$importuploaded,$fixuperrors); + $allmaps = {}; while (@files) { my ($name, $url, $residx) = @{ shift(@files) }; if (($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$}) @@ -287,7 +289,7 @@ sub group_import { $env{'form.output'}=$newmapstr; my $result=&Apache::lonnet::finishuserfileupload($coursenum,$coursedom, 'output',$1.$2); - if ($result != m|^/uploaded/|) { + if ($result !~ m{^/uploaded/}) { $errtext.='Map not saved: A network error occurred when trying to save the new map. '; $fatal = 2; } @@ -296,6 +298,24 @@ sub group_import { } } if ($url) { + if (($caller eq 'londocs') && + ($folder =~ /^default/)) { + if (($url =~ /\.(page|sequence)$/) && (!$donechk)) { + my $chome = &Apache::lonnet::homeserver($coursenum,$coursedom); + my $cid = $coursedom.'_'.$coursenum; + $allmaps = + &Apache::loncommon::allmaps_incourse($coursedom,$coursenum, + $chome,$cid); + $donechk = 1; + } + if ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$}) { + &contained_map_check($url,$folder,\%removefrommap,\%removeparam, + \%addedmaps,\%hierarchy,\%titles,$allmaps); + $importuploaded = 1; + } elsif ($url =~ m{^/res/.+\.(page|sequence)$}) { + next if ($allmaps->{$url}); + } + } if (!$residx || defined($LONCAPA::map::zombies[$residx])) { $residx = &LONCAPA::map::getresidx($url,$residx); @@ -305,66 +325,86 @@ sub group_import { if ($url=~m{^http://} || $url=~m{^https://}) { $ext = 'true'; } $url = &LONCAPA::map::qtunescape($url); $name = &LONCAPA::map::qtunescape($name); + if ($name eq '') { + $name = &mt('Web Page'); + } + if ($url =~ m{^/uploaded/$coursedom/$coursenum/((?:docs|supplemental)/(?:default|\d+))/new\.html$}) { + my $filepath = $1; + my $fname = $name; + if ($fname =~ /^\W+$/) { + $fname = 'web'; + } else { + $fname =~ s/\W/_/g; + } + if (length($fname > 15)) { + $fname = substr($fname,0,14); + } + my $initialtext = &mt('Replace with your own content.'); + my $newhtml = < + + + +$name + + +$initialtext + + +END + $env{'form.output'}=$newhtml; + my $result = + &Apache::lonnet::finishuserfileupload($coursenum,$coursedom, + 'output', + "$filepath/$residx/$fname.html"); + if ($result =~ m{^/uploaded/}) { + $url = $result; + if ($filepath =~ /^supplemental/) { + $name = time.'___&&&___'.$env{'user.name'}.'___&&&___'. + $env{'user.domain'}.'___&&&___'.$name; + } + } else { + return (&mt('Failed to save new web page.'),1); + } + } $LONCAPA::map::resources[$residx] = join(':', ($name, $url, $ext, 'normal', 'res')); } } - return &storemap($coursenum, $coursedom, $folder.'.'.$container,1); -} - -sub breadcrumbs { - my ($allowed,$crstype)=@_; - &Apache::lonhtmlcommon::clear_breadcrumbs(); - my (@folders); - if ($env{'form.pagepath'}) { - @folders = split('&',$env{'form.pagepath'}); - } else { - @folders=split('&',$env{'form.folderpath'}); - } - my $folderpath; - my $plain=''; - my $randompick=-1; - my $isencrypted=0; - my $ishidden=0; - my $is_random_order=0; - while (@folders) { - my $folder=shift(@folders); - my $foldername=shift(@folders); - if ($folderpath) {$folderpath.='&';} - $folderpath.=$folder.'&'.$foldername; - my $url; - if ($allowed) { - $url = '/adm/coursedocs?folderpath='; - } else { - $url = '/adm/supplemental?folderpath='; - } - $url .= &escape($folderpath); - my $name=&unescape($foldername); -# randompick number, hidden, encrypted, random order, is appended with ":"s to the foldername - $name=~s/\:(\d*)\:(\w*)\:(\w*):(\d*)$//; - if ($1 ne '') { - $randompick=$1; - } else { - $randompick=-1; - } - if ($2) { $ishidden=1; } - if ($3) { $isencrypted=1; } - if ($4 ne '') { $is_random_order = 1; } - if ($folder eq 'supplemental') { - $name = &mt('Supplemental '.$crstype.' Content'); - } - &Apache::lonhtmlcommon::add_breadcrumb( - {'href'=>$url, - 'title'=>$name, - 'text'=>$name, - 'no_mt'=>1, - }); - $plain.=$name.' > '; - } - $plain=~s/\>\;\s*$//; - return (&Apache::lonhtmlcommon::breadcrumbs(undef,undef,0,'nohelp', - undef, undef, 1 ),$randompick,$ishidden, - $isencrypted,$plain,$is_random_order); + if ($importuploaded) { + my %import_errors; + my %updated = ( + removefrommap => \%removefrommap, + removeparam => \%removeparam, + ); + my ($result,$msgsarray,$lockerror) = + &apply_fixups($folder,1,$coursedom,$coursenum,\%import_errors,\%updated); + if (keys(%import_errors) > 0) { + $fixuperrors = + '

'."\n". + &mt('The following files are either dependencies of a web page or references within a folder and/or composite page for which errors occurred during import:')."\n". + '

'."\n"; + } + if (ref($msgsarray) eq 'ARRAY') { + if (@{$msgsarray} > 0) { + $fixuperrors .= '

'. + join('
',@{$msgsarray}). + '

'; + } + } + if ($lockerror) { + $fixuperrors .= '

'. + $lockerror. + '

'; + } + } + my ($errtext,$fatal) = + &storemap($coursenum, $coursedom, $folder.'.'.$container,1); + return ($errtext,$fatal,$fixuperrors); } sub log_docs { @@ -445,17 +485,15 @@ sub docs_change_log { my %orderhash; my $container='sequence'; my $pathitem; - if ($env{'form.pagepath'}) { + if ($env{'form.folderpath'} =~ /\:1$/) { $container='page'; - $pathitem = ''; - } else { - my $folderpath=$env{'form.folderpath'}; - if ($folderpath eq '') { - $folderpath = 'default&'.&escape(&mt('Main '.$crstype.' Documents')); - } - $pathitem = ''; } + my $folderpath=$env{'form.folderpath'}; + if ($folderpath eq '') { + $folderpath = 'default&'.&escape(&mt('Main '.$crstype.' Documents').':::::'); + } + $pathitem = ''; my $readfile="/uploaded/$coursedom/$coursenum/$folder.$container"; my $jumpto = $readfile; $jumpto =~ s{^/}{}; @@ -463,7 +501,8 @@ sub docs_change_log { if ($supplementalflag) { $tid = 2; } - my ($breadcrumbtrail) = &breadcrumbs($allowed,$crstype); + my ($breadcrumbtrail) = + &Apache::lonhtmlcommon::docs_breadcrumbs($allowed,$crstype,1); $r->print($breadcrumbtrail. &generate_edit_table($tid,\%orderhash,undef,$iconpath,$jumpto, $readfile)); @@ -706,7 +745,7 @@ sub print_paste_buffer { $is_external = 1; } - my ($canpaste,$nopaste,$othercrs,$areachange,$is_uploaded_map); + my ($canpaste,$nopaste,$othercrs,$areachange); if ($folder =~ /^supplemental/) { $canpaste = &supp_pasteable($env{'docs.markedcopy_url'}); unless ($canpaste) { @@ -751,7 +790,7 @@ sub print_paste_buffer { $buffer = $type.': '. &LONCAPA::map::qtescape($env{'docs.markedcopy_title'}).' ('. &LONCAPA::map::qtescape($env{'docs.markedcopy_url'}).')'; - } else { + } else { my $icon = &Apache::loncommon::icon($extension); if ($extension eq 'sequence' && $env{'docs.markedcopy_url'} =~ m{/default_\d+\.sequence$ }x) { @@ -763,19 +802,36 @@ sub print_paste_buffer { } if ($canpaste) { $r->print('
'.$buffer); - if (($is_uploaded_map) && (!$areachange)) { - if ((!$othercourse) && ($env{'docs.markedcopy_cmd'} eq 'cut')) { + if ((!$areachange) && (!$othercourse) && + ($env{'docs.markedcopy_cmd'} eq 'cut')) { + if (($is_uploaded_map) || + ($env{'docs.markedcopy_url'} =~ /(bulletinboard|smppg)$/) || + ($env{'docs.markedcopy_url'} =~ m{^/uploaded/$coursedom/$coursenum/(?:docs|supplemental)/(.+)$})) { + my ($copytext,$movetext); + if ($is_uploaded_map) { + $copytext = &mt('Copy to new folder'); + $movetext = &mt('Move old folder'); + } elsif ($env{'docs.markedcopy_url'} =~ /bulletinboard$/) { + $copytext = &mt('Copy to new bulletin board (not posts)'); + $movetext = &mt('Move old bulletin board (not posts)'); + } elsif ($env{'docs.markedcopy_url'} =~ /smppg$/) { + $copytext = &mt('Copy to new simple page'); + $movetext = &mt('Move old simple page'); + } else { + $copytext = &mt('Copy to new uploaded document'); + $movetext = &mt('Move old uploaded document'); + } $r->print((' 'x 4).''. ''. &mt('Show Paste Options').'
'. '
'.(' 'x 4). ''.(' ' x2). + $copytext.''.(' ' x2). '
'); - if ($env{'docs.markedcopy_nested'}) { + $movetext.'
'); + if (($is_uploaded_map) && ($env{'docs.markedcopy_nested'})) { $r->print('
'.&mt('Folder to paste contains sub-folders'). '
'); my @pastemaps = split(/\&/,$env{'docs.markedcopy_nested'}); @@ -813,16 +869,9 @@ sub print_paste_buffer { } } $r->print('
'.$othercrs); - if ($container eq 'page') { - $r->print(' - - -'); - } else { - $r->print(' + $r->print(' '); - } $r->print(''); } else { $r->print(&mt('Paste buffer contains:').' '.$buffer. @@ -957,30 +1006,23 @@ sub do_paste_from_buffer { %dbcopies,%zombies,%params,%docmoves,%mapmoves,%newsubdir,%newurls); $oldurl = $url; if ($is_map) { - if ($folder =~ /^default/) { - my $lastchange = &Apache::lonnet::get_coursechange($coursedom,$coursenum); - if ($lastchange > $env{'request.course.tied'}) { - &reinit_role($coursedom,$coursenum,$env{"course.$env{'request.course.id'}.home"}); - } - } # If pasting a map, check if map contains other maps - my (%allmaps,%hierarchy,%titles); + my ($allmaps,%hierarchy,%titles); + $allmaps = {}; if ($folder =~ /^default/) { - my $navmap = Apache::lonnavmaps::navmap->new(); - if (defined($navmap)) { - foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_map() },1,0,1)) { - $allmaps{$res->src()} = 1; - } - } + $allmaps = + &Apache::loncommon::allmaps_incourse($coursedom,$coursenum, + $env{"course.$env{'request.course.id'}.home"}, + $env{'request.course.id'}); } &contained_map_check($url,$folder,\%removefrommap,\%removeparam, - \%addedmaps,\%hierarchy,\%titles,\%allmaps); + \%addedmaps,\%hierarchy,\%titles,$allmaps); if ($url=~ m{^/uploaded/}) { my $newurl; unless ($env{'form.docs.markedcopy_options'} eq 'move') { ($newurl,my $error) = &get_newmap_url($url,$folder,$prefixchg,$coursedom,$coursenum, - $srcdom,$srcnum,\$title,\%allmaps,\%newurls); + $srcdom,$srcnum,\$title,$allmaps,\%newurls); if ($error) { return ($error); } @@ -995,15 +1037,17 @@ sub do_paste_from_buffer { } if (($srcdom ne $coursedom) || ($srcnum ne $coursenum) || ($prefixchg) || (($newurl ne '') && ($newurl ne $url))) { - unless (&url_paste_fixups($url,$folder,$prefixchg,$coursedom,$coursenum, - \%allmaps,\%rewrites,\%retitles,\%copies,\%dbcopies, + unless (&url_paste_fixups($url,$folder,$prefixchg,$coursedom, + $coursenum,$srcdom,$srcnum,$allmaps, + \%rewrites,\%retitles,\%copies,\%dbcopies, \%zombies,\%params,\%mapmoves,\%mapchanges,\%tomove, \%newsubdir,\%newurls)) { $mapmoves{$url} = 1; } $url = $newurl; } elsif ($env{'docs.markedcopy_nested'}) { - &url_paste_fixups($url,$folder,$prefixchg,$coursedom,$coursenum,\%allmaps,\%rewrites, + &url_paste_fixups($url,$folder,$prefixchg,$coursedom,$coursenum, + $srcdom,$srcnum,$allmaps,\%rewrites, \%retitles,\%copies,\%dbcopies,\%zombies,\%params,\%mapmoves, \%mapchanges,\%tomove,\%newsubdir,\%newurls); } @@ -1012,28 +1056,40 @@ sub do_paste_from_buffer { &Apache::lonnet::delenv('docs.markedcopy'); # if pasting published map (main content are only) check map is not already in course if ($folder =~ /^default/) { - if ($allmaps{$url}) { + if ((ref($allmaps) eq 'HASH') && ($allmaps->{$url})) { return (&mt('Paste failed: only one instance of a particular published sequence or page is allowed within each course.')); } } } } - if ($url=~ m{/smppg$}) { - my $db_name = &Apache::lonsimplepage::get_db_name($url); - if ($db_name =~ /^smppage_/) { - #simple pages, need to copy the db contents to a new one. - my %contents=&Apache::lonnet::dump($db_name,$coursedom,$coursenum); - my $now = time(); - $db_name =~ s{_\d*$ }{_$now}x; - my $dbresult=&Apache::lonnet::put($db_name,\%contents, - $coursedom,$coursenum); - if ($dbresult eq 'ok') { - $url =~ s{/(\d*)/smppg$ }{/$now/smppg}x; + my $lockerrors; + if ($url=~ m{/(bulletinboard|smppg)$}) { + my $prefix = $1; + #need to copy the db contents to a new one, unless this is a move. + my %info = ( + src => $url, + cdom => $coursedom, + cnum => $coursenum, + ); + my (%lockerr,$msg); + unless ($env{'form.docs.markedcopy_options'} eq 'move') { + my ($newurl,$result,$errtext) = + &dbcopy(\%info,$coursedom,$coursenum,\%lockerr); + if ($result eq 'ok') { + $url = $newurl; $title=&mt('Copy of').' '.$title; } else { - return (&mt('Paste failed: An error occurred when copying the simple page.')); + if ($prefix eq 'smppg') { + $msg = &mt('Paste failed: An error occurred when copying the simple page.').' '.$errtext; + } elsif ($prefix eq 'bulletinboard') { + $msg = &mt('Paste failed: An error occurred when copying the bulletin board.').' '.$errtext; + } + return ($result,undef,[$msg],$lockerr{$prefix}); + } + if ($lockerr{$prefix}) { + $lockerrors = $lockerr{$prefix}; } - } + } } $title = &LONCAPA::map::qtunescape($title); my $ext='false'; @@ -1060,7 +1116,9 @@ sub do_paste_from_buffer { if ($newdocsdir eq '') { $newdocsdir = 'default'; } - if (($prefixchg) || ($srcdom ne $coursedom) || ($srcnum ne $coursenum)) { + if (($prefixchg) || + ($srcdom ne $coursedom) || ($srcnum ne $coursenum) || + ($env{'form.docs.markedcopy_options'} ne 'move')) { my $newpath = "$newprefix/$newdocsdir/$newidx/$rem"; $url = &Apache::lonclonecourse::writefile($env{'request.course.id'},$newpath, @@ -1078,16 +1136,34 @@ sub do_paste_from_buffer { } # Apply any changes to maps, or copy dependencies for uploaded HTML pages my ($result,$save_err); - $result = - &apply_fixups($folder,$is_map,$prefixchg,$coursedom,$coursenum,$oldurl, - $url,\%removefrommap,\%removeparam,\%rewrites,\%retitles, - \%copies,\%dbcopies,\%zombies,\%params,\%docmoves, - \%mapmoves,\%newsubdir,$errors,\%before,\%after); + my %updated = ( + rewrites => \%rewrites, + zombies => \%zombies, + removefrommap => \%removefrommap, + removeparam => \%removeparam, + dbcopies => \%dbcopies, + retitles => \%retitles, + ); + my %info = ( + newsubdir => \%newsubdir, + params => \%params, + before => \%before, + after => \%after, + ); + my %moves = ( + copies => \%copies, + docmoves => \%docmoves, + mapmoves => \%mapmoves, + ); + ($result,my $msgsarray,my $lockerror) = + &apply_fixups($folder,$is_map,$coursedom,$coursenum,$errors, + \%updated,\%info,\%moves,$prefixchg,$oldurl,$url,'paste'); + $lockerrors .= $lockerror; if ($result eq 'ok') { if ($is_map) { my ($errtext,$fatal) = &mapread($coursenum,$coursedom, $folder.'.'.$container); - return $errtext if ($fatal); + return ($errtext,$save_err,$msgsarray,$lockerrors) if ($fatal); if ($#LONCAPA::map::order<1) { my $idx=&LONCAPA::map::getresidx(); @@ -1118,13 +1194,13 @@ sub do_paste_from_buffer { $save_err = $errtext; } } - + if ($env{'form.docs.markedcopy_options'} eq 'move') { &Apache::lonnet::delenv('docs.markedcopy'); &Apache::lonnet::delenv('docs.markedcopy_nested'); &Apache::lonnet::delenv('docs.markedcopy_nestednames'); } - return ($result,$save_err); + return ($result,$save_err,$msgsarray,$lockerrors); } sub get_newmap_url { @@ -1188,20 +1264,96 @@ sub get_newmap_url { } sub dbcopy { - my ($url,$coursedom,$coursenum) = @_; - if ($url=~ m{/smppg$}) { - my $db_name = &Apache::lonsimplepage::get_db_name($url); - if ($db_name =~ /^smppage_/) { - #simple pages, need to copy the db contents to a new one. - my %contents=&Apache::lonnet::dump($db_name,$coursedom,$coursenum); - my $now = time(); - $db_name =~ s{_\d*$ }{_$now}x; - my $result=&Apache::lonnet::put($db_name,\%contents, - $coursedom,$coursenum); - $url =~ s{/(\d*)/smppg$ }{/$now/smppg}x; + my ($dbref,$coursedom,$coursenum,$lockerrorsref) = @_; + my ($url,$result,$errtext); + my $url = $dbref->{'src'}; + if (ref($dbref) eq 'HASH') { + if ($url =~ m{/(smppg|bulletinboard)$}) { + my $prefix = $1; + if (($dbref->{'cdom'} =~ /^$match_domain$/) && + ($dbref->{'cnum'} =~ /^$match_courseid$/)) { + my $db_name; + my $marker = (split(m{/},$url))[4]; + $marker=~s/\D//g; + if ($dbref->{'src'} =~ m{/smppg$}) { + $db_name = + &Apache::lonsimplepage::get_db_name($url,$marker, + $dbref->{'cdom'}, + $dbref->{'cnum'}); + } else { + $db_name = 'bulletinpage_'.$marker; + } + my ($suffix,$freedlock,$error) = + &Apache::lonnet::get_timebased_id($prefix,'num','templated', + $coursedom,$coursenum, + 'concat'); + if (!$suffix) { + if ($prefix eq 'smppg') { + $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a simple page [_1].',$url); + } else { + $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a bulletin board [_1].',$url); + } + if ($error) { + $errtext .= '
'.$error; + } + } else { + #need to copy the db contents to a new one. + my %contents=&Apache::lonnet::dump($db_name, + $dbref->{'cdom'}, + $dbref->{'cnum'}); + if (exists($contents{'uploaded.photourl'})) { + my $photo = $contents{'uploaded.photourl'}; + my ($subdir,$fname) = + ($photo =~ m{^/uploaded/$match_domain/$match_courseid/+(bulletin|simplepage)/(?:|\d+/)([^/]+)$}); + my $newphoto; + if ($fname ne '') { + my $content = &Apache::lonnet::getfile($photo); + unless ($content eq '-1') { + $env{'form.'.$suffix.'.photourl'} = $content; + $newphoto = + &Apache::lonnet::finishuserfileupload($coursenum,$coursedom,$suffix.'.photourl',"$subdir/$suffix/$fname"); + delete($env{'form.'.$suffix.'.photourl'}); + } + } + if ($newphoto =~ m{^/uploaded/}) { + $contents{'uploaded.photourl'} = $newphoto; + } + } + $db_name =~ s{_\d*$ }{_$suffix}x; + $result=&Apache::lonnet::put($db_name,\%contents, + $coursedom,$coursenum); + if ($result eq 'ok') { + $url =~ s{/(\d*)/(smppg|bulletinboard)$}{/$suffix/$2}x; + } + } + if (($freedlock ne 'ok') && (ref($lockerrorsref) eq 'HASH')) { + $lockerrorsref->{$prefix} = + '
'. + &mt('There was a problem removing a lockfile.'); + if ($prefix eq 'smppg') { + $lockerrorsref->{$prefix} .= + &mt('This will prevent creation of additional simple pages in this course.'); + } else { + $lockerrorsref->{$prefix} .= &mt('This will prevent creation of additional bulletin boards in this course.'); + } + $lockerrorsref->{$prefix} .= &mt('Please contact the domain coordinator for your LON-CAPA domain.').'
'; + } + } + } elsif ($url =~ m{/syllabus$}) { + if (($dbref->{'cdom'} =~ /^$match_domain$/) && + ($dbref->{'cnum'} =~ /^$match_courseid$/)) { + if (($dbref->{'cdom'} ne $coursedom) || + ($dbref->{'cnum'} ne $coursenum)) { + my %contents=&Apache::lonnet::dump('syllabus', + $dbref->{'cdom'}, + $dbref->{'cnum'}); + $result=&Apache::lonnet::put('syllabus',\%contents, + $coursedom,$coursenum); + } + } } } - return $url; + return ($url,$result,$errtext); } sub uniqueness_check { @@ -1242,7 +1394,7 @@ sub contained_map_check { $titles->{$url}{$token->[2]->{'id'}} = $token->[2]->{'title'}; } else { if ($allmaps->{$ressrc}) { - $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc; + $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc; } elsif (ref($addedmaps->{$ressrc}) eq 'ARRAY') { $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc; } else { @@ -1266,18 +1418,10 @@ sub contained_map_check { return; } -sub reinit_role { - my ($cdom,$cnum,$chome) = @_; - my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum"); - unless ($ferr) { - &Apache::loncommon::update_content_constraints($cdom,$cnum,$chome,$cdom.'_'.$cnum); - } - return; -} - sub url_paste_fixups { - my ($oldurl,$folder,$prefixchg,$cdom,$cnum,$allmaps,$rewrites,$retitles,$copies, - $dbcopies,$zombies,$params,$mapmoves,$mapchanges,$tomove,$newsubdir,$newurls) = @_; + my ($oldurl,$folder,$prefixchg,$cdom,$cnum,$fromcdom,$fromcnum,$allmaps, + $rewrites,$retitles,$copies,$dbcopies,$zombies,$params,$mapmoves, + $mapchanges,$tomove,$newsubdir,$newurls) = @_; my $checktitle; if (($prefixchg) && ($oldurl =~ m{^/uploaded/$match_domain/$match_courseid/supplemental})) { @@ -1304,13 +1448,13 @@ sub url_paste_fixups { my $title = $token->[2]->{'title'}; if ($checktitle) { if ($title =~ m{\d+\Q___&&&___\E$match_username\Q___&&&___\E$match_domain\Q___&&&___\E(.+)$}) { - $retitles->{$oldurl}{$ressrc} = $id; + $retitles->{$oldurl}{$id} = $ressrc; } } next if ($token->[2]->{'type'} eq 'external'); if ($token->[2]->{'type'} eq 'zombie') { next if ($skip); - $zombies->{$oldurl}{$ressrc} = $id; + $zombies->{$oldurl}{$id} = $ressrc; $changed = 1; } elsif ($ressrc =~ m{^/uploaded/($match_domain)/($match_courseid)/(.+)$}) { my $srcdom = $1; @@ -1322,10 +1466,11 @@ sub url_paste_fixups { my $prefix = $1; $mapname = $prefix.$2; if ($tomove->{$mapname}) { - &url_paste_fixups($ressrc,$folder,$prefixchg,$cdom,$cnum,$allmaps, - $rewrites,$retitles,$copies,$dbcopies,$zombies, - $params,$mapmoves,$mapchanges,$tomove,$newsubdir, - $newurls); + &url_paste_fixups($ressrc,$folder,$prefixchg,$cdom,$cnum, + $srcdom,$srcnum,$allmaps,$rewrites, + $retitles,$copies,$dbcopies,$zombies, + $params,$mapmoves,$mapchanges,$tomove, + $newsubdir,$newurls); next; } else { ($newurl,my $error) = @@ -1343,28 +1488,39 @@ sub url_paste_fixups { ($mapchanges->{$oldurl}) || (($newurl ne '') && ($newurl ne $oldurl))) { if ($rem =~ /^(default|supplemental)(_?\d*).(sequence|page)$/) { - $rewrites->{$oldurl}{$ressrc} = $id; + $rewrites->{$oldurl}{$id} = $ressrc; $mapchanges->{$ressrc} = 1; - unless (&url_paste_fixups($ressrc,$folder,$prefixchg,$cdom,$cnum,$allmaps, - $rewrites,$retitles,$copies,$dbcopies,$zombies, - $params,$mapmoves,$mapchanges,$tomove,$newsubdir, - $newurls)) { + unless (&url_paste_fixups($ressrc,$folder,$prefixchg,$cdom, + $cnum,$srcdom,$srcnum,$allmaps, + $rewrites,$retitles,$copies,$dbcopies, + $zombies,$params,$mapmoves,$mapchanges, + $tomove,$newsubdir,$newurls)) { $mapmoves->{$ressrc} = 1; } $changed = 1; } else { - $rewrites->{$oldurl}{$ressrc} = $id; + $rewrites->{$oldurl}{$id} = $ressrc; $copies->{$oldurl}{$ressrc} = $id; $changed = 1; } } - } elsif ($ressrc =~ m{^/adm/($match_domain)/($match_courseid)/(.+)$}) { - next if ($skip); + } elsif ($ressrc =~ m{^/adm/($match_domain)/($match_courseid)/.+$}) { + next if ($skip); my $srcdom = $1; my $srcnum = $2; if (($srcdom ne $cdom) || ($srcnum ne $cnum)) { - $rewrites->{$oldurl}{$ressrc} = $id; - $dbcopies->{$oldurl}{$ressrc} = $id; + $rewrites->{$oldurl}{$id} = $ressrc; + $dbcopies->{$oldurl}{$id}{'src'} = $ressrc; + $dbcopies->{$oldurl}{$id}{'cdom'} = $srcdom; + $dbcopies->{$oldurl}{$id}{'cnum'} = $srcnum; + $changed = 1; + } + } elsif ($ressrc =~ m{^/adm/$match_domain/$match_username/\d+/(smppg|bulletinboard)$}) { + if (($fromcdom ne $cdom) || ($fromcnum ne $cnum) || + ($env{'form.docs.markedcopy_options'} ne 'move')) { + $dbcopies->{$oldurl}{$id}{'src'} = $ressrc; + $dbcopies->{$oldurl}{$id}{'cdom'} = $fromcdom; + $dbcopies->{$oldurl}{$id}{'cnum'} = $fromcnum; $changed = 1; } } elsif ($ressrc =~ m{^/public/($match_domain)/($match_courseid)/(.+)$}) { @@ -1372,8 +1528,9 @@ sub url_paste_fixups { my $srcdom = $1; my $srcnum = $2; if (($srcdom ne $cdom) || ($srcnum ne $cnum)) { - $rewrites->{$oldurl}{$ressrc} = $id; - $dbcopies->{$oldurl}{$ressrc} = $id; + $dbcopies->{$oldurl}{$id}{'src'} = $ressrc; + $dbcopies->{$oldurl}{$id}{'cdom'} = $srcdom; + $dbcopies->{$oldurl}{$id}{'cnum'} = $srcnum; $changed = 1; } } @@ -1393,24 +1550,73 @@ sub url_paste_fixups { } sub apply_fixups { - my ($folder,$is_map,$prefixchg,$cdom,$cnum,$oldurl,$url,$removefrommap, - $removeparam,$rewrites,$retitles,$copies,$dbcopies,$zombies,$params, - $docmoves,$mapmoves,$newsubdir,$errors,$before,$after) = @_; - foreach my $key (keys(%{$copies}),keys(%{$docmoves})) { + my ($folder,$is_map,$cdom,$cnum,$errors,$updated,$info,$moves,$prefixchg, + $oldurl,$url,$caller) = @_; + my (%rewrites,%zombies,%removefrommap,%removeparam,%dbcopies,%retitles, + %params,%newsubdir,%before,%after,%copies,%docmoves,%mapmoves,@msgs, + %lockerrors,$lockmsg); + if (ref($updated) eq 'HASH') { + if (ref($updated->{'rewrites'}) eq 'HASH') { + %rewrites = %{$updated->{'rewrites'}}; + } + if (ref($updated->{'zombies'}) eq 'HASH') { + %zombies = %{$updated->{'zombies'}}; + } + if (ref($updated->{'removefrommap'}) eq 'HASH') { + %removefrommap = %{$updated->{'removefrommap'}}; + } + if (ref($updated->{'removeparam'}) eq 'HASH') { + %removeparam = %{$updated->{'removeparam'}}; + } + if (ref($updated->{'dbcopies'}) eq 'HASH') { + %dbcopies = %{$updated->{'dbcopies'}}; + } + if (ref($updated->{'retitles'}) eq 'HASH') { + %retitles = %{$updated->{'retitles'}}; + } + } + if (ref($info) eq 'HASH') { + if (ref($info->{'newsubdir'}) eq 'HASH') { + %newsubdir = %{$info->{'newsubdir'}}; + } + if (ref($info->{'params'}) eq 'HASH') { + %params = %{$info->{'params'}}; + } + if (ref($info->{'before'}) eq 'HASH') { + %before = %{$info->{'before'}}; + } + if (ref($info->{'after'}) eq 'HASH') { + %after = %{$info->{'after'}}; + } + } + if (ref($moves) eq 'HASH') { + if (ref($moves->{'copies'}) eq 'HASH') { + %copies = %{$moves->{'copies'}}; + } + if (ref($moves->{'docmoves'}) eq 'HASH') { + %docmoves = %{$moves->{'docmoves'}}; + } + if (ref($moves->{'mapmoves'}) eq 'HASH') { + %mapmoves = %{$moves->{'mapmoves'}}; + } + } + foreach my $key (keys(%copies),keys(%docmoves)) { my @allcopies; - if (ref($copies->{$key}) eq 'HASH') { - my %added; - foreach my $innerkey (keys(%{$copies->{$key}})) { - if (($innerkey ne '') && (!$added{$innerkey})) { - push(@allcopies,$innerkey); - $added{$innerkey} = 1; + if (exists($copies{$key})) { + if (ref($copies{$key}) eq 'HASH') { + my %added; + foreach my $innerkey (keys(%{$copies{$key}})) { + if (($innerkey ne '') && (!$added{$innerkey})) { + push(@allcopies,$innerkey); + $added{$innerkey} = 1; + } } + undef(%added); } - undef(%added); } if ($key eq $oldurl) { - if ((exists($docmoves->{$key}))) { - unless (grep(/^\Q$oldurl\E/,@allcopies)) { + if ((exists($docmoves{$key}))) { + unless (grep(/^\Q$oldurl\E$/,@allcopies)) { push(@allcopies,$oldurl); } } @@ -1423,16 +1629,16 @@ sub apply_fixups { my $content = &Apache::lonnet::getfile($item); unless ($content eq '-1') { my $storefn; - if (($key eq $oldurl) && (ref($docmoves) eq 'HASH') && (exists($docmoves->{$key}))) { - $storefn = $docmoves->{$key}; + if (($key eq $oldurl) && (exists($docmoves{$key}))) { + $storefn = $docmoves{$key}; } else { $storefn = $relpath; $storefn =~s{^/uploaded/$match_domain/$match_courseid/}{}; - if ($prefixchg) { - $storefn =~ s/^\Q$before->{'doc'}\E/$after->{'doc'}/; + if ($prefixchg && $before{'doc'} && $after{'doc'}) { + $storefn =~ s/^\Q$before{'doc'}\E/$after{'doc'}/; } - if ($newsubdir->{$key}) { - $storefn =~ s#^(docs|supplemental)/\Q$oldsubdir\E/#$1/$newsubdir->{$key}#; + if ($newsubdir{$key}) { + $storefn =~ s#^(docs|supplemental)/\Q$oldsubdir\E/#$1/$newsubdir{$key}/#; } } ©_dependencies($item,$storefn,$relpath,$errors,\$content); @@ -1440,7 +1646,7 @@ sub apply_fixups { &Apache::lonclonecourse::writefile($env{'request.course.id'}, $storefn.$fname,$content); if ($copyurl eq '/adm/notfound.html') { - if ((ref($docmoves) eq 'HASH') && (exists($docmoves->{$oldurl}))) { + if (exists($docmoves{$oldurl})) { return &mt('Paste failed: an error occurred copying the file.'); } elsif (ref($errors) eq 'HASH') { $errors->{$item} = 1; @@ -1451,14 +1657,14 @@ sub apply_fixups { } } } - foreach my $key (keys(%{$mapmoves})) { + foreach my $key (keys(%mapmoves)) { my $storefn=$key; $storefn=~s{^/uploaded/$match_domain/$match_courseid/}{}; - if ($prefixchg) { - $storefn =~ s/^\Q$before->{'map'}\E/$after->{'map'}/; + if ($prefixchg && $before{'map'} && $after{'map'}) { + $storefn =~ s/^\Q$before{'map'}\E/$after{'map'}/; } - if ($newsubdir->{$key}) { - $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir->{$key}/; + if ($newsubdir{$key}) { + $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/; } my $mapcontent = &Apache::lonnet::getfile($key); if ($mapcontent eq '-1') { @@ -1478,105 +1684,106 @@ sub apply_fixups { } my %updates; if ($is_map) { - foreach my $key (keys(%{$rewrites})) { - $updates{$key} = 1; - } - foreach my $key (keys(%{$zombies})) { - $updates{$key} = 1; - } - foreach my $key (keys(%{$removefrommap})) { - $updates{$key} = 1; - } - foreach my $key (keys(%{$removeparam})) { - $updates{$key} = 1; - } - foreach my $key (keys(%{$dbcopies})) { - $updates{$key} = 1; - } - foreach my $key (keys(%{$retitles})) { - $updates{$key} = 1; + if (ref($updated) eq 'HASH') { + foreach my $type (keys(%{$updated})) { + if (ref($updated->{$type}) eq 'HASH') { + foreach my $key (keys(%{$updated->{$type}})) { + $updates{$key} = 1; + } + } + } } foreach my $key (keys(%updates)) { my (%torewrite,%toretitle,%toremove,%remparam,%currparam,%zombie,%newdb); - if (ref($rewrites->{$key}) eq 'HASH') { - %torewrite = %{$rewrites->{$key}}; - } - if (ref($retitles->{$key}) eq 'HASH') { - %toretitle = %{$retitles->{$key}}; - } - if (ref($removefrommap->{$key}) eq 'HASH') { - %toremove = %{$removefrommap->{$key}}; + if (ref($rewrites{$key}) eq 'HASH') { + %torewrite = %{$rewrites{$key}}; } - if (ref($removeparam->{$key}) eq 'HASH') { - %remparam = %{$removeparam->{$key}}; + if (ref($retitles{$key}) eq 'HASH') { + %toretitle = %{$retitles{$key}}; } - if (ref($zombies->{$key}) eq 'HASH') { - %zombie = %{$zombies->{$key}}; + if (ref($removefrommap{$key}) eq 'HASH') { + %toremove = %{$removefrommap{$key}}; } - if (ref($dbcopies->{$key}) eq 'HASH') { - foreach my $item (keys(%{$dbcopies->{$key}})) { - $newdb{$item} = &dbcopy($item); + if (ref($removeparam{$key}) eq 'HASH') { + %remparam = %{$removeparam{$key}}; + } + if (ref($zombies{$key}) eq 'HASH') { + %zombie = %{$zombies{$key}}; + } + if (ref($dbcopies{$key}) eq 'HASH') { + foreach my $idx (keys(%{$dbcopies{$key}})) { + if (ref($dbcopies{$key}{$idx}) eq 'HASH') { + my ($newurl,$result,$errtext) = + &dbcopy($dbcopies{$key}{$idx},$cdom,$cnum,\%lockerrors); + if ($result eq 'ok') { + $newdb{$idx} = $newurl; + } elsif (ref($errors) eq 'HASH') { + $errors->{$key} = 1; + } + push(@msgs,$errtext); + } } } - if (ref($params->{$key}) eq 'HASH') { - %currparam = %{$params->{$key}}; + if (ref($params{$key}) eq 'HASH') { + %currparam = %{$params{$key}}; } my ($errtext,$fatal) = &LONCAPA::map::mapread($key); if ($fatal) { - return $errtext; + return ($errtext); } for (my $i=0; $i<@LONCAPA::map::zombies; $i++) { if (defined($LONCAPA::map::zombies[$i])) { my ($title,$src,$ext,$type)=split(/\:/,$LONCAPA::map::zombies[$i]); - if ($zombie{$src} eq $i) { + if ($zombie{$i} eq $src) { undef($LONCAPA::map::zombies[$i]); } } } - for (my $i=0; $i<@LONCAPA::map::resources; $i++) { - if (defined($LONCAPA::map::resources[$i])) { + for (my $i=0; $i<@LONCAPA::map::order; $i++) { + my $idx = $LONCAPA::map::order[$i]; + if (defined($LONCAPA::map::resources[$idx])) { my $changed; - my ($title,$src,$ext,$type)=split(/\:/,$LONCAPA::map::resources[$i]); - if ($toremove{$src} eq $i) { + my ($title,$src,$ext,$type)=split(/\:/,$LONCAPA::map::resources[$idx]); + if ((exists($toremove{$idx})) && ($toremove{$idx} eq $src)) { splice(@LONCAPA::map::order,$i,1); - if (ref($currparam{$i}) eq 'ARRAY') { - foreach my $name (@{$currparam{$i}}) { - &LONCAPA::map::delparameter($i,'parameter_'.$name); + if (ref($currparam{$idx}) eq 'ARRAY') { + foreach my $name (@{$currparam{$idx}}) { + &LONCAPA::map::delparameter($idx,'parameter_'.$name); } } next; } my $origsrc = $src; - if ((exists($toretitle{$src})) && ($toretitle{$src} eq $i)) { + if ((exists($toretitle{$idx})) && ($toretitle{$idx} eq $src)) { if ($title =~ m{^\d+\Q___&&&___\E$match_username\Q___&&&___\E$match_domain\Q___&&&___\E(.+)$}) { $changed = 1; } } - if ((exists($torewrite{$src})) && ($torewrite{$src} eq $i)) { + if ((exists($torewrite{$idx})) && ($torewrite{$idx} eq $src)) { $src =~ s{^/(uploaded|adm|public)/$match_domain/$match_courseid/}{/$1/$cdom/$cnum/}; if ($origsrc =~ m{^/uploaded/}) { - if ($prefixchg) { + if ($prefixchg && $before{'map'} && $after{'map'}) { if ($src =~ /\.(page|sequence)$/) { - $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before->{'map'}\E#$1$after->{'map'}#; + $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before{'map'}\E#$1$after{'map'}#; } else { - $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before->{'doc'}\E#$1$after->{'doc'}#; + $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before{'doc'}\E#$1$after{'doc'}#; } } - if ($newsubdir->{$origsrc}) { - if ($src =~ /\.(page|sequence)$/) { - $src =~ s#^(/uploaded/$match_domain/$match_courseid/(?:default|supplemental)_)(\d+)#$1$newsubdir->{$origsrc}#; - } else { - $src =~ s#^(/uploaded/$match_domain/$match_courseid/\w+/)(\d+)#$1$newsubdir->{$origsrc}#; + if ($origsrc =~ /\.(page|sequence)$/) { + if ($newsubdir{$origsrc}) { + $src =~ s#^(/uploaded/$match_domain/$match_courseid/(?:default|supplemental)_)(\d+)#$1$newsubdir{$origsrc}#; } + } elsif ($newsubdir{$key}) { + $src =~ s#^(/uploaded/$match_domain/$match_courseid/\w+/)(\d+)#$1$newsubdir{$key}#; } } $changed = 1; - } elsif ($newdb{$src} ne '') { - $src = $newdb{$src}; + } elsif ($newdb{$idx} ne '') { + $src = $newdb{$idx}; $changed = 1; } if ($changed) { - $LONCAPA::map::resources[$i] = join(':',($title,$src,$ext,$type)); + $LONCAPA::map::resources[$idx] = join(':',($title,$src,$ext,$type)); } } } @@ -1587,6 +1794,9 @@ sub apply_fixups { } } } + if (values(%lockerrors) > 0) { + $lockmsg = join('
',values(%lockerrors)); + } my $storefn; if ($key eq $oldurl) { $storefn = $url; @@ -1594,25 +1804,27 @@ sub apply_fixups { } else { $storefn = $key; $storefn=~s{^/uploaded/$match_domain/$match_courseid/}{}; - if ($prefixchg) { - $storefn =~ s/^\Q$before->{'map'}\E/$after->{'map'}/; + if ($prefixchg && $before{'map'} && $after{'map'}) { + $storefn =~ s/^\Q$before{'map'}\E/$after{'map'}/; } - if ($newsubdir->{$key}) { - $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir->{$key}/; + if ($newsubdir{$key}) { + $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/; } } my $report; if ($folder !~ /^supplemental/) { $report = 1; } - my ($outtext,$errtext) = + (my $outtext,$errtext) = &LONCAPA::map::storemap("/uploaded/$cdom/$cnum/$storefn",1,$report); if ($errtext) { - return &mt('Paste failed: an error occurred saving the folder or page.'); + if ($caller eq 'paste') { + return (&mt('Paste failed: an error occurred saving the folder or page.')); + } } } } - return 'ok'; + return ('ok',\@msgs,$lockmsg); } sub copy_dependencies { @@ -1743,15 +1955,24 @@ sub handle_edit_cmd { sub editor { my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$crstype, - $supplementalflag,$orderhash,$iconpath,$uploadtag)=@_; - my $container= ($env{'form.pagepath'}) ? 'page' - : 'sequence'; - - my ($breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,$is_random_order) = - &breadcrumbs($allowed,$crstype); - $r->print($breadcrumbtrail); + $supplementalflag,$orderhash,$iconpath,$pathitem)=@_; + my ($randompick,$ishidden,$isencrypted,$plain,$is_random_order,$container); + if ($allowed) { + (my $breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain, + $is_random_order,$container) = + &Apache::lonhtmlcommon::docs_breadcrumbs($allowed,$crstype,1); + $r->print($breadcrumbtrail); + } elsif ($env{'form.folderpath'} =~ /\:1$/) { + $container = 'page'; + } else { + $container = 'sequence'; + } - my $jumpto = "uploaded/$coursedom/$coursenum/$folder.$container"; + my $jumpto; + + unless ($supplementalflag) { + $jumpto = "'uploaded/$coursedom/$coursenum/$folder.$container'"; + } unless ($allowed) { $randompick = -1; @@ -1791,9 +2012,22 @@ sub editor { if ($env{'form.pastemarked'}) { my %paste_errors; - my ($paste_res,$save_error) = + my ($paste_res,$save_error,$pastemsgarray,$lockerror) = &do_paste_from_buffer($coursenum,$coursedom,$folder,$container, \%paste_errors); + if (ref($pastemsgarray) eq 'ARRAY') { + if (@{$pastemsgarray} > 0) { + + $r->print('

'. + join('
',@{$pastemsgarray}). + '

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

'. + $lockerror. + '

'); + } if ($save_error ne '') { return $save_error; } @@ -1827,13 +2061,57 @@ sub editor { foreach my $item (split(/\&/,$env{'form.importdetail'})) { if (defined($item)) { my ($name,$url,$residx)= - map {&unescape($_)} split(/\=/,$item); + map { &unescape($_); } split(/\=/,$item); + if ($url =~ m{^\Q/uploaded/$coursedom/$coursenum/\E(default|supplemental)_new\.(sequence|page)$}) { + my ($suffix,$errortxt,$locknotfreed) = + &new_timebased_suffix($coursedom,$coursenum,'map',$1,$2); + if ($locknotfreed) { + $r->print($locknotfreed); + } + if ($suffix) { + $url =~ s/_new\./_$suffix./; + } else { + return $errortxt; + } + } elsif ($url =~ m{^/adm/$match_domain/$match_username/new/(smppg|bulletinboard)$}) { + my $type = $1; + my ($suffix,$errortxt,$locknotfreed) = + &new_timebased_suffix($coursedom,$coursenum,$type); + if ($locknotfreed) { + $r->print($locknotfreed); + } + if ($suffix) { + $url =~ s{^(/adm/$match_domain/$match_username)/new}{$1/$suffix}; + } else { + return $errortxt; + } + } elsif ($url =~ m{^/uploaded/$coursedom/$coursenum/(docs|supplemental)/(default|\d+)/new.html$}) { + if ($supplementalflag) { + next unless ($1 eq 'supplemental'); + if ($folder eq 'supplemental') { + next unless ($2 eq 'default'); + } else { + next unless ($folder eq 'supplemental_'.$2); + } + } else { + next unless ($1 eq 'docs'); + if ($folder eq 'default') { + next unless ($2 eq 'default'); + } else { + next unless ($folder eq 'default_'.$2); + } + } + } push(@imports, [$name, $url, $residx]); } } - ($errtext,$fatal)=&group_import($coursenum, $coursedom, $folder, - $container,'londocs',@imports); + ($errtext,$fatal,my $fixuperrors) = + &group_import($coursenum, $coursedom, $folder,$container, + 'londocs',@imports); return $errtext if ($fatal); + if ($fixuperrors) { + $r->print($fixuperrors); + } } # Loading a complete map if ($env{'form.loadmap'}) { @@ -1900,35 +2178,67 @@ sub editor { unless ($name) { $idx++; next; } $output .= &entryline($idx,$name,$url,$folder,$allowed,$res, $coursenum,$coursedom,$crstype, - $uploadtag,$supplementalflag); + $pathitem,$supplementalflag,$container); $idx++; $shown++; } &Apache::loncommon::end_data_table_count(); - - if ($shown) { - $to_show = &Apache::loncommon::start_scrollbox('900px','880px','400px','contentscroll') - .&Apache::loncommon::start_data_table(undef,'contentlist'); - if ($allowed) { - $to_show .= &Apache::loncommon::start_data_table_header_row() - .'' - .'' - .''; - if ($folder !~ /^supplemental/) { - $to_show .= ''; + + if (($allowed) || ($supplementalflag && $folder eq 'supplemental')) { + my $toolslink = '
'.&mt('Move').''.&mt('Actions').''.&mt('Document').''.&mt('Settings').'
' + .'
' + .&Apache::loncommon::help_open_menu('Navigation Screen', + 'Navigation_Screen',undef,'RAT') + .''.&mt('Tools:').'

'; + if ($shown) { + if ($allowed) { + $to_show = &Apache::loncommon::start_scrollbox('900px','880px','400px','contentscroll') + .&Apache::loncommon::start_data_table(undef,'contentlist') + .&Apache::loncommon::start_data_table_header_row() + .''.&mt('Move').'' + .''.&mt('Actions').'' + .''.&mt('Document').''; + if ($folder !~ /^supplemental/) { + $to_show .= ''.&mt('Settings').''; + } + $to_show .= &Apache::loncommon::end_data_table_header_row() + .$output.' ' + .&Apache::loncommon::end_data_table() + .'
' + .&Apache::loncommon::end_scrollbox(); + } else { + $to_show .= $toolslink + .&Apache::loncommon::start_data_table('LC_tableOfContent') + .$output.' ' + .&Apache::loncommon::end_data_table(); + } + } else { + if (!$allowed) { + $to_show .= $toolslink; } - $to_show .= &Apache::loncommon::end_data_table_header_row(); + $to_show .= &Apache::loncommon::start_scrollbox('400px','380px','200px','contentscroll') + .'
' + .&mt('Currently no documents.') + .'
' + .&Apache::loncommon::end_scrollbox(); } - $to_show .= $output.' ' - .&Apache::loncommon::end_data_table() - .'
' - .&Apache::loncommon::end_scrollbox(); } else { - $to_show .= &Apache::loncommon::start_scrollbox('400px','380px','200px','contentscroll') - .'
' - .&mt('Currently no documents.') - .'
' - .&Apache::loncommon::end_scrollbox(); + if ($shown) { + $to_show = '
' + .&Apache::loncommon::start_data_table('LC_tableOfContent') + .$output + .&Apache::loncommon::end_data_table() + .'
'; + } else { + $to_show = '
' + .&mt('Currently no documents.') + .'
' + } } my $tid = 1; if ($supplementalflag) { @@ -1940,19 +2250,6 @@ sub editor { $readfile)); &print_paste_buffer($r,$container,$folder,$coursedom,$coursenum); } else { - if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) { - #Function Box for Supplemental Content for users with mdc priv. - my $funcname = &mt('Folder Editor'); - $r->print( - &Apache::loncommon::head_subbox( - &Apache::lonhtmlcommon::start_funclist(). - &Apache::lonhtmlcommon::add_item_funclist( - ''. - ''.$funcname.''. - ''.$funcname.''). - &Apache::lonhtmlcommon::end_funclist())); - } $r->print($to_show); } return; @@ -1973,19 +2270,15 @@ sub process_file_upload { my $errtext=''; my $fatal=0; my $container='sequence'; - if ($env{'form.pagepath'}) { + if ($env{'form.folderpath'} =~ /:1$/) { $container='page'; } ($errtext,$fatal)= - &mapread($coursenum,$coursedom,$folder.'.'.$container); + &mapread($coursenum,$coursedom,$folder.'.'.$container); if ($#LONCAPA::map::order<1) { $LONCAPA::map::order[0]=1; $LONCAPA::map::resources[1]=''; } - if ($fatal) { - $$upload_output = '
'.&mt('The uploaded file has not been stored as an error occurred reading the contents of the current folder.').'
'; - return; - } my $destination = 'docs/'; if ($folder =~ /^supplemental/) { $destination = 'supplemental/'; @@ -1995,6 +2288,10 @@ sub process_file_upload { } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) { $destination .= $2.'/'; } + if ($fatal) { + $$upload_output = '
'.&mt('The uploaded file has not been stored as an error occurred reading the contents of the current folder.').'
'; + return; + } # this is for a course, not a user, so set context to coursedoc. my $newidx=&LONCAPA::map::getresidx(); $destination .= $newidx; @@ -2063,7 +2360,6 @@ sub process_file_upload { my $archiveurl = &HTML::Entities::encode($url,'<>&"'); my %archiveitems = ( folderpath => $env{'form.folderpath'}, - pagepath => $env{'form.pagepath'}, cmd => $nextphase, newidx => $newidx, position => $position, @@ -2118,16 +2414,14 @@ sub is_supplemental_title { sub entryline { my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$coursedom, - $crstype,$uploadtag,$supplementalflag)=@_; - my ($foldertitle,$pagetitle,$renametitle); + $crstype,$pathitem,$supplementalflag,$container)=@_; + my ($foldertitle,$renametitle); if (&is_supplemental_title($title)) { ($title,$foldertitle,$renametitle) = &Apache::loncommon::parse_supplemental_title($title); - $pagetitle = $foldertitle; } else { $title=&HTML::Entities::encode($title,'"<>&\''); $renametitle=$title; $foldertitle=$title; - $pagetitle=$title; } my $orderidx=$LONCAPA::map::order[$index]; @@ -2138,30 +2432,29 @@ sub entryline { my $line=&Apache::loncommon::start_data_table_row(); my ($form_start,$form_end,$form_common); # Edit commands - my ($container, $type, $esc_path, $path, $symb); + my ($esc_path, $path, $symb); if ($env{'form.folderpath'}) { - $type = 'folder'; - $container = 'sequence'; $esc_path=&escape($env{'form.folderpath'}); $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); # $htmlfoldername=&HTML::Entities::encode($env{'form.foldername'},'<>&"'); } - if ($env{'form.pagepath'}) { - $type = $container = 'page'; - $esc_path=&escape($env{'form.pagepath'}); - $path = &HTML::Entities::encode($env{'form.pagepath'},'<>&"'); - } - if (!$supplementalflag && $residx) { + my $isexternal; + if ($residx) { my $currurl = $url; $currurl =~ s{^http(|s)(:|:)//}{/adm/wrapper/ext/}; - my $path = 'uploaded/'. - $env{'course.'.$env{'request.course.id'}.'.domain'}.'/'. - $env{'course.'.$env{'request.course.id'}.'.num'}.'/'; - $symb = &Apache::lonnet::encode_symb($path.$folder.".$container", - $residx, - &Apache::lonnet::declutter($currurl)); + if ($currurl =~ m{^/adm/wrapper/ext/}) { + $isexternal = 1; + } + if (!$supplementalflag) { + my $path = 'uploaded/'. + $env{'course.'.$env{'request.course.id'}.'.domain'}.'/'. + $env{'course.'.$env{'request.course.id'}.'.num'}.'/'; + $symb = &Apache::lonnet::encode_symb($path.$folder.".$container", + $residx, + &Apache::lonnet::declutter($currurl)); + } } - my %lt; + my ($renamelink,%lt); if ($allowed) { my $incindex=$index+1; my $selectbox=''; @@ -2258,10 +2551,7 @@ sub entryline { $nocopy=1; } } - my $copylink=' '; - my $cutlink=' '; - my $removelink=' '; - + my ($copylink,$cutlink,$removelink); my $skip_confirm = 0; if ( $folder =~ /^supplemental/ || ($url =~ m{( /smppg$ @@ -2269,32 +2559,49 @@ sub entryline { |/aboutme$ |/navmaps$ |/bulletinboard$ - |\.html$ - |^/adm/wrapper/ext)}x)) { + |\.html$)}x) + || $isexternal) { $skip_confirm = 1; } - if (!$nocopy) { + if ($nocopy) { + $copylink=(<$lt{'cp'} +ENDCOPY + } else { $copylink=(<$lt{'cp'} +$lt{'cp'} ENDCOPY } - if (!$nocut) { + if ($nocut) { + $cutlink=(<$lt{'ct'} +ENDCUT + } else { $cutlink=(<$lt{'ct'} +$lt{'ct'} ENDCUT } - if (!$noremove) { + if ($noremove) { $removelink=(<$lt{'rm'} +$lt{'rm'} ENDREM + } else { + $removelink=(<$lt{'rm'} +ENDREM + } + unless ($isexternal) { + $renamelink=(<$lt{'rn'} +ENDREN } $form_start = '
'; $form_common=(< - + + END @@ -2302,12 +2609,12 @@ END $line.=(<
- + $lt{'up'}
- + $lt{'dw'}
@@ -2318,11 +2625,11 @@ END $selectbox $form_end - + $removelink $cutlink - $lt{'rn'} $copylink + END @@ -2331,22 +2638,18 @@ END my ($extension)=($url=~/\.(\w+)$/); my $uploaded=($url=~/^\/*uploaded\//); my $icon=&Apache::loncommon::icon($url); - my $isfolder=0; - my $ispage=0; - my $folderarg; - my $pagearg; - my $pagefile; + my $isfolder; + my $ispage; + my $containerarg; if ($uploaded) { if (($extension eq 'sequence') || ($extension eq 'page')) { $url=~/\Q$coursenum\E\/([\/\w]+)\.\Q$extension\E$/; - my $containerarg = $1; + $containerarg = $1; if ($extension eq 'sequence') { $icon=$iconpath.'navmap.folder.closed.gif'; - $folderarg=$containerarg; $isfolder=1; } else { $icon=$iconpath.'page.gif'; - $pagearg=$containerarg; $ispage=1; } if ($allowed) { @@ -2359,15 +2662,11 @@ END } } - my $editlink; + my ($editlink,$extresform); my $orig_url = $url; $orig_url=~s{http(:|:)//https(:|:)//}{https$2//}; - my $external = ($url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/}); + $url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/}; if (!$supplementalflag && $residx && $symb) { - if ($container eq 'page') { - $url=&Apache::lonnet::clutter((&Apache::lonnet::decode_symb($symb))[2]); - $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb); - } if ((!$isfolder) && (!$ispage)) { (undef,undef,$url)=&Apache::lonnet::decode_symb($symb); $url=&Apache::lonnet::clutter($url); @@ -2383,7 +2682,6 @@ END } } elsif ($url=~m|^/ext/|) { $url='/adm/wrapper'.$url; - $external = 1; } if (&Apache::lonnet::symbverify($symb,$url)) { $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb); @@ -2393,101 +2691,93 @@ END } } my ($rand_pick_text,$rand_order_text); - if ($isfolder || $extension eq 'sequence') { + if ($isfolder || $ispage || $extension eq 'sequence' || $extension eq 'page') { my $foldername=&escape($foldertitle); my $folderpath=$env{'form.folderpath'}; if ($folderpath) { $folderpath.='&' }; + if (!$allowed && $supplementalflag) { + $folderpath.=$containerarg.'&'.$foldername; + $url.='folderpath='.&escape($folderpath); + } else { # Append randompick number, hidden, and encrypted with ":" to foldername, # so it gets transferred between levels - $folderpath.=$folderarg.'&'.$foldername.':'.(&LONCAPA::map::getparameter($orderidx, + $folderpath.=$containerarg.'&'.$foldername. + ':'.(&LONCAPA::map::getparameter($orderidx, 'parameter_randompick'))[0] .':'.((&LONCAPA::map::getparameter($orderidx, 'parameter_hiddenresource'))[0]=~/^yes$/i) .':'.((&LONCAPA::map::getparameter($orderidx, 'parameter_encrypturl'))[0]=~/^yes$/i) .':'.((&LONCAPA::map::getparameter($orderidx, - 'parameter_randomorder'))[0]=~/^yes$/i); - $url.='folderpath='.&escape($folderpath); - my $rpicknum = (&LONCAPA::map::getparameter($orderidx, - 'parameter_randompick'))[0]; - my $rpckchk; - if ($rpicknum) { - $rpckchk = ' checked="checked"'; - } - my $formname = 'edit_rpick_'.$orderidx; - $rand_pick_text = + 'parameter_randomorder'))[0]=~/^yes$/i) + .':'.$ispage; + $url.='folderpath='.&escape($folderpath); + my $rpicknum = (&LONCAPA::map::getparameter($orderidx, + 'parameter_randompick'))[0]; + my $rpckchk; + if ($rpicknum) { + $rpckchk = ' checked="checked"'; + } + my $formname = 'edit_rpick_'.$orderidx; + $rand_pick_text = ''."\n". $form_common."\n". ''; - if ($rpicknum ne '') { - $rand_pick_text .= ': '.$rpicknum.''; - } - $rand_pick_text .= ''; - my $ro_set= - ((&LONCAPA::map::getparameter($orderidx,'parameter_randomorder'))[0]=~/^yes$/i?' checked="checked"':''); - $rand_order_text = + if ($rpicknum ne '') { + $rand_pick_text .= ': '.$rpicknum.''; + } + $rand_pick_text .= '
'; + my $ro_set= + ((&LONCAPA::map::getparameter($orderidx,'parameter_randomorder'))[0]=~/^yes$/i?' checked="checked"':''); + $rand_order_text = $form_start. $form_common.' '; + } + } elsif ($supplementalflag && !$allowed) { + $url .= ($url =~ /\?/) ? '&':'?'; + $url .= 'folderpath='.&HTML::Entities::encode($esc_path,'<>&"'); + if ($title) { + $url .= '&title='.&HTML::Entities::encode($renametitle,'<>&"'); + } + if ($isexternal && $orderidx) { + $url .= '&idx='.$orderidx; + } } - if ($ispage) { - my $pagename=&escape($pagetitle); - my $pagepath; - my $folderpath=$env{'form.folderpath'}; - if ($folderpath) { $pagepath = $folderpath.'&' }; - $pagepath.=$pagearg.'&'.$pagename; - $url.='pagepath='.&escape($pagepath). - '&pagesymb='.&escape($symb); - } + my ($tdalign,$tdwidth); if ($allowed) { my $fileloc = &Apache::lonnet::declutter(&Apache::lonnet::filelocation('',$orig_url)); - - if ($external) { - $editlink = <<"EXTLNK"; -   - - $lt{'ed'} -
- -
-EXTLNK - } else { - my ($cfile,$home,$switchserver,$uploaded) = - &Apache::lonnet::can_edit_resource($fileloc,$coursenum,$coursedom); - if (($cfile ne '') && ($symb ne '')) { + if ($isexternal) { + ($editlink,$extresform) = + &Apache::lonextresedit::extedit_form(0,$residx,$orig_url,$title,$pathitem); + } elsif (!$isfolder && !$ispage) { + my ($cfile,$home,$switchserver,$forceedit,$forceview) = + &Apache::lonnet::can_edit_resource($fileloc,$coursenum,$coursedom,$orig_url); + if (($cfile ne '') && ($symb ne '' || $supplementalflag)) { my $jscall = &Apache::lonhtmlcommon::jump_to_editres($cfile,$home, $switchserver, - $uploaded,$symb); + $forceedit, + undef,$symb, + &escape($env{'form.folderpath'}), + $renametitle,'','',1); if ($jscall) { - $editlink = ' '.&mt('Edit').''; + $editlink = ''.&mt('Edit').' '."\n"; } } } + $tdalign = ' align="right" valign="top"'; + $tdwidth = ' width="80%"'; } my $reinit; if ($crstype eq 'Community') { $reinit = &mt('(re-initialize community to access)'); } else { $reinit = &mt('(re-initialize course to access)'); - } - $line.=''; + } + $line.=''.$editlink.$renamelink; if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) { $line.=''; } elsif ($url) { @@ -2496,7 +2786,7 @@ EXTLNK } else { $line.=''; } - $line.=''; + $line.=''; if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) { $line.=''.$title.''; } elsif ($url) { @@ -2505,7 +2795,7 @@ EXTLNK } else { $line.=$title.' '.$reinit.''; } - $line.=$editlink.""; + $line.="$extresform"; $rand_pick_text = ' ' if ($rand_pick_text eq ''); $rand_order_text = ' ' if ($rand_order_text eq ''); if (($allowed) && ($folder!~/^supplemental/)) { @@ -2536,6 +2826,56 @@ ENDPARMS return $line; } +sub new_timebased_suffix { + my ($coursedom,$coursenum,$type,$area,$container) = @_; + my ($prefix,$namespace,$idtype,$errtext,$locknotfreed); + if ($type eq 'map') { + $prefix = 'docs'; + if ($area eq 'supplemental') { + $prefix = 'supp'; + } + $prefix .= $container; + $namespace = 'uploadedmaps'; + } else { + $prefix = $type; + $namespace = 'templated'; + } + $idtype = 'concat'; + my ($suffix,$freedlock,$error) = + &Apache::lonnet::get_timebased_id($prefix,'num',$namespace, + $coursedom,$coursenum); + if (!$suffix) { + if ($type eq 'map') { + $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new folder/page.'); + } elsif ($type eq 'smppg') { + $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new simple page.'); + } else { + $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new bulletin board.'); + } + if ($error) { + $errtext .= '
'.$error; + } + } + if ($freedlock ne 'ok') { + $locknotfreed = + '
'. + &mt('There was a problem removing a lockfile.').' '; + if ($type eq 'map') { + &mt('This will prevent creation of additional folders or composite pages in this course.'); + } elsif ($type eq 'smppg') { + $locknotfreed .= + &mt('This will prevent creation of additional simple pages in this course.'); + } else { + $locknotfreed .= + &mt('This will prevent creation of additional bulletin boards in this course.'); + } + $locknotfreed .= + ' '.&mt('Please contact the domain coordinator for your LON-CAPA domain.'). + '
'; + } + return ($suffix,$errtext,$locknotfreed); +} + =pod =item tiehash() @@ -2631,7 +2971,7 @@ sub checkonthis { $r->print(''.&mt('connection down').''); } elsif ($result eq 'not_found') { unless ($url=~/\$/) { - $r->print(''.&mt('not found').''); + $r->print(''.&mt('not found').''); } else { $r->print(''.&mt('unable to verify variable URL').''); } @@ -2677,7 +3017,7 @@ sub list_symbs { $r->print(&Apache::loncommon::start_data_table_row(). ''.$res->compTitle().''. ''.$res->symb().''. - &Apache::loncommon::start_data_table_row()); + &Apache::loncommon::end_data_table_row()); $count ++; } if (!$count) { @@ -2687,6 +3027,7 @@ sub list_symbs { } $r->print(&Apache::loncommon::end_data_table()); } + $r->print(&endContentScreen()); } @@ -2717,6 +3058,7 @@ sub verifycontent { } &untiehash(); $r->print('

'.&mt('Done').'

'); + $r->print(&endContentScreen()); } @@ -2796,7 +3138,7 @@ sub checkversions { if ($env{'form.timerange'} eq 'all') { # show all documents $header=&mt('All Documents in '.$crstype); - $allsel=1; + $allsel=' selected="selected"'; foreach my $key (keys(%hash)) { if ($key=~/^ids\_(\/res\/.+)$/) { my $src=$1; @@ -2817,19 +3159,19 @@ sub checkversions { .&mt('seconds'); if ($env{'form.timerange'}==-1) { $seltext='since start of course'; - $startsel='selected'; + $startsel=' selected="selected"'; $env{'form.timerange'}=time; } $starttime=time-$env{'form.timerange'}; if ($env{'form.timerange'}==2592000) { $seltext=&mt('during the last month').' ('.&Apache::lonlocal::locallocaltime($starttime).')'; - $monthsel='selected'; + $monthsel=' selected="selected"'; } elsif ($env{'form.timerange'}==604800) { $seltext=&mt('during the last week').' ('.&Apache::lonlocal::locallocaltime($starttime).')'; - $weeksel='selected'; + $weeksel=' selected="selected"'; } elsif ($env{'form.timerange'}==86400) { $seltext=&mt('since yesterday').' ('.&Apache::lonlocal::locallocaltime($starttime).')'; - $daysel='selected'; + $daysel=' selected="selected"'; } $header=&mt('Content changed').' '.$seltext; } else { @@ -2867,11 +3209,11 @@ sub checkversions {
$lt{'cd'}
@@ -2887,111 +3229,93 @@ $lt{'sc'}: - ENDHEADERS #number of columns for version history - my $num_ver_col = 1; $r->print( - &Apache::loncommon::start_data_table(). - &Apache::loncommon::start_data_table_header_row(). - ''. - "". - "". - "". - ''. - ''); + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + ''. + "". + "". + "". + ''. + &Apache::loncommon::end_data_table_header_row() + ); foreach my $key (sort(keys(%changes))) { #excludes not versionable problems from resource version history: - if ($changes{$key}>$starttime && $key !~ /^\/res\/lib\/templates/) { - my ($root,$extension)=($key=~/^(.*)\.(\w+)$/); - my $currentversion=&Apache::lonnet::getversion($key); - if ($currentversion<0) { - $currentversion=''.&mt('Could not be determined.').''; - } - my $linkurl=&Apache::lonnet::clutter($key); + next unless ($changes{$key}>$starttime && $key !~ /^\/res\/lib\/templates/); + my ($root,$extension)=($key=~/^(.*)\.(\w+)$/); + my $currentversion=&Apache::lonnet::getversion($key); + if ($currentversion<0) { + $currentversion=''.&mt('Could not be determined.').''; + } + my $linkurl=&Apache::lonnet::clutter($key); $r->print( - &Apache::loncommon::end_data_table_header_row(). &Apache::loncommon::start_data_table_row(). - ''. - ''. - ''); - if ($cols_output != $num_ver_col) { - $r->print(''); + # List all available versions + $r->print(''.&Apache::loncommon::end_data_table_row()); } - $r->print(''.&Apache::loncommon::end_data_table_row(). - &Apache::loncommon::end_data_table(). - ''); + $r->print( + &Apache::loncommon::end_data_table(). + ''. + '' + ); &untiehash(); + $r->print(&endContentScreen()); } sub mark_hash_old { @@ -3023,11 +3347,6 @@ sub changewarning { my $pathvar='folderpath'; my $path=&escape($env{'form.folderpath'}); if (!defined($url)) { - if (defined($env{'form.pagepath'})) { - $pathvar='pagepath'; - $path=&escape($env{'form.pagepath'}); - $path.='&pagesymb='.&escape($env{'form.pagesymb'}); - } $url='/adm/coursedocs?'.$pathvar.'='.$path; } my $course_type = &Apache::loncommon::course_type(); @@ -3158,8 +3477,9 @@ sub handler { 'Docs_About_My_Personal_Info,Docs_Editing_Templated_Pages'); $help{'Group Portfolio'} = &Apache::loncommon::help_open_topic('Docs_About_Group_Files'); $help{'Caching'} = &Apache::loncommon::help_open_topic('Caching'); - - + $help{'Course Roster'} = &Apache::loncommon::help_open_topic('Docs_Course_Roster'); + $help{'Web Page'} = &Apache::loncommon::help_open_topic('Docs_Web_Page'); + my $allowed; # URI is /adm/supplemental when viewing supplemental docs in non-edit mode. unless ($r->uri eq '/adm/supplemental') { @@ -3201,9 +3521,9 @@ sub handler { # Get the parameters that may be needed # &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['folderpath','pagepath', - 'pagesymb','forcesupplement','forcestandard', - 'tools','symb','command']); + ['folderpath', + 'forcesupplement','forcestandard', + 'tools','symb','command','supppath']); # standard=1: this is a "new-style" course with an uploaded map as top level # standard=2: this is a "old-style" course, and there is nothing we can do @@ -3217,7 +3537,7 @@ sub handler { my $supplementalflag=($env{'form.folderpath'}=~/^supplemental/); - if (($env{'form.folderpath'}=~/^default/) || $env{'form.folderpath'} eq "" || ($env{'form.pagepath'})) { + if (($env{'form.folderpath'}=~/^default/) || ($env{'form.folderpath'} eq "")) { $supplementalflag=0; } if ($env{'form.forcesupplement'}) { $supplementalflag=1; } @@ -3232,106 +3552,58 @@ sub handler { my $addentries = {}; my $container; my $containertag; - my $uploadtag; + my $pathitem; # Do we directly jump somewhere? - if ($env{'form.command'} eq 'direct') { - my ($mapurl,$id,$resurl); + if (($env{'form.command'} eq 'direct') || ($env{'form.command'} eq 'directnav')) { if ($env{'form.symb'} ne '') { - ($mapurl,$id,$resurl) = &Apache::lonnet::decode_symb($env{'form.symb'}); - if ($resurl=~/\.(sequence|page)$/) { - $mapurl=$resurl; - } elsif ($resurl eq 'adm/navmaps') { - $mapurl=$env{'course.'.$env{'request.course.id'}.'.url'}; - } - my $mapresobj; - my $navmap = Apache::lonnavmaps::navmap->new(); - if (ref($navmap)) { - $mapresobj = $navmap->getResourceByUrl($mapurl); - } - $mapurl=~s{^.*/([^/]+)\.(\w+)$}{$1}; - my $type=$2; - my $path; - if (ref($mapresobj)) { - my $pcslist = $mapresobj->map_hierarchy(); - if ($pcslist ne '') { - foreach my $pc (split(/,/,$pcslist)) { - next if ($pc <= 1); - my $res = $navmap->getByMapPc($pc); - if (ref($res)) { - my $thisurl = $res->src(); - $thisurl=~s{^.*/([^/]+)\.\w+$}{$1}; - my $thistitle = $res->title(); - $path .= '&'. - &Apache::lonhtmlcommon::entity_encode($thisurl).'&'. - &Apache::lonhtmlcommon::entity_encode($thistitle). - ':'.$res->randompick(). - ':'.$res->randomout(). - ':'.$res->encrypted(). - ':'.$res->randomorder(); - } - } - } - $path .= '&'.&Apache::lonhtmlcommon::entity_encode($mapurl).'&'. - &Apache::lonhtmlcommon::entity_encode($mapresobj->title()). - ':'.$mapresobj->randompick(). - ':'.$mapresobj->randomout(). - ':'.$mapresobj->encrypted(). - ':'.$mapresobj->randomorder(); - } else { - my $maptitle = &Apache::lonnet::gettitle($mapurl); - $path = '&default&...::::'. - '&'.&Apache::lonhtmlcommon::entity_encode($mapurl).'&'. - &Apache::lonhtmlcommon::entity_encode($maptitle).'::::'; - } - $path = 'default&'. - &Apache::lonhtmlcommon::entity_encode('Main Course Documents'). - $path; - if ($type eq 'sequence') { - $env{'form.folderpath'}=$path; - $env{'form.pagepath'}=''; - } else { - $env{'form.pagepath'}=$path; - $env{'form.folderpath'}=''; - } + $env{'form.folderpath'}= + &Apache::loncommon::symb_to_docspath($env{'form.symb'}); + &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => + $env{'form.command'}.'_'.$env{'form.symb'}}); } elsif ($env{'form.supppath'} ne '') { $env{'form.folderpath'}=$env{'form.supppath'}; + &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => + $env{'form.command'}.'_'.$env{'form.supppath'}}); } } elsif ($env{'form.command'} eq 'editdocs') { - $env{'form.folderpath'} = 'default&'. - &Apache::lonhtmlcommon::entity_encode('Main Course Content'); - $env{'form.pagepath'}=''; + $env{'form.folderpath'} = 'default&'. + &Apache::lonhtmlcommon::entity_encode('Main Course Content'). + ':::::'; + &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => $env{'form.command'}}); } elsif ($env{'form.command'} eq 'editsupp') { - $env{'form.folderpath'} = 'default&'. + $env{'form.folderpath'} = 'supplemental&'. &Apache::lonhtmlcommon::entity_encode('Supplemental Content'); - $env{'form.pagepath'}=''; + &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/supplemental'}); + } elsif ($env{'form.command'} eq 'contents') { + &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/navmaps'}); + } elsif ($env{'form.command'} eq 'home') { + &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/menu'}); } + # Where do we store these for when we come back? my $stored_folderpath='docs_folderpath'; if ($supplementalflag) { $stored_folderpath='docs_sup_folderpath'; } -# No folderpath, no pagepath, see if we have something stored - if ((!$env{'form.folderpath'}) && (!$env{'form.pagepath'})) { +# No folderpath, and in edit mode, see if we have something stored + if ((!$env{'form.folderpath'}) && $allowed) { &Apache::loncommon::restore_course_settings($stored_folderpath, - {'folderpath' => 'scalar'}); + {'folderpath' => 'scalar'}); + unless (&unescape($env{'form.folderpath'}) =~ m{^(default|supplemental)&}) { + undef($env{'form.folderpath'}); + } } # If we are not allowed to make changes, all we can see are supplemental docs if (!$allowed) { - $env{'form.pagepath'}=''; unless ($env{'form.folderpath'} =~ /^supplemental/) { $env{'form.folderpath'} = &supplemental_base(); } } -# If we still not have a folderpath, see if we can resurrect at pagepath - if (!$env{'form.folderpath'} && $allowed) { - &Apache::loncommon::restore_course_settings($stored_folderpath, - {'pagepath' => 'scalar'}); - } # Make the zeroth entry in supplemental docs page paths, so we can get to top level if ($env{'form.folderpath'} =~ /^supplemental_\d+/) { $env{'form.folderpath'} = &supplemental_base() @@ -3339,48 +3611,42 @@ sub handler { $env{'form.folderpath'}; } # If after all of this, we still don't have any paths, make them - unless (($env{'form.pagepath'}) || ($env{'form.folderpath'})) { + unless ($env{'form.folderpath'}) { if ($supplementalflag) { $env{'form.folderpath'}=&supplemental_base(); } else { - $env{'form.folderpath'}='default'; + $env{'form.folderpath'}='default'.&escape(&mt('Main '.$crstype.' Documents')). + ':::::'; } } # Store this unless ($toolsflag) { - &Apache::loncommon::store_course_settings($stored_folderpath, - {'pagepath' => 'scalar', - 'folderpath' => 'scalar'}); + if ($allowed) { + &Apache::loncommon::store_course_settings($stored_folderpath, + {'folderpath' => 'scalar'}); + } + my $folderpath; if ($env{'form.folderpath'}) { - my (@folderpath)=split('&',$env{'form.folderpath'}); - $env{'form.foldername'}=&unescape(pop(@folderpath)); - $env{'form.folder'}=pop(@folderpath); - $container='sequence'; - } - if ($env{'form.pagepath'}) { - my (@pagepath)=split('&',$env{'form.pagepath'}); - $env{'form.pagename'}=&unescape(pop(@pagepath)); - $env{'form.folder'}=pop(@pagepath); - $container='page'; - $containertag = ''. - ''; - $uploadtag = - ''. - ''. - ''; + $folderpath = $env{'form.folderpath'}; + my (@folders)=split('&',$env{'form.folderpath'}); + $env{'form.foldername'}=&unescape(pop(@folders)); + if ($env{'form.foldername'} =~ /\:1$/) { + $container = 'page'; + } else { + $container = 'sequence'; + } + $env{'form.folder'}=pop(@folders); } else { - my $folderpath=$env{'form.folderpath'}; - if (!$folderpath) { - if ($env{'form.folder'} eq '' || - $env{'form.folder'} eq 'supplemental') { - $folderpath='default&'. - &escape(&mt('Main '.$crstype.' Documents')); - } + if ($env{'form.folder'} eq '' || + $env{'form.folder'} eq 'supplemental') { + $folderpath='default&'. + &escape(&mt('Main '.$crstype.' Documents')). + ':::::'; } - $containertag = ''; - $uploadtag = ''; } + $containertag = ''; + $pathitem = ''; if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) { $showdoc='/'.$1; } @@ -3418,7 +3684,7 @@ sub handler { @tabids = ('002','ee2','ff2'); } else { @tabids = ('aa1','bb1','cc1','ff1'); - unless ($env{'form.pagepath'}) { + unless ($env{'form.folderpath'} =~ /\:1$/) { unshift(@tabids,'001'); push(@tabids,('dd1','ee1')); } @@ -3427,7 +3693,8 @@ sub handler { $script .= &editing_js($udom,$uname,$supplementalflag). &history_tab_js(). &inject_data_js(). - &Apache::lonhtmlcommon::resize_scrollbox_js('docs',$tabidstr); + &Apache::lonhtmlcommon::resize_scrollbox_js('docs',$tabidstr). + &Apache::lonextresedit::extedit_javascript(); $addentries = { onload => "javascript:resize_scrollbox('contentscroll','1','1');", }; @@ -3449,22 +3716,26 @@ sub handler { # Breadcrumbs &Apache::lonhtmlcommon::clear_breadcrumbs(); - unless ($showdoc) { + + if ($showdoc) { + $r->print(&Apache::loncommon::start_page("$crstype documents",undef, + {'force_register' => $showdoc,})); + } elsif ($r->uri eq '/adm/supplemental') { + my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype); + $r->print(&Apache::loncommon::start_page("Supplemental $crstype Content",undef, + {'bread_crumbs' => $brcrum,})); + } else { &Apache::lonhtmlcommon::add_breadcrumb({ href=>"/adm/coursedocs",text=>"$crstype Contents"}); $r->print(&Apache::loncommon::start_page("$crstype Contents", $script, - {'force_register' => $showdoc, - 'add_entries' => $addentries, - }) + {'add_entries' => $addentries} + ) .&Apache::loncommon::help_open_menu('','',273,'RAT') .&Apache::lonhtmlcommon::breadcrumbs( 'Editing '.$crstype.' Contents', 'Docs_Adding_Course_Doc') ); - } else { - $r->print(&Apache::loncommon::start_page("$crstype documents",undef, - {'force_register' => $showdoc,})); } my %allfiles = (); @@ -3527,9 +3798,6 @@ sub handler { } elsif ((!$showdoc) && (!$uploadphase)) { # ----------------------------------------------------------------------------- my %lt=&Apache::lonlocal::texthash( - 'uplm' => 'Upload a new main '.lc($crstype).' document', - 'upls' => 'Upload a new supplemental '.lc($crstype).' document', - 'impp' => 'Import a document', 'copm' => 'All documents out of a published map into this folder', 'upfi' => 'Upload File', 'upld' => 'Import Content', @@ -3539,21 +3807,20 @@ sub handler { 'impm' => 'Import from Assembled Map', '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', + 'webp' => 'Blank Web Page (editable)', 'drbx' => 'Drop Box', 'scuf' => 'External Scores (handgrade, upload, clicker)', 'bull' => 'Discussion Board', 'mypi' => 'My Personal Information Page', 'grpo' => 'Group Portfolio', 'rost' => 'Course Roster', - 'abou' => 'Personal Information Page for a User', + 'abou' => 'Personal Information Page for a User', 'imsf' => 'IMS Import', 'imsl' => 'Import IMS package', 'cms' => 'Origin of IMS package', @@ -3561,14 +3828,7 @@ sub handler { 'file' => 'File', 'title' => 'Title', 'comment' => 'Comment', - 'url' => 'URL', - 'prev' => 'Preview', - 'lnk' => 'Add Link', 'parse' => 'Upload embedded images/multimedia files if HTML file', - 'nd' => 'Upload Document', - 'pm' => 'Published Map', - 'sd' => 'Special Document', - 'mo' => 'More Options', ); # ----------------------------------------------------------------------------- my $fileupload=(< $lt{'imsf'} $help{'Importing_IMS_Course'}
-
'.&mt('Resources').'$lt{'mr'}$lt{'ve'}$lt{'vu'}'.&mt('History').''.&mt('Resources').'$lt{'mr'}$lt{'ve'}$lt{'vu'}'.&mt('History').''.&Apache::lonnet::gettitle($linkurl).'
'. + '
'.&Apache::lonnet::gettitle($linkurl).'
'. ''.$linkurl.'
'.$currentversion.'
('. + '
'.$currentversion.'
('. &Apache::lonlocal::locallocaltime(&Apache::lonnet::metadata($root.'.'.$extension,'lastrevisiondate')).')
'); -# Used in course - my $usedversion=$hash{'version_'.$linkurl}; - if (($usedversion) && ($usedversion ne 'mostrecent')) { - if($usedversion != $currentversion){ + '' + ); + # Used in course + my $usedversion=$hash{'version_'.$linkurl}; + if (($usedversion) && ($usedversion ne 'mostrecent')) { + if ($usedversion != $currentversion) { $r->print(''.$usedversion.''); - }else{ + } else { $r->print($usedversion); } - } else { - $r->print($currentversion); - } - $r->print(''); -# Set version - $r->print(&Apache::loncommon::select_form($setversions{$linkurl}, - 'set_version_'.$linkurl, - {'select_form_order' => - ['',1..$currentversion,'mostrecent'], - '' => '', - 'mostrecent' => &mt('most recent'), - map {$_,$_} (1..$currentversion)})); - my $lastold=1; - for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) { - my $url=$root.'.'.$prevvers.'.'.$extension; - if (&Apache::lonnet::metadata($url,'lastrevisiondate')< - $starttime) { - $lastold=$prevvers; - } - } - # - # Code to figure out how many version entries should go in - # each of the four columns - my $entries_per_col = 0; - my $num_entries = ($currentversion-$lastold); - if ($num_entries % $num_ver_col == 0) { - $entries_per_col = $num_entries/$num_ver_col; } else { - $entries_per_col = $num_entries/$num_ver_col + 1; + $r->print($currentversion); } - my $entries_count = 0; - $r->print(''); - my $cols_output = 1; - for (my $prevvers=$lastold;$prevvers<$currentversion;$prevvers++) { - my $url=$root.'.'.$prevvers.'.'.$extension; - $r->print(''.&mt('Version').' '.$prevvers.' ('. - &Apache::lonlocal::locallocaltime( - &Apache::lonnet::metadata($url, - 'lastrevisiondate') - ). - ')'); - if (&Apache::loncommon::fileembstyle($extension) eq 'ssi') { - $r->print(' '.&mt('Diffs').''); - } - $r->print('
'); - if (++$entries_count % $entries_per_col == 0) { - $r->print('
'); - $cols_output++; - } - } - } - while($cols_output++ < $num_ver_col) { - $r->print(''); + $r->print(''); + # Set version + $r->print(&Apache::loncommon::select_form( + $setversions{$linkurl}, + 'set_version_'.$linkurl, + {'select_form_order' => ['',1..$currentversion,'mostrecent'], + '' => '', + 'mostrecent' => &mt('most recent'), + map {$_,$_} (1..$currentversion)})); + my $lastold=1; + for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) { + my $url=$root.'.'.$prevvers.'.'.$extension; + if (&Apache::lonnet::metadata($url,'lastrevisiondate')<$starttime) { + $lastold=$prevvers; + } + } + $r->print(''); + for (my $prevvers=$lastold;$prevvers<$currentversion;$prevvers++) { + my $url=$root.'.'.$prevvers.'.'.$extension; + $r->print( + '' + .'' + .&mt('Version [_1]',$prevvers).'' + .' ('.&Apache::lonlocal::locallocaltime( + &Apache::lonnet::metadata($url,'lastrevisiondate')) + .')'); + if (&Apache::loncommon::fileembstyle($extension) eq 'ssi') { + $r->print( + ' &'). + '" target="diffs">'.&mt('Diffs').''); } - } + $r->print('
'); + } + $r->print('