--- loncom/interface/londocs.pm 2012/02/28 02:02:16 1.477 +++ loncom/interface/londocs.pm 2012/06/30 23:11:11 1.488 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.477 2012/02/28 02:02:16 raeburn Exp $ +# $Id: londocs.pm,v 1.488 2012/06/30 23:11:11 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -40,7 +40,9 @@ use Apache::lonxml; use Apache::lonclonecourse; use Apache::lonnavmaps; use Apache::lonnavdisplay(); +use Apache::lonuserstate(); use HTML::Entities; +use HTML::TokeParser; use GDBM_File; use Apache::lonlocal; use Cwd; @@ -100,12 +102,17 @@ sub authorhosts { my $allowed=0; my $myhome=&Apache::lonnet::homeserver($ca,$cd); my @ids=&Apache::lonnet::current_machine_ids(); - foreach my $id (@ids) { if ($id eq $myhome) { $allowed=1; } } + foreach my $id (@ids) { + if ($id eq $myhome) { + $allowed=1; + last; + } + } if ($allowed) { $home++; - $outhash{'home_'.$ca.'@'.$cd}=1; + $outhash{'home_'.$ca.':'.$cd}=1; } else { - $outhash{'otherhome_'.$ca.'@'.$cd}=$myhome; + $outhash{'otherhome_'.$ca.':'.$cd}=$myhome; $other++; } } @@ -114,27 +121,6 @@ sub authorhosts { } -sub dumpbutton { - my ($home,$other,%outhash)=&authorhosts(); - my $crstype = &Apache::loncommon::course_type(); - if ($home+$other==0) { return ''; } - if ($home) { - my $link = - "" - .&mt('Dump '.$crstype.' Documents to Construction Space') - .''; - return - $link.' ' - .&Apache::loncommon::help_open_topic('Docs_Dump_Course_Docs') - .'
'; - } else { - return - &mt('Dump '.$crstype.' Documents to Construction Space: available on other servers'); - } -} - sub clean { my ($title)=@_; $title=~s/[^\w\/\!\$\%\^\*\-\_\=\+\;\:\,\\\|\`\~]+/\_/gs; @@ -146,16 +132,22 @@ sub clean { sub dumpcourse { 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')); + $r->print(&Apache::loncommon::start_page('Dump '.$crstype.' Content to Authoring Space')."\n". + &Apache::lonhtmlcommon::breadcrumbs('Dump '.$crstype.' Content to Authoring Space')."\n"); + $r->print(&startContentScreen('tools')); my ($home,$other,%outhash)=&authorhosts(); - unless ($home) { return ''; } + unless ($home) { + $r->print(&endContentScreen()); + return ''; + } my $origcrsid=$env{'request.course.id'}; my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid); if (($env{'form.authorspace'}) && ($env{'form.authorfolder'}=~/\w/)) { # Do the dumping - unless ($outhash{'home_'.$env{'form.authorspace'}}) { return ''; } + unless ($outhash{'home_'.$env{'form.authorspace'}}) { + $r->print(&endContentScreen()); + return ''; + } my ($ca,$cd)=split(/\@/,$env{'form.authorspace'}); $r->print('

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

'); my $title=$env{'form.authorfolder'}; @@ -206,10 +198,15 @@ sub dumpcourse { } } } else { + $r->print(&mt('Searching ...').'
'); + $r->rflush(); # Input form + $r->print(''."\n"); unless ($home==1) { - $r->print( - '

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

'); } foreach my $key (sort(keys(%outhash))) { if ($key=~/^home_(.+)$/) { @@ -218,20 +215,23 @@ sub dumpcourse { ''); } else { $r->print(''); + &Apache::loncommon::plainname(split(/\:/,$1)).''); } } } unless ($home==1) { - $r->print(''); + $r->print(''."\n"); } my $title=$origcrsdata{'description'}; $title=~s/[\/\s]+/\_/gs; $title=&clean($title); - $r->print('

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

' - .'
'); + $r->print('
'. + '
'.&mt('Folder in Authoring Space').''. + ''. + '

'."\n"); &tiehash(); - $r->print('

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

' + $r->print('

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

' .&Apache::loncommon::start_data_table() .&Apache::loncommon::start_data_table_header_row() .''.&mt('Internal Filename').'' @@ -259,14 +259,9 @@ sub dumpcourse { $r->print(&Apache::loncommon::end_data_table()); &untiehash(); $r->print( - '

'); + '

'); } -} - -sub exportbutton { - my $crstype = &Apache::loncommon::course_type(); - return "".&mt('IMS Export')."". - &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs').'
'; + $r->print(&endContentScreen()); } sub group_import { @@ -430,24 +425,48 @@ sub log_docs { } } - - - - 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 ($r,$coursenum,$coursedom,$folder,$allowed,$crstype,$iconpath)=@_; + my $supplementalflag=($env{'form.folderpath'}=~/^supplemental/); + my $js = ''."\n"; + $r->print(&Apache::loncommon::start_page('Content Change Log',$js)); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Content Change Log')); + $r->print(&startContentScreen('docs')); + my %orderhash; + my $container='sequence'; + my $pathitem; + if ($env{'form.pagepath'}) { + $container='page'; + $pathitem = ''; + } else { + my $folderpath=$env{'form.folderpath'}; + if ($folderpath eq '') { + $folderpath = 'default&'.&escape(&mt('Main '.$crstype.' Documents')); + } + $pathitem = ''; + } + my $readfile="/uploaded/$coursedom/$coursenum/$folder.$container"; + my $jumpto = $readfile; + $jumpto =~ s{^/}{}; + my $tid = 1; + my ($breadcrumbtrail) = &breadcrumbs($allowed,$crstype); + $r->print($breadcrumbtrail. + &generate_edit_table($tid,\%orderhash,undef,$iconpath,$jumpto, + $readfile)); my %docslog=&Apache::lonnet::dump('nohist_docslog', $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'}); if ((keys(%docslog))[0]=~/^error\:/) { undef(%docslog); } - $r->print('
'. - ''); - my %saveable_parameters = ('show' => 'scalar',); &Apache::loncommon::store_course_settings('docs_log', \%saveable_parameters); @@ -461,9 +480,14 @@ sub docs_change_log { 'randomorder' => 'Randomly ordered', 'set' => 'set to', 'del' => 'deleted'); - $r->print(&Apache::loncommon::display_filter(). - ''. - '
'); + my $filter = &Apache::loncommon::display_filter('docslog')."\n". + $pathitem."\n". + ''. + (' 'x2).''; + $r->print('
'. + '
'.&mt('Display of Content Changes').''."\n". + &makedocslogform($filter,1). + '

'); $r->print(&Apache::loncommon::start_data_table().&Apache::loncommon::start_data_table_header_row(). ''.&mt('Time').''.&mt('User').''.&mt('Folder').''.&mt('Before').''. &mt('After').''. @@ -507,18 +531,30 @@ sub docs_change_log { ':'.$docslog{$id}{'exe_udom'}.''. $send_msg_link.''. $docslog{$id}{'logentry'}{'folder'}.''); + my $is_supp = 0; + if ($docslog{$id}{'logentry'}{'currentfolder'} =~ /^supplemental/) { + $is_supp = 1; + } # Before for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) { my $oldname=(split(/\:/,$docslog{$id}{'logentry'}{'before_resources_'.$idx}))[0]; my $newname=(split(/\:/,$docslog{$id}{'logentry'}{'after_resources_'.$idx}))[0]; if ($oldname ne $newname) { - $r->print(&LONCAPA::map::qtescape($oldname)); + my $shown = &LONCAPA::map::qtescape($oldname); + if ($is_supp) { + $shown = &Apache::loncommon::parse_supplemental_title($shown); + } + $r->print($shown); } } $r->print(''); @@ -529,13 +565,21 @@ sub docs_change_log { 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)); + my $shown = &LONCAPA::map::qtescape($newname); + if ($is_supp) { + $shown = &Apache::loncommon::parse_supplemental_title(&LONCAPA::map::qtescape($newname)); + } + $r->print($shown); } } $r->print(''); @@ -558,7 +602,10 @@ sub docs_change_log { if (!($env{'form.show'} eq &mt('all') || $shown<=$env{'form.show'})) { last; } } - $r->print(&Apache::loncommon::end_data_table()); + $r->print(&Apache::loncommon::end_data_table()."\n". + &makesimpleeditform($pathitem)."\n". + ''); + $r->print(&endContentScreen()); } sub update_paste_buffer { @@ -577,7 +624,7 @@ sub update_paste_buffer { 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); + ($title) = &Apache::loncommon::parse_supplemental_title($title); } elsif ($env{'docs.markedcopy_supplemental'}) { &Apache::lonnet::delenv('docs.markedcopy_supplemental'); } @@ -589,23 +636,42 @@ sub update_paste_buffer { } sub print_paste_buffer { - my ($r,$container) = @_; + my ($r,$container,$folder) = @_; return if (!defined($env{'docs.markedcopy_url'})); + my $is_external; + my $extension = (split(/\./,$env{'docs.markedcopy_url'}))[-1]; + if ($env{'docs.markedcopy_url'} =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//} ) { + $is_external = 1; + } + + my $canpaste; + if ($folder =~ /^supplemental/) { + $canpaste = &supp_pasteable($env{'docs.markedcopy_url'}); + } else { + $canpaste = 1; + } + + my $pasteinfo; + if ($canpaste) { + $pasteinfo = '
' + .' '; + } else { + $pasteinfo = &mt('Paste buffer contains:').' '; + } + $r->print('
' .''.&mt('Clipboard').'' - .'' - .' ' - ); + .$pasteinfo + ); my $type; - if ($env{'docs.markedcopy_url'} =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//} ) { + if ($is_external) { $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) { @@ -613,19 +679,36 @@ sub print_paste_buffer { $icon .= '/navmap.folder.closed.gif'; } $icon = ''; - $r->print($icon.$type.': '. &parse_supplemental_title(&LONCAPA::map::qtescape($env{'docs.markedcopy_title'}))); + $r->print($icon.$type.': '. &Apache::loncommon::parse_supplemental_title(&LONCAPA::map::qtescape($env{'docs.markedcopy_title'}))); } - if ($container eq 'page') { - $r->print(' + if ($canpaste) { + if ($container eq 'page') { + $r->print(' '); - } else { - $r->print(' + } else { + $r->print(' '); + } + $r->print(''); + } else { + $r->print('

'.&mt('Paste into Supplemental Content unavailable for this type of content.').'

'); + } + $r->print('
'); +} + +sub supp_pasteable { + my ($url) = @_; + if (($url =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//}) || + (($url =~ /\.sequence$/) && ($url =~ m{^/uploaded/})) || + ($url =~ m{^/uploaded/$match_domain/$match_courseid/(docs|supplemental)/(default|\d+)/\d+/}) || + ($url =~ m{^/adm/$match_domain/$match_username/aboutme}) || + ($url =~ m{^/public/$match_domain/$match_courseid/syllabus})) { + return 1; } - $r->print(''); + return; } sub do_paste_from_buffer { @@ -635,15 +718,37 @@ sub do_paste_from_buffer { return; } +# Supplemental content may only include certain types of content + if ($folder =~ /^supplemental/) { + unless (&supp_pasteable($env{'docs.markedcopy_url'})) { + return &mt('Paste failed: content type is not supported within Supplemental Content'); + } + } + # 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 ($oldurl,%removefrommap,%addedmaps,%rewrites,%copies,%dbcopies,%zombies,%params); + if ($url=~/\.(page|sequence)$/) { + # If pasting a map, check if map contains other maps + &contained_map_check($url,$folder,\%removefrommap,\%addedmaps); + if (keys(%addedmaps) > 0) { + &reinit_role($coursedom,$coursenum,$env{"course.$env{'request.course.id'}.home"}); + } + my %allmaps; + 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; + } + } + if ($url=~ m{^/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+)$}) { + if ($oldid =~ m{^(/uploaded/$match_domain/$match_courseid/)(\D+)(\d+)$}) { my $path = $1; my $prefix = $2; my $ancestor = $3; @@ -651,40 +756,58 @@ sub do_paste_from_buffer { $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 $counter = 0; + my $newurl=$oldid.$newid.'.'.$ext; + my $is_unique = &uniqueness_check($newurl); + if ($allmaps{$newurl}) { + $is_unique = 0; } - } - 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'); + while (!$is_unique && $allmaps{$newurl} && $counter < 100) { + $counter ++; + $newid ++; + $newurl = $oldid.$newid; + $is_unique = &uniqueness_check($newurl); + } + if ($is_unique) { + if ($path =~ m{^/uploaded/($match_domain)/($match_courseid)/$}) { + my $srcdom = $1; + my $srcnum = $2; + if (($srcdom ne $coursedom) && ($srcnum ne $coursenum)) { + if (&Apache::lonnet::allowed('mdc',$srcdom.'_'.$srcnum)) { + &url_paste_fixups($oldid,$ext,$coursedom,$coursenum, + \%allmaps, \%rewrites,\%copies,\%dbcopies,\%zombies,\%params); + } else { + return &mt('Paste failed: Item is from a different course which you do not have rights to edit'); + } + } + } } else { - return &mt('Paste failed: an error occurred saving the folder'); + 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'); + } } - } - $url = $newurl; - } + 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; + } elsif ($url=~m {^/res/}) { # 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'); + &Apache::lonnet::delenv('docs.markedcopy'); + if ($allmaps{$url}) { + return &mt('Paste failed: only one instance of a particular published sequence or page is allowed within each course.'); + } + } } if ($url=~ m{/smppg$}) { my $db_name = &Apache::lonsimplepage::get_db_name($url); @@ -705,12 +828,43 @@ sub do_paste_from_buffer { $url = &LONCAPA::map::qtunescape($url); # Now insert the URL at the bottom my $newidx = &LONCAPA::map::getresidx($url); + my $relpath; + if (($folder =~ /^supplemental/) && + ($url =~ m{^/uploaded/$coursedom/$coursenum/docs/(.+)})) { + $relpath = $1; + } elsif (($folder =~ /^default/) && + ($url =~ m{^/uploaded/$coursedom/$coursenum/supplemental/(.+)})) { + $relpath = $1; + } + if ($relpath ne '') { + my ($prefix,$subdir,$rem) = ($relpath =~ m{^(default|\d+)/(\d+)/(.+)$}); + my ($newloc,$newsubdir) = ($folder =~ /^(default|supplemental)_?(\d*)/); + my $newprefix = $newloc; + if ($newloc eq 'default') { + $newprefix = 'docs'; + } + if ($newsubdir eq '') { + $newsubdir = 'default'; + } + my $newpath = "$newprefix/$newsubdir/$newidx/$rem"; + $url = + &Apache::lonclonecourse::writefile($env{'request.course.id'},$newpath, + &Apache::lonnet::getfile($url)); + if ($url eq '/adm/notfound.html') { + return &mt('Paste failed: an error occurred saving the file.'); + } + } + my $noparams = 0; + if ((ref($params{$oldurl}) eq 'HASH') && ($relpath ne '') && ($folder =~ /^supplemental/)) { + $noparams = 1; + } + &apply_fixups($coursedom,$coursenum,$oldurl,$url,$noparams,\%rewrites,\%copies,\%dbcopies,\%zombies,\%params); if ($env{'docs.markedcopy_supplemental'}) { if ($folder =~ /^supplemental/) { $title = $env{'docs.markedcopy_supplemental'}; } else { (undef,undef,$title) = - &parse_supplemental_title($env{'docs.markedcopy_supplemental'}); + &Apache::loncommon::parse_supplemental_title($env{'docs.markedcopy_supplemental'}); } } else { if ($folder=~/^supplemental/) { @@ -725,6 +879,23 @@ sub do_paste_from_buffer { # Store the result } +sub dbcopy { + my ($url,$coursedom,$coursenum) = @_; + if ($url=~ m{/smppg$}) { + my $db_name = &Apache::lonsimplepage::get_db_name($url); + if ($db_name =~ /^smppage_/) { + #simple pages, need to copy the db contents to a new one. + my %contents=&Apache::lonnet::dump($db_name,$coursedom,$coursenum); + my $now = time(); + $db_name =~ s{_\d*$ }{_$now}x; + my $result=&Apache::lonnet::put($db_name,\%contents, + $coursedom,$coursenum); + $url =~ s{/(\d*)/smppg$ }{/$now/smppg}x; + } + } + return $url; +} + sub uniqueness_check { my ($newurl) = @_; my $unique = 1; @@ -739,6 +910,188 @@ sub uniqueness_check { return $unique; } +sub contained_map_check { + my ($url,$folder,$removefrommap,$addedmaps) = @_; + my $content = &Apache::lonnet::getfile($url); + unless ($content eq '-1') { + my $parser = HTML::TokeParser->new(\$content); + $parser->attr_encoded(1); + while (my $token = $parser->get_token) { + next if ($token->[0] ne 'S'); + if ($token->[1] eq 'resource') { + next if ($token->[2]->{'type'} eq 'zombie'); + my $ressrc = $token->[2]->{'src'}; + if ($folder =~ /^supplemental/) { + unless (&supp_pasteable($ressrc)) { + $removefrommap->{$url}{$token->[2]->{'id'}}; + next; + } + } + if ($ressrc =~ /\.(sequence|page)$/) { + if (ref($addedmaps->{$ressrc}) eq 'ARRAY') { + push(@{$addedmaps->{$ressrc}},$url); + } else { + $addedmaps->{$ressrc} = [$url]; + } + &contained_map_check($ressrc,$folder,$removefrommap,$addedmaps); + } + } elsif ($token->[1] !~ /^resource|map|link$/) { + if ($folder =~ /^supplemental/) { + $removefrommap->{$url}{$token->[1]}; + } + } + } + } + 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,$ext,$cdom,$cnum,$allmaps,$rewrites,$copies,$dbcopies,$zombies,$params) = @_; + my $file = &Apache::lonnet::getfile("$oldurl.$ext"); + return if ($file eq '-1'); + my $parser = HTML::TokeParser->new(\$file); + $parser->attr_encoded(1); + while (my $token = $parser->get_token) { + next if ($token->[0] ne 'S'); + if ($token->[1] eq 'resource') { + my $ressrc = $token->[2]->{'src'}; + next if ($ressrc eq ''); + next if ($token->[2]->{'type'} eq 'external'); + my $id = $token->[2]->{'id'}; + if ($token->[2]->{'type'} eq 'zombie') { + $zombies->{$oldurl}{$ressrc} = $id; + } elsif ($ressrc =~ m{^/uploaded/($match_domain)/($match_courseid)/(.+)}) { + my $srccdom = $1; + my $srccnum = $2; + my $rem = $3; + if (($srccdom ne $cdom) || ($srccnum ne $cnum)) { + if ($rem =~ /^(default|supplemental)(_?\d*).(sequence|page)$/) { + $rewrites->{$oldurl}{$ressrc} = $id; + &url_paste_fixups($ressrc,$3,$cdom,$cnum,$allmaps,$rewrites,$copies,$dbcopies,$zombies,$params); + } else { + $copies->{$oldurl}{$ressrc} = $id; + } + } + } elsif ($ressrc =~ m{^/adm/($match_domain)/($match_courseid)/(.+)$}) { + my $srccdom = $1; + my $srccnum = $2; + if (($srccdom ne $cdom) || ($srccnum ne $cnum)) { + $rewrites->{$oldurl}{$ressrc} = $id; + $dbcopies->{$oldurl}{$ressrc} = $id; + } + } elsif ($ressrc =~ m{^/public/($match_domain)/($match_courseid)/(.+)$}) { + my $srccdom = $1; + my $srccnum = $2; + if (($srccdom ne $cdom) || ($srccnum ne $cnum)) { + $rewrites->{$oldurl}{$ressrc} = $id; + $dbcopies->{$oldurl}{$ressrc} = $id; + } + } + } elsif ($token->[1] eq 'param') { + my $to = $token->[2]->{'to'}; + if ($to ne '') { + if (ref($params->{$oldurl}{$to}) eq 'ARRAY') { + push (@{$params->{$oldurl}{$to}},$token->[2]->{'name'}); + } else { + @{$params->{$oldurl}{$to}} = ($token->[2]->{'name'}); + } + } + } + } + return; +} + +sub apply_fixups { + my ($cdom,$cnum,$oldurl,$url,$noparams,$rewrites,$copies,$dbcopies,$zombies,$params) = @_; + my (%newdb,%newdoc); + if (ref($dbcopies->{$oldurl}) eq 'HASH') { + foreach my $item (keys(%{$dbcopies->{$oldurl}})) { + $newdb{$item} = &dbcopy($item); + } + } + if (ref($copies->{$oldurl}) eq 'HASH') { + foreach my $item (keys(%{$copies->{$oldurl}})) { + my $content = &Apache::lonnet::getfile($item); + my $newcontent; + unless ($content eq '-1') { + my $mm = new File::MMagic; + my $mimetype = $mm->checktype_contents($content); + if ($mimetype eq 'text/html') { + my (%allfiles,%codebase,$state); + my ($embedded,$num,$delnum) = + &Apache::loncommon::ask_for_embedded_content( + '/adm/dependencies',$state,\%allfiles,\%codebase, + {'error_on_invalid_names' => 1, + 'ignore_remote_references' => 1, + 'docs_url' => $oldurl}); + if ($embedded) { + #FIXME Need to check for dependencies and copy and update refs. + } + $newcontent = $content; + } else { + $newcontent = $content; + } + my $storefn=$item; + $storefn=~s{^/\w+/$match_domain/$match_courseid/}{}; + $newdoc{$item} = &Apache::lonclonecourse::writefile($env{'request.course.id'},$storefn,$newcontent); + } + } + } + if (((ref($rewrites->{$oldurl}) eq 'HASH') || (ref($zombies->{$oldurl}) eq 'HASH')) || + ($noparams) || (keys(%newdb) > 0) || (keys(%newdoc) > 0)) { + my $map = &Apache::lonnet::getfile($url); + my $newcontent; + unless ($map eq '-1') { + my $parser = HTML::TokeParser->new(\$map); + $parser->attr_encoded(1); + while (my $token = $parser->get_token) { + if ($token->[0] eq 'S') { + next if ($token->[2]->{'type'} eq 'zombie'); + next if (($token->[1] eq 'param') && $noparams); + if ($token->[1] eq 'resource') { + my $src = $token->[2]->{'src'}; + my $id = $token->[2]->{'id'}; + if (($rewrites->{$oldurl}{$src} eq $id) || ($newdb{$src} ne '') + || ($newdoc{$src} ne '')) { + if (ref($rewrites->{$oldurl}) eq 'HASH') { + if ($rewrites->{$oldurl}{$src} eq $id) { + $token->[2]->{'src'} =~ s{^(/uploaded|adm|public)/$match_domain/$match_courseid/}{$1/$cdom/$cnum}; + } + } elsif ($newdb{$src} ne '') { + $token->[2]->{'src'} = $newdb{$src}; + } + $newcontent .= "<$token->[1] "; + foreach my $attr (@{$token->[3]}) { + $newcontent .= ' '.$attr.'="'.$token->[2]->{$attr},'"' + } + $newcontent .= ' />'; + } else { + $newcontent .= $token->[4]."\n"; + } + } + } elsif ($token->[0] eq 'E') { + $newcontent .= $token->[2]."\n"; + } + } + } + my $storefn=$url; + $storefn=~s{^/\w+/$match_domain/$match_courseid/}{}; + my $storeres = + &Apache::lonclonecourse::writefile($env{'request.course.id'},$storefn, + $newcontent); + } + return; +} + my %parameter_type = ( 'randompick' => 'int_pos', 'hiddenresource' => 'string_yesno', 'encrypturl' => 'string_yesno', @@ -816,6 +1169,16 @@ sub editor { my $container= ($env{'form.pagepath'}) ? 'page' : 'sequence'; + my ($breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,$is_random_order) = + &breadcrumbs($allowed,$crstype); + $r->print($breadcrumbtrail); + + my $jumpto = "uploaded/$coursedom/$coursenum/$folder.$container"; + + unless ($allowed) { + $randompick = -1; + } + my ($errtext,$fatal) = &mapread($coursenum,$coursedom, $folder.'.'.$container); return $errtext if ($fatal); @@ -827,16 +1190,6 @@ sub editor { $LONCAPA::map::resources[$idx]=''; } - my ($breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,$is_random_order) = - &breadcrumbs($allowed,$crstype); - $r->print($breadcrumbtrail); - - my $jumpto = "uploaded/$coursedom/$coursenum/$folder.$container"; - - unless ($allowed) { - $randompick = -1; - } - # ------------------------------------------------------------ Process commands # ---------------- if they are for this folder and user allowed to make changes @@ -988,8 +1341,10 @@ sub editor { $tid = 2; } if ($allowed) { - $r->print(&generate_edit_table($tid,$orderhash,$to_show,$iconpath,$jumpto)); - &print_paste_buffer($r,$container); + my $readfile="/uploaded/$coursedom/$coursenum/$folder.$container"; + $r->print(&generate_edit_table($tid,$orderhash,$to_show,$iconpath,$jumpto, + $readfile)); + &print_paste_buffer($r,$container,$folder); } else { if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) { #Function Box for Supplemental Content for users with mdc priv. @@ -1120,43 +1475,49 @@ sub process_file_upload { position => $position, phase => $nextphase, comment => $comment, - ); + ); + my ($destination,$dir_root) = &embedded_destination($coursenum,$coursedom); + my @current = &get_dir_list($url,$coursenum,$coursedom,$newidx); $$upload_output = $showupload. &Apache::loncommon::decompress_form($mimetype, $archiveurl,'/adm/coursedocs',$noextract, - \%archiveitems); + \%archiveitems,\@current); } } } return $nextphase; } -sub is_supplemental_title { - my ($title) = @_; - return scalar($title =~ m/^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/); +sub get_dir_list { + my ($url,$coursenum,$coursedom,$newidx) = @_; + my ($destination,$dir_root) = &embedded_destination(); + my ($dirlistref,$listerror) = + &Apache::lonnet::dirlist("$dir_root/$destination/$newidx",$coursedom,$coursenum,1); + my @dir_lines; + my $dirptr=16384; + if (ref($dirlistref) eq 'ARRAY') { + foreach my $dir_line (sort + { + my ($afile)=split('&',$a,2); + my ($bfile)=split('&',$b,2); + return (lc($afile) cmp lc($bfile)); + } (@{$dirlistref})) { + my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$dir_line,16); + $filename =~ s/\s+$//; + next if ($filename =~ /^\.\.?$/); + my $isdir = 0; + if ($dirptr&$testdir) { + $isdir = 1; + } + push(@dir_lines, [$filename,$dom,$isdir,$size,$mtime,$obs]); + } + } + return @dir_lines; } -sub parse_supplemental_title { +sub is_supplemental_title { my ($title) = @_; - - my ($foldertitle,$renametitle); - if ($title =~ /&&&/) { - $title = &HTML::Entites::decode($title); - } - if ($title =~ m/^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/) { - $renametitle=$4; - my ($time,$uname,$udom) = ($1,$2,$3); - $foldertitle=&Apache::lontexconvert::msgtexconverted($4); - my $name = &Apache::loncommon::plainname($uname,$udom); - $name = &HTML::Entities::encode($name,'"<>&\''); - $renametitle = &HTML::Entities::encode($renametitle,'"<>&\''); - $title=''.&Apache::lonlocal::locallocaltime($time).' '. - $name.':
'.$foldertitle; - } - if (wantarray) { - return ($title,$foldertitle,$renametitle); - } - return $title; + return scalar($title =~ m/^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/); } # --------------------------------------------------------------- An entry line @@ -1165,7 +1526,7 @@ sub entryline { 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); + ($title,$foldertitle,$renametitle) = &Apache::loncommon::parse_supplemental_title($title); $pagetitle = $foldertitle; } else { $title=&HTML::Entities::encode($title,'"<>&\''); @@ -1181,7 +1542,7 @@ sub entryline { $renametitle=~s/\"\;/\\\"/g; $renametitle=~s/ /%20/g; my $line=&Apache::loncommon::start_data_table_row(); - my ($form_start,$form_end); + my ($form_start,$form_end,$form_common); # Edit commands my ($container, $type, $esc_path, $path, $symb); if ($env{'form.folderpath'}) { @@ -1264,16 +1625,18 @@ sub entryline { if (!$nocopy) { $copylink=(<$lt{'cp'} +$lt{'cp'} ENDCOPY } if (!$nocut) { $cutlink=(<$lt{'ct'} +$lt{'ct'} ENDCUT } - $form_start = (< + $form_start = ' +
+'; + $form_common=(< @@ -1295,6 +1658,7 @@ END $form_start + $form_common $selectbox $form_end @@ -1378,7 +1742,7 @@ END $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb); } } - my ($parameterset,$rand_order_text) = (' ', ' '); + my ($rand_pick_text,$rand_order_text); if ($isfolder || $extension eq 'sequence') { my $foldername=&escape($foldertitle); my $folderpath=$env{'form.folderpath'}; @@ -1394,16 +1758,27 @@ END .':'.((&LONCAPA::map::getparameter($orderidx, 'parameter_randomorder'))[0]=~/^yes$/i); $url.='folderpath='.&escape($folderpath).$cpinfo; - $parameterset=''; + 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 =' -'; + $rand_order_text = +$form_start. +$form_common.' +'; } if ($ispage) { my $pagename=&escape($pagetitle); @@ -1439,7 +1814,7 @@ END if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) { $line.=''; } elsif ($url) { - $line.=&Apache::loncommon::modal_link($url.(($url=~/\?/)?'&':'?').'inhibitmenu=yes', + $line.=&Apache::loncommon::modal_link($url.(($url=~/\?/)?'&':'?').'inhibitmenu=yes', '',600,500); } else { $line.=''; @@ -1448,12 +1823,14 @@ END if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) { $line.=''.$title.''; } elsif ($url) { - $line.=&Apache::loncommon::modal_link($url.(($url=~/\?/)?'&':'?').'inhibitmenu=yes', + $line.=&Apache::loncommon::modal_link($url.(($url=~/\?/)?'&':'?').'inhibitmenu=yes', $title,600,500); } else { $line.=$title.' '.$reinit.''; } $line.=$external.""; + $rand_pick_text = ' ' if ($rand_pick_text eq ''); + $rand_order_text = ' ' if ($rand_order_text eq ''); if (($allowed) && ($folder!~/^supplemental/)) { my %lt=&Apache::lonlocal::texthash( 'hd' => 'Hidden', @@ -1465,15 +1842,17 @@ END $line.=(< $form_start + $form_common $form_end
$form_start + $form_common $form_end - $form_start $parameterset $form_end
- $form_start $rand_order_text $form_end + $rand_pick_text
+ $rand_order_text ENDPARMS } $line.=&Apache::loncommon::end_data_table_row(); @@ -1592,7 +1971,7 @@ sub checkonthis { =item list_symbs() -List Symbs +List Content Identifiers =cut @@ -1600,9 +1979,9 @@ 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'); + $r->print(&Apache::loncommon::start_page('List of Content Identifiers')); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Content Identifiers')); + $r->print(&startContentScreen('tools')); my $navmap = Apache::lonnavmaps::navmap->new(); if (!defined($navmap)) { $r->print('

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

'. @@ -1611,11 +1990,25 @@ sub list_symbs { ''); &Apache::lonnet::logthis('Symb list failed - could not create navmap object in '.lc($crstype).':'.$env{'request.course.id'}); } else { - $r->print("
\n");
+        $r->print('

'.&mt("$crstype Content Identifiers").'

'. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + ''.&mt('Title').''.&mt('Identifier').''. + &Apache::loncommon::end_data_table_header_row()."\n"); + my $count; foreach my $res ($navmap->retrieveResources()) { - $r->print($res->compTitle()."\t".$res->symb()."\n"); + $r->print(&Apache::loncommon::start_data_table_row(). + ''.$res->compTitle().''. + ''.$res->symb().''. + &Apache::loncommon::start_data_table_row()); + $count ++; + } + if (!$count) { + $r->print(&Apache::loncommon::start_data_table_row(). + ''.&mt("$crstype is empty").''. + &Apache::loncommon::end_data_table_row()); } - $r->print("\n
\n"); + $r->print(&Apache::loncommon::end_data_table()); } } @@ -1623,13 +2016,15 @@ sub list_symbs { sub verifycontent { my ($r) = @_; my $crstype = &Apache::loncommon::course_type(); - $r->print(&Apache::loncommon::start_page('Verify '.$crstype.' Documents')); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$crstype.' Documents')); - &startContentScreen($r,'tools'); + $r->print(&Apache::loncommon::start_page('Verify '.$crstype.' Documents')); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$crstype.' Documents')); + $r->print(&startContentScreen('tools')); + $r->print('

'.&mt($crstype.' content verification').'

'); $hashtied=0; undef %alreadyseen; %alreadyseen=(); &tiehash(); + foreach my $key (keys(%hash)) { if ($hash{$key}=~/\.(page|sequence)$/) { if (($key=~/^src_/) && ($alreadyseen{&unescape($hash{$key})})) { @@ -1659,7 +2054,7 @@ sub checkversions { 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'); + $r->print(&startContentScreen('tools')); my $header=''; my $startsel=''; @@ -1712,9 +2107,11 @@ sub checkversions { if (&Apache::lonnet::put('resourceversions',\%newsetversions, $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') { - $r->print('

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

'); + $r->print(&Apache::loncommon::confirmwrapper( + &Apache::lonhtmlcommon::confirm_success(&mt('Your Version Settings have been Saved')))); } else { - $r->print('

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

'); + $r->print(&Apache::loncommon::confirmwrapper( + &Apache::lonhtmlcommon::confirm_success(&mt('An Error Occured while Attempting to Save your Version Settings'),1))); } &mark_hash_old(); } @@ -1771,6 +2168,7 @@ sub checkversions { 'lw' => 'Version changes since last Week', 'sy' => 'Version changes since Yesterday', 'al' => 'All Resources (possibly large output)', + 'cd' => 'Change display', 'sd' => 'Display', 'fi' => 'File', 'md' => 'Modification Date', @@ -1780,12 +2178,17 @@ sub checkversions { 'sv' => 'Set Versions to be used in '.$crstype.' according to Selections below', 'sm' => 'Keep all Resources up-to-date with most recent Versions (default)', 'sc' => 'Set all Resource Versions to current Version (Fix Versions)', - 'di' => 'Differences'); + 'di' => 'Differences', + 'save' => 'Save changes', + 'vers' => 'Version choice(s) for specific resources', + 'act' => 'Actions'); $r->print(<$header
- -
+
+
+$lt{'cd'} -

$header

- +
+
+
+
+$lt{'act'} +$lt{'sm'}:
+$lt{'sc'}: +
+
+
+
+

$lt{'vers'}

+ 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(). + ''. + "". + "". + "". + ''. + ''); 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.'); + $currentversion=''.&mt('Could not be determined.').''; } my $linkurl=&Apache::lonnet::clutter($key); - $r->print( - ''. - ''. - ''. - ''. - ''. - ''. - ''. + ''. + ''); my $lastold=1; for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) { my $url=$root.'.'.$prevvers.'.'.$extension; @@ -1857,13 +2272,13 @@ ENDHEADERS # each of the four columns my $entries_per_col = 0; my $num_entries = ($currentversion-$lastold); - if ($num_entries % 4 == 0) { - $entries_per_col = $num_entries/4; + if ($num_entries % $num_ver_col == 0) { + $entries_per_col = $num_entries/$num_ver_col; } else { - $entries_per_col = $num_entries/4 + 1; + $entries_per_col = $num_entries/$num_ver_col + 1; } my $entries_count = 0; - $r->print(''); - if ($cols_output != 4) { - $r->print(''); + if ($cols_output != $num_ver_col) { + $r->print(''."\n"); } } - $r->print('
'.&mt('Resources').'$lt{'mr'}$lt{'ve'}$lt{'vu'}'.&mt('History').'


'. - &Apache::lonnet::gettitle($linkurl). - '
   '. - ''.$linkurl. - '
'. - &Apache::lonlocal::locallocaltime( - &Apache::lonnet::metadata($root.'.'.$extension, - 'lastrevisiondate') - ). - 'Most Recent: '. - ''.$currentversion.''. - 'In '.$crstype.': '. - ''); + $r->print( + &Apache::loncommon::end_data_table_header_row(). + &Apache::loncommon::start_data_table_row(). + ''.&Apache::lonnet::gettitle($linkurl).'
'. + ''.$linkurl.'
'.$currentversion.'
('. + &Apache::lonlocal::locallocaltime(&Apache::lonnet::metadata($root.'.'.$extension,'lastrevisiondate')).')
'); # Used in course my $usedversion=$hash{'version_'.$linkurl}; if (($usedversion) && ($usedversion ne 'mostrecent')) { - $r->print($usedversion); + if($usedversion != $currentversion){ + $r->print(''.$usedversion.''); + }else{ + $r->print($usedversion); + } } else { $r->print($currentversion); } - $r->print(''. - 'Use: '); + $r->print(''); # Set version $r->print(&Apache::loncommon::select_form($setversions{$linkurl}, 'set_version_'.$linkurl, @@ -1843,7 +2259,6 @@ ENDHEADERS '' => '', 'mostrecent' => &mt('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; @@ -1882,21 +2297,21 @@ ENDHEADERS } $r->print('
'); if (++$entries_count % $entries_per_col == 0) { - $r->print('
'); + $r->print(''); $cols_output++; } } } - while($cols_output++ < 4) { - $r->print('') + while($cols_output++ < $num_ver_col) { + $r->print(''); } - $r->print('
'); - $r->print('

'.&mt('Done').'

'); + $r->print(''.&Apache::loncommon::end_data_table_row(). + &Apache::loncommon::end_data_table(). + ''); &untiehash(); } @@ -1960,7 +2375,7 @@ $help{'Caching'}.'

'."\n\n"); sub init_breadcrumbs { my ($form,$text)=@_; &Apache::lonhtmlcommon::clear_breadcrumbs(); - &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs", + &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?tools=1", text=>&Apache::loncommon::course_type().' Editor', faq=>273, bug=>'Instructor Interface', @@ -1995,23 +2410,24 @@ sub create_form_ul { # sub startContentScreen { - my ($r,$mode)=@_; - $r->print(''."\n"; + $output .= '
'. + '
'. + '
'; + return $output; } # @@ -2019,8 +2435,7 @@ sub startContentScreen { # sub endContentScreen { - my ($r)=@_; - $r->print('
'); + return ''; } sub supplemental_base { @@ -2032,7 +2447,14 @@ sub handler { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK if $r->header_only; + +# get course data my $crstype = &Apache::loncommon::course_type(); + my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'}; + my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'}; + +# graphics settings + $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL').'/'); # # --------------------------------------------- Initialize help topics for this @@ -2066,20 +2488,29 @@ sub handler { $allowed = &Apache::lonnet::allowed('mdc',$env{'request.course.id'}); } - if ($allowed && $env{'form.verify'}) { + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['chooseserver', + 'inhibitmenu']); + if ($allowed && $env{'form.chooseserver'}) { + &choose_dump_server($r); + return OK; + } elsif ($allowed && $env{'form.verify'}) { &init_breadcrumbs('verify','Verify Content'); &verifycontent($r); } elsif ($allowed && $env{'form.listsymbs'}) { - &init_breadcrumbs('listsymbs','List Symbs'); + &init_breadcrumbs('listsymbs','List Content IDs'); &list_symbs($r); } elsif ($allowed && $env{'form.docslog'}) { &init_breadcrumbs('docslog','Show Log'); - &docs_change_log($r); + my $folder = $env{'form.folder'}; + if ($folder eq '') { + $folder='default'; + } + &docs_change_log($r,$coursenum,$coursedom,$folder,$allowed,$crstype,$iconpath); } elsif ($allowed && $env{'form.versions'}) { &init_breadcrumbs('versions','Check/Set Resource Versions'); &checkversions($r); } elsif ($allowed && $env{'form.dumpcourse'}) { - &init_breadcrumbs('dumpcourse','Dump '.&Apache::loncommon::course_type().' Documents to Construction Space'); + &init_breadcrumbs('dumpcourse','Dump '.&Apache::loncommon::course_type().' Content to Authoring Space'); &dumpcourse($r); } elsif ($allowed && $env{'form.exportcourse'}) { &init_breadcrumbs('exportcourse','IMS Export'); @@ -2087,22 +2518,23 @@ sub handler { } else { # # Done catching special calls -# The whole rest is for course and supplemental documents +# The whole rest is for course and supplemental documents and utilities menu # Get the parameters that may be needed # &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['folderpath','pagepath', 'pagesymb','forcesupplement','forcestandard', - 'symb','command']); + 'tools','symb','command']); # standard=1: this is a "new-style" course with an uploaded map as top level # standard=2: this is a "old-style" course, and there is nothing we can do my $standard=($env{'request.course.uri'}=~/^\/uploaded\//); -# Decide whether this should display supplemental or main content +# Decide whether this should display supplemental or main content or utilities # supplementalflag=1: show supplemental documents # supplementalflag=0: show standard documents +# toolsflag=1: show utilities my $supplementalflag=($env{'form.folderpath'}=~/^supplemental/); @@ -2113,6 +2545,8 @@ sub handler { if ($env{'form.forcestandard'}) { $supplementalflag=0; } unless ($allowed) { $supplementalflag=1; } unless ($standard) { $supplementalflag=1; } + my $toolsflag=0; + if ($env{'form.tools'}) { $toolsflag=1; } my $script=''; my $showdoc=0; @@ -2235,81 +2669,90 @@ sub handler { } # 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'}=&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 = - ''. - ''. - ''; - } 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')); + unless ($toolsflag) { + &Apache::loncommon::store_course_settings($stored_folderpath, + {'pagepath' => 'scalar', + 'folderpath' => 'scalar'}); + if ($env{'form.folderpath'}) { + my (@folderpath)=split('&',$env{'form.folderpath'}); + $env{'form.foldername'}=&unescape(pop(@folderpath)); + $env{'form.folder'}=pop(@folderpath); + $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 = + ''. + ''. + ''; + } 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; + } + 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'); } } - $containertag = ''; - $uploadtag = ''; - } - if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) { - $showdoc='/'.$1; - } - 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'); - } } -# get course data - my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'}; - my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'}; - # get personal data my $uname=$env{'user.name'}; my $udom=$env{'user.domain'}; my $plainname=&escape(&Apache::loncommon::plainname($uname,$udom)); -# graphics settings - - $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL') . "/"); - if ($allowed) { - my @tabids; - if ($supplementalflag) { - @tabids = ('002','ee2','ff2'); + if ($toolsflag) { + $script .= &inject_data_js(); + my ($home,$other,%outhash)=&authorhosts(); + if (!$home && $other) { + my @hosts; + foreach my $aurole (keys(%outhash)) { + unless(grep(/^\Q$outhash{$aurole}\E/,@hosts)) { + push(@hosts,$outhash{$aurole}); + } + } + $script .= &dump_switchserver_js(@hosts); + } } else { - @tabids = ('aa1','bb1','cc1','ff1'); - unless ($env{'form.pagepath'}) { - unshift(@tabids,'001'); - push(@tabids,('dd1','ee1')); + my @tabids; + if ($supplementalflag) { + @tabids = ('002','ee2','ff2'); + } else { + @tabids = ('aa1','bb1','cc1','ff1'); + unless ($env{'form.pagepath'}) { + unshift(@tabids,'001'); + push(@tabids,('dd1','ee1')); + } } + my $tabidstr = join("','",@tabids); + $script .= &editing_js($udom,$uname,$supplementalflag). + &history_tab_js(). + &inject_data_js(). + &Apache::lonhtmlcommon::resize_scrollbox_js('docs',$tabidstr); + $addentries = { + onload => "javascript:resize_scrollbox('contentscroll','1','1');", + }; } - my $tabidstr = join("','",@tabids); - $script .= &editing_js($udom,$uname,$supplementalflag). - &resize_contentdiv_js($tabidstr); - $addentries = { - onload => "javascript:resize_contentdiv('contentscroll','1','1');", - }; } # -------------------------------------------------------------------- Body tag $script = ' - if (newscrollboxw != scrollboxw) { - var newscrolltablew = newscrollboxw+offsetw; - scrolltable.style.width = newscrolltablew+"px"; - } - } +ENDSWJS - if (contentlistid.offsetWidth != contentlistwstart) { - listwchange = 1; - } + my $startpage = &Apache::loncommon::start_page('Choose server',$js, + {'only_body' => 1, + 'js_ready' => 1,}); + my $endpage = &Apache::loncommon::end_page({'js_ready' => 1}); - if (activeTab == 'cc1') { - if (document.getElementById('cc_hrule') != null) { - document.getElementById('cc_hrule').style.width=actabw+"px"; - } - } else { - if (activeTab == 'bb1') { - if (document.getElementById('bb_hrule') != null) { - document.getElementById('bb_hrule').style.width=actabw+"px"; - } - } else { - if (activeTab == 'ee2') { - if (document.getElementById('ee_hrule') != null) { - document.getElementById('ee_hrule').style.width=actabw+"px"; - } - } - } + my $hostpicker; + my $count = 0; + foreach my $host (sort(@hosts)) { + my $checked; + if ($count == 0) { + $checked = ' checked="checked"'; } + $hostpicker .= '  '; + $count++; } - if ((chkh == 1) || (listwchange)) { - var primaryheight = document.getElementById("LC_nav_bar").offsetHeight; - var secondaryheight = document.getElementById("LC_secondary_menu").offsetHeight; - var crumbsheight = document.getElementById("LC_breadcrumbs").offsetHeight; - var dccidheight = document.getElementById("dccid").offsetHeight; - - var uploadresultheight = 0; - if (document.getElementById("uploadfileresult") != null) { - uploadresultheight = document.getElementById("uploadfileresult").offsetHeight; - } - var tabbedheight = document.getElementById("tabbededitor").offsetHeight; - var contenteditorheight = document.getElementById("contenteditor").offsetHeight; - var scrollboxheight = scrollbox.offsetHeight; - var scrollboxscrollheight = scrollbox.scrollHeight; - var freevspace = vph-(primaryheight+secondaryheight+crumbsheight+dccidheight+uploadresultheight+tabbedheight+contenteditorheight); - - var minvscrollbox = 200; - var offsetv = 20; - var newscrollboxheight; - if (freevspace < 0) { - newscrollboxheight = scrollboxheight+freevspace-offsetv; - if (newscrollboxheight < minvscrollbox) { - newscrollboxheight = minvscrollbox; - } - scrollbox.style.height = newscrollboxheight + "px"; - } else { - if (scrollboxscrollheight > scrollboxheight) { - if (freevspace > offsetv) { - newscrollboxheight = scrollboxheight+freevspace-offsetv; - if (newscrollboxheight < minvscrollbox) { - newscrollboxheight = minvscrollbox; - } - scrollbox.style.height = newscrollboxheight+"px"; - } - } - } - scrollboxheight = scrollbox.offsetHeight; - var contentlistheight = document.getElementById("contentlist").offsetHeight; + + return <<"ENDSWITCHJS"; - if (scrollboxscrollheight <= scrollboxheight) { - if ((contentlistheight+offsetv)$lt{'duco'}<\\/h3>\\n'+ + '

$lt{'yone'}<\\/p>\\n'+ + '

$lt{'chos'}<\\/legend>\\n'+ + '
\\n'+ + '$hostpicker\\n'+ + '

\\n'+ + '\\n'+ + '<\\/form><\\/fieldset><\\/div>
\\n'); + newWindow.document.writeln('$endpage'); + newWindow.document.close(); + newWindow.focus(); +} + +ENDSWITCHJS +} + +sub makedocslogform { + my ($formelems,$docslog) = @_; + return <<"LOGSFORM"; + + + $formelems +
+LOGSFORM } -ENDRESIZESCRIPT - return; +sub makesimpleeditform { + my ($formelems) = @_; + return <<"SIMPFORM"; +
+ + $formelems +
+SIMPFORM } 1; @@ -3694,21 +4157,12 @@ sets @resources - array with the resourc Return hash with valid author names -=item dumpbutton() - -Generate "dump" button - =item clean() =item dumpcourse() Actually dump course - -=item exportbutton() - - Generate "export" button - =item group_import() Imports the given (name, url) resources into the course @@ -3738,8 +4192,6 @@ Generate "dump" button =item is_supplemental_title() -=item parse_supplemental_title() - =item entryline() =item tiehash() @@ -3768,6 +4220,48 @@ Check Versions Breadcrumbs for special functions +=item create_list_elements() + +=item create_form_ul() + +=item startContentScreen() + +=item endContentScreen() + +=item supplemental_base() + +=item embedded_form_elems() + +=item embedded_destination() + +=item return_to_editor() + +=item decompression_info() + +=item decompression_phase_one() + +=item decompression_phase_two() + +=item remove_archive() + +=item generate_admin_menu() + +=item generate_edit_table() + +=item editing_js() + +=item history_tab_js() + +=item inject_data_js() + +=item dump_switchserver_js() + +=item resize_scrollbox_js() + +=item makedocslogform() + +=item makesimpleeditform() + =back =cut