--- loncom/interface/londocs.pm 2016/08/06 20:00:29 1.484.2.63 +++ loncom/interface/londocs.pm 2019/08/16 16:12:37 1.484.2.82 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.484.2.63 2016/08/06 20:00:29 raeburn Exp $ +# $Id: londocs.pm,v 1.484.2.82 2019/08/16 16:12:37 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -139,7 +139,43 @@ sub clean { return $title; } - +sub default_folderpath { + my ($coursenum,$coursedom,$navmapref) = @_; + return unless ($coursenum && $coursedom && ref($navmapref)); +# Check if entire course is hidden and/or encrypted + my ($hiddenmap,$encryptmap,$folderpath,$hiddentop); + my $toplevel = "uploaded/$coursedom/$coursenum/default.sequence"; + unless (ref($$navmapref)) { + $$navmapref = Apache::lonnavmaps::navmap->new(); + } + if (ref($$navmapref)) { + if (lc($$navmapref->get_mapparam(undef,$toplevel,"0.hiddenresource")) eq 'yes') { + my $filterFunc = sub { my $res = shift; return (!$res->randomout() && !$res->is_map()) }; + my @resources = $$navmapref->retrieveResources($toplevel,$filterFunc,1,1); + unless (@resources) { + $hiddenmap = 1; + unless ($env{'request.role.adv'}) { + $hiddentop = 1; + if ($env{'form.folder'}) { + undef($env{'form.folder'}); + } + } + } + } + if (lc($$navmapref->get_mapparam(undef,$toplevel,"0.encrypturl")) eq 'yes') { + $encryptmap = 1; + } + } + unless ($hiddentop) { + $folderpath='default&'.&escape(&mt('Main Content')). + '::'.$hiddenmap.':'.$encryptmap.'::'; + } + if (wantarray) { + return ($folderpath,$hiddentop); + } else { + return $folderpath; + } +} sub dumpcourse { my ($r) = @_; @@ -791,12 +827,14 @@ sub log_docs { } sub docs_change_log { - my ($r,$coursenum,$coursedom,$folder,$allowed,$crstype,$iconpath)=@_; + my ($r,$coursenum,$coursedom,$folder,$allowed,$crstype,$iconpath,$canedit)=@_; my $supplementalflag=($env{'form.folderpath'}=~/^supplemental/); + my $navmap; my $js = ''."\n"; + .''."\n" + .''."\n"; # Breadcrumbs &Apache::lonhtmlcommon::clear_breadcrumbs(); @@ -4784,34 +5365,52 @@ sub handler { $r->print(&Apache::loncommon::start_page("$crstype documents",undef, {'force_register' => $showdoc,})); } elsif ($toolsflag) { + my ($breadtext,$breadtitle); + $breadtext = "$crstype Editor"; + if ($canedit) { + $breadtitle = 'Editing '.$crstype.' Contents'; + } else { + $breadtext .= ' (View-only mode)'; + $breadtitle = 'Viewing '.$crstype.' Contents'; + } &Apache::lonhtmlcommon::add_breadcrumb({ - href=>"/adm/coursedocs",text=>"$crstype Contents"}); + href=>"/adm/coursedocs",text=>$breadtext}); $r->print(&Apache::loncommon::start_page("$crstype Contents", $script) .&Apache::loncommon::help_open_menu('','',273,'RAT') .&Apache::lonhtmlcommon::breadcrumbs( - 'Editing Course Contents') + $breadtitle) ); } elsif ($r->uri eq '/adm/supplemental') { my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype); $r->print(&Apache::loncommon::start_page("Supplemental $crstype Content",undef, {'bread_crumbs' => $brcrum,})); } else { + my ($breadtext,$breadtitle,$helpitem); + $breadtext = "$crstype Editor"; + if ($canedit) { + $breadtitle = 'Editing '.$crstype.' Contents'; + $helpitem = 'Docs_Adding_Course_Doc'; + } else { + $breadtext .= ' (View-only mode)'; + $breadtitle = 'Viewing '.$crstype.' Contents'; + $helpitem = 'Docs_Viewing_Course_Doc'; + } &Apache::lonhtmlcommon::add_breadcrumb({ - href=>"/adm/coursedocs",text=>"$crstype Contents"}); + href=>"/adm/coursedocs",text=>$breadtext}); $r->print(&Apache::loncommon::start_page("$crstype Contents", $script, {'add_entries' => $addentries} ) .&Apache::loncommon::help_open_menu('','',273,'RAT') .&Apache::lonhtmlcommon::breadcrumbs( - 'Editing '.$crstype.' Contents', - 'Docs_Adding_Course_Doc') + $breadtitle, + $helpitem) ); } my %allfiles = (); my %codebase = (); my ($upload_result,$upload_output,$uploadphase); - if ($allowed) { + if ($canedit) { if (($env{'form.uploaddoc.filename'}) && ($env{'form.cmd'}=~/^upload_(\w+)/)) { my $context = $1; @@ -4819,6 +5418,7 @@ sub handler { undef($hadchanges); $uploadphase = &process_file_upload(\$upload_output,$coursenum,$coursedom, \%allfiles,\%codebase,$context,$crstype); + undef($navmap); if ($hadchanges) { &mark_hash_old(); } @@ -4863,7 +5463,7 @@ sub handler { if ($allowed && $toolsflag) { $r->print(&startContentScreen('tools')); - $r->print(&generate_admin_menu($crstype)); + $r->print(&generate_admin_menu($crstype,$canedit)); $r->print(&endContentScreen()); } elsif ((!$showdoc) && (!$uploadphase)) { # ----------------------------------------------------------------------------- @@ -4903,11 +5503,46 @@ sub handler { 'bb6' => 'Blackboard 6', 'angel5' => 'ANGEL 5.5', 'webctce4' => 'WebCT 4 Campus Edition', + 'er' => 'Editing rights unavailable for your current role.', ); # ----------------------------------------------------------------------------- + # Calculate free quota space for a user or course. A javascript function checks + # file size to determine if upload should be allowed. + my $quotatype = 'unofficial'; + if ($crstype eq 'Community') { + $quotatype = 'community'; + } elsif ($env{'course.'.$coursedom.'_'.$coursenum.'.internal.coursecode'}) { + $quotatype = 'official'; + } elsif ($env{'course.'.$coursedom.'_'.$coursenum.'.internal.textbook'}) { + $quotatype = 'textbook'; + } + my $disk_quota = &Apache::loncommon::get_user_quota($coursenum,$coursedom, + 'course',$quotatype); # expressed in MB + my $current_disk_usage = 0; + foreach my $subdir ('docs','supplemental') { + $current_disk_usage += &Apache::lonnet::diskusage($coursedom,$coursenum, + "userfiles/$subdir",1); # expressed in kB + } + my $free_space = 1024 * ((1024 * $disk_quota) - $current_disk_usage); + my $usage = $current_disk_usage/1024; # in MB + my $quota = $disk_quota; + my $percent; + if ($disk_quota == 0) { + $percent = 100.0; + } else { + $percent = 100*($usage/$disk_quota); + } + $usage = sprintf("%.2f",$usage); + $quota = sprintf("%.2f",$quota); + $percent = sprintf("%.0f",$percent); + my $quotainfo = '

'.&mt('Currently using [_1] of the [_2] available.', + $percent.'%',$quota.' MB').'

'; + my $fileupload=(< - + + FIUP my $checkbox=(< --> CHBO my $imsfolder = $env{'form.folder'}; @@ -4932,7 +5567,7 @@ CHBO

$lt{'cms'}:  - @@ -4942,7 +5577,7 @@ CHBO

- + IMSFORM @@ -4957,7 +5592,7 @@ IMSFORM $fileupload
$lt{'title'}:
- + $pathitem
@@ -4965,11 +5600,17 @@ IMSFORM $checkbox
- + FUFORM + my $mapimportjs; + if ($canedit) { + $mapimportjs = "javascript:openbrowser('mapimportform','importmap','sequence,page','');"; + } else { + $mapimportjs = "javascript:alert('".&js_escape($lt{'er'})."');"; + } my $importpubform=(< $lt{'impm'}$help{'Load_Map'} @@ -4980,31 +5621,42 @@ FUFORM $lt{'copm'}
-  $lt{'selm'}
- + onfocus="this.blur();$mapimportjs" $disabled /> +  $lt{'selm'}
+ SEDFFORM + + my $fromstoredjs; + if ($canedit) { + $fromstoredjs = 'open_StoredLinks_Import()'; + } else { + $fromstoredjs = "alert('".&js_escape($lt{'er'})."')"; + } + my @importpubforma = ( { ''.$lt{srch}.'' => $pathitem."$lt{'srch'}" }, { ''.$lt{impo}.'' => "$lt{'impo'}$help{'Importing_LON-CAPA_Resource'}" }, - { ''.$lt{lnks}.'' => "$lt{'lnks'}" }, + { ''.$lt{lnks}.'' => ''.$lt{'lnks'}.'' }, { ''.$lt{impm}.'' => $importpubform } ); $importpubform = &create_form_ul(&create_list_elements(@importpubforma)); my $extresourcesform = &Apache::lonextresedit::extedit_form(0,0,undef,undef,$pathitem, - $help{'Adding_External_Resource'}); + $help{'Adding_External_Resource'}, + undef,undef,$disabled); if ($allowed) { my $folder = $env{'form.folder'}; if ($folder eq '') { $folder='default'; } - my $output = &update_paste_buffer($coursenum,$coursedom,$folder); - if ($output) { - $r->print($output); + if ($canedit) { + my $output = &update_paste_buffer($coursenum,$coursedom,$folder); + if ($output) { + $r->print($output); + } } $r->print(< @@ -5041,7 +5693,7 @@ HIDDENFORM if ($allowed) { my $folder=$env{'form.folder'}; - if ($folder eq '' || $supplementalflag) { + if ((($folder eq '') && (!$hiddentop)) || ($supplementalflag)) { $folder='default'; $savefolderpath = $env{'form.folderpath'}; $env{'form.folderpath'}='default&'.&escape(&mt('Main Content')); @@ -5069,7 +5721,7 @@ HIDDENFORM $pathitem - $lt{'navc'} + $lt{'navc'} $help{'Navigate_Content'} NNFORM @@ -5130,7 +5782,7 @@ NBFORM $pathitem - $lt{'mypi'} + $lt{'mypi'} $help{'My Personal Information Page'} NAMFORM @@ -5150,7 +5802,7 @@ NASOFORM $pathitem - $lt{'rost'} + $lt{'rost'} $help{'Course_Roster'} NROSTFORM @@ -5213,7 +5865,7 @@ NFFORM $pathitem - $lt{'syll'} + $lt{'syll'} $help{'Syllabus'} @@ -5225,14 +5877,14 @@ NSYLFORM $pathitem - $lt{'grpo'} + $lt{'grpo'} $help{'Group Portfolio'} NGFFORM @specialdocumentsforma=( {''.$lt{newp}.''=>$newpageform}, - {''.$lt{syll}.''=>$newsylform}, - {''.$lt{navc}.''=>$newnavform}, + {''.$lt{syll}.''=>$newsylform}, + {''.$lt{navc}.''=>$newnavform}, {''.$lt{sipa}.''=>$newsmppageform}, {''.$lt{webp}.''=>$newwebpageform}, ); @@ -5264,8 +5916,8 @@ NGFFORM {''.$lt{bull}.''=>$newbulform}, {''.$lt{mypi}.''=>$newaboutmeform}, {''.$lt{abou}.''=>$newaboutsomeoneform}, - {''.$lt{rost}.''=>$newrosterform}, - {''.$lt{grpo}.''=>$newgroupfileform}, + {''.$lt{rost}.''=>$newrosterform}, + {''.$lt{grpo}.''=>$newgroupfileform}, ); $communityform = &create_form_ul(&create_list_elements(@communityforma)); @@ -5283,12 +5935,16 @@ unless ($container eq 'page') { $hadchanges=0; unless (($supplementalflag || $toolsflag)) { my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, - $supplementalflag,\%orderhash,$iconpath,$pathitem); + $supplementalflag,\%orderhash,$iconpath,$pathitem, + $canedit,\$navmap,$hiddentop); + undef($navmap); if ($error) { $r->print('

'.$error.'

'); } if ($hadchanges) { - &mark_hash_old(); + unless (&is_hash_old()) { + &mark_hash_old(); + } } &changewarning($r,''); @@ -5348,7 +6004,8 @@ SNFFORM my $supextform = &Apache::lonextresedit::extedit_form(1,0,undef,undef,$pathitem, - $help{'Adding_External_Resource'}); + $help{'Adding_External_Resource'}, + undef,undef,$disabled); my $supnewsylform=(< @@ -5356,7 +6013,7 @@ SNFFORM $pathitem - $lt{'syll'} + $lt{'syll'} $help{'Syllabus'} SNSFORM @@ -5367,7 +6024,7 @@ SNSFORM $pathitem - $lt{'mypi'} + $lt{'mypi'} $help{'My Personal Information Page'} SNAMFORM @@ -5394,9 +6051,9 @@ SWEBFORM my @specialdocs = ( - {''.$lt{syll}.'' + {''.$lt{syll}.'' =>$supnewsylform}, - {''.$lt{mypi}.'' + {''.$lt{mypi}.'' =>$supnewaboutmeform}, {''.$lt{webp}.''=>$supwebpageform}, @@ -5416,7 +6073,8 @@ my %suporderhash = ( ); if ($supplementalflag) { my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, - $supplementalflag,\%suporderhash,$iconpath,$pathitem); + $supplementalflag,\%suporderhash,$iconpath,$pathitem, + $canedit); if ($error) { $r->print('

'.$error.'

'); } else { @@ -5470,6 +6128,7 @@ my %suporderhash = ( sub embedded_form_elems { my ($phase,$primaryurl,$newidx) = @_; my $folderpath = &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); + $newidx =~s /\D+//g; return < @@ -5490,7 +6149,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); } @@ -5516,6 +6179,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"; @@ -5621,7 +6287,7 @@ sub remove_archive { } sub generate_admin_menu { - my ($crstype) = @_; + my ($crstype,$canedit) = @_; my $lc_crstype = lc($crstype); my ($home,$other,%outhash)=&authorhosts(); my %lt= ( # do not translate here @@ -5679,7 +6345,9 @@ sub generate_admin_menu { linktitle => "List the unique identifier used for each resource instance in your $lc_crstype" }, ] - }, + }); + if ($canedit) { + push(@menu, { categorytitle=>'Export', items =>[ { linktext => $lt{'imse'}, @@ -5698,6 +6366,7 @@ sub generate_admin_menu { }, ] }); + } return '
'."\n". ''."\n". &Apache::lonhtmlcommon::generate_menu(@menu)."\n". @@ -5706,15 +6375,16 @@ sub generate_admin_menu { sub generate_edit_table { my ($tid,$orderhash_ref,$to_show,$iconpath,$jumpto,$readfile, - $need_save,$copyfolder) = @_; + $need_save,$copyfolder,$canedit) = @_; return unless(ref($orderhash_ref) eq 'HASH'); my %orderhash = %{$orderhash_ref}; - my $form; - my $activetab; - my $active; + my ($form, $activetab, $active, $disabled); if (($env{'form.active'} ne '') && ($env{'form.active'} ne '00')) { $activetab = $env{'form.active'}; } + unless ($canedit) { + $disabled = ' disabled="disabled"'; + } my $backicon = $iconpath.'clickhere.gif'; my $backtext = &mt('Exit Editor'); $form = '
'. @@ -5778,7 +6448,7 @@ sub generate_edit_table { - +
END @@ -5804,7 +6474,8 @@ END } sub editing_js { - my ($udom,$uname,$supplementalflag) = @_; + my ($udom,$uname,$supplementalflag,$coursedom,$coursenum, + $canedit,$hostname,$navmapref) = @_; my %js_lt = &Apache::lonlocal::texthash( p_mnf => 'Name of New Folder', t_mnf => 'New Folder', @@ -5844,6 +6515,7 @@ sub editing_js { noor => 'No actions selected or changes to settings specified.', noch => 'No changes to settings specified.', noac => 'No actions selected.', + edri => 'Editing rights unavailable for your current role.', ); &js_escape(\%js_lt); @@ -5853,11 +6525,10 @@ sub editing_js { if (&HTML::Entities::decode($env{'environment.internal.'.$env{'request.course.id'}.'.docs_folderpath.folderpath'}) =~ /\:1$/) { $main_container_page = 1; } - my $toplevelmain = - &escape(&mt('Main Content').':::::'); + my $backtourl; + my $toplevelmain = &escape(&default_folderpath($coursenum,$coursedom,$navmapref)); my $toplevelsupp = &supplemental_base(); - my $backtourl; if ($env{'docs.exit.'.$env{'request.course.id'}} =~ /^direct_(.+)$/) { my $caller = $1; if ($caller =~ /^supplemental/) { @@ -5866,8 +6537,41 @@ sub editing_js { my ($map,$id,$res)=&Apache::lonnet::decode_symb($caller); $res = &Apache::lonnet::clutter($res); if (&Apache::lonnet::is_on_map($res)) { - $backtourl = &HTML::Entities::encode(&Apache::lonnet::clutter($res),'<>&"').'?symb='. + my ($url,$anchor); + if ($res =~ /^([^#]+)#([^#]+)$/) { + $url = $1; + $anchor = $2; + if (($caller =~ m{^([^#]+)\Q#$anchor\E$})) { + $caller = $1.&escape('#').$anchor; + } + } else { + $url = $res; + } + $backtourl = &HTML::Entities::encode(&Apache::lonnet::clutter($url),'<>&"').'?symb='. &HTML::Entities::encode($caller,'<>&"'); + if ($backtourl =~ m{^\Q/public/$coursedom/$coursenum/syllabus\E}) { + if (($ENV{'SERVER_PORT'} == 443) && + ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) { + unless (&Apache::lonnet::uses_sts()) { + if ($hostname ne '') { + $backtourl = 'http://'.$hostname.$backtourl; + } + $backtourl .= (($backtourl =~ /\?/) ? '&':'?').'usehttp=1'; + } + } + } elsif ($backtourl =~ m{^/adm/wrapper/ext/(?!https:)}) { + if (($ENV{'SERVER_PORT'} == 443) && ($hostname ne '')) { + unless (&Apache::lonnet::uses_sts()) { + if ($hostname ne '') { + $backtourl = 'http://'.$hostname.$backtourl; + } + $backtourl .= (($backtourl =~ /\?/) ? '&':'?').'usehttp=1'; + } + } + } + if ($anchor ne '') { + $backtourl .= '#'.&HTML::Entities::encode($anchor,'<>&"'); + } $backtourl = &Apache::loncommon::escape_single($backtourl); } else { $backtourl = '/adm/navmaps'; @@ -5889,9 +6593,11 @@ sub editing_js { $fieldsets = "'suppext','suppdoc'"; } - return <