--- loncom/interface/londocs.pm 2017/06/22 02:11:26 1.484.2.72.2.1 +++ loncom/interface/londocs.pm 2020/01/16 15:21:23 1.484.2.72.2.7 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.484.2.72.2.1 2017/06/22 02:11:26 raeburn Exp $ +# $Id: londocs.pm,v 1.484.2.72.2.7 2020/01/16 15:21:23 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -43,6 +43,7 @@ use Apache::lonnavdisplay(); use Apache::lonextresedit(); use Apache::lontemplate(); use Apache::lonsimplepage(); +use Apache::loncourserespicker(); use HTML::Entities; use HTML::TokeParser; use GDBM_File; @@ -2598,7 +2599,8 @@ sub apply_fixups { } } } - for (my $i=0; $i<@LONCAPA::map::order; $i++) { + my $total = scalar(@LONCAPA::map::order) - 1; + for (my $i=$total; $i>=0; $i--) { my $idx = $LONCAPA::map::order[$i]; if (defined($LONCAPA::map::resources[$idx])) { my $changed; @@ -2608,7 +2610,7 @@ sub apply_fixups { splice(@LONCAPA::map::order,$i,1); if (ref($currparam{$idx}) eq 'ARRAY') { foreach my $name (@{$currparam{$idx}}) { - &LONCAPA::map::delparameter($idx,'parameter_'.$name); + &LONCAPA::map::delparameter($idx,$name); } } next; @@ -2650,7 +2652,7 @@ sub apply_fixups { foreach my $idx (keys(%remparam)) { if (ref($remparam{$idx}) eq 'ARRAY') { foreach my $name (@{$remparam{$idx}}) { - &LONCAPA::map::delparameter($idx,'parameter_'.$name); + &LONCAPA::map::delparameter($idx,$name); } } } @@ -3925,7 +3927,7 @@ END } } if ($url ne '') { - $url.=(($url=~/\?/)?'&':'?').'symb='.&HTML::Entities::encode($shownsymb,'"<>&'); + $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($shownsymb); } } elsif (!$env{'request.role.adv'}) { my $checkencrypt; @@ -3946,7 +3948,7 @@ END my $shownsymb = &Apache::lonenc::encrypted($symb); my $shownurl = &Apache::lonenc::encrypted($url); if (&Apache::lonnet::symbverify($shownsymb,$shownurl)) { - $url = $shownurl.(($shownurl=~/\?/)?'&':'?').'symb='.&HTML::Entities::encode($shownsymb,'"<>&'); + $url = $shownurl.(($shownurl=~/\?/)?'&':'?').'symb='.&escape($shownsymb); if ($env{'request.enc'} ne '') { delete($env{'request.enc'}); } @@ -4086,7 +4088,8 @@ $form_end; if ($isexternal) { ($editlink,$extresform) = &Apache::lonextresedit::extedit_form(0,$residx,$orig_url,$title,$pathitem, - undef,undef,undef,$disabled); + undef,undef,undef,undef,undef,undef, + undef,$disabled); } elsif ($orig_url =~ m{^/adm/$coursedom/$coursenum/\d+/ext\.tool$}) { ($editlink,$extresform) = &Apache::lonextresedit::extedit_form(0,$residx,$orig_url,$title,$pathitem, @@ -4495,6 +4498,47 @@ sub list_symbs { $r->print(&endContentScreen()); } +sub short_urls { + my ($r,$canedit) = @_; + my $crstype = &Apache::loncommon::course_type(); + my $formname = 'shortenurl'; + $r->print(&Apache::loncommon::start_page('Display/Set Shortened URLs')); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Shortened URLs')); + $r->print(&startContentScreen('tools')); + my ($navmap,$errormsg) = + &Apache::loncourserespicker::get_navmap_object($crstype,'shorturls'); + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my (%maps,%resources,%titles); + if (!ref($navmap)) { + $r->print($errormsg. + &endContentScreen()); + return ''; + } else { + $r->print('

'.&mt('Tiny URLs for deep-linking into course').'

'."\n"); + $r->rflush(); + my $readonly; + if ($canedit) { + my ($numnew,$errors) = &Apache::loncommon::make_short_symbs($cdom,$cnum,$navmap); + if ($numnew) { + $r->print('

'.&mt('Created [quant,_1,URL]',$numnew).'

'); + } + if ((ref($errors) eq 'ARRAY') && (@{$errors} > 0)) { + $r->print(&mt('The following errors occurred when processing your request to create shortened URLs:').'

'); + } + } else { + $readonly = 1; + } + my %currtiny = &Apache::lonnet::dump('tiny',$cdom,$cnum); + $r->print(&Apache::loncourserespicker::create_picker($navmap,'shorturls',$formname,$crstype,undef, + undef,undef,undef,undef,undef,\%currtiny,$readonly)); + } + $r->print(&endContentScreen()); +} sub verifycontent { my ($r) = @_; @@ -4985,12 +5029,20 @@ sub handler { $disabled = ' disabled="disabled"'; } &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['inhibitmenu']); + if ($env{'form.inhibitmenu'}) { + unless ($env{'form.inhibitmenu'} eq 'yes') { + delete($env{'form.inhibitmenu'}); + } + } if ($allowed && $env{'form.verify'}) { &init_breadcrumbs('verify','Verify Content','Docs_Verify_Content'); &verifycontent($r); } elsif ($allowed && $env{'form.listsymbs'}) { &init_breadcrumbs('listsymbs','List Content IDs'); &list_symbs($r); + } elsif ($allowed && $env{'form.shorturls'}) { + &init_breadcrumbs('shorturls','Set/Display Shortened URLs','Docs_Short_URLs'); + &short_urls($r,$canedit); } elsif ($allowed && $env{'form.docslog'}) { &init_breadcrumbs('docslog','Show Log'); my $folder = $env{'form.folder'}; @@ -5018,6 +5070,25 @@ sub handler { 'forcesupplement','forcestandard', 'tools','symb','command','supppath']); + foreach my $item ('forcesupplement','forcestandard','tools') { + next if ($env{'form.'.$item} eq ''); + unless ($env{'form.'.$item} eq '1') { + delete($env{'form.'.$item}); + } + } + + if ($env{'form.command'}) { + unless ($env{'form.command'} =~ /^(direct|directnav|editdocs|editsupp|contents|home)$/) { + delete($env{'form.command'}); + } + } + + if ($env{'form.symb'}) { + my ($mapurl,$id,$resurl) = &Apache::lonnet::decode_symb($env{'form.symb'}); + unless (($id =~ /^\d+$/) && (&Apache::lonnet::is_on_map($resurl))) { + delete($env{'form.symb'}); + } + } # 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 @@ -5040,6 +5111,38 @@ sub handler { my $toolsflag=0; if ($env{'form.tools'}) { $toolsflag=1; } + if ($env{'form.folderpath'} ne '') { + my @items = split(/\&/,$env{'form.folderpath'}); + my $badpath; + for (my $i=0; $i<@items; $i++) { + my $odd = $i%2; + if (($odd) && (!$supplementalflag) && ($items[$i] !~ /^[^:]*:(|\d+):(|1):(|1):(|1):(|1)$/)) { + $badpath = 1; + } elsif ((!$odd) && ($items[$i] !~ /^(default|supplemental)(|_\d+)$/)) { + $badpath = 1; + } + last if ($badpath); + } + if ($badpath) { + delete($env{'form.folderpath'}); + } + } + + if ($env{'form.supppath'} ne '') { + my @items = split(/\&/,$env{'form.supppath'}); + my $badpath; + for (my $i=0; $i<@items; $i++) { + my $odd = $i%2; + if ((!$odd) && ($items[$i] !~ /^supplemental(|_\d+)$/)) { + $badpath = 1; + } + last if ($badpath); + } + if ($badpath) { + delete($env{'form.supppath'}); + } + } + my $script=''; my $showdoc=0; my $addentries = {}; @@ -5309,6 +5412,7 @@ sub handler { undef($hadchanges); $uploadphase = &process_file_upload(\$upload_output,$coursenum,$coursedom, \%allfiles,\%codebase,$context,$crstype); + undef($navmap); if ($hadchanges) { &mark_hash_old(); } @@ -5536,7 +5640,7 @@ SEDFFORM my $extresourcesform = &Apache::lonextresedit::extedit_form(0,0,undef,undef,$pathitem, $help{'Adding_External_Resource'}, - undef,undef,$disabled); + undef,undef,undef,undef,undef,undef,$disabled); my $exttoolform = &Apache::lonextresedit::extedit_form(0,0,undef,undef,$pathitem, $help{'Adding_External_Tool'},undef, @@ -5842,9 +5946,10 @@ unless ($container eq 'page') { $r->print('

'.$error.'

'); } if ($hadchanges) { - &mark_hash_old(); + unless (&is_hash_old()) { + &mark_hash_old(); + } } - &changewarning($r,''); } } @@ -5903,8 +6008,8 @@ SNFFORM my $supextform = &Apache::lonextresedit::extedit_form(1,0,undef,undef,$pathitem, $help{'Adding_External_Resource'}, - undef,undef,$disabled); - + undef,undef,undef,undef,undef,undef, + $disabled); my $supexttoolform = &Apache::lonextresedit::extedit_form(1,0,undef,undef,$pathitem, $help{'Adding_External_Tool'}, @@ -6037,6 +6142,7 @@ my %suporderhash = ( sub embedded_form_elems { my ($phase,$primaryurl,$newidx) = @_; my $folderpath = &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); + $newidx =~s /\D+//g; return < @@ -6057,7 +6163,11 @@ sub embedded_destination { } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) { $destination .= $2.'/'; } - $destination .= $env{'form.newidx'}; + my $newidx = $env{'form.newidx'}; + $newidx =~s /\D+//g; + if ($newidx) { + $destination .= $newidx; + } my $dir_root = '/userfiles'; return ($destination,$dir_root); } @@ -6083,6 +6193,9 @@ sub decompression_info { } unshift(@hiddens,$pathitem); foreach my $item (@hiddens) { + if ($item eq 'newidx') { + next if ($env{'form.'.$item} =~ /\D/); + } if ($env{'form.'.$item}) { $hiddenelem .= ''."\n"; @@ -6195,6 +6308,7 @@ sub generate_admin_menu { 'vc' => 'Verify Content', 'cv' => 'Check/Set Resource Versions', 'ls' => 'List Resource Identifiers', + 'ct' => 'Display/Set Shortened URLs for Deep-linking', 'imse' => 'Export contents to IMS Archive', 'dcd' => "Copy $crstype Content to Authoring Space", ); @@ -6245,6 +6359,13 @@ sub generate_admin_menu { icon => 'symbs.png', linktitle => "List the unique identifier used for each resource instance in your $lc_crstype" }, + { linktext => $lt{'ct'}, + url => "javascript:injectData(document.courseverify,'dummy','shorturls','$lt{'ct'}')", + permission => 'F', + help => 'Docs_Short_URLs', + icon => 'shorturls.png', + linktitle => "Set shortened URLs for a resource or folder in your $lc_crstype for use in deep-linking" + }, ] }); if ($canedit) { @@ -6447,8 +6568,13 @@ sub editing_js { } else { $url = $res; } - $backtourl = &HTML::Entities::encode(&Apache::lonnet::clutter($url),'<>&"').'?symb='. - &HTML::Entities::encode($caller,'<>&"'); + $backtourl = &HTML::Entities::encode(&Apache::lonnet::clutter($url),'<>&"'); + if ($backtourl =~ m{^\Q/uploaded/$coursedom/$coursenum/\Edefault_\d+\.sequence$}) { + $backtourl .= '?navmap=1'; + } else { + $backtourl .= '?symb='. + &HTML::Entities::encode($caller,'<>&"'); + } if ($anchor ne '') { $backtourl .= '#'.&HTML::Entities::encode($anchor,'<>&"'); } @@ -7663,7 +7789,9 @@ check on this Verify Content -=item devalidateversioncache() & checkversions() +=item devalidateversioncache() + +=item checkversions() Check Versions