--- loncom/interface/londocs.pm 2018/01/12 01:54:56 1.650 +++ loncom/interface/londocs.pm 2022/10/22 17:24:54 1.684 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.650 2018/01/12 01:54:56 raeburn Exp $ +# $Id: londocs.pm,v 1.684 2022/10/22 17:24:54 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -46,6 +46,7 @@ use Apache::lonsimplepage(); use Apache::lonhomework(); use Apache::lonpublisher(); use Apache::lonparmset(); +use Apache::loncourserespicker(); use HTML::Entities; use HTML::TokeParser; use GDBM_File; @@ -90,7 +91,7 @@ sub storemap { if ($map =~ /^default/) { $hadchanges=1; - } else { + } elsif ($contentchg) { $suppchanges=1; } return ($errtext,0); @@ -182,6 +183,45 @@ sub default_folderpath { } } +sub validate_folderpath { + my ($supplementalflag) = @_; + 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'}); + } + } + return; +} + +sub validate_suppath { + 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'}); + } + } + return; +} + sub dumpcourse { my ($r) = @_; my $crstype = &Apache::loncommon::course_type(); @@ -832,26 +872,27 @@ sub group_import { } my $ext = 'false'; if ($url=~m{^http://} || $url=~m{^https://}) { $ext = 'true'; } - $name = &LONCAPA::map::qtunescape($name); - if ($name eq '') { - $name = &LONCAPA::map::qtunescape(&mt('Web Page')); - } if ($url =~ m{^/uploaded/$coursedom/$coursenum/((?:docs|supplemental)/(?:default|\d+))/new\.html$}) { my $filepath = $1; - my $fname = $name; - if ($fname =~ /^\W+$/) { + my $fname; + if ($name eq '') { + $name = &mt('Web Page'); $fname = 'web'; } else { - $fname =~ s/\W/_/g; - } - if (length($fname) > 15) { - $fname = substr($fname,0,14); + $fname = $name; + $fname=&Apache::lonnet::clean_filename($fname); + if ($fname eq '') { + $fname = 'web'; + } elsif (length($fname) > 15) { + $fname = substr($fname,0,14); + } } + my $title = &Apache::loncommon::cleanup_html($name); my $initialtext = &mt('Replace with your own content.'); my $newhtml = < -$name +$title $initialtext @@ -873,6 +914,7 @@ END return (&mt('Failed to save new web page.'),1); } } + $name = &LONCAPA::map::qtunescape($name); $url = &LONCAPA::map::qtunescape($url); $LONCAPA::map::resources[$residx] = join(':', ($name, $url, $ext, 'normal', 'res')); @@ -913,7 +955,6 @@ END &storemap($coursenum, $coursedom, $folder.'.'.$container,1); unless ($fatal) { if ($folder =~ /^supplemental/) { - &Apache::lonnet::get_numsuppfiles($coursenum,$coursedom,1); my ($errtext,$fatal) = &mapread($coursenum,$coursedom, $folder.'.'.$container); } @@ -1216,13 +1257,19 @@ sub update_paste_buffer { # 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}; - my $mapidx = $env{'docs.markedcopy_map_'.$suffix}; - if (($cid =~ /^$match_domain(?:_)$match_courseid$/) && - ($url ne '')) { - $pasteurls{$cid.'_'.$url.'_'.$mapidx} = 1; - } + my $cid = $env{'docs.markedcopy_crs_'.$suffix}; + my $url = $env{'docs.markedcopy_url_'.$suffix}; + my $mapidx = $env{'docs.markedcopy_map_'.$suffix}; + if (($cid =~ /^$match_domain(?:_)$match_courseid$/) && + ($url ne '')) { + if ($url eq '/res/lib/templates/simpleproblem.problem') { + $pasteurls{$cid.'_'.$mapidx} = 1; + } elsif ($url =~ m{^/res/$match_domain/$match_username/}) { + $pasteurls{$url} = 1; + } else { + $pasteurls{$cid.'_'.$url} = 1; + } + } } } @@ -1231,7 +1278,7 @@ sub update_paste_buffer { my @pathitems = split(/\&/,$env{'form.folderpath'}); my @folderconf = split(/\:/,$pathitems[-1]); - my $ispage = $folderconf[4]; + my $ispage = $folderconf[5]; foreach my $item (@possibles) { my ($orderidx,$cmd) = split(/:/,$item); @@ -1244,7 +1291,13 @@ sub update_paste_buffer { $env{'form.folderpath'},\%curr_groups); next if ($denied{'copy'}); $url=~s{http(:|:)//https(:|:)//}{https$2//}; - next if (exists($pasteurls{$coursedom.'_'.$coursenum.'_'.$mapidx})); + if ($url eq '/res/lib/templates/simpleproblem.problem') { + next if (exists($pasteurls{$coursedom.'_'.$coursenum.'_'.$mapidx})); + } elsif ($url =~ m{^/res/$match_domain/$match_username/}) { + next if (exists($pasteurls{$url})); + } else { + next if (exists($pasteurls{$coursedom.'_'.$coursenum.'_'.$url})); + } my ($suffix,$errortxt,$locknotfreed) = &new_timebased_suffix($env{'user.domain'},$env{'user.name'},'paste'); if ($suffix ne '') { @@ -1441,7 +1494,7 @@ sub print_paste_buffer { } $pasteitems .= ''; if ($nopaste) { - $pasteitems .= $nopaste; + $pasteitems .= ' '.$nopaste.''; } else { if ($othercrs) { $pasteitems .= $othercrs; @@ -1789,7 +1842,7 @@ sub do_paste_from_buffer { %msgs = &Apache::lonlocal::texthash ( notinsupp => 'Paste failed: content type is not supported within Supplemental Content', notincrs => 'Paste failed: Item is from a different course which you do not have rights to edit.', - notindom => 'Paste failed: Item is an external tool from a course in a different donain.', + notindom => 'Paste failed: Item is an external tool from a course in a different domain.', duplicate => 'Paste failed: only one instance of a particular published sequence or page is allowed within each course.', ); @@ -1818,14 +1871,7 @@ sub do_paste_from_buffer { # Retrieve information about all course maps in main content area my $allmaps = {}; - if ($folder =~ /^default/) { - $allmaps = - &Apache::loncommon::allmaps_incourse($coursedom,$coursenum, - $env{"course.$env{'request.course.id'}.home"}, - $env{'request.course.id'}); - } - - my (@toclear,%mapurls,%lockerrs,%msgerrs,%results); + my (@toclear,%mapurls,%lockerrs,%msgerrs,%results,$donechk); # Loop over the items to paste foreach my $suffix (@dopaste) { @@ -1843,6 +1889,13 @@ sub do_paste_from_buffer { if ($is_map{$suffix}) { # If pasting a map, check if map contains other maps my (%hierarchy,%titles); + if (($folder =~ /^default/) && (!$donechk)) { + $allmaps = + &Apache::loncommon::allmaps_incourse($coursedom,$coursenum, + $env{"course.$env{'request.course.id'}.home"}, + $env{'request.course.id'}); + $donechk = 1; + } &contained_map_check($url,$folder,$coursenum,$coursedom, \%removefrommap,\%removeparam,\%addedmaps, \%hierarchy,\%titles,$allmaps); @@ -1908,7 +1961,7 @@ sub do_paste_from_buffer { cnum => $coursenum, ); if ($prefix eq 'ext.tool') { - if ($prefixchg{$suffix} eq 'docstosupp') { + if ($prefixchg{$suffix} eq 'docstosupp') { $info{'delgradable'} = 1; } } @@ -2004,7 +2057,7 @@ sub do_paste_from_buffer { $coursedom,$coursenum,$template,$newidx,"$folder.$container"); } } elsif ($url =~ /ext\.tool$/) { - if (($newidx) && ($folder=~/^default/)) { + if (($newidx) && ($folder=~/^default/)) { my $marker = (split(m{/},$url))[4]; my %toolsettings = &Apache::lonnet::dump('exttool_'.$marker,$coursedom,$coursenum); my $val = 'no'; @@ -2328,7 +2381,9 @@ sub copy_templated_files { my @simpleprobqtypes = qw(radio option string essay numerical); my $qtype=$srcparms{$srcprefix.'questiontype'}; if (grep(/^\Q$qtype\E$/,@simpleprobqtypes)) { - my %newdata; + my %newdata = ( + $newprefix.'questiontype' => $qtype, + ); foreach my $type (@simpleprobqtypes) { if ($type eq $qtype) { $newdata{"$weightprefix.$type.weight"}=1; @@ -2557,7 +2612,7 @@ sub url_paste_fixups { my $rem = $3; my ($is_exttool,$exttoolchg); if ($rem =~ m{\d+/ext\.tool$}) { - $is_exttool = 1; + $is_exttool = 1; } if (($srcdom ne $cdom) || ($srcnum ne $cnum)) { $rewrites->{$oldurl}{$id} = $ressrc; @@ -2744,6 +2799,15 @@ sub apply_fixups { $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/; } my $mapcontent = &Apache::lonnet::getfile($key); + if (($mapcontent eq '-1') && ($before{'map'} eq 'supplemental') && + ($after{'map'} eq 'default') && + ($key =~ m{^/uploaded/$match_domain/$match_courseid/supplemental_\d+\.sequence$})) { + $mapcontent = ''."\n". + ''."\n". + ''."\n". + ''."\n". + ''; + } if ($mapcontent eq '-1') { if (ref($errors) eq 'HASH') { $errors->{$key} = 1; @@ -2802,9 +2866,7 @@ sub apply_fixups { } } if (ref($resdatacopy{$key}) eq 'HASH') { - if ($newsubdir{$key}) { - - } + my ($gotnewmapname,$newmapname,$srcfolder,$srccontainer); foreach my $idx (keys(%{$resdatacopy{$key}})) { if (ref($resdatacopy{$key}{$idx}) eq 'HASH') { my $srcurl = $resdatacopy{$key}{$idx}{'src'}; @@ -2814,15 +2876,18 @@ sub apply_fixups { ($resdatacopy{$key}{$idx}{'cnum'} =~ /^$match_courseid$/)) { my $srcdom = $resdatacopy{$key}{$idx}{'cdom'}; my $srcnum = $resdatacopy{$key}{$idx}{'cnum'}; - my ($newmapname) = ($key =~ m{/([^/]+)$}); - my ($srcfolder,$srccontainer) = split(/\./,$newmapname); + unless ($gotnewmapname) { + ($newmapname) = ($key =~ m{/([^/]+)$}); + ($srcfolder,$srccontainer) = split(/\./,$newmapname); + if ($newsubdir{$key}) { + $newmapname =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/; + } + $gotnewmapname = 1; + } my $srcmapinfo = $srcfolder.':'.$idx; if ($srccontainer eq 'page') { $srcmapinfo .= ':1'; } - if ($newsubdir{$key}) { - $newmapname =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/; - } ©_templated_files($srcurl,$srcdom,$srcnum,$srcmapinfo,$cdom, $cnum,$template,$idx,$newmapname); } @@ -3212,11 +3277,28 @@ sub editor { return $errtext if ($fatal); } + my (%supphidden,%suppids,$suppmapid); + if ($#LONCAPA::map::order<1) { my $idx=&LONCAPA::map::getresidx(); if ($idx<=0) { $idx=1; } $LONCAPA::map::order[0]=$idx; $LONCAPA::map::resources[$idx]=''; + } elsif ($supplementalflag && !$allowed) { + my ($supplemental) = &Apache::lonnet::get_supplemental($coursenum,$coursedom); + if (ref($supplemental) eq 'HASH') { + if (ref($supplemental->{'hidden'}) eq 'HASH') { + %supphidden = %{$supplemental->{'hidden'}}; + } + if (ref($supplemental->{'ids'}) eq 'HASH') { + %suppids = %{$supplemental->{'ids'}}; + } + } + if ($folder eq 'supplemental') { + $suppmapid = 0; + } elsif ($folder =~ /^supplemental_(\d+)$/) { + $suppmapid = $1; + } } # ------------------------------------------------------------ Process commands @@ -3500,11 +3582,15 @@ sub editor { push(@allmapidx,$res); } + if (($supplementalflag) && (!$allowed) && (!$env{'request.role.adv'})) { + next if ($supphidden{$suppmapid.':'.$res}); + } $output .= &entryline($idx,$name,$url,$folder,$allowed,$res, $coursenum,$coursedom,$crstype, $pathitem,$supplementalflag,$container, \%filters,\%curr_groups,$ltitoolsref,$canedit, - $isencrypted,$navmapref,$hostname); + $isencrypted,$navmapref,$hostname, + \%supphidden,\%suppids,$suppmapid); $idx++; $shown++; } @@ -3513,10 +3599,14 @@ sub editor { my $need_save; if ($allowed || ($supplementalflag && $folder eq 'supplemental')) { my $toolslink; - if ($allowed) { + if ($allowed || $canedit) { + my $helpitem = 'Navigation_Screen'; + if (!$allowed) { + $helpitem = 'Supplemental_Navigation'; + } $toolslink = '' .'' - .''; - if ($folder !~ /^supplemental/) { - $to_show .= ''; - } - $to_show .= &Apache::loncommon::end_data_table_header_row(); + .'' + .'' + .&Apache::loncommon::end_data_table_header_row(); if ($folder !~ /^supplemental/) { $lists{'canhide'} = join(',',@allidx); $lists{'canrandomlyorder'} = join(',',@allmapidx); @@ -3884,7 +3972,8 @@ sub is_supplemental_title { sub entryline { my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$coursedom, $crstype,$pathitem,$supplementalflag,$container,$filtersref,$currgroups, - $ltitoolsref,$canedit,$isencrypted,$navmapref,$hostname)=@_; + $ltitoolsref,$canedit,$isencrypted,$navmapref,$hostname, + $supphidden,$suppids,$suppmapid)=@_; my ($foldertitle,$renametitle,$oldtitle); if (&is_supplemental_title($title)) { ($title,$foldertitle,$renametitle) = &Apache::loncommon::parse_supplemental_title($title); @@ -3911,7 +4000,7 @@ sub entryline { my $line=&Apache::loncommon::start_data_table_row(); my ($form_start,$form_end,$form_common,$form_param); # Edit commands - my ($esc_path, $path, $symb, $curralias); + my ($esc_path, $path, $symb, $shownsymb, $curralias); if ($env{'form.folderpath'}) { $esc_path=&escape($env{'form.folderpath'}); $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); @@ -4141,11 +4230,19 @@ END my ($editlink,$extresform,$anchor,$hiddenres,$nomodal); my $orig_url = $url; $orig_url=~s{http(:|:)//https(:|:)//}{https$2//}; - $url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/}; + if ($container eq 'page') { + $url=~s{^http(|s)(:|:)//}{/ext/}; + } else { + $url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/}; + } if (!$supplementalflag && $residx && $symb) { if ((!$isfolder) && (!$ispage)) { (undef,undef,$url)=&Apache::lonnet::decode_symb($symb); - $url=&Apache::lonnet::clutter($url); + if (($url =~ m{^ext/}) && ($container eq 'page')) { + $url=&Apache::lonnet::clutter_with_no_wrapper($url); + } else { + $url=&Apache::lonnet::clutter($url); + } if ($url=~/^\/*uploaded\//) { $url=~/\.(\w+)$/; my $embstyle=&Apache::loncommon::fileembstyle($1); @@ -4159,7 +4256,7 @@ END } elsif ($url=~m{^(|/adm/wrapper)/ext/([^#]+)}) { my $wrapped = $1; my $exturl = $2; - if ($wrapped eq '') { + if (($wrapped eq '') && ($container ne 'page')) { $url='/adm/wrapper'.$url; } if (($ENV{'SERVER_PORT'} == 443) && ($exturl !~ /^https:/)) { @@ -4170,37 +4267,16 @@ END } elsif ($url eq "/public/$coursedom/$coursenum/syllabus") { if (($ENV{'SERVER_PORT'} == 443) && ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) { - $url .= '?usehttp=1'; + unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) { + $url .= '?usehttp=1'; + } $nomodal = 1; } } - if (&Apache::lonnet::symbverify($symb,$url)) { - my $shownsymb = $symb; - if ($isexternal) { - if ($url =~ /^([^#]+)#([^#]+)$/) { - $url = $1; - $anchor = $2; - if ($symb =~ m{^([^#]+)\Q#$anchor\E$}) { - $shownsymb = $1.&escape('#').$anchor; - } - } - } - unless ($env{'request.role.adv'}) { - if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) { - $url = ''; - } - if (&Apache::lonnet::EXT('resource.0.hiddenresource',$symb) =~ /^yes$/i) { - $url = ''; - $hiddenres = 1; - } - } - if ($url ne '') { - $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($shownsymb); - } - } elsif (!$env{'request.role.adv'}) { - my $checkencrypt; + my ($checkencrypt,$shownurl); + if (!$env{'request.role.adv'}) { if (((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i) || - $isencrypted || (&Apache::lonnet::EXT('resource.0.encrypturl',$symb) =~ /^yes$/i)) { + ($isencrypted) || (&Apache::lonnet::EXT('resource.0.encrypturl',$symb) =~ /^yes$/i)) { $checkencrypt = 1; } elsif (ref($navmapref)) { unless (ref($$navmapref)) { @@ -4208,26 +4284,43 @@ END } if (ref($$navmapref)) { if (lc($$navmapref->get_mapparam($symb,undef,"0.encrypturl")) eq 'yes') { - $checkencrypt = 1; + $checkencrypt = 1; } } } - if ($checkencrypt) { - my $shownsymb = &Apache::lonenc::encrypted($symb); - my $shownurl = &Apache::lonenc::encrypted($url); - if (&Apache::lonnet::symbverify($shownsymb,$shownurl)) { - $url = $shownurl.(($shownurl=~/\?/)?'&':'?').'symb='.&escape($shownsymb); - if ($env{'request.enc'} ne '') { - delete($env{'request.enc'}); - } - } else { - $url=''; - } + } + if ($checkencrypt) { + my $currenc = $env{'request.enc'}; + $env{'request.enc'} = 1; + $shownsymb = &Apache::lonenc::encrypted($symb); + $shownurl = &Apache::lonenc::encrypted($url); + if (&Apache::lonnet::symbverify($symb,$url)) { + $url = $shownurl; } else { - $url=''; + $url = ''; } - } else { - $url=''; + $env{'request.enc'} = $currenc; + } elsif (&Apache::lonnet::symbverify($symb,$url)) { + $shownsymb = $symb; + if ($isexternal) { + $url =~ s/\#[^#]+$//; + if ($container eq 'page') { + $url = &Apache::lonnet::clutter($url); + } + } + $shownurl = $url; + } + unless ($env{'request.role.adv'}) { + if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) { + $url = ''; + } + if (&Apache::lonnet::EXT('resource.0.hiddenresource',$symb) =~ /^yes$/i) { + $url = ''; + $hiddenres = 1; + } + } + if ($url ne '') { + $url = $shownurl.(($shownurl=~/\?/)?'&':'?').'symb='.&escape($shownsymb); } } } elsif ($supplementalflag) { @@ -4236,8 +4329,11 @@ END $url = $1; $anchor = $2; if (($url =~ m{^(|/adm/wrapper)/ext/(?!https:)}) && ($ENV{'SERVER_PORT'} == 443)) { - if ($hostname ne '') { - $url = 'http://'.$hostname.$url; + unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) { + if ($hostname ne '') { + $url = 'http://'.$hostname.$url; + } + $url .= (($url =~ /\?/) ? '&':'?').'usehttp=1'; } $nomodal = 1; } @@ -4245,10 +4341,12 @@ END } elsif ($url =~ m{^\Q/public/$coursedom/$coursenum/syllabus\E}) { if (($ENV{'SERVER_PORT'} == 443) && ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) { - if ($hostname ne '') { - $url = 'http://'.$hostname.$url; + unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) { + if ($hostname ne '') { + $url = 'http://'.$hostname.$url; + } + $url .= (($url =~ /\?/) ? '&':'?').'usehttp=1'; } - $url .= (($url =~ /\?/) ? '&':'?').'usehttp=1'; $nomodal = 1; } } @@ -4262,6 +4360,11 @@ END if (!$allowed && $supplementalflag) { $folderpath.=$containerarg.'&'.$foldername; $url.='folderpath='.&escape($folderpath); + if (ref($supphidden) eq 'HASH') { + if ($supphidden->{$suppmapid.':'.$residx}) { + $hiddenfolder = 1; + } + } } else { my $rpicknum = (&LONCAPA::map::getparameter($orderidx, 'parameter_randompick'))[0]; @@ -4355,6 +4458,11 @@ $form_end; if ($anchor ne '') { $url .= '&anchor='.&HTML::Entities::encode($anchor,'"<>&'); } + if (ref($supphidden) eq 'HASH') { + if ($supphidden->{$suppmapid.':'.$residx}) { + $hiddenres = 1; + } + } } my ($tdalign,$tdwidth); if ($allowed) { @@ -4382,7 +4490,7 @@ $form_end; &Apache::lonhtmlcommon::jump_to_editres($cfile,$home, $switchserver, $forceedit, - undef,$symb, + undef,$symb,$shownsymb, &escape($env{'form.folderpath'}), $renametitle,$hostname, '','',1,$suppanchor); @@ -4429,8 +4537,7 @@ $form_end; } else { $link = $url; } - $link = &js_escape($link.(($url=~/\?/)?'&':'?').'inhibitmenu=yes'. - (($anchor ne '')?$anchor:'')); + $link = &js_escape($link.(($url=~/\?/)?'&':'?').'inhibitmenu=yes'.$anchor); if ($nomodal) { $line.=''. ''; @@ -4444,6 +4551,17 @@ $form_end; $line.=''; if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) { $line.=''.$title.''; + if (!$allowed && $supplementalflag && $canedit && $isfolder) { + my $editicon = &Apache::loncommon::lonhttpdurl('/res/adm/pages').'/editmap.png'; + my $editurl = $url; + $editurl =~ s{^\Q/adm/supplemental?\E}{/adm/coursedocs?command=direct&forcesupplement=1&}; + $line .= ' '.''. + ''.&mt('Edit Content').''. + ''; + } + if ((($hiddenfolder) || ($hiddenres)) && (!$allowed) && ($supplementalflag)) { + $line.= ' ('.&mt('hidden').') '; + } } elsif ($url) { if ($nomodal) { $line.=''. @@ -4464,32 +4582,37 @@ $form_end; $line .= ''; $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', - 'ec' => 'URL hidden'); - my ($enctext,$hidtext); - if ((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i) { - $enctext = ' checked="checked"'; - if (($ishash) && (ref($filtersref->{'encrypturl'}) eq 'ARRAY')) { - push(@{$filtersref->{'encrypturl'}},$orderidx); - } - } + if ($allowed) { + my %lt=&Apache::lonlocal::texthash( + 'hd' => 'Hidden', + 'ec' => 'URL hidden'); + my ($enctext,$hidtext,$formhidden,$formurlhidden); if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) { $hidtext = ' checked="checked"'; if (($ishash) && (ref($filtersref->{'randomorder'}) eq 'ARRAY')) { push(@{$filtersref->{'hiddenresource'}},$orderidx); } } - my $formhidden = 'edit_hiddenresource_'.$orderidx; - my $formurlhidden = 'edit_encrypturl_'.$orderidx; - $line.=(<
$form_param $form_common $form_end +ENDPARMS + if ($folder =~/^supplemental/) { + $line.= "\n
ENDPARMS + } } $line.=&Apache::loncommon::end_data_table_row(); return $line; @@ -4812,6 +4936,48 @@ 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::get_requested_shorturls($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 contentverifyform { my ($r) = @_; my $crstype = &Apache::loncommon::course_type(); @@ -4826,7 +4992,7 @@ sub contentverifyform { &mt('No').''.(' 'x2). '

'. - ''. + ''. ''. '

'); $r->print(&endContentScreen()); @@ -5182,13 +5348,17 @@ sub changewarning { if (!defined($message)) { $message='Changes will become active for your current session after [_1], or the next time you log in.'; } + my $windowname = 'loncapaclient'; + if ($env{'request.lti.login'}) { + $windowname .= 'lti'; + } $r->print("\n\n". ''."\n". -'
'. +''. '

'. &mt($message,' internal_redirect($redirect); return OK; } + } else { + $r->internal_redirect($redirect); } } } @@ -5419,7 +5597,7 @@ sub handler { # Get the parameters that may be needed # &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['folderpath', + ['folderpath','title', 'forcesupplement','forcestandard', 'tools','symb','command','supppath']); @@ -5466,35 +5644,11 @@ sub handler { 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'}); - } + &validate_folderpath($supplementalflag); } 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'}); - } + &validate_suppath(); } my $script=''; @@ -5553,6 +5707,9 @@ sub handler { } else { undef($env{'form.folderpath'}); } + if ($env{'form.folderpath'} ne '') { + &validate_folderpath($supplementalflag); + } } # If we are not allowed to make changes, all we can see are supplemental docs @@ -5577,7 +5734,7 @@ sub handler { undef($env{'form.folderpath'}); } else { $folderurl = "uploaded/$coursedom/$coursenum/$folder"; - if ((split(/\:/,$pathitems[-1]))[4]) { + if ((split(/\:/,$pathitems[-1]))[5]) { $folderurl .= '.page'; } else { $folderurl .= '.sequence'; @@ -5671,7 +5828,7 @@ sub handler { my $tid = 1; my @tabids; if ($supplementalflag) { - @tabids = ('002','ee2','ff2'); + @tabids = ('002','dd2','ee2','ff2'); $tid = 2; } else { @tabids = ('aa1','bb1','cc1','ff1'); @@ -5713,8 +5870,14 @@ sub handler { &Apache::lonhtmlcommon::clear_breadcrumbs(); if ($showdoc) { - $r->print(&Apache::loncommon::start_page("$crstype documents",undef, - {'force_register' => $showdoc,})); + my $args; + if ($supplementalflag) { + my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$env{'form.title'},1); + $args = {'bread_crumbs' => $brcrum}; + } else { + $args = {'force_register' => $showdoc}; + } + $r->print(&Apache::loncommon::start_page("$crstype documents",undef,$args)); } elsif ($toolsflag) { my ($breadtext,$breadtitle); $breadtext = "$crstype Editor"; @@ -5732,6 +5895,12 @@ sub handler { $breadtitle) ); } elsif ($r->uri eq '/adm/supplemental') { + unless ($env{'request.role.adv'}) { + unless (&Apache::lonnet::has_unhidden_suppfiles($coursenum,$coursedom)) { + $r->internal_redirect('/adm/navmaps'); + return OK; + } + } my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype); $r->print(&Apache::loncommon::start_page("Supplemental $crstype Content",undef, {'bread_crumbs' => $brcrum,})); @@ -5762,6 +5931,7 @@ sub handler { my %codebase = (); my ($upload_result,$upload_output,$uploadphase); if ($canedit) { + undef($suppchanges); if (($env{'form.uploaddoc.filename'}) && ($env{'form.cmd'}=~/^upload_(\w+)/)) { my $context = $1; @@ -5773,6 +5943,10 @@ sub handler { if ($hadchanges) { &mark_hash_old(); } + if ($suppchanges) { + &Apache::lonnet::update_supp_caches($coursedom,$coursenum); + undef($suppchanges); + } $r->print($upload_output); } elsif ($env{'form.phase'} eq 'upload_embedded') { # Process file upload - phase two - upload embedded objects @@ -5910,8 +6084,8 @@ sub handler { my $fileupload=(< - - + + FIUP my $checkbox=(<print(''."\n" ); @@ -6122,7 +6300,7 @@ HIDDENFORM my $newnavform=(< - + $pathitem @@ -6132,7 +6310,7 @@ HIDDENFORM NNFORM my $newsmppageform=(< - + $pathitem $lt{'sipa'} @@ -6142,7 +6320,7 @@ NSPFORM my $newsmpproblemform=(< - + $pathitem $lt{'sipr'} @@ -6153,7 +6331,7 @@ NSPROBFORM my $newdropboxform=(< - + $pathitem $lt{'drbx'} @@ -6163,7 +6341,7 @@ NDBFORM my $newexuploadform=(< - + $pathitem $lt{'scuf'} @@ -6173,7 +6351,7 @@ NEXUFORM my $newbulform=(< - + $pathitem $lt{'bull'} @@ -6183,7 +6361,7 @@ NBFORM my $newaboutmeform=(< - + $pathitem @@ -6194,7 +6372,7 @@ NAMFORM my $newaboutsomeoneform=(< - + $pathitem $lt{'abou'} @@ -6203,7 +6381,7 @@ NASOFORM my $newrosterform=(< - + $pathitem @@ -6224,7 +6402,7 @@ NROSTFORM } my $newwebpageform =(< - + $pathitem $lt{'webp'} @@ -6407,7 +6585,7 @@ NWEBFORM

' .&Apache::loncommon::help_open_menu('Navigation Screen', - 'Navigation_Screen',undef,'RAT') + $helpitem,undef,'RAT') .''.&mt('Tools:').''.&mt('Actions').''.&mt('Document').''.&mt('Settings').''.&mt('Document').''.&mt('Settings').'"; + } else { + if ((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i) { + $enctext = ' checked="checked"'; + if (($ishash) && (ref($filtersref->{'encrypturl'}) eq 'ARRAY')) { + push(@{$filtersref->{'encrypturl'}},$orderidx); + } + } + $formurlhidden = 'edit_encrypturl_'.$orderidx; + $line.=(< $form_param @@ -4500,6 +4623,7 @@ $form_end; $rand_pick_text
$rand_order_text