--- loncom/interface/portfolio.pm 2005/02/11 00:18:14 1.73 +++ loncom/interface/portfolio.pm 2008/12/05 10:23:56 1.200 @@ -1,3 +1,8 @@ +# The LearningOnline Network +# portfolio browser +# +# $Id: portfolio.pm,v 1.200 2008/12/05 10:23:56 bisitz Exp $ +# # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). @@ -29,368 +34,1735 @@ use Apache::lonnet; use Apache::lontexconvert; use Apache::lonfeedback; use Apache::lonlocal; +use Apache::lonnet; +use Apache::longroup; +use Apache::lonhtmlcommon; +use HTML::Entities; +use LONCAPA; + +sub group_args { + my $output; + if (defined($env{'form.group'})) { + $output .= '&group='.$env{'form.group'}; + if (defined($env{'form.ref'})) { + $output .= '&ref='.$env{'form.ref'}; + } + } + return $output; +} + +sub group_form_data { + my $output; + if (defined($env{'form.group'})) { + $output = ''; + if (exists($env{'form.ref'})) { + $output .= ''; + } + } + return $output; +} # receives a file name and path stub from username/userfiles/portfolio/ # returns an anchor tag consisting encoding filename and currentpath sub make_anchor { - my ($filename, $current_path, $current_mode, $field_name) = @_; - my $anchor = ''.$filename.''; + my ($url, $anchor_fields, $inner_text) = @_; + if ($$anchor_fields{'continue'} ne 'true') {$$anchor_fields{'continue'} = 'false'}; + my $anchor = ''.$inner_text.''; return $anchor; } + my $dirptr=16384; sub display_common { - my ($r,$current_path,$is_empty,$dir_list)=@_; - my $iconpath= $r->dir_config('lonIconsURL') . "/"; - $r->print(''); - $r->print('
'); - my $displayOut = '
'; - $displayOut .= ''. - ''. - ''. - ''. - ''. - ''. - '
'; - $r->print($displayOut); - $r->print('
'); - $displayOut = '
'; - $displayOut .= ''. - ''. - ''. - ''. - ''. - ''. - '
'; - $r->print($displayOut); - $r->print('
'); + my ($r,$url,$current_path,$is_empty,$dir_list,$can_upload)=@_; + my $namespace = &get_namespace(); + my $port_path = &get_port_path(); + if ($can_upload) { + my $groupitem = &group_form_data(); + + my $iconpath= $r->dir_config('lonIconsURL') . "/"; + my %lt=&Apache::lonlocal::texthash( + 'upload' => 'Upload', + 'upload_label' => 'Upload file to current directory', + 'createdir' => 'Create Subdirectory', + 'createdir_label' => + 'Create subdirectory in current directory', + 'parse' => 'If HTML file, upload embedded images/multimedia/css/linked files' + ); + my $escuri = &HTML::Entities::encode($r->uri,'&<>"'); + my $help_fileupload = &Apache::loncommon::help_open_topic('Portfolio AddFiles'); + my $help_createdir = &Apache::loncommon::help_open_topic('Portfolio CreateDirectory'); + + # FIXME: This line should be deleted once Portfolio uses breadcrumbs + $r->print(&Apache::loncommon::help_open_topic('Portfolio About', &mt('Help on the portfolio'))); + + my $parse_check; + if (!&suppress_embed_prompt()) { + $parse_check = <<"END"; +
+ + + +END + } + + $r->print('
'); + # Upload File + $r->print('
' + .'
' + .'
' + .''.$lt{'upload_label'}.'' + .$groupitem + .'' + .'' + .'' + .'' + .'' + .'' + .$help_fileupload + .$parse_check + .'
' + .'
' + .'
' + ); + # Create Subdirectory + $r->print('
' + .'
' + .'
' + .''.$lt{'createdir_label'}.'' + .''.$groupitem + .'' + .'' + .'' + .'' + .'' + .$help_createdir + .'
' + .'
' + .'
' + ); + $r->print('
'); + } # end "if can_upload" + my @tree = split (/\//,$current_path); - $r->print(''.&make_anchor('portfolio','/',$ENV{"form.mode"},$ENV{"form.fieldname"}).'/'); + my %anchor_fields = ( + 'selectfile' => $port_path, + 'currentpath' => '/', + 'mode' => $env{"form.mode"}, + 'fieldname' => $env{"form.fieldname"}, + 'continue' => $env{"form.continue"} + ); + $r->print(''.&make_anchor($url,\%anchor_fields,$port_path).'/'); if (@tree > 1){ - my $newCurrentPath = ''; + my $newCurrentPath = '/'; for (my $i = 1; $i< @tree; $i++){ $newCurrentPath .= $tree[$i].'/'; - $r->print(&make_anchor($tree[$i],'/'.$newCurrentPath, $ENV{"form.mode"},$ENV{"form.fieldname"}).'/'); + my %anchor_fields = ( + 'selectfile' => $tree[$i], + 'currentpath' => $newCurrentPath, + 'mode' => $env{"form.mode"}, + 'fieldname' => $env{"form.fieldname"}, + 'continue' => $env{"form.continue"} + ); + $r->print(&make_anchor($url,\%anchor_fields,$tree[$i]).'/'); } } - $r->print(''); - &Apache::lonhtmlcommon::store_recent('portfolio',$current_path,$current_path); - $r->print('
'. - &Apache::lonhtmlcommon::select_recent('portfolio','currentpath', + $r->print(''); + $r->print(&Apache::loncommon::help_open_topic('Portfolio ChangeDirectory')); + &Apache::lonhtmlcommon::store_recent($namespace,$current_path,$current_path); + $r->print('
'. + &Apache::lonhtmlcommon::select_recent($namespace,'currentpath', 'this.form.submit();')); $r->print("
"); } -sub display_directory { - my ($r,$current_path,$is_empty,$dir_list)=@_; - my $iconpath= $r->dir_config('lonIconsURL') . "/"; - my $display_out; - my %locked_files = &Apache::lonnet::get_marked_as_readonly_hash ($ENV{'user.domain'},$ENV{'user.name'}); - if ($is_empty && ($current_path ne '/')) { - $display_out = '
'. - ''. - ''. - ''. - ''. - '
'; - - $r->print($display_out); - return; - } - $r->print(''. - ''); - my $href_location="/uploaded/$ENV{'user.domain'}/$ENV{'user.name'}/portfolio$current_path"; - $r->print(''); - foreach my $line (sort - { - my ($afile)=split('&',$a,2); - my ($bfile)=split('&',$b,2); - return (lc($afile) cmp lc($bfile)); - } (@$dir_list)) { - #$strip holds directory/file name - #$dom - my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$line,16); - if (($filename ne '.') && ($filename ne '..')) { - if ($dirptr&$testdir) { - $r->print(''); - $r->print(''); - $r->print(''); - $r->print(''); - } else { - $r->print(''); - if (exists $locked_files{$current_path.$filename}){ - $r->print(''); - } else { - $r->print(' - '); - } - $r->print(''); - $r->print(''); - $r->print(''); - $r->print(''); - $r->print(''); + +sub display_directory_line { + my ($r,$select_mode, $filename, $mtime, $size, $css_class, + $line, $access_controls, $curr_access, $now, $version_flag, + $href_location, $url, $current_path, $access_admin_text, $versions)=@_; + + my $fullpath = &prepend_group($current_path.$filename); + $r->print(&Apache::loncommon::start_data_table_row()); + $r->print($line); # contains first two cells of table + my $lock_info; + if ($version_flag) { # versioned can't be versioned, so TRUE when root file + $r->print(''); + $r->print(''); + } else { # this is a graded or handed back file + my ($user,$domain) = &get_name_dom($env{'form.group'}); + my $permissions_hash = &Apache::lonnet::get_portfile_permissions($domain,$user); + if (defined($$permissions_hash{$fullpath})) { + foreach my $array_item (@{$$permissions_hash{$fullpath}}) { + if (ref($array_item) eq 'ARRAY') { + if ($$array_item[-1] eq 'handback') { + $lock_info = 'Handback'; + } elsif ($$array_item[-1] eq 'graded') { + $lock_info = 'Graded'; + } + } } } + if ($lock_info) { + my %anchor_fields = ('lockinfo' => $fullpath); + if ($versions) { # hold the folder open + my ($fname,$version,$extension) = &Apache::grades::file_name_version_ext($fullpath); + $fname =~ s|^/||; + $anchor_fields{'showversions'} = $fname.'.'.$extension; + } + $lock_info = &make_anchor(undef,\%anchor_fields,$lock_info); + } + $r->print(''); + } + # $r->print(''); + $r->print(''); + $r->print(''); + if ($select_mode ne 'true') { + $r->print(''); # Display status + $r->print(''); + } else { + $r->print(''); # Display status } -# pink bg -# blue bg -# $r->print(&display_directory($current_path, $currentFile, @dir_list)); -# $r->print('>
Actions NameSizeLast Modified
Go to ...'.&make_anchor($filename.'/',$current_path.$filename.'/',$ENV{'form.mode'},$ENV{"form.fieldname"}).'
Locked - RenameMeta - '. - $filename.''.$size.''.&Apache::lonlocal::locallocaltime($mtime).'
'.$version_flag.''.$lock_info.''.$$version_flag{$filename}.''); + $r->print(''.&make_anchor($href_location.$filename,undef,$filename).''.$size.''.&Apache::lonlocal::locallocaltime($mtime).'  ' + .&mt($curr_access).'   ' + ); + my %anchor_fields = ( + 'access' => $filename, + 'currentpath' => $current_path + ); + $r->print(&make_anchor($url, \%anchor_fields, $access_admin_text).'  
'); -# $r->print(&display_actions($current_path, $currentFile, $isEmpty)); - $r->print('
- - - - '); + $r->print(&Apache::loncommon::end_data_table_row().$/); } -sub display_file_select { - my ($r,$current_path,$is_empty,$dir_list)=@_; + +sub display_directory { + my ($r,$url,$current_path,$is_empty,$dir_list,$group,$can_upload, + $can_modify,$can_delete,$can_setacl)=@_; my $iconpath= $r->dir_config('lonIconsURL') . "/"; my $display_out; - my $checked_files = &Apache::lonnet::files_in_path($ENV{'user.name'}, $ENV{'form.currentpath'}); - if ($is_empty && ($current_path ne '/')) { - $display_out = '
'. + my $select_mode; + my $checked_files; + my $port_path = &get_port_path(); + my ($uname,$udom) = &get_name_dom($group); + my $access_admin_text = &mt('View Status'); + if ($can_setacl) { + $access_admin_text = &mt('View/Change Status'); + } + + my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom, + $uname); + my %locked_files = &Apache::lonnet::get_marked_as_readonly_hash( + $current_permissions,$group); + my %access_controls = &Apache::lonnet::get_access_controls($current_permissions,$group); + my $now = time; + if ($env{"form.mode"} eq 'selectfile') { + &select_files($r); + $checked_files =&Apache::lonnet::files_in_path($uname,$env{'form.currentpath'}); + $select_mode = 'true'; + } + if ($is_empty && ($current_path ne '/') && $can_delete) { + $display_out = ''. + &group_form_data(). ''. + '

'. ''. + '

'. ''. ''. - '
'; $r->print($display_out); return; } - $r->print(''. - ''); - my $href_location="/uploaded/$ENV{'user.domain'}/$ENV{'user.name'}/portfolio$current_path"; - $r->print(''); - foreach my $line (sort + if ($select_mode eq 'true') { + $r->print(''); + $r->print(&Apache::loncommon::start_data_table() + .&Apache::loncommon::start_data_table_header_row() + .'' + .'' + .'' + .'' + .'' + .'' + .&Apache::loncommon::end_data_table_header_row() + ); + } else { + $r->print(''); + $r->print(&Apache::loncommon::help_open_topic('Portfolio FileList', + &mt('Using the portfolio file list'))); + $r->print(&Apache::loncommon::start_data_table() + .&Apache::loncommon::start_data_table_header_row() + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .&Apache::loncommon::end_data_table_header_row()); + } + $r->print("\n".&group_form_data()."\n"); + + my $href_location="/uploaded/$udom/$uname/$port_path".$current_path; + my $href_edit_location="/editupload/$udom/$uname/$port_path".$current_path; + my @dir_lines; + my %versioned; + foreach my $dir_line (sort { my ($afile)=split('&',$a,2); my ($bfile)=split('&',$b,2); return (lc($afile) cmp lc($bfile)); } (@$dir_list)) { - #$strip holds directory/file name - #$dom - my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$line,16); + my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$dir_line,16); $filename =~ s/\s+$//; - if (($filename ne '.') && ($filename ne '..')) { + my ($fname,$version,$extension) = &Apache::grades::file_name_version_ext($filename); + if ($version) { + my $fullpath = &prepend_group($current_path.$fname.'.'.$extension); + push(@{ $versioned{$fullpath} }, + [$filename,$dom,$testdir,$size,$mtime,$obs,]); + } else { + push(@dir_lines, [$filename,$dom,$testdir,$size,$mtime,$obs]); + } + } + foreach my $dir_line (@dir_lines) { + my ($filename,$dom,$testdir,$size,$mtime,$obs) = @$dir_line; + my ($fname,$version,$extension) = &Apache::grades::file_name_version_ext($filename); + if (($filename ne '.') && ($filename ne '..') && ($filename !~ /\.meta$/ ) && ($filename !~ /(.*)\.(\d+)\.([^\.]*)$/)) { + my $version_flag; + my $show_versions; + my $fullpath = &prepend_group($current_path.$filename); + if ($env{'form.showversions'} =~ /$filename/) { + $show_versions = 'true'; + } + if (exists($versioned{$fullpath})) { + my %anchor_fields = ( + 'selectfile' => $fullpath, + 'continue' => 'false', + 'currentpath' => $current_path, + ); + if ($show_versions) { + # Must preserve other possible showversion files + my $version_remainder = $env{'form.showversions'}; + $version_remainder =~ s/$filename//g; + $anchor_fields{'showversions'} = $version_remainder; + $version_flag = &make_anchor('portfolio',\%anchor_fields, + ''.&mt('opened folder').''); + } else { + # allow multiple files to show versioned + $anchor_fields{'showversions'} = $env{'form.showversions'}.','.$filename; + $version_flag = &make_anchor('portfolio',\%anchor_fields, + ''.&mt('closed folder').''); + } + } else { + $version_flag = ' '; + } if ($dirptr&$testdir) { - $r->print(''); - $r->print(''); - $r->print(''); + my $colspan_folder=''; + my $colspan_fill=''; + if ($select_mode eq 'true'){ + $colspan_fill=' colspan="3"'; + } else { + $colspan_folder=' colspan="2"'; + $colspan_fill=' colspan="4"'; + } + $r->print(''); + $r->print(''.&mt('closed folder').'' + .''); + my %anchor_fields = ( + 'selectfile' => $filename.'/', + 'currentpath' => $current_path.$filename.'/', + 'mode' => $env{"form.mode"}, + 'fieldname' => $env{"form.fieldname"}, + 'continue' => $env{"form.continue"} + ); + $r->print('' + .''); + $r->print(' '); $r->print(''); } else { - $r->print(''); - $r->print(''); - $r->print(''); - $r->print(''); - $r->print(''); - $r->print(''); - $r->print(''); + my $css_class = 'LC_browser_file'; + my $line; + if ($select_mode eq 'true') { + $line=''; + $css_class= 'LC_browser_file_locked'; + } else { + if (!$can_modify) { + $line .= ''; + } + } + my $curr_access; + if ($select_mode ne 'true') { + my $pub_access = 0; + my $guest_access = 0; + my $cond_access = 0; + foreach my $key (sort(keys(%{$access_controls{$fullpath}}))) { + my ($num,$scope,$end,$start) = &unpack_acc_key($key); + if (($now > $start) && (!$end || $end > $now)) { + if ($scope eq 'public') { + $pub_access = 1; + } elsif ($scope eq 'guest') { + $guest_access = 1; + } else { + $cond_access = 1; + } + } + } + if (!$pub_access && !$guest_access && !$cond_access) { + $curr_access = &mt('Private'); + } else { + my @allaccesses; + if ($pub_access) { + push(@allaccesses,&mt('Public')); + } + if ($guest_access) { + push(@allaccesses,&mt('Passphrase-protected')); + } + if ($cond_access) { + push(@allaccesses,&mt('Conditional')); + } + $curr_access = join('+ ',@allaccesses); + } + } + &display_directory_line($r,$select_mode, $filename, $mtime, $size, $css_class, $line, + \%access_controls, $curr_access,$now, $version_flag, $href_location, + $url, $current_path, $access_admin_text); + if ($show_versions) { + foreach my $dir_line (@{ $versioned{$fullpath} }) { + my ($v_filename,$dom,$testdir,$size,$mtime,$obs) = + @$dir_line; + $line = ''; + &display_directory_line($r,$select_mode, $v_filename, $mtime, $size, + $css_class, $line, \%access_controls, $curr_access, $now, + undef, $href_location, $url, $current_path, $access_admin_text, 1); + } + } } } } - $r->print('
Select NameSizeLast Modified
'.&mt('Select').'  '.&mt('Name').''.&mt('Size').''.&mt('Last Modified').' '.&mt('Actions'). &Apache::loncommon::help_open_topic('Portfolio FileAction').'  '.&mt('Name').&Apache::loncommon::help_open_topic('Portfolio OpenFile').''.&mt('Size').''.&mt('Last Modified').' '.&mt('Current Access Status').&Apache::loncommon::help_open_topic('Portfolio ShareFile').'
Go to ...'.&make_anchor($filename.'/',$current_path.$filename.'/',$ENV{'form.mode'},$ENV{"form.fieldname"}).'
'.&mt('Go to ...').''.$version_flag.''.&make_anchor($url,\%anchor_fields,$filename.'/').'
print("CHECKED"); - } - $r->print('>'. - $filename.''.$size.''.&Apache::lonlocal::locallocaltime($mtime).'
$fullpath + ); + $line.=''.&make_anchor($url,\%anchor_fields,&mt('Locked')).''; + } else { + $line .= ''; + } + if ($can_delete) { + $line .= ''; + } + if ($can_modify) { + my $cat=''.&mt('Catalog Information').
+                            ''; + my %anchor_fields = ( + 'rename' => $filename, + currentpath => $current_path + ); + $line .= &make_anchor($url,\%anchor_fields,&mt('Rename')); + $line .= ''.&make_anchor($href_edit_location.$filename.'.meta',\%anchor_fields,$cat); + # ''.$cat.''; + } + $line .= ' 
- - - -
- + if ($select_mode eq 'true') { + $r->print(&Apache::loncommon::end_data_table().' + + + +

+
+ +

- '); + '); + } else { + $r->print(&Apache::loncommon::end_data_table()); + if ($can_delete) { + $r->print(' +

+ '. + &Apache::loncommon::help_open_topic('Portfolio DeleteFile').' +

+ + + ' + ); + } + } } sub open_form { - my ($r)=@_; + my ($r,$url)=@_; my @files=&Apache::loncommon::get_env_multiple('form.selectfile'); - $r->print('
'); + $r->print(''); $r->print(''); + $env{'form.action'}.'" />'); $r->print(''); foreach (@files) { $r->print(''); } $r->print(''); + $env{'form.currentpath'}.'" />'); } sub close_form { - my ($r)=@_; - $r->print('

'); - $r->print('
+ my ($r,$url,$button_text)=@_; + if (!defined($button_text)) { + $button_text = { + 'continue' => &mt('Continue'), + 'cancel' => &mt('Cancel'), + }; + } + $r->print('

'); + $r->print(&group_form_data().'

'); + $r->print('

- -

'); - + $env{'form.currentpath'}.'" />'. + &group_form_data()); + $r->print("\n".' +

'); } sub display_file { my ($path,$filename)=@_; my $display_file_text; - if (!defined($path)) { $path=$ENV{'form.currentpath'}; } + my $file_start=''; + my $file_end=''; + if (!defined($path)) { $path=$env{'form.currentpath'}; } if (!defined($filename)) { - $filename=$ENV{'form.selectfile'}; - $display_file_text = ''.$path.$filename.''; + $filename=$env{'form.selectfile'}; + $display_file_text = $file_start.$path.$filename.$file_end; } elsif (ref($filename) eq "ARRAY") { - foreach (@$filename) { - $display_file_text .= ''.$path.$_.'
'; + foreach my $file (@$filename) { + $display_file_text .= $file_start.$path.$file.$file_end.'
'; } } elsif (ref($filename) eq "SCALAR") { - $display_file_text = ''.$path.$filename.''; + $display_file_text = $file_start.$path.$$filename.$file_end; + } else { + $display_file_text = $file_start.$path.$filename.$file_end; } return $display_file_text; } sub done { - return ('

'.&mt('Done').'

'); + my ($message,$url)=@_; + unless (defined $message) { + $message='Done'; + } + my %anchor_fields = ( + 'showversions' => $env{'form.showversions'}, + 'currentpath' => $env{'form.currentpath'}, + 'fieldname' => $env{'form.fieldname'}, + 'mode' => $env{'form.mode'} + ); + my $result = '

'.&make_anchor($url,\%anchor_fields,&mt($message)).'

'; + return $result; } sub delete { - my ($r)=@_; + my ($r,$url,$group)=@_; my @check; - my $file_name = $ENV{'form.currentpath'}.$ENV{'form.selectfile'}; + my $file_name = $env{'form.currentpath'}.$env{'form.selectfile'}; + $file_name = &prepend_group($file_name); my @files=&Apache::loncommon::get_env_multiple('form.selectfile'); - - if (&Apache::lonnet::is_locked($file_name,$ENV{'user.domain'},$ENV{'user.name'} ) eq 'true') { - $r->print ("The file is locked and cannot be deleted.
"); - $r->print(&done()); + my ($uname,$udom) = &get_name_dom($group); + if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') { + $r->print(&mt('The file is locked and cannot be deleted.').'
'); + $r->print(&done('Back',$url)); } else { if (scalar(@files)) { - &open_form($r); - $r->print('

'.&mt('Delete').' '.&display_file(undef,\@files).'?

'); - &close_form($r); + &open_form($r,$url); + $r->print('

'.&mt('Delete [_1]?',&display_file(undef,\@files)).'

'); + &close_form($r,$url); } else { $r->print("No file was checked to delete.
"); - $r->print(&done()); + $r->print(&done(undef,$url)); } } } sub delete_confirmed { - my ($r)=@_; + my ($r,$url,$group)=@_; my @files=&Apache::loncommon::get_env_multiple('form.selectfile'); my $result; + my ($uname,$udom) = &get_name_dom($group); + my $port_path = &get_port_path(); + my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom, + $uname); foreach my $delete_file (@files) { - $result=&Apache::lonnet::removeuserfile($ENV{'user.name'}, - $ENV{'user.domain'},'portfolio'. - $ENV{'form.currentpath'}. + $result=&Apache::lonnet::removeuserfile($uname,$udom,$port_path. + $env{'form.currentpath'}. $delete_file); if ($result ne 'ok') { - $r->print(' An error occured ('.$result. - ') while trying to delete '.&display_file(undef, $delete_file).'
'); + $r->print('' + .&mt('An error occurred ([_1]) while trying to delete [_2].' + ,$result,&display_file(undef, $delete_file)) + .'

'); + } else { + $r->print(&mt('File: [_1] deleted.', + &display_file(undef,$delete_file))); + my $file_name = $env{'form.currentpath'}.$delete_file; + $file_name = &prepend_group($file_name); + my %access_controls = + &Apache::lonnet::get_access_controls($current_permissions, + $group,$file_name); + if (keys(%access_controls) > 0) { + my %changes; + foreach my $key (keys(%{$access_controls{$file_name}})) { + $changes{'delete'}{$key} = 1; + } + if (keys(%changes) > 0) { + my ($outcome,$deloutcome,$new_values,$translation) = + &Apache::lonnet::modify_access_controls($file_name,\%changes, + $udom,$uname); + if ($outcome ne 'ok') { + $r->print('
'.&mt("An error occurred ([_1]) while ". + "trying to delete access controls for the file.",$outcome). + '

'); + } else { + if ($deloutcome eq 'ok') { + $r->print('
'.&mt('Access controls also deleted for the file.').'

'); + } else { + $r->print(''.'
'. + &mt("An error occurred ([_1]) while ". + "trying to delete access controls for the file.",$deloutcome). + '


'); + } + } + } + } } } - $r->print(&done()); + $r->print(&done(undef,$url)); } sub delete_dir { - my ($r)=@_; - &open_form($r); - $r->print('

'.&mt('Delete').' '.&display_file().'?

'); - &close_form($r); + my ($r,$url)=@_; + &open_form($r,$url); + $r->print('

'.&mt('Delete [_1]?',&display_file()).'

'); + &close_form($r,$url); } sub delete_dir_confirmed { - my ($r)=@_; - my $directory_name = $ENV{'form.currentpath'}; - $directory_name =~ m/\/$/; - $directory_name = $`; - my $result=&Apache::lonnet::removeuserfile($ENV{'user.name'}, - $ENV{'user.domain'},'portfolio'. + my ($r,$url,$group)=@_; + my $directory_name = $env{'form.currentpath'}; + $directory_name =~ s|/$||; # remove any trailing slash + my ($uname,$udom) = &get_name_dom($group); + my $namespace = &get_namespace(); + my $port_path = &get_port_path(); + my $result=&Apache::lonnet::removeuserfile($uname,$udom,$port_path. $directory_name); if ($result ne 'ok') { - $r->print(' An error occured (dir) ('.$result. - ') while trying to delete '.$directory_name.'
'); + $r->print('' + .&mt('An error occurred (dir) ([_1]) while trying to delete [_2].' + ,$result,$directory_name) + .'
'); } else { # now remove from recent -# $r->print('
removing '.$directory_name.'
print(&done()); + $r->print(&done(undef,$url)); } sub rename { - my ($r)=@_; - my $file_name = $ENV{'form.currentpath'}.$ENV{'form.rename'}; - if (&Apache::lonnet::is_locked($file_name,$ENV{'user.domain'},$ENV{'user.name'}) eq 'true') { - $r->print ("The file is locked and cannot be renamed.
"); - $r->print(&done()); - } else { - &open_form($r); - $r->print('

'.&mt('Rename').' '.&display_file().' to - ?

'); - &close_form($r); + my ($r,$url,$group)=@_; + my $file_name = $env{'form.currentpath'}.$env{'form.rename'}; + my ($uname,$udom) = &get_name_dom($group); + $file_name = &prepend_group($file_name); + if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') { + $r->print("The file is locked and cannot be renamed.
"); + $r->print(&done(undef,$url)); + } else { + &open_form($r,$url); + $r->print('

'.&mt('Rename [_1] to [_2]?', &display_file() + , '').'

'); + &close_form($r,$url); } } sub rename_confirmed { - my ($r)=@_; - my $filenewname=&Apache::lonnet::clean_filename($ENV{'form.filenewname'}); + my ($r,$url,$group)=@_; + my $filenewname=&Apache::lonnet::clean_filename($env{'form.filenewname'}); + my ($uname,$udom) = &get_name_dom($group); + my $port_path = &get_port_path(); if ($filenewname eq '') { - $r->print(''. + $r->print(''. &mt("Error: no valid filename was provided to rename to."). - '
'); - $r->print(&done()); + '
'); + $r->print(&done(undef,$url)); return; } + my $chg_access; my $result= - &Apache::lonnet::renameuserfile($ENV{'user.name'},$ENV{'user.domain'}, - 'portfolio'.$ENV{'form.currentpath'}.$ENV{'form.selectfile'}, - 'portfolio'.$ENV{'form.currentpath'}.$filenewname); - if ($result ne 'ok') { - $r->print(' An errror occured ('.$result. - ') while trying to rename '.&display_file().' to '. - &display_file(undef,$filenewname).'
'); + &Apache::lonnet::renameuserfile($uname,$udom, + $port_path.$env{'form.currentpath'}.$env{'form.selectfile'}, + $port_path.$env{'form.currentpath'}.$filenewname); + if ($result eq 'ok') { + $chg_access = &access_for_renamed($filenewname,$group,$udom,$uname); + } else { + $r->print(''. + &mt('An error occurred ([_1]) while trying to rename [_2] to [_3].' + ,$result,&display_file(),&display_file('',$filenewname)) + .'
'); + return; + } + if ($filenewname ne $env{'form.filenewname'}) { + $r->print(&mt("The new file name was changed from:
[_1] to [_2]", + ''.&display_file('',$env{'form.filenewname'}).'', + ''.&display_file('',$filenewname).'')); + } + $r->print($chg_access); + $r->print(&done(undef,$url)); +} + +sub access_for_renamed { + my ($filenewname,$group,$udom,$uname) = @_; + my $oldfile = $env{'form.currentpath'}.$env{'form.selectfile'}; + $oldfile = &prepend_group($oldfile); + my $newfile = $env{'form.currentpath'}.$filenewname; + $newfile = &prepend_group($newfile); + my $current_permissions = + &Apache::lonnet::get_portfile_permissions($udom,$uname); + my %access_controls = + &Apache::lonnet::get_access_controls($current_permissions, + $group,$oldfile); + my $chg_text; + if (keys(%access_controls) > 0) { + my %change_old; + my %change_new; + foreach my $key (keys(%{$access_controls{$oldfile}})) { + $change_old{'delete'}{$key} = 1; + $change_new{'activate'}{$key} = $access_controls{$oldfile}{$key}; + } + my ($outcome,$deloutcome,$new_values,$translation) = + &Apache::lonnet::modify_access_controls($oldfile,\%change_old, + $udom,$uname); + if ($outcome ne 'ok') { + $chg_text ='

'.&mt("An error occurred ([_1]) while ". + "trying to delete access control records for the old name.",$outcome). + '
'; + } else { + if ($deloutcome ne 'ok') { + $chg_text = '


'. + &mt("An error occurred ([_1]) while ". + "trying to delete access control records for the old name.",$deloutcome). + '

'; + } + } + ($outcome,$deloutcome,$new_values,$translation) = + &Apache::lonnet::modify_access_controls($newfile,\%change_new, + $udom,$uname); + if ($outcome ne 'ok') { + $chg_text .= '

'. + &mt("An error occurred ([_1]) while ". + "trying to update access control records for the new name.",$outcome). + '
'; + } + if ($chg_text eq '') { + $chg_text = '

'.&mt('Access controls updated to reflect the name change.'); + } + } + return $chg_text; +} + +sub display_access { + my ($r,$url,$group,$can_setacl,$port_path,$action) = @_; + my ($uname,$udom) = &get_name_dom($group); + my $file_name = $env{'form.currentpath'}.$env{'form.access'}; + $file_name = &prepend_group($file_name); + my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom, + $uname); + my %access_controls = &Apache::lonnet::get_access_controls($current_permissions,$group,$file_name); + my $aclcount = keys(%access_controls); + my ($header,$info); + if ($action eq 'chgaccess') { + $header = '

'.&mt('Allowing others to retrieve file: [_1]',$port_path.$env{'form.currentpath'}.$env{'form.access'}).'

'; + $info .= &mt('Access to this file by others can be set to be one or more of the following types: public, passphrase-protected or conditional.'); + $info .= '
'. + &mt('A listing of files viewable without log-in is available at: ')."http://$ENV{'SERVER_NAME'}/adm/$udom/$uname/aboutme/portfolio.
"; + if ($group eq '') { + $info .= &mt("For logged in users a 'Display file listing' link will also appear (when there are viewable files) on your personal information page:"); + } else { + $info .= &mt("For logged in users a 'Display file listing' link will also appear (when there are viewable files) on the course information page:"); + } + $info .= "
http://$ENV{'SERVER_NAME'}/adm/$udom/$uname/aboutme
"; + if ($group ne '') { + $info .= &mt("Users with privileges to edit course contents may add a course information page to a course using the 'Course Info' button in DOCS").'
'; + } + } else { + $header = '

'.&mt('Conditional access controls for file: [_1]',$port_path.$env{'form.currentpath'}.$env{'form.access'}).'

'. + &explain_conditionals().'
'; + } + if ($can_setacl) { + &open_form($r,$url); + $r->print($header.$info); + $r->print('
'.&Apache::loncommon::help_open_topic('Portfolio ShareFile SetAccess', &mt('Help on setting up share access'))); + $r->print(&Apache::loncommon::help_open_topic('Portfolio ShareFile ChangeSetting', &mt('Help on changing settings'))); + $r->print(&Apache::loncommon::help_open_topic('Portfolio ShareFile StopAccess', &mt('Help on removing share access'))); + &access_setting_table($r,$url,$file_name,$access_controls{$file_name}, + $action); + my $button_text = { + 'continue' => &mt('Proceed'), + 'cancel' => &mt('Return to directory'), + }; + &close_form($r,$url,$button_text); + } else { + $r->print($header); + if ($aclcount) { + $r->print($info); + } + &view_access_settings($r,$url,$access_controls{$file_name},$aclcount); + } +} + +sub explain_conditionals { + return + &mt('Conditional files are accessible to logged-in users with accounts in the LON-CAPA network, who satisfy the conditions you set.').'
'."\n". + &mt('The conditions can include affiliation with a particular course, or a user account in a specific domain.').'
'."\n". + &mt('Alternatively access can be granted to people with specific LON-CAPA usernames and domains.'); +} + +sub view_access_settings { + my ($r,$url,$access_controls,$aclcount) = @_; + my ($showstart,$showend); + my %todisplay; + foreach my $key (sort(keys(%{$access_controls}))) { + my ($num,$scope,$end,$start) = &unpack_acc_key($key); + $todisplay{$scope}{$key} = $$access_controls{$key}; + } + if ($aclcount) { + $r->print('

'.&mt('Current access controls defined for this file:').'

'); + $r->print(&Apache::loncommon::start_data_table()); + $r->print(&Apache::loncommon::start_data_table_header_row()); + $r->print(''.&mt('Access control').''.&mt('Dates available'). + ''.&mt('Additional information').''); + $r->print(&Apache::loncommon::end_data_table_header_row()); + my $count = 1; + my $chg = 'none'; + &build_access_summary($r,$count,$chg,%todisplay); + $r->print(&Apache::loncommon::end_data_table()); + } else { + $r->print(&mt('No access control settings currently exist for this file.').'
'); + } + my %anchor_fields = ( + 'currentpath' => $env{'form.currentpath'} + ); + $r->print('
'.&make_anchor($url, \%anchor_fields, &mt('Return to directory'))); + return; +} + +sub build_access_summary { + my ($r,$count,$chg,%todisplay) = @_; + my ($showstart,$showend); + my %scope_desc = ( + public => 'Public', + guest => 'Passphrase-protected', + domains => 'Conditional: domain-based', + users => 'Conditional: user-based', + course => 'Conditional: course-based', + ); + my @allscopes = ('public','guest','domains','users','course'); + foreach my $scope (@allscopes) { + if ((!(exists($todisplay{$scope}))) || (ref($todisplay{$scope}) ne 'HASH')) { + next; + } + foreach my $key (sort(keys(%{$todisplay{$scope}}))) { + if ($count) { + $r->print(&Apache::loncommon::start_data_table_row()); + } + my ($num,$scope,$end,$start) = &unpack_acc_key($key); + my $content = $todisplay{$scope}{$key}; + if ($chg eq 'delete') { + $showstart = &mt('Deleted'); + $showend = $showstart; + } else { + $showstart = localtime($start); + if ($end == 0) { + $showend = &mt('No end date'); + } else { + $showend = localtime($end); + } + } + $r->print(''.&mt($scope_desc{$scope})); + if ($scope eq 'course') { + if ($chg ne 'delete') { + my $cid = $content->{'domain'}.'_'.$content->{'number'}; + my %course_description = &Apache::lonnet::coursedescription($cid); + $r->print('
('.$course_description{'description'}.')'); + } + } + $r->print(''.&mt('Start: ').$showstart. + '
'.&mt('End: ').$showend.''); + if ($chg ne 'delete') { + if ($scope eq 'guest') { + $r->print(&mt('Passphrase').': '.$content->{'password'}); + } elsif ($scope eq 'course') { + $r->print(''); + $r->print(''); + $r->print(''); + $r->print(''); + foreach my $id (sort(keys(%{$content->{'roles'}}))) { + $r->print(''); + foreach my $item ('role','access','section','group') { + $r->print(''); + } + $r->print(''); + } + $r->print('
'.&mt('Roles').''. + &mt('Access').''. + &mt('Sections').''.&mt('Groups').'
'); + if ($item eq 'role') { + my $ucscope = $scope; + $ucscope =~ s/^(\w)/uc($1)/e; + my $role_output; + foreach my $role (@{$content->{'roles'}{$id}{$item}}) { + if ($role eq 'all') { + $role_output .= $role.','; + } elsif ($role =~ /^cr/) { + $role_output .= (split('/',$role))[3].','; + } else { + $role_output .= &Apache::lonnet::plaintext($role,$ucscope).','; + } + } + $role_output =~ s/,$//; + $r->print($role_output); + } else { + $r->print(join(',',@{$content->{'roles'}{$id}{$item}})); + } + $r->print('
'); + } elsif ($scope eq 'domains') { + $r->print(&mt('Domains: ').join(',',@{$content->{'dom'}})); + } elsif ($scope eq 'users') { + my $curr_user_list = &sort_users($content->{'users'}); + $r->print(&mt('Users: ').$curr_user_list); + } else { + $r->print(' '); + } + } else { + $r->print(' '); + } + $r->print(''); + $r->print(&Apache::loncommon::end_data_table_row()); + $count ++; + } + } +} + + +sub update_access { + my ($r,$url,$group,$port_path) = @_; + my $totalprocessed = 0; + my %processing; + my %title = ( + 'activate' => 'New control(s) added', + 'delete' => 'Existing control(s) deleted', + 'update' => 'Existing control(s) modified', + ); + my $changes; + foreach my $chg (sort(keys(%title))) { + @{$processing{$chg}} = &Apache::loncommon::get_env_multiple('form.'.$chg); + $totalprocessed += @{$processing{$chg}}; + foreach my $num (@{$processing{$chg}}) { + my $scope = $env{'form.scope_'.$num}; + my ($start,$end) = &get_dates_from_form($num); + my $newkey = $num.':'.$scope.'_'.$end.'_'.$start; + if ($chg eq 'delete') { + $$changes{$chg}{$newkey} = 1; + } else { + $$changes{$chg}{$newkey} = + &build_access_record($num,$scope,$start,$end,$chg); + } + } + } + my $file_name = $env{'form.currentpath'}.$env{'form.selectfile'}; + $r->print('

'.&mt('Allowing others to retrieve file: [_1]', + $port_path.$file_name).'

'."\n"); + $file_name = &prepend_group($file_name); + my ($uname,$udom) = &get_name_dom($group); + my ($errors,$outcome,$deloutcome,$new_values,$translation); + if ($totalprocessed) { + ($outcome,$deloutcome,$new_values,$translation) = + &Apache::lonnet::modify_access_controls($file_name,$changes,$udom, + $uname); + } + my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom, + $uname); + my %access_controls = + &Apache::lonnet::get_access_controls($current_permissions, + $group,$file_name); + if ($totalprocessed) { + if ($outcome eq 'ok') { + my $updated_controls = $access_controls{$file_name}; + my ($showstart,$showend); + $r->print(&Apache::loncommon::start_data_table()); + $r->print(&Apache::loncommon::start_data_table_header_row()); + $r->print(''.&mt('Type of change').''. + &mt('Access control').''.&mt('Dates available'). + ''.&mt('Additional information').''); + $r->print(&Apache::loncommon::end_data_table_header_row()); + foreach my $chg (sort(keys(%processing))) { + if (@{$processing{$chg}} > 0) { + if ($chg eq 'delete') { + if (!($deloutcome eq 'ok')) { + $errors .=''. + &mt('A problem occurred deleting access controls: [_1]',$deloutcome). + ''; + next; + } + } + my $numchgs = @{$processing{$chg}}; + $r->print(&Apache::loncommon::start_data_table_row()); + $r->print(''.&mt($title{$chg}). + '.'); + my $count = 0; + my %todisplay; + foreach my $key (sort(keys(%{$$changes{$chg}}))) { + my ($num,$scope,$end,$start) = &unpack_acc_key($key); + my $newkey = $key; + if ($chg eq 'activate') { + $newkey =~ s/^(\d+)/$$translation{$1}/; + } + $todisplay{$scope}{$newkey} = $$updated_controls{$newkey}; + } + &build_access_summary($r,$count,$chg,%todisplay); + } + } + $r->print(&Apache::loncommon::end_data_table()); + } else { + if ((@{$processing{'activate'}} > 0) || (@{$processing{'update'}} > 0)) { + $errors .= ''. + &mt('A problem occurred saving access control settings: [_1]',$outcome). + ''; + } + } + if ($errors) { + $r->print($errors); + } + } + my $allnew = 0; + my $totalnew = 0; + my $status = 'new'; + my ($firstitem,$lastitem); + foreach my $newitem ('course','domains','users') { + $allnew += $env{'form.new'.$newitem}; + } + if ($allnew > 0) { + my $now = time; + my $then = $now + (60*60*24*180); # six months approx. + &open_form($r,$url); + foreach my $newitem ('course','domains','users') { + if ($env{'form.new'.$newitem} > 0) { + $r->print('
'.&mt('Add new [_1]-based access control for portfolio file: [_2]',&mt($newitem),$env{'form.currentpath'}.$env{'form.selectfile'}).'

'); + $firstitem = $totalnew; + $lastitem = $totalnew + $env{'form.new'.$newitem}; + $totalnew = $lastitem; + my @numbers; + for (my $i=$firstitem; $i<$lastitem; $i++) { + push (@numbers,$i); + } + &display_access_row($r,$status,$newitem,\@numbers, + $access_controls{$file_name},$now,$then); + } + } + &close_form($r,$url); + } else { + my %anchor_fields = ( + 'currentpath' => $env{'form.currentpath'}, + 'access' => $env{'form.selectfile'} + ); + $r->print('
'.&make_anchor($url, \%anchor_fields, &mt('Display all access settings for this file'))); + delete $anchor_fields{'access'}; + $r->print('     '.&make_anchor($url,\%anchor_fields,&mt('Return to directory'))); + } + return; +} + +sub build_access_record { + my ($num,$scope,$start,$end,$chg) = @_; + my $record = { + type => $scope, + time => { + start => $start, + end => $end + }, + }; + + if ($scope eq 'guest') { + $record->{'password'} = $env{'form.password'}; + } elsif ($scope eq 'course') { + $record->{'domain'} = $env{'form.crsdom_'.$num}; + $record->{'number'} = $env{'form.crsnum_'.$num}; + my @role_ids; + my @delete_role_ids = + &Apache::loncommon::get_env_multiple('form.delete_role_'.$num); + my @preserves = + &Apache::loncommon::get_env_multiple('form.preserve_role_'.$num); + if (@delete_role_ids) { + foreach my $id (@preserves) { + if (grep {$_ = $id} (@delete_role_ids)) { + next; + } + push(@role_ids,$id); + } + } else { + push(@role_ids,@preserves); + } + + my $next_id = $env{'form.add_role_'.$num}; + if ($next_id) { + push(@role_ids,$next_id); + } + + foreach my $id (@role_ids) { + my (@roles,@accesses,@sections,@groups); + if (($id == $next_id) && ($chg eq 'update')) { + @roles = split(/,/,$env{'form.role_'.$num.'_'.$next_id}); + @accesses = split(/,/,$env{'form.access_'.$num.'_'.$next_id}); + @sections = split(/,/,$env{'form.section_'.$num.'_'.$next_id}); + @groups = split(/,/,$env{'form.group_'.$num.'_'.$next_id}); + } else { + @roles = &Apache::loncommon::get_env_multiple('form.role_'.$num.'_'.$id); + @accesses = &Apache::loncommon::get_env_multiple('form.access_'.$num.'_'.$id); + @sections = &Apache::loncommon::get_env_multiple('form.section_'.$num.'_'.$id); + @groups = &Apache::loncommon::get_env_multiple('form.group_'.$num.'_'.$id); + } + $record->{'roles'}{$id}{'role'} = \@roles; + $record->{'roles'}{$id}{'access'} = \@accesses; + $record->{'roles'}{$id}{'section'} = \@sections; + $record->{'roles'}{$id}{'group'} = \@groups; + } + } elsif ($scope eq 'domains') { + my @doms = &Apache::loncommon::get_env_multiple('form.dom_'.$num); + $record->{'dom'} = \@doms; + } elsif ($scope eq 'users') { + my $userlist = $env{'form.users_'.$num}; + $userlist =~ s/\s+//sg; + my %userhash = map { ($_,1) } (split(/,/,$userlist)); + foreach my $user (keys(%userhash)) { + my ($uname,$udom) = split(/:/,$user); + push(@{$record->{'users'}}, { + 'uname' => $uname, + 'udom' => $udom + }); + } + } + return $record; +} + +sub get_dates_from_form { + my ($id) = @_; + my $startdate; + my $enddate; + $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate_'.$id); + $enddate = &Apache::lonhtmlcommon::get_date_from_form('enddate_'.$id); + if ( exists ($env{'form.noend_'.$id}) ) { + $enddate = 0; + } + return ($startdate,$enddate); +} + +sub sort_users { + my ($users) = @_; + my @curr_users = map { + $_->{'uname'}.':'.$_->{'udom'} + } (@{$users}); + my $curr_user_list = join(",\n",sort(@curr_users)); + return $curr_user_list; +} + +sub access_setting_table { + my ($r,$url,$filename,$access_controls,$action) = @_; + my ($public,$publictext); + $publictext ='Off'; + my ($guest,$guesttext); + $guesttext = 'Off'; + my @courses = (); + my @domains = (); + my @users = (); + my $now = time; + my $then = $now + (60*60*24*180); # six months approx. + my ($num,$scope,$publicnum,$guestnum); + my (%acl_count,%end,%start,%conditionals); + foreach my $key (sort(keys(%{$access_controls}))) { + ($num,$scope,$end{$key},$start{$key}) = &unpack_acc_key($key); + if ($scope eq 'public') { + $public = $key; + $publicnum = $num; + $publictext = &acl_status($start{$key},$end{$key},$now); + } elsif ($scope eq 'guest') { + $guest=$key; + $guestnum = $num; + $guesttext = &acl_status($start{$key},$end{$key},$now); + } else { + $conditionals{$scope}{$key} = $$access_controls{$key}; + if ($scope eq 'course') { + push(@courses,$key); + } elsif ($scope eq 'domains') { + push(@domains,$key); + } elsif ($scope eq 'users') { + push(@users,$key); + } + } + $acl_count{$scope} ++; + } + $r->print('
'); + if ($action eq 'chgaccess') { + &standard_settings($r,$now,$then,$url,$filename,\%acl_count,\%start, + \%end,$public,$publicnum,$publictext,$guest,$guestnum, + $guesttext,$access_controls,%conditionals); + } else { + &condition_setting($r,$access_controls,$now,$then,\%acl_count, + \@domains,\@users,\@courses); + } + $r->print('
'); +} + +sub standard_settings { + my ($r,$now,$then,$url,$filename,$acl_count,$start,$end,$public,$publicnum, + $publictext,$guest,$guestnum,$guesttext,$access_controls,%conditionals)=@_; + $r->print('

'.&mt('Public access: [_1]',&mt($publictext)).'

'); + $r->print(&Apache::loncommon::start_data_table()); + $r->print(&Apache::loncommon::start_data_table_header_row()); + $r->print(''.&mt('Action').''.&mt('Dates available').''); + $r->print(&Apache::loncommon::end_data_table_header_row()); + $r->print(&Apache::loncommon::start_data_table_row()); + if ($public) { + $r->print(''.&actionbox('old',$publicnum,'public').''. + &dateboxes($publicnum,$start->{$public},$end->{$public}).''); + } else { + $r->print(''.&actionbox('new','0','public').''. + &dateboxes('0',$now,$then).''); + } + $r->print(&Apache::loncommon::end_data_table_row()); + $r->print(&Apache::loncommon::end_data_table()); + $r->print(' '); + $r->print('

'.&mt('Passphrase-protected access: [_1]',&mt($guesttext)).'

'); + $r->print(&Apache::loncommon::start_data_table()); + $r->print(&Apache::loncommon::start_data_table_header_row()); + $r->print(''.&mt('Action').''.&mt('Dates available'). + ''. &mt('Passphrase').''); + $r->print(&Apache::loncommon::end_data_table_header_row()); + $r->print(&Apache::loncommon::start_data_table_row()); + my $passwd; + if ($guest) { + $passwd = $$access_controls{$guest}{'password'}; + $r->print(''.&actionbox('old',$guestnum,'guest').''. + &dateboxes($guestnum,$start->{$guest},$end->{$guest}).''); + } else { + $r->print(''.&actionbox('new','1','guest').''. + &dateboxes('1',$now,$then).''); + } + $r->print(''); + $r->print(&Apache::loncommon::end_data_table_row()); + $r->print(&Apache::loncommon::end_data_table()); + $r->print(' '. + ''); + my $numconditionals = 0; + my $conditionstext; + my %cond_status; + foreach my $scope ('domains','users','course') { + $numconditionals += $acl_count->{$scope}; + if ($acl_count->{$scope} > 0) { + if ($conditionstext ne 'Active') { + foreach my $key (keys(%{$conditionals{$scope}})) { + $conditionstext = &acl_status($start->{$key},$end->{$key},$now); + if ($conditionstext eq 'Active') { + last; + } + } + } + } + } + if ($conditionstext eq '') { + $conditionstext = 'Off'; } - if ($filenewname ne $ENV{'form.filenewname'}) { - $r->print("The new file name was changed from:
".$ENV{'form.filenewname'}." to $filenewname "); + my %anchor_fields = ( + 'access' => $env{'form.selectfile'}, + 'action' => 'chgconditions', + 'currentpath' => $env{'form.currentpath'}, + ); + $r->print('

'.&mt('Conditional access: [_1]',&mt($conditionstext)).'

'); + if ($numconditionals > 0) { + my $count = 1; + my $chg = 'none'; + $r->print(&mt('You have previously set [_1] conditional access controls.',$numconditionals).' '.&make_anchor($url,\%anchor_fields,&mt('Change Conditions')).'

'); + $r->print(&Apache::loncommon::start_data_table()); + $r->print(&Apache::loncommon::start_data_table_header_row()); + $r->print(''.&mt('Access control').''.&mt('Dates available'). + ''.&mt('Additional information').''); + $r->print(&Apache::loncommon::end_data_table_header_row()); + &build_access_summary($r,$count,$chg,%conditionals); + $r->print(&Apache::loncommon::end_data_table()); + } else { + $r->print(&make_anchor($url,\%anchor_fields,&mt('Add conditional access')).' '.&mt('based on domain, username, or course affiliation.')); } - $r->print(&done()); } + +sub condition_setting { + my ($r,$access_controls,$now,$then,$acl_count,$domains,$users,$courses) = @_; + $r->print(''); + &access_element($r,'domains',$acl_count,$domains,$access_controls,$now,$then); + $r->print(' '); + &access_element($r,'users',$acl_count,$users,$access_controls,$now,$then); + $r->print(''); + if ($acl_count->{course} > 0) { + $r->print(''); + } else { + $r->print(''); + } + &access_element($r,'course',$acl_count,$courses,$access_controls,$now,$then); + $r->print(''); + $r->print(''); +} + +sub acl_status { + my ($start,$end,$now) = @_; + if ($start > $now) { + return 'Inactive'; + } + if ($end && $end<$now) { + return 'Inactive'; + } + return 'Active'; +} + +sub access_element { + my ($r,$type,$acl_count,$items,$access_controls,$now,$then) = @_; + my $title = $type; + $title =~ s/s$//; + $title =~ s/^(\w)/uc($1)/e; + $r->print('

'.&mt('[_1]-based conditional access: ',&mt($title))); + if ($$acl_count{$type}) { + $r->print($$acl_count{$type}.' '); + if ($$acl_count{$type} > 1) { + $r->print(&mt('conditions')); + } else { + $r->print(&mt('condition')); + } + } else { + $r->print(&mt('Off')); + } + $r->print('

'); + &display_access_row($r,'old',$type,$items,$access_controls,$now,$then); + return; +} + +sub display_access_row { + my ($r,$status,$type,$items,$access_controls,$now,$then) = @_; + if (@{$items} > 0) { + my @all_doms; + my $colspan = 3; + my $uctype = $type; + $uctype =~ s/^(\w)/uc($1)/e; + $r->print(&Apache::loncommon::start_data_table()); + $r->print(&Apache::loncommon::start_data_table_header_row()); + $r->print(''.&mt('Action?').''.&mt($uctype).''. + &mt('Dates available').''); + if ($type eq 'course' && $status eq 'old') { + $r->print(''.&mt('Allowed [_1] member affiliations',$type). + ''); + $colspan ++; + } elsif ($type eq 'domains') { + @all_doms = sort(&Apache::lonnet::all_domains()); + } + $r->print(&Apache::loncommon::end_data_table_header_row()); + foreach my $key (@{$items}) { + $r->print(&Apache::loncommon::start_data_table_row()); + if ($type eq 'course') { + &course_row($r,$status,$type,$key,$access_controls,$now,$then); + } elsif ($type eq 'domains') { + &domains_row($r,$status,$key,\@all_doms,$access_controls,$now, + $then); + } elsif ($type eq 'users') { + &users_row($r,$status,$key,$access_controls,$now,$then); + } + $r->print(&Apache::loncommon::end_data_table_row()); + } + if ($status eq 'old') { + $r->print(&Apache::loncommon::start_data_table_row()); + $r->print(''.&additional_item($type). + ''); + $r->print(&Apache::loncommon::end_data_table_row()); + } + $r->print(&Apache::loncommon::end_data_table()); + } else { + $r->print(&mt('No [_1]-based conditions defined.',&mt($type)).'
' + .&additional_item($type)); + } + return; +} + +sub course_js { + return qq| + +|; +} + +sub course_row { + my ($r,$status,$type,$item,$access_controls,$now,$then) = @_; + my $content; + my $defdom = $env{'user.domain'}; + if ($status eq 'old') { + $content = $$access_controls{$item}; + $defdom = $content->{'domain'}; + } + my $js = &Apache::loncommon::coursebrowser_javascript($defdom) + .&course_js(); + my $uctype = $type; + $uctype =~ s/^(\w)/uc($1)/e; + my ($num,$scope,$end,$start) = &set_identifiers($status,$item,$now,$then, + $type); + $r->print(''.$js.&actionbox($status,$num,$scope).''); + if ($status eq 'old') { + my $cid = $content->{'domain'}.'_'.$content->{'number'}; + my %course_description = &Apache::lonnet::coursedescription($cid); + $r->print(''.$course_description{'description'}.''); + } elsif ($status eq 'new') { + $r->print(''.&Apache::loncommon::selectcourse_link('portform','crsnum_'.$num,'crsdom_'.$num,'description_'.$num,$num.'_1',undef,$uctype).'  '); + } + $r->print(''.&dateboxes($num,$start,$end)); + my $newrole_id = 1; + if ($status eq 'old') { + $r->print(''); + my $max_id = 0; + if (keys(%{$content->{'roles'}}) > 0) { + $r->print(''. + ''. + ''. + ''. + ''); + foreach my $role_id (sort(keys(%{$content->{'roles'}}))) { + if ($role_id > $max_id) { + $max_id = $role_id; + } + $max_id ++; + my $role_selects = &role_selectors($num,$role_id,$type,$content,'display'); + $r->print(''.$role_selects.''); + } + $r->print('
'.&mt('Action').''.&mt('Roles').''.&mt('Access').''.&mt('Sections').''.&mt('Groups').'

'); + } + $r->print('
'.&mt('Add a roles-based condition'). + ' {'domain'}','$content->{'number'}', + '$uctype'".')" value="" />'); + $newrole_id = $max_id; + } else { + $r->print(''); + } + $r->print(&add_course_role($num,$newrole_id)); + $r->print(''); + return; +} + +sub add_course_role { + my ($num,$max_id) = @_; + my $output; + $output .=''. + ''. + ''. + ''; + return $output; +} + +sub domains_row { + my ($r,$status,$item,$all_doms,$access_controls,$now,$then) = @_; + my ($num,$scope,$end,$start) = &set_identifiers($status,$item,$now,$then, + 'domains'); + my $dom_select = ''; + $r->print(''.&actionbox($status,$num,$scope).''.$dom_select. + ''.&dateboxes($num,$start,$end).''); +} + +sub users_row { + my ($r,$status,$item,$access_controls,$now,$then) = @_; + my ($num,$scope,$end,$start) = &set_identifiers($status,$item,$now,$then, + 'users'); + my $curr_user_list; + if ($status eq 'old') { + my $content = $$access_controls{$item}; + $curr_user_list = &sort_users($content->{'users'}); + } + $r->print(''.&actionbox($status,$num,$scope).''.&mt("Format for users' username:domain information:").'
sparty:msu,illini:uiuc ... etc.
'.&dateboxes($num,$start,$end).''); +} + +sub additional_item { + my ($type) = @_; + my $output = &mt('Add new [_1] condition(s)?',&mt($type)).' '.&mt('Number to add: ').''; + return $output; +} + +sub actionbox { + my ($status,$num,$scope) = @_; + my $output = '
'. + ''; + return $output; +} + +sub dateboxes { + my ($num,$start,$end) = @_; + my $noend; + if ($end == 0) { + $noend = 'checked="checked"'; + } + my $startdate = &Apache::lonhtmlcommon::date_setter('portform', + 'startdate_'.$num,$start,undef,undef,undef,1,undef, + undef,undef,1); + my $enddate = &Apache::lonhtmlcommon::date_setter('portform', + 'enddate_'.$num,$end,undef,undef,undef,1,undef, + undef,undef,1). '  '; + + my $output = &mt('Start: ').$startdate.'
'.&mt('End: ').$enddate; + return $output; +} + +sub unpack_acc_key { + my ($acc_key) = @_; + my ($num,$scope,$end,$start) = ($acc_key =~ /^([^:]+):([a-z]+)_(\d*)_?(\d*)$/); + return ($num,$scope,$end,$start); +} + +sub set_identifiers { + my ($status,$item,$now,$then,$scope) = @_; + if ($status eq 'old') { + return(&unpack_acc_key($item)); + } else { + return($item,$scope,$then,$now); + } +} + +sub role_selectors { + my ($num,$role_id,$type,$content,$caller) = @_; + my ($output,$cdom,$cnum,$longid); + if ($caller eq 'display') { + $longid = '_'.$num.'_'.$role_id; + $cdom = $$content{'domain'}; + $cnum = $$content{'number'}; + } elsif ($caller eq 'rolepicker') { + $cdom = $env{'form.cdom'}; + $cnum = $env{'form.cnum'}; + } + my $uctype = $type; + $uctype =~ s/^(\w)/uc($1)/e; + my ($sections,$groups,$allroles,$rolehash,$accesshash) = + &Apache::loncommon::get_secgrprole_info($cdom,$cnum,1,$uctype); + if (!@{$sections}) { + @{$sections} = ('none'); + } else { + unshift(@{$sections},('all','none')); + } + if (!@{$groups}) { + @{$groups} = ('none'); + } else { + unshift(@{$groups},('all','none')); + } + my @allacesses = sort(keys(%{$accesshash})); + my (%sectionhash,%grouphash); + foreach my $sec (@{$sections}) { + $sectionhash{$sec} = $sec; + } + foreach my $grp (@{$groups}) { + $grouphash{$grp} = $grp; + } + my %lookup = ( + 'role' => $rolehash, + 'access' => $accesshash, + 'section' => \%sectionhash, + 'group' => \%grouphash, + ); + my @allaccesses = sort(keys(%{$accesshash})); + my %allitems = ( + 'role' => $allroles, + 'access' => \@allaccesses, + 'section' => $sections, + 'group' => $groups, + ); + foreach my $item ('role','access','section','group') { + $output .= ''; + } + $output .= ''; + return $output; +} + +sub role_options_window { + my ($r) = @_; + my $type = $env{'form.type'}; + my $rolenum = $env{'form.setroles'}; + my ($num,$role_id) = ($rolenum =~ /^([\d_]+)_(\d+)$/); + my $role_elements; + foreach my $item ('role','access','section','group') { + $role_elements .= "'".$item.'_'.$rolenum."',"; + } + $role_elements =~ s/,$//; + my $role_selects = &role_selectors($num,$role_id,$type,undef, + 'rolepicker'); + $r->print(<<"END_SCRIPT"); + +END_SCRIPT + $r->print(&mt('Select roles, course status, section(s) and group(s) for users who will be able to access the portfolio file.')); + $r->print('
'.$role_selects.'
'.&mt('Roles').''.&mt('[_1] status',$type).''.&mt('Sections').''.&mt('Groups').'

'); + return; +} + sub select_files { - my ($r)=@_; - if ($ENV{'form.continue'} eq 'true') { + my ($r) = @_; + if ($env{'form.continue'} eq 'true') { # here we update the selections for the currentpath # eventually, have to handle removing those not checked, but . . . - my @items=&Apache::loncommon::get_env_multiple('form.selectfile'); - &Apache::lonnet::save_selected_files($ENV{'user.name'}, $ENV{'form.currentpath'}, @items); + my @items=&Apache::loncommon::get_env_multiple('form.checkfile'); + if (scalar(@items)){ + &Apache::lonnet::save_selected_files($env{'user.name'}, $env{'form.currentpath'}, @items); + } } else { - if ($ENV{'form.currentpath'} eq '/') { #empty the file for a fresh start - # &Apache::lonnet::clear_selected_files($ENV{'user.name'}); - } + &Apache::lonnet::clear_selected_files($env{'user.name'}); } - my @files = &Apache::lonnet::files_not_in_path($ENV{'user.name'}, $ENV{'form.currentpath'}); + my @files = &Apache::lonnet::files_not_in_path($env{'user.name'}, $env{'form.currentpath'}); my $java_files = join ",", @files; if ($java_files) { $java_files.=','; } my $javascript =(< + ENDSMP $r->print($javascript); - $r->print("

Select portfolio files

- Check as many as you wish in response to the essay problem.
"); - $r->print("Files selected from other directories:
"); - foreach (&Apache::lonnet::files_not_in_path($ENV{'user.name'}, $ENV{'form.currentpath'})) { - $r->print($_."
"); - } + $r->print("

".&mt('Select portfolio files')."

"); + my @otherfiles=&Apache::lonnet::files_not_in_path($env{'user.name'}, $env{'form.currentpath'}); + if (@otherfiles) { + $r->print(&Apache::loncommon::start_data_table() + .&Apache::loncommon::start_data_table_header_row() + .''.&mt('Files selected from other directories:')."" + .&Apache::loncommon::end_data_table_header_row() + ); + foreach my $file (@otherfiles) { + $r->print(&Apache::loncommon::start_data_table_row() + .''.$file."" + .&Apache::loncommon::end_data_table_row() + ); + } + $r->print(&Apache::loncommon::end_data_table() + .'
' + ); + } + $r->print('
' + .&mt('Check as many files as you wish in response to the problem:') + .'
' + ); } -sub upload { - my ($r)=@_; - my $fname=$ENV{'form.uploaddoc.filename'}; - my $filesize = (length($ENV{'form.uploaddoc'})) / 1000; #express in k (1024?) - my $disk_quota = 20000; # expressed in k - $fname=&Apache::lonnet::clean_filename($fname); - my $portfolio_root = &Apache::loncommon::propath($ENV{'user.domain'}, - $ENV{'user.name'}). - '/userfiles/portfolio'; + + +sub check_for_upload { + my ($path,$fname,$group,$element) = @_; + my $disk_quota = &get_quota($group); + my $filesize = (length($env{'form.'.$element})) / 1000; #express in k (1024?) + my $portfolio_root = &get_portfolio_root(); + my $port_path = &get_port_path(); + my ($uname,$udom) = &get_name_dom($group); # Fixme --- Move the checking for existing file to LOND error return - my @dir_list=&Apache::lonnet::dirlist($ENV{'form.currentpath'}, - $ENV{'user.domain'}, - $ENV{'user.name'},$portfolio_root); + my @dir_list=&get_dir_list($portfolio_root,$path,$group); my $found_file = 0; + my $locked_file = 0; foreach my $line (@dir_list) { - my ($filename)=split(/\&/,$line,2); - if ($filename eq $fname){ + my ($file_name)=split(/\&/,$line,2); + if ($file_name eq $fname){ + $file_name = $path.$file_name; + $file_name = &prepend_group($file_name); $found_file = 1; + if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') { + $locked_file = 1; + } } } - my $current_disk_usage = &Apache::lonnet::diskusage($ENV{'user.domain'}, $ENV{'user.name'},$portfolio_root); - if ((($current_disk_usage/1000) + $filesize) > $disk_quota){ - $r->print('Unable to upload '.$fname.' (size = '.$filesize.' kilobytes. Disk quota will be exceeded.'. - '
Disk quota is '.$disk_quota.' kilobytes. Your current disk usage is '.$current_disk_usage.' kilobytes.'); - } - elsif ($found_file){ - $r->print('Unable to upload '.$fname.', a file by that name was found in '.$ENV{'form.currentpath'}.''. - '
To upload, rename or delete existing '.$fname.' in '.$ENV{'form.currentpath'}); - } else { - my $result=&Apache::lonnet::userfileupload('uploaddoc','', - 'portfolio'.$ENV{'form.currentpath'}); - if ($result !~ m|^/uploaded/|) { - $r->print(' An errror occured ('.$result. - ') while trying to upload '.&display_file().'
'); + my $getpropath = 1; + my $current_disk_usage = &Apache::lonnet::diskusage($udom,$uname,$portfolio_root,$getpropath); + + if (($current_disk_usage + $filesize) > $disk_quota){ + my $msg = ''. + &mt('Unable to upload [_1]. (size = [_2] kilobytes). Disk quota will be exceeded.',''.$fname.'',$filesize).''. + '
'.&mt('Disk quota is [_1] kilobytes. Your current disk usage is [_2] kilobytes.',$disk_quota,$current_disk_usage); + return ('will_exceed_quota',$msg); + } elsif ($found_file) { + if ($locked_file) { + my $msg = ''; + $msg .= &mt('Unable to upload [_1]. A locked file by that name was found in [_2].',''.$fname.'',''.$port_path.$env{'form.currentpath'}.''); + $msg .= '
'; + $msg .= &mt('You will be able to rename or delete existing [_1] after a grade has been assigned.',''.$fname.''); + return ('file_locked',$msg); + } else { + my $msg = ''; + $msg .= &mt('Unable to upload [_1]. A file by that name was found in [_2].',''.$fname.'',$port_path.$env{'form.currentpath'}); + $msg .= ''; + $msg .= '
'; + $msg .= &mt('To upload, rename or delete existing [_1] in [_2].',''.$fname.'', $port_path.$env{'form.currentpath'}); + return ('file_exists',$msg); + } + } +} + +sub upload { + my ($r,$url,$group)=@_; + my $fname=&Apache::lonnet::clean_filename($env{'form.uploaddoc.filename'}); + my $disk_quota = &get_quota($group); + my $portfolio_root = &get_portfolio_root(); + my $port_path = &get_port_path(); + my ($uname,$udom) = &get_name_dom($group); + my $getpropath = 1; + my $current_disk_usage = &Apache::lonnet::diskusage($udom,$uname,$portfolio_root,$getpropath); + my ($state,$msg) = + &Apache::loncommon::check_for_upload($env{'form.currentpath'},$fname, + $group,'uploaddoc',$portfolio_root, + $port_path,$disk_quota, + $current_disk_usage,$uname,$udom); + if ($state eq 'will_exceed_quota' + || $state eq 'file_locked' + || $state eq 'file_exists' ) { + $r->print($msg.&done('Back',$url)); + return; + } + + my (%allfiles,%codebase,$mode); + if ($env{'form.uploaddoc.filename'} =~ m/(\.htm|\.html|\.shtml)$/i) { + if ($env{'form.parserflag'}) { + $mode = 'parse'; } } - $r->print(&done()); + my $result= + &Apache::lonnet::userfileupload('uploaddoc','', + $port_path.$env{'form.currentpath'}, + $mode,\%allfiles,\%codebase); + if ($result !~ m|^/uploaded/|) { + $r->print(''.&mt('An error occurred ([_1]) while trying to upload [_2].' + ,$result,&display_file()).'
'); + $r->print(&done('Back',$url)); + } else { + if (%allfiles) { + if (!&suppress_embed_prompt()) { + my $state = < + + + +STATE + $r->print("

".&mt("Reference Warning")."

"); + $r->print("

".&mt("Completed upload of the file. This file contained references to other files. You must upload the referenced files or else the uploaded file may not work properly.")."

"); + $r->print("

".&mt("Please select the locations from which the referenced files are to be uploaded.")."

"); + $r->print(&Apache::loncommon::ask_for_embedded_content('/adm/portfolio',$state,\%allfiles,\%codebase, + {'error_on_invalid_names' => 1, + 'ignore_remote_references' => 1,})); + $r->print('

Or '.&done('Return to directory',$url).'

'); + } + } else { + $r->print(&done(undef,$url)); + } + } +} + +sub lock_info { + my ($r,$url,$group) = @_; + my ($uname,$udom) = &get_name_dom($group); + my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom, + $uname); + my $file_name = $env{'form.lockinfo'}; + $file_name = &prepend_group($file_name); + if (defined($file_name) && defined($$current_permissions{$file_name})) { + foreach my $array_item (@{$$current_permissions{$file_name}}) { + next if (ref($array_item) ne 'ARRAY'); + + my $filetext; + if (defined($group)) { + $filetext = ''.$env{'form.lockinfo'}. + ' (group: '.$group.')'; + } else { + $filetext = ''.$file_name.''; + } + + my $title =''.&Apache::lonnet::gettitle($$array_item[0]). + '
'; + if ($$array_item[-1] eq 'graded') { + $r->print(&mt('[_1] was submitted in response to problem: [_2]', + $filetext,$title)); + } elsif ($$array_item[-1] eq 'handback') { + $r->print(&mt('[_1] was handed back in response to problem: [_2]', + $filetext,$title)); + } else { + # submission style lock + $r->print(&mt('[_1] was submitted in response to problem: [_2]', + $filetext,$title)); + } + my %course_description = + &Apache::lonnet::coursedescription($$array_item[1]); + if ( $course_description{'description'} ne '') { + $r->print(&mt('In the course:').' '.$course_description{'description'}.'
'); + } + } + } + $r->print(&done(&mt('Back'),$url)); + return 'ok'; } sub createdir { - my ($r)=@_; - my $newdir=&Apache::lonnet::clean_filename($ENV{'form.newdir'}); + my ($r,$url,$group)=@_; + my $newdir=&Apache::lonnet::clean_filename($env{'form.newdir'}); if ($newdir eq '') { - $r->print(''. + $r->print(''. &mt("Error: no directory name was provided."). - '
'); - $r->print(&done()); + '
'); + $r->print(&done(undef,$url)); return; - } - my $portfolio_root = &Apache::loncommon::propath($ENV{'user.domain'}, - $ENV{'user.name'}). - '/userfiles/portfolio'; - my @dir_list=&Apache::lonnet::dirlist($ENV{'form.currentpath'}, - $ENV{'user.domain'}, - $ENV{'user.name'},$portfolio_root); + } + my $portfolio_root = &get_portfolio_root(); + my @dir_list=&get_dir_list($portfolio_root,undef,$group); my $found_file = 0; foreach my $line (@dir_list) { my ($filename)=split(/\&/,$line,2); @@ -480,94 +1973,410 @@ sub createdir { } } if ($found_file){ - $r->print(' Unable to create a directory named '.$newdir. - ' a file or directory by that name already exists.
'); + $r->print('' + .&mt('Unable to create a directory named [_1].',''.$newdir.'') + .' '.&mt('A file or directory by that name already exists.').'
'); } else { - my $result=&Apache::lonnet::mkdiruserfile($ENV{'user.name'}, - $ENV{'user.domain'},'portfolio'.$ENV{'form.currentpath'}.$newdir); + my ($uname,$udom) = &get_name_dom($group); + my $port_path = &get_port_path(); + my $result=&Apache::lonnet::mkdiruserfile($uname,$udom, + $port_path.$env{'form.currentpath'}.$newdir); if ($result ne 'ok') { - $r->print(' An errror occured ('.$result. - ') while trying to create a new directory '.&display_file().'
'); + $r->print('' + .&mt('An error occurred ([_1]) while trying to create a new directory [_2].' + ,$result,&display_file()) + .'
'); } } - if ($newdir ne $ENV{'form.newdir'}) { - $r->print("The new directory name was changed from:
".$ENV{'form.newdir'}." to $newdir "); + if ($newdir ne $env{'form.newdir'}) { + $r->print(&mt('The new directory name was changed from [_1] to [_2].' + ,''.$env{'form.newdir'}.'',''.$newdir.'')); + } + $r->print(&done(undef,$url)); +} + +sub get_portfolio_root { + my ($udom,$uname,$group) = @_; + if (!(defined($udom)) || !(defined($uname))) { + ($uname,$udom) = &get_name_dom($group); + } + my $path = '/userfiles/portfolio'; + if (!defined($group)) { + if (defined($env{'form.group'})) { + $group = $env{'form.group'}; + } + } + if (defined($group)) { + $path = '/userfiles/groups/'.$group.'/portfolio'; + } + return $path; +} + +sub get_group_quota { + my ($group) = @_; + my $group_quota; + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,$group); + if (%curr_groups) { + my %group_info = &Apache::longroup::get_group_settings( + $curr_groups{$group}); + $group_quota = $group_info{'quota'}; #expressed in Mb + if ($group_quota) { + $group_quota = 1000 * $group_quota; #expressed in k + } + } + return $group_quota; +} + +sub get_dir_list { + my ($portfolio_root,$path,$group) = @_; + $path ||= $env{'form.currentpath'}; + my ($uname,$udom) = &get_name_dom($group); + my $getpropath = 1; + return &Apache::lonnet::dirlist($portfolio_root.$path,$udom,$uname,$getpropath); +} + +sub get_name_dom { + my ($group) = @_; + my ($uname,$udom); + if (defined($group)) { + $udom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + $uname = $env{'course.'.$env{'request.course.id'}.'.num'}; + } else { + $udom = $env{'user.domain'}; + $uname = $env{'user.name'}; + } + return ($uname,$udom); +} + +sub prepend_group { + my ($filename) = @_; + if (defined($env{'form.group'})) { + $filename = $env{'form.group'}.$filename; } - $r->print(&done()); + return $filename; } +sub get_namespace { + my $namespace = 'portfolio'; + if (defined($env{'form.group'})) { + my ($uname,$udom) = &get_name_dom($env{'form.group'}); + $namespace .= '_'.$udom.'_'.$uname.'_'.$env{'form.group'}; + } + return $namespace; +} + +sub get_port_path { + my $port_path; + if (defined($env{'form.group'})) { + $port_path = "groups/$env{'form.group'}/portfolio"; + } else { + $port_path = 'portfolio'; + } + return $port_path; +} + +sub missing_priv { + my ($r,$url,$priv) = @_; + my $longtext = { + upload => 'upload files', + delete => 'delete files', + rename => 'rename files', + setacl => 'set access controls for files', + }; + my $escpath = &HTML::Entities::encode($env{'form.currentpath'},'&<>"'); + my $rtnlink = 'print(&mt('in this portfolio.')); + } + $rtnlink .= '">'.&mt('Return to directory').''; + $r->print('
'.$rtnlink); + $r->print(&Apache::loncommon::end_page()); + return; +} + +sub coursegrp_portfolio_header { + my ($cdom,$cnum,$grp_desc)=@_; + my $gpterm = &Apache::loncommon::group_term(); + my $ucgpterm = $gpterm; + $ucgpterm =~ s/^(\w)/uc($1)/e; + if ($env{'form.ref'}) { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"/adm/coursegroups", + text=>"Groups", + title=>"Course Groups"}); + } + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"/adm/$cdom/$cnum/$env{'form.group'}/smppg?ref=$env{'form.ref'}", + text=>"$ucgpterm: $grp_desc", + title=>"Go to group's home page"}, + {href=>"/adm/coursegrp_portfolio?".&group_args(), + text=>"Group Portfolio", + title=>"Display group portfolio"}); + my $output = &Apache::lonhtmlcommon::breadcrumbs( + &mt('[_1] portfolio files - [_2]',$gpterm,$grp_desc)); + return $output; +} + +sub get_quota { + my ($group) = @_; + my $disk_quota; + if (defined($group)) { + my $grp_quota = &get_group_quota($group); # quota expressed in k + if ($grp_quota ne '') { + $disk_quota = $grp_quota; + } else { + $disk_quota = 0; + } + } else { + $disk_quota = &Apache::loncommon::get_user_quota($env{'user.name'}, + $env{'user.domain'}); #expressed in Mb + $disk_quota = 1000 * $disk_quota; # convert from Mb to kb + } + return $disk_quota; +} + +sub suppress_embed_prompt { + my $suppress_prompt = 0; + if (($env{'request.role'} =~ /^st/) && ($env{'request.course.id'} ne '')) { + if ($env{'course.'.$env{'request.course.id'}.'.suppress_embed_prompt'} eq 'yes') { + $suppress_prompt = 1; + } + } + return $suppress_prompt; +} + + sub handler { # this handles file management my $r = shift; - my $bodytag; - my $portfolio_root = &Apache::loncommon::propath($ENV{'user.domain'}, - $ENV{'user.name'}). - '/userfiles/portfolio'; &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['selectfile','currentpath','meta', - 'currentfile','action','fieldname','mode','rename']); - if ($ENV{"form.mode"} eq 'selectfile'){ - $bodytag = &Apache::loncommon::bodytag('Portfolio Manager',undef,undef,1); + ['selectfile','currentpath','meta','lockinfo','currentfile','action', + 'fieldname','mode','rename','continue','group','access','setnum', + 'cnum','cdom','type','setroles','showversions','ref']); + my ($uname,$udom,$portfolio_root,$url,$caller,$title,$group,$grp_desc); + if ($r->uri =~ m|^(/adm/)([^/]+)|) { + $url = $1.$2; + $caller = $2; + } + my ($can_modify,$can_delete,$can_upload,$can_setacl); + if ($caller eq 'coursegrp_portfolio') { + # Needs to be in a course + if (! ($env{'request.course.fn'})) { + # Not in a course + $env{'user.error.msg'}= + "/adm/coursegrp_portfolio:rgf:0:0:Cannot view group portfolio"; + return HTTP_NOT_ACCEPTABLE; + } + my $earlyout = 0; + my $view_permission = + &Apache::lonnet::allowed('vcg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')); + $env{'form.group'} =~ s/\W//g; + $group = $env{'form.group'}; + if ($group ne '') { + ($uname,$udom) = &get_name_dom($group); + my %curr_groups = &Apache::longroup::coursegroups($udom,$uname, + $group); + if (%curr_groups) { + my %grp_content = &Apache::longroup::get_group_settings( + $curr_groups{$group}); + $grp_desc = &unescape($grp_content{'description'}); + if (($view_permission) || (&Apache::lonnet::allowed('rgf', + $env{'request.course.id'}.'/'.$group))) { + $portfolio_root = &get_portfolio_root(); + } else { + $r->print(&mt('You do not have the privileges required to access the shared files space for this group.')); + $earlyout = 1; + } + } else { + $r->print(&mt('Not a valid group for this course')); + $earlyout = 1; + } + $title = &mt('Group files for [_1]', $group); + } else { + $r->print(&mt('Invalid group')); + $earlyout = 1; + } + if ($earlyout) { return OK; } + if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) { + $can_modify = 1; + $can_delete = 1; + $can_upload = 1; + $can_setacl = 1; + } else { + if (&Apache::lonnet::allowed('agf',$env{'request.course.id'}.'/'.$group)) { + $can_setacl = 1; + } + if (&Apache::lonnet::allowed('ugf',$env{'request.course.id'}.'/'.$group)) { + $can_upload = 1; + } + if (&Apache::lonnet::allowed('mgf',$env{'request.course.id'}.'/'.$group)) { + $can_modify = 1; + } + if (&Apache::lonnet::allowed('dgf',$env{'request.course.id'}.'/'.$group)) { + $can_delete = 1; + } + } } else { - $bodytag = &Apache::loncommon::bodytag('Portfolio Manager'); + ($uname,$udom) = &get_name_dom(); + $portfolio_root = &get_portfolio_root(); + $title = &mt('Portfolio Manager'); + $can_modify = 1; + $can_delete = 1; + $can_upload = 1; + $can_setacl = 1; } + my $port_path = &get_port_path(); &Apache::loncommon::no_cache($r); &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; # Give the LON-CAPA page header - $r->print(''. - &mt('Portfolio Manager'). - "\n". - $bodytag); + if ($env{"form.mode"} eq 'selectfile'){ + $r->print(&Apache::loncommon::start_page($title,undef, + {'only_body' => 1})); + } elsif ($env{'form.action'} eq 'rolepicker') { + $r->print(&Apache::loncommon::start_page('New role-based condition',undef, + {'no_nav_bar' => 1, })); + } else { + $r->print(&Apache::loncommon::start_page($title)); + } $r->rflush(); - if (($ENV{'form.storeupl'} eq 'Upload') & (!$ENV{'form.uploaddoc.filename'})){ - $r->print(' No file was selected to upload.'. - 'To upload a file, click Browse...'. - ', select a file, then click Upload,'); - } - if ($ENV{'form.meta'}) { - &open_form($r); -# $r->print(&edit_meta_data($r, $ENV{'form.currentpath'}.$ENV{'form.selectfile'})); - $r->print('Edit the meta data
'); - &close_form($r); - } - if ($ENV{'form.store'}) { - } - - if ($ENV{'form.uploaddoc.filename'}) { - &upload($r); - } elsif ($ENV{'form.action'} eq 'delete' && $ENV{'form.confirmed'}) { - &delete_confirmed($r); - } elsif ($ENV{'form.action'} eq 'delete') { - &delete($r); - } elsif ($ENV{'form.action'} eq 'deletedir' && $ENV{'form.confirmed'}) { - &delete_dir_confirmed($r); - } elsif ($ENV{'form.action'} eq 'deletedir'){ - &delete_dir($r); - } elsif ($ENV{'form.action'} eq 'rename' && $ENV{'form.confirmed'}) { - &rename_confirmed($r); - } elsif ($ENV{'form.rename'}) { - $ENV{'form.selectfile'} = $ENV{'form.rename'}; - $ENV{'form.action'} = 'rename'; - &rename($r); - } elsif ($ENV{'form.createdir'}) { - &createdir($r); + my ($blocked,$blocktext) = + &Apache::loncommon::blocking_status('port',$uname,$udom); + if ($blocked) { + $r->print($blocktext); + $r->print(&Apache::loncommon::end_page()); + return OK; + } + if (($env{'form.storeupl'}) & (!$env{'form.uploaddoc.filename'})){ + $r->print(''); + $r->print(&mt('No file was selected to upload.').' '); + $r->print(&mt('To upload a file, click Browse... and select a file, then click Upload.')); + $r->print(''); + } + if ($env{'form.meta'}) { + &open_form($r,$url); + $r->print(&mt('Edit the meta data').'
'); + &close_form($r,$url); + } + if ($env{'form.store'}) { + } + + if ($env{'form.uploaddoc.filename'}) { + if ($can_upload) { + &upload($r,$url,$group); + } else { + &missing_priv($r,$url,'upload'); + } + } elsif ($env{'form.action'} eq 'upload_embedded') { + if ($can_upload) { + my $disk_quota = &get_quota($group); + my $getpropath = 1; + my $current_disk_usage = + &Apache::lonnet::diskusage($udom,$uname,$portfolio_root,$getpropath); + $r->print( + &Apache::loncommon::upload_embedded('portfolio',$port_path,$uname,$udom, + $group,$portfolio_root,$group,$disk_quota,$current_disk_usage)); + $r->print(&done(undef,$url)); + } else { + &missing_priv($r,$url,'upload'); + } + } elsif ($env{'form.action'} eq 'delete' && $env{'form.confirmed'}) { + if ($can_delete) { + &delete_confirmed($r,$url,$group); + } else { + &missing_priv($r,$url,'delete'); + } + } elsif ($env{'form.action'} eq 'delete') { + if ($can_delete) { + &delete($r,$url,$group); + } else { + &missing_priv($r,$url,'delete'); + } + } elsif ($env{'form.action'} eq 'deletedir' && $env{'form.confirmed'}) { + if ($can_delete) { + &delete_dir_confirmed($r,$url,$group); + } else { + &missing_priv($r,$url,'delete'); + } + } elsif ($env{'form.action'} eq 'deletedir') { + if ($can_delete) { + &delete_dir($r,$url); + } else { + &missing_priv($r,$url,'delete'); + } + } elsif ($env{'form.action'} eq 'rename' && $env{'form.confirmed'}) { + if ($can_modify) { + &rename_confirmed($r,$url,$group); + } else { + &missing_priv($r,$url,'rename'); + } + } elsif ($env{'form.rename'}) { + $env{'form.selectfile'} = $env{'form.rename'}; + $env{'form.action'} = 'rename'; + if ($can_modify) { + &rename($r,$url,$group); + } else { + &missing_priv($r,$url,'rename'); + } + } elsif ($env{'form.access'}) { + $env{'form.selectfile'} = $env{'form.access'}; + if (!defined($env{'form.action'})) { + $env{'form.action'} = 'chgaccess'; + } + &display_access($r,$url,$group,$can_setacl,$port_path,$env{'form.action'}); + } elsif (($env{'form.action'} eq 'chgaccess') || + ($env{'form.action'} eq 'chgconditions')) { + if ($can_setacl) { + &update_access($r,$url,$group,$port_path); + } else { + &missing_priv($r,$url,'setacl'); + } + } elsif ($env{'form.action'} eq 'rolepicker') { + if ($can_setacl) { + &role_options_window($r); + } else { + &missing_priv($r,$url,'setacl'); + } + } elsif ($env{'form.createdir'}) { + if ($can_upload) { + &createdir($r,$url,$group); + } else { + &missing_priv($r,$url,'upload'); + } + } elsif ($env{'form.lockinfo'}) { + &lock_info($r,$url,$group); } else { my $current_path='/'; - if ($ENV{'form.currentpath'}) { - $current_path = $ENV{'form.currentpath'}; + if ($env{'form.currentpath'}) { + $current_path = $env{'form.currentpath'}; } - my @dir_list=&Apache::lonnet::dirlist($current_path, - $ENV{'user.domain'}, - $ENV{'user.name'},$portfolio_root); + if ($caller eq 'coursegrp_portfolio') { + &Apache::lonhtmlcommon::clear_breadcrumbs(); + $r->print(&coursegrp_portfolio_header($udom,$uname,$grp_desc)); + } + my @dir_list=&get_dir_list($portfolio_root,$current_path,$group); if ($dir_list[0] eq 'no_such_dir'){ # two main reasons for this: # 1) never been here, so directory structure not created # 2) back-button navigation after deleting a directory if ($current_path eq '/'){ - &Apache::lonnet::mkdiruserfile($ENV{'user.name'}, - $ENV{'user.domain'},'portfolio'); + &Apache::lonnet::mkdiruserfile($uname,$udom, + &get_port_path()); } else { # some directory that snuck in get rid of the directory # from the recent pulldown, just in case @@ -576,22 +2385,18 @@ sub handler { $current_path = '/'; # force it back to the root } # now grab the directory list again, for the first time - @dir_list=&Apache::lonnet::dirlist($current_path, - $ENV{'user.domain'}, - $ENV{'user.name'},$portfolio_root); + @dir_list=&get_dir_list($portfolio_root,$current_path,$group); } # need to know if directory is empty so it can be removed if desired my $is_empty=(@dir_list == 2); - &display_common($r,$current_path,$is_empty,\@dir_list); - if ($ENV{"form.mode"} eq 'selectfile'){ - &select_files($r); - &display_file_select($r,$current_path,$is_empty,\@dir_list); - } else { - &display_directory($r,$current_path,$is_empty,\@dir_list); - } - $r->print("\n\n"); - return OK; + &display_common($r,$url,$current_path,$is_empty,\@dir_list, + $can_upload); + &display_directory($r,$url,$current_path,$is_empty,\@dir_list,$group, + $can_upload,$can_modify,$can_delete,$can_setacl); + $r->print(&Apache::loncommon::end_page()); } + return OK; } + 1; __END__ 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.