--- loncom/interface/portfolio.pm 2010/11/28 00:04:05 1.231 +++ loncom/interface/portfolio.pm 2012/12/17 06:29:02 1.239 @@ -1,7 +1,7 @@ # The LearningOnline Network # portfolio browser # -# $Id: portfolio.pm,v 1.231 2010/11/28 00:04:05 raeburn Exp $ +# $Id: portfolio.pm,v 1.239 2012/12/17 06:29:02 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -122,6 +122,7 @@ END .'<input name="uploaddoc" type="file" />' .'<input type="hidden" name="currentpath" value="'.$current_path.'" />' .'<input type="hidden" name="action" value="'.$env{"form.action"}.'" />' + .'<input type="hidden" name="symb" value="'.$env{"form.symb"}.'" />' .'<input type="hidden" name="fieldname" value="'.$env{"form.fieldname"}.'" />' .'<input type="hidden" name="mode" value="'.$env{"form.mode"}.'" />' .'<input type="submit" name="storeupl" value="'.$lt{'upload'}.'" />' @@ -139,6 +140,7 @@ END .'<input name="newdir" type="text" />'.$groupitem .'<input type="hidden" name="currentpath" value="'.$current_path.'" />' .'<input type="hidden" name="action" value="'.$env{"form.action"}.'" />' + .'<input type="hidden" name="symb" value="'.$env{"form.symb"}.'" />' .'<input type="hidden" name="fieldname" value="'.$env{"form.fieldname"}.'" />' .'<input type="hidden" name="mode" value="'.$env{"form.mode"}.'" />' .'<input type="submit" name="createdir" value="'.$lt{'createdir'}.'" />' @@ -155,6 +157,7 @@ END 'selectfile' => $port_path, 'currentpath' => '/', 'mode' => $env{"form.mode"}, + 'symb' => $env{"form.symb"}, 'fieldname' => $env{"form.fieldname"}, 'continue' => $env{"form.continue"} ); @@ -168,6 +171,7 @@ END 'selectfile' => $tree[$i], 'currentpath' => $newCurrentPath, 'mode' => $env{"form.mode"}, + 'symb' => $env{"form.symb"}, 'fieldname' => $env{"form.fieldname"}, 'continue' => $env{"form.continue"} ); @@ -177,7 +181,7 @@ END $r->print('</span>'); $r->print(&Apache::loncommon::help_open_topic('Portfolio ChangeDirectory')); &Apache::lonhtmlcommon::store_recent($namespace,$current_path,$current_path); - $r->print('<br /><form method="post" action="'.$url.'?mode='.$env{"form.mode"}.'&fieldname='.$env{"form.fieldname"}.&group_args()); + $r->print('<br /><form method="post" action="'.$url.'?mode='.$env{"form.mode"}.'&fieldname='.$env{"form.fieldname"}.'&symb='.$env{'form.symb'}.&group_args()); $r->print('">'. &Apache::lonhtmlcommon::select_recent($namespace,'currentpath', 'this.form.submit();')); @@ -379,22 +383,24 @@ sub display_directory { 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)) { - my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$dir_line,16); - $filename =~ s/\s+$//; - 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]); - } + if (ref($dir_list) eq 'ARRAY') { + foreach my $dir_line (sort + { + my ($afile)=split('&',$a,2); + my ($bfile)=split('&',$b,2); + return (lc($afile) cmp lc($bfile)); + } (@{$dir_list})) { + my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$dir_line,16); + $filename =~ s/\s+$//; + 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]); + } + } } my $zerobyte; foreach my $dir_line (@dir_lines) { @@ -445,6 +451,7 @@ sub display_directory { 'selectfile' => $filename.'/', 'currentpath' => $current_path.$filename.'/', 'mode' => $env{"form.mode"}, + 'symb' => $env{"form.symb"}, 'fieldname' => $env{"form.fieldname"}, 'continue' => $env{"form.continue"} ); @@ -552,6 +559,7 @@ sub display_directory { $r->print(' <input type="hidden" name="continue" value="true" /> <input type="hidden" name="fieldname" value="'.$env{'form.fieldname'}.'" /> + <input type="hidden" name="symb" value="'.$env{'form.symb'}.'" /> <input type="hidden" name="mode" value="selectfile" /> <p> <input type="submit" name="submit" value="'.&mt('Select checked files, and continue selecting').'" /><br /> @@ -639,9 +647,10 @@ sub done { 'showversions' => $env{'form.showversions'}, 'currentpath' => $env{'form.currentpath'}, 'fieldname' => $env{'form.fieldname'}, + 'symb' => $env{'form.symb'}, 'mode' => $env{'form.mode'} ); - my $result = '<h3>'.&make_anchor($url,\%anchor_fields,&mt($message)).'</h3>'; + my $result = '<p>'.&make_anchor($url,\%anchor_fields,&mt($message)).'</p>'; return $result; } @@ -661,7 +670,7 @@ sub delete { $r->print('<p>'.&mt('Delete [_1]?',&display_file(undef,\@files)).'</p>'); &close_form($r,$url); } else { - $r->print("No file was checked to delete.<br />"); + $r->print('<p class="LC_warning">'.&mt('No file was checked to delete.').'</p>'); $r->print(&done(undef,$url)); } } @@ -972,11 +981,11 @@ sub build_access_summary { $showstart = &mt('Deleted'); $showend = $showstart; } else { - $showstart = localtime($start); + $showstart = &Apache::lonlocal::locallocaltime($start); if ($end == 0) { $showend = &mt('No end date'); } else { - $showend = localtime($end); + $showend = &Apache::lonlocal::locallocaltime($end); } } $r->print('<td>'.&mt($scope_desc{$scope})); @@ -2088,6 +2097,7 @@ sub hidden_elems { } return <<END; <input type="hidden" name="currentpath" value="$env{'form.currentpath'}" /> +<input type="hidden" name="symb" value="$env{'form.symb'}" /> <input type="hidden" name="fieldname" value="$env{'form.fieldname'}" /> <input type="hidden" name="mode" value="$env{'form.mode'}" /> <input type="hidden" name="showversions" value="$env{'form.showversions'}" /> @@ -2109,7 +2119,10 @@ sub print_dependency_form { $r->print('<h3>'.&mt("Reference Information").'</h3>'); } if ($num) { - $r->print('<p>'.&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.").'</p>'. + $r->print('<p>'.&mt('Completed upload of the file.').' '. + &mt('This file contained references to other files.').' '. + &mt('You must upload the referenced files or else the uploaded file may not work properly.'). + '</p>'. '<p>'.&mt("Please select the locations from which the referenced files are to be uploaded.").'</p>'. $embedded. '<p>'.&mt('or').'</p>'.&done('Return to directory',$url)); @@ -2130,7 +2143,6 @@ sub overwrite { my $port_path = &get_port_path(); my $fname = &Apache::lonnet::clean_filename($env{'form.filename'}); my (%allfiles,%codebase,$mode,$mimetype); - my $mode; unless (&suppress_embed_prompt()) { if ($env{'form.parserflag'}) { if ($fname =~ /\.s?html?$/i) { @@ -2250,12 +2262,14 @@ sub createdir { return; } my $portfolio_root = &get_portfolio_root(); - my @dir_list=&get_dir_list($portfolio_root,undef,$group); + my ($dirlistref,$listerror) = &get_dir_list($portfolio_root,undef,$group); my $found_file = 0; - foreach my $line (@dir_list) { - my ($filename)=split(/\&/,$line,2); - if ($filename eq $newdir){ - $found_file = 1; + if (ref($dirlistref) eq 'ARRAY') { + foreach my $line (@{$dirlistref}) { + my ($filename)=split(/\&/,$line,2); + if ($filename eq $newdir){ + $found_file = 1; + } } } if ($found_file){ @@ -2365,12 +2379,13 @@ sub get_port_path { sub missing_priv { my ($r,$url,$priv) = @_; - my $longtext = { + my %longtext = + &Apache::lonlocal::texthash( 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 = '<a href="'.$url; if ($url =~ /\?/) { @@ -2380,13 +2395,13 @@ sub missing_priv { } $rtnlink .= 'currentpath='.$escpath; $r->print('<h3>'.&mt('Action disallowed').'</h3>'); - $r->print(&mt('You do not have sufficient privileges to [_1] ', - $longtext->{$priv})); + $r->print(&mt('You do not have sufficient privileges to [_1]', + $longtext{$priv})); if (defined($env{'form.group'})) { - $r->print(&mt("in the group's group portfolio.")); + $r->print(' '.&mt("in the group's group portfolio.")); $rtnlink .= &group_args() } else { - $r->print(&mt('in this portfolio.')); + $r->print(' '.&mt('in this portfolio.')); } $rtnlink .= '">'.&mt('Return to directory').'</a>'; $r->print('<br />'.$rtnlink); @@ -2448,6 +2463,7 @@ sub embedded_form_elems { my ($container) = @_; my $state = <<STATE; <input type="hidden" name="currentpath" value="$env{'form.currentpath'}" /> + <input type="hidden" name="symb" value="$env{'form.symb'}" /> <input type="hidden" name="fieldname" value="$env{'form.fieldname'}" /> <input type="hidden" name="mode" value="$env{'form.mode'}" /> <input type="hidden" name="container" value="$container" /> @@ -2464,7 +2480,7 @@ sub handler { &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['selectfile','currentpath','meta','lockinfo','currentfile','action', 'fieldname','mode','rename','continue','group','access','setnum', - 'cnum','cdom','type','setroles','showversions','ref']); + 'cnum','cdom','type','setroles','showversions','ref','symb']); my ($uname,$udom,$portfolio_root,$url,$caller,$title,$group,$grp_desc); if ($r->uri =~ m|^(/adm/)([^/]+)|) { $url = $1.$2; @@ -2567,15 +2583,45 @@ sub handler { } } $r->rflush(); + # Check if access to portfolio is blocked by one or more blocking events in courses. my ($blocked,$blocktext) = &Apache::loncommon::blocking_status('port',$uname,$udom); if ($blocked) { - $r->print($blocktext); - $r->print(&Apache::loncommon::end_page()); - return OK; + my $evade_block; + # If portfolio display is in a window popped up from a "Select Portfolio Files" + # link in a .task resource, check if access to the task included proctor validation + # of check-in to a slot limited by IP. + # If so, and the slot is between its open and close dates, override the block. + if ($env{'request.course.id'} && $env{'form.symb'}) { + (undef,undef,my $res) = &Apache::lonnet::decode_symb($env{'form.symb'}); + if ($res =~ /\.task$/i) { + my %history = + &Apache::lonnet::restore($env{'form.symb'},$env{'request.course.id'}, + $env{'user.domain'},$env{'user.name'}); + my $version = $history{'resource.0.version'}; + if ($history{'resource.'.$version.'.0.checkedin'}) { + if ($history{'resource.'.$version.'.0.checkedin.slot'}) { + my %slot = &Apache::lonnet::get_slot($history{'resource.'.$version.'.0.checkedin.slot'}); + if ($slot{'ip'}) { + if (&Apache::loncommon::check_ip_acc($slot{'ip'})) { + my $now = time; + if (($slot{'slottime'} < $now) && ($slot{'endtime'} > $now)) { + $evade_block = 1; + } + } + } + } + } + } + } + unless ($evade_block) { + $r->print($blocktext); + $r->print(&Apache::loncommon::end_page()); + return OK; + } } if (($env{'form.storeupl'}) & (!$env{'form.uploaddoc.filename'})){ - $r->print('<span class="LC_error">'); + $r->print('<span class="LC_warning">'); $r->print(&mt('No file was selected to upload.').' '); $r->print(&mt('To upload a file, click <strong>Browse...</strong> and select a file, then click <strong>Upload</strong>.')); $r->print('</span>'); @@ -2615,8 +2661,11 @@ sub handler { } } elsif ($env{'form.action'} eq 'modify_orightml') { if ($can_upload) { - $r->print(&Apache::loncommon::modify_html_refs('portfolio',$port_path,$uname,$udom,$group,$portfolio_root,$group)); - $r->print(&done('Return to directory',$url)); + my $result = + &Apache::loncommon::modify_html_refs('portfolio',$port_path,$uname,$udom,$group, + $portfolio_root,$group); + $r->print($result. + &done('Return to directory',$url)); } else { &missing_priv($r,$url,'upload'); } @@ -2704,8 +2753,9 @@ sub handler { &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'){ + my ($dirlistref,$listerror) = + &get_dir_list($portfolio_root,$current_path,$group); + if ($listerror 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 @@ -2720,13 +2770,22 @@ sub handler { $current_path = '/'; # force it back to the root } # now grab the directory list again, for the first time - @dir_list=&get_dir_list($portfolio_root,$current_path,$group); + ($dirlistref,$listerror) = + &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,$url,$current_path,$is_empty,\@dir_list, + my $is_empty; + if ($listerror eq 'empty') { + $is_empty = 1; + } elsif (ref($dirlistref) eq 'ARRAY') { + if ((scalar(@{$dirlistref}) == 2) && ($dirlistref->[0] =~ /^\.+\&/) + && ($dirlistref->[1] =~ /^\.+\&/)) { + $is_empty = 1; + } + } + &display_common($r,$url,$current_path,$is_empty,$dirlistref, $can_upload,$group); - &display_directory($r,$url,$current_path,$is_empty,\@dir_list,$group, + &display_directory($r,$url,$current_path,$is_empty,$dirlistref,$group, $can_upload,$can_modify,$can_delete,$can_setacl); } $r->print(&Apache::loncommon::end_page());