--- loncom/interface/londocs.pm 2013/04/03 02:41:22 1.484.2.30 +++ loncom/interface/londocs.pm 2012/07/05 21:33:39 1.489 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.484.2.30 2013/04/03 02:41:22 raeburn Exp $ +# $Id: londocs.pm,v 1.489 2012/07/05 21:33:39 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::lonextresedit(); +use Apache::lonuserstate(); use HTML::Entities; use HTML::TokeParser; use GDBM_File; @@ -69,14 +69,10 @@ sub mapread { } sub storemap { - my ($coursenum,$coursedom,$map,$contentchg)=@_; - my $report; - if (($contentchg) && ($map =~ /^default/)) { - $report = 1; - } + my ($coursenum,$coursedom,$map)=@_; my ($outtext,$errtext)= &LONCAPA::map::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'. - $map,1,$report); + $map,1); if ($errtext) { return ($errtext,2); } $hadchanges=1; @@ -152,7 +148,7 @@ sub dumpcourse { $r->print(&endContentScreen()); return ''; } - my ($ca,$cd)=split(/\:/,$env{'form.authorspace'}); + my ($ca,$cd)=split(/\@/,$env{'form.authorspace'}); $r->print('
'."\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". - '
'.
- join('
',@{$msgsarray}).
- '
'. - $lockerror. - '
'; + $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; } - } - my ($errtext,$fatal) = - &storemap($coursenum, $coursedom, $folder.'.'.$container,1); - return ($errtext,$fatal,$fixuperrors); + if ($2) { $ishidden=1; } + if ($3) { $isencrypted=1; } + if ($4 ne '') { $is_random_order = 1; } + if ($folder eq 'supplemental') { + $name = &mt('Supplemental '.$crstype.' Content'); + } + &Apache::lonhtmlcommon::add_breadcrumb( + {'href'=>$url.$cpinfo, + 'title'=>$name, + 'text'=>$name, + 'no_mt'=>1, + }); + $plain.=$name.' > '; + } + $plain=~s/\>\;\s*$//; + return (&Apache::lonhtmlcommon::breadcrumbs(undef,undef,0,'nohelp', + undef, undef, 1 ),$randompick,$ishidden, + $isencrypted,$plain,$is_random_order); } sub log_docs { - return &Apache::lonnet::write_log('course','docslog',@_); + return &Apache::lonnet::instructor_log('docslog',@_); } { @@ -485,15 +442,17 @@ sub docs_change_log { my %orderhash; my $container='sequence'; my $pathitem; - if ($env{'form.folderpath'} =~ /\:1$/) { + 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 $folderpath=$env{'form.folderpath'}; - if ($folderpath eq '') { - $folderpath = 'default&'.&escape(&mt('Main '.$crstype.' Content').':::::'); - } - $pathitem = ''; my $readfile="/uploaded/$coursedom/$coursenum/$folder.$container"; my $jumpto = $readfile; $jumpto =~ s{^/}{}; @@ -501,8 +460,7 @@ sub docs_change_log { if ($supplementalflag) { $tid = 2; } - my ($breadcrumbtrail) = - &Apache::lonhtmlcommon::docs_breadcrumbs($allowed,$crstype,1); + my ($breadcrumbtrail) = &breadcrumbs($allowed,$crstype); $r->print($breadcrumbtrail. &generate_edit_table($tid,\%orderhash,undef,$iconpath,$jumpto, $readfile)); @@ -654,343 +612,94 @@ sub docs_change_log { } sub update_paste_buffer { - my ($coursenum,$coursedom,$folder) = @_; - my (@possibles,%removals,%cuts); - if ($env{'form.multiremove'}) { - $env{'form.multiremove'} =~ s/,$//; - map { $removals{$_} = 1; } split(/,/,$env{'form.multiremove'}); - } - if (($env{'form.multicopy'}) || ($env{'form.multicut'})) { - if ($env{'form.multicut'}) { - $env{'form.multicut'} =~ s/,$//; - foreach my $item (split(/,/,$env{'form.multicut'})) { - unless ($removals{$item}) { - $cuts{$item} = 1; - push(@possibles,$item.':cut'); - } - } - } - if ($env{'form.multicopy'}) { - $env{'form.multicopy'} =~ s/,$//; - foreach my $item (split(/,/,$env{'form.multicopy'})) { - unless ($removals{$item} || $cuts{$item}) { - push(@possibles,$item.':copy'); - } - } - } - } elsif ($env{'form.markcopy'}) { - @possibles = split(/,/,$env{'form.markcopy'}); - } + my ($coursenum,$coursedom) = @_; - return if (@possibles == 0); + return if (!defined($env{'form.markcopy'})); return if (!defined($env{'form.copyfolder'})); + return if ($env{'form.markcopy'} < 0); my ($errtext,$fatal) = &mapread($coursenum,$coursedom, $env{'form.copyfolder'}); - return if ($fatal); - my %curr_groups = &Apache::longroup::coursegroups(); + return if ($fatal); -# Retrieve current paste buffer suffixes. - my @currpaste = split(/,/,$env{'docs.markedcopies'}); - my (%pasteurls,@newpaste); - -# Construct identifiers for current contents of user's paste buffer - if (@currpaste) { - foreach my $suffix (@currpaste) { - my $cid = $env{'docs.markedcopy_crs_'.$suffix}; - my $url = $env{'docs.markedcopy_url_'.$suffix}; - if (($cid =~ /^$match_domain(?:_)$match_courseid$/) && - ($url ne '')) { - $pasteurls{$cid.'_'.$url}; - } - } +# Mark for copying + my ($title,$url)=split(':',$LONCAPA::map::resources[$LONCAPA::map::order[$env{'form.markcopy'}]]); + if (&is_supplemental_title($title)) { + &Apache::lonnet::appenv({'docs.markedcopy_supplemental' => $title}); + ($title) = &Apache::loncommon::parse_supplemental_title($title); + } elsif ($env{'docs.markedcopy_supplemental'}) { + &Apache::lonnet::delenv('docs.markedcopy_supplemental'); } + $url=~s{http(:|:)//https(:|:)//}{https$2//}; -# Mark items for copying (skip any items already in user's paste buffer) - my %addtoenv; - - foreach my $item (@possibles) { - my ($orderidx,$cmd) = split(/:/,$item); - next if ($orderidx =~ /\D/); - next unless (($cmd eq 'cut') || ($cmd eq 'copy') || ($cmd eq 'remove')); - my ($title,$url)=split(':',$LONCAPA::map::resources[$orderidx]); - my %denied = &action_restrictions($coursenum,$coursedom, - &LONCAPA::map::qtescape($url), - $env{'form.folderpath'},\%curr_groups); - next if ($denied{'copy'}); - $url=~s{http(:|:)//https(:|:)//}{https$2//}; - next if (exists($pasteurls{$coursedom.'_'.$coursenum.'_'.$url})); - my ($suffix,$errortxt,$locknotfreed) = - &new_timebased_suffix($env{'user.domain'},$env{'user.name'},'paste'); - push(@newpaste,$suffix); - if ($locknotfreed) { - return $locknotfreed; - last; - } - if (&is_supplemental_title($title)) { - &Apache::lonnet::appenv({'docs.markedcopy_supplemental_'.$suffix => $title}); - ($title) = &Apache::loncommon::parse_supplemental_title($title); - } - - $addtoenv{'docs.markedcopy_title_'.$suffix} = $title, - $addtoenv{'docs.markedcopy_url_'.$suffix} = $url, - $addtoenv{'docs.markedcopy_cmd_'.$suffix} = $cmd, - $addtoenv{'docs.markedcopy_crs_'.$suffix} = $env{'request.course.id'}; - - if ($url =~ m{^/uploaded/$match_domain/$match_courseid/(default|supplemental)_?(\d*)\.(page|sequence)$}) { - my $prefix = $1; - my $subdir =$2; - if ($subdir eq '') { - $subdir = $prefix; - } - my (%addedmaps,%removefrommap,%removeparam,%hierarchy,%titles,%allmaps); - &contained_map_check($url,$folder,\%removefrommap,\%removeparam,\%addedmaps, - \%hierarchy,\%titles,\%allmaps); - if (ref($hierarchy{$url}) eq 'HASH') { - my ($nested,$nestednames); - &recurse_uploaded_maps($url,$subdir,\%hierarchy,\%titles,\$nested,\$nestednames); - $nested =~ s/\&$//; - $nestednames =~ s/\Q___&&&___\E$//; - if ($nested ne '') { - $addtoenv{'docs.markedcopy_nested_'.$suffix} = $nested; - } - if ($nestednames ne '') { - $addtoenv{'docs.markedcopy_nestednames_'.$suffix} = $nestednames; - } - } - } - } - if (@newpaste) { - $addtoenv{'docs.markedcopies'} = join(',',(@currpaste,@newpaste)); - } - &Apache::lonnet::appenv(\%addtoenv); + &Apache::lonnet::appenv({'docs.markedcopy_title' => $title, + 'docs.markedcopy_url' => $url}); delete($env{'form.markcopy'}); } -sub recurse_uploaded_maps { - my ($url,$dir,$hierarchy,$titlesref,$nestref,$namesref) = @_; - if (ref($hierarchy->{$url}) eq 'HASH') { - my @maps = map { $hierarchy->{$url}{$_}; } sort { $a <=> $b } (keys(%{$hierarchy->{$url}})); - my @titles = map { $titlesref->{$url}{$_}; } sort { $a <=> $b } (keys(%{$titlesref->{$url}})); - my (@uploaded,@names,%shorter); - for (my $i=0; $i<@maps; $i++) { - my ($inner) = ($maps[$i] =~ m{^/uploaded/$match_domain/$match_courseid/(?:default|supplemental)_(\d+)\.(?:page|sequence)$}); - if ($inner ne '') { - push(@uploaded,$inner); - push(@names,&escape($titles[$i])); - $shorter{$maps[$i]} = $inner; - } - } - $$nestref .= "$dir:".join(',',@uploaded).'&'; - $$namesref .= "$dir:".(join(',',@names)).'___&&&___'; - foreach my $map (@maps) { - if ($shorter{$map} ne '') { - &recurse_uploaded_maps($map,$shorter{$map},$hierarchy,$titlesref,$nestref,$namesref); - } - } - } - return; -} - sub print_paste_buffer { - my ($r,$container,$folder,$coursedom,$coursenum) = @_; - return if (!defined($env{'docs.markedcopies'})); + my ($r,$container,$folder) = @_; + return if (!defined($env{'docs.markedcopy_url'})); - unless (($env{'form.pastemarked'}) || ($env{'form.clearmarked'})) { - return if ($env{'docs.markedcopies'} eq ''); + 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 @currpaste = split(/,/,$env{'docs.markedcopies'}); - my ($pasteitems,@pasteable); - -# Construct identifiers for current contents of user's paste buffer - foreach my $suffix (@currpaste) { - next if ($suffix =~ /\D/); - my $cid = $env{'docs.markedcopy_crs_'.$suffix}; - my $url = $env{'docs.markedcopy_url_'.$suffix}; - if (($cid =~ /^$match_domain\_$match_courseid$/) && - ($url ne '')) { - my ($is_external,$othercourse,$fromsupp,$is_uploaded_map,$parent, - $canpaste,$nopaste,$othercrs,$areachange); - my $extension = (split(/\./,$env{'docs.markedcopy_url_'.$suffix}))[-1]; - if ($url =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//} ) { - $is_external = 1; - } - if ($folder =~ /^supplemental/) { - $canpaste = &supp_pasteable($env{'docs.markedcopy_url_'.$suffix}); - unless ($canpaste) { - $nopaste = &mt('Paste into Supplemental Content unavailable.'); - } - } else { - $canpaste = 1; - } - if ($canpaste) { - if ($url =~ m{^/uploaded/($match_domain)/($match_courseid)/(.+)$}) { - my $srcdom = $1; - my $srcnum = $2; - my $rem = $3; - if (($srcdom ne $coursedom) || ($srcnum ne $coursenum)) { - $othercourse = 1; - if ($env{"user.priv.cm./$srcdom/$srcnum"} =~ /\Q:mdc&F\E/) { - if ($canpaste) { - $othercrs = ''.&mt('Paste into Supplemental Content unavailable for this type of content.').'
'); } + $r->print(''); } sub supp_pasteable { @@ -1005,640 +714,210 @@ sub supp_pasteable { return; } -sub paste_popup_js { - my %lt = &Apache::lonlocal::texthash( - show => 'Show Options', - hide => 'Hide Options', - none => 'No items selected from clipboard.', - ); - return <<"END"; - -function showPasteOptions(suffix) { - document.getElementById('pasteoptions_'+suffix).style.display='block'; - document.getElementById('pasteoptionstext_'+suffix).innerHTML = ' $lt{'hide'}'; - return; -} - -function hidePasteOptions(suffix) { - document.getElementById('pasteoptions_'+suffix).style.display='none'; - document.getElementById('pasteoptionstext_'+suffix).innerHTML =' $lt{'show'}'; - return; -} - -function showOptions(caller,suffix) { - if (document.getElementById('pasteoptionstext_'+suffix)) { - if (caller.checked) { - document.getElementById('pasteoptionstext_'+suffix).innerHTML =' $lt{'show'}'; - } else { - document.getElementById('pasteoptionstext_'+suffix).innerHTML =''; - } - if (document.getElementById('pasteoptions_'+suffix)) { - document.getElementById('pasteoptions_'+suffix).style.display='none'; - } - } - return; -} - -function validateClipboard() { - var numchk = 0; - if (document.pasteform.pasting.length > 1) { - for (var i=0; i'.
- join('
',@{$pastemsgarray}).
- '
'.$paste_res.'
'); } - if ($lockerror) { - $r->print(''. - $lockerror. - '
'); - } - if ($save_error ne '') { - return $save_error; - } - if ($paste_res) { - my %errortext = &Apache::lonlocal::texthash ( - fail => 'Storage of folder contents failed', - failread => 'Reading folder contents failed', - failstore => 'Storage of folder contents failed', - ); - if ($errortext{$paste_res}) { - $r->print(''.$errortext{$paste_res}.'
'); - } - } - if (keys(%paste_errors) > 0) { - $r->print(''."\n". - &mt('The following files are either dependencies of a web page or references within a folder and/or composite page which could not be copied during the paste operation:')."\n". - '
'.$output.'
'); - } - } + } $r->print($upload_output); -# Rename, cut, copy or remove a single resource if (&handle_edit_cmd()) { - my $contentchg; - if ($env{'form.cmd'} =~ m{^(del|cut)_}) { - $contentchg = 1; - } - ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container,$contentchg); + ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container); return $errtext if ($fatal); } - -# Cut, copy and/or remove multiple resources - if ($env{'form.multichange'}) { - my %allchecked = ( - cut => {}, - remove => {}, - ); - my $needsupdate; - foreach my $which (keys(%allchecked)) { - $env{'form.multi'.$which} =~ s/,$//; - if ($env{'form.multi'.$which}) { - map { $allchecked{$which}{$_} = 1; } split(/,/,$env{'form.multi'.$which}); - if (ref($allchecked{$which}) eq 'HASH') { - $needsupdate += scalar(keys(%{$allchecked{$which}})); - } - } - } - if ($needsupdate) { - my $haschanges = 0; - my %curr_groups = &Apache::longroup::coursegroups(); - my $total = scalar(@LONCAPA::map::order) - 1; - for (my $i=$total; $i>=0; $i--) { - my $res = $LONCAPA::map::order[$i]; - my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]); - $name=&LONCAPA::map::qtescape($name); - $url=&LONCAPA::map::qtescape($url); - next unless ($name && $url); - my %denied = - &action_restrictions($coursenum,$coursedom,$url, - $env{'form.folderpath'},\%curr_groups); - foreach my $which (keys(%allchecked)) { - next if ($denied{$which}); - next unless ($allchecked{$which}{$res}); - if ($which eq 'remove') { - if (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) && - ($url!~/$LONCAPA::assess_page_seq_re/)) { - &Apache::lonnet::removeuploadedurl($url); - } else { - &LONCAPA::map::makezombie($res); - } - splice(@LONCAPA::map::order,$i,1); - $haschanges ++; - } elsif ($which eq 'cut') { - &LONCAPA::map::makezombie($res); - splice(@LONCAPA::map::order,$i,1); - $haschanges ++; - } - } - } - if ($haschanges) { - ($errtext,$fatal) = - &storemap($coursenum,$coursedom,$folder.'.'.$container,1); - return $errtext if ($fatal); - } - } - } - # Group import/search if ($env{'form.importdetail'}) { my @imports; foreach my $item (split(/\&/,$env{'form.importdetail'})) { if (defined($item)) { my ($name,$url,$residx)= - map { &unescape($_); } split(/\=/,$item); - 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); - } - } - } + map {&unescape($_)} split(/\=/,$item); push(@imports, [$name, $url, $residx]); } } - ($errtext,$fatal,my $fixuperrors) = - &group_import($coursenum, $coursedom, $folder,$container, - 'londocs',@imports); + ($errtext,$fatal)=&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'}) { @@ -2553,7 +1307,7 @@ sub editor { $LONCAPA::map::order[$#LONCAPA::map::order+1]=$idx; } ($errtext,$fatal)=&storemap($coursenum,$coursedom, - $folder.'.'.$container,1); + $folder.'.'.$container); return $errtext if ($fatal); } else { $r->print(''.&mt('No map selected.').'
'); @@ -2597,17 +1351,8 @@ sub editor { $r->print(''); } - my ($to_show,$output,@allidx,@allmapidx,%filters,%lists,%curr_groups); - %filters = ( - canremove => [], - cancut => [], - cancopy => [], - hiddenresource => [], - encrypturl => [], - randomorder => [], - randompick => [], - ); - %curr_groups = &Apache::longroup::coursegroups(); + my ($to_show,$output); + &Apache::loncommon::start_data_table_count(); #setup a row counter foreach my $res (@LONCAPA::map::order) { my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]); @@ -2615,110 +1360,36 @@ sub editor { $url=&LONCAPA::map::qtescape($url); unless ($name) { $name=(split(/\//,$url))[-1]; } unless ($name) { $idx++; next; } - push(@allidx,$res); - if ($url =~ m{/uploaded/.+\.(page|sequence)$}) { - push(@allmapidx,$res); - } $output .= &entryline($idx,$name,$url,$folder,$allowed,$res, - $coursenum,$coursedom,$crstype, - $pathitem,$supplementalflag,$container, - \%filters,\%curr_groups); + $coursenum,$crstype); $idx++; $shown++; } &Apache::loncommon::end_data_table_count(); - - my $need_save; - if (($allowed) || ($supplementalflag && $folder eq 'supplemental')) { - my $toolslink = '' - .&Apache::loncommon::help_open_menu('Navigation Screen', - 'Navigation_Screen',undef,'RAT') - .' | '.&mt('Tools:').' | ' - .'
|