File:  [LON-CAPA] / loncom / interface / portfolio.pm
Revision 1.120: download - view: text, annotated - select for diffs
Fri Jun 23 20:15:24 2006 UTC (17 years, 11 months ago) by raeburn
Branches: MAIN
CVS tags: HEAD
Enforcing privileges for actions on course group portfolio files. Tabular display of access controls provided for group members with access to group repository, but without privilege needed to add/delete/update access controls for group files. Some text improvements, and case fixes for triggering correct roles nomenclature when dependent on Course/Group context.

    1: # Copyright Michigan State University Board of Trustees
    2: #
    3: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    4: #
    5: # LON-CAPA is free software; you can redistribute it and/or modify
    6: # it under the terms of the GNU General Public License as published by
    7: # the Free Software Foundation; either version 2 of the License, or 
    8: # (at your option) any later version.
    9: #
   10: # LON-CAPA is distributed in the hope that it will be useful,
   11: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   12: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13: # GNU General Public License for more details.
   14: #
   15: # You should have received a copy of the GNU General Public License
   16: # along with LON-CAPA; if not, write to the Free Software
   17: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   18: #
   19: # /home/httpd/html/adm/gpl.txt
   20: #
   21: # http://www.lon-capa.org/
   22: #
   23: 
   24: package Apache::portfolio;
   25: use strict;
   26: use Apache::Constants qw(:common :http);
   27: use Apache::loncommon;
   28: use Apache::lonnet;
   29: use Apache::lontexconvert;
   30: use Apache::lonfeedback;
   31: use Apache::lonlocal;
   32: use Apache::lonnet;
   33: use Apache::longroup;
   34: use HTML::Entities;
   35: use LONCAPA;
   36: 
   37: # receives a file name and path stub from username/userfiles/portfolio/
   38: # returns an anchor tag consisting encoding filename and currentpath
   39: sub make_anchor {
   40:     my ($url, $filename, $current_path, $current_mode, $field_name,
   41:         $continue_select,$group) = @_;
   42:     if ($continue_select ne 'true') {$continue_select = 'false'};
   43:     my $anchor = '<a href="'.$url.'?selectfile='.$filename.'&amp;currentpath='.$current_path.'&amp;mode='.$current_mode.'&amp;continue='.$continue_select.'&amp;fieldname='.$field_name;
   44:     if (defined($group)) {
   45:         $anchor .= '&amp;group='.$group;
   46:     }
   47:     $anchor .= '">'.$filename.'</a>';
   48:     return $anchor;
   49: }
   50: my $dirptr=16384;
   51: sub display_common {
   52:     my ($r,$url,$current_path,$is_empty,$dir_list,$group,$can_upload)=@_;
   53:     my $namespace = &get_namespace($group);
   54:     my $port_path = &get_port_path($group);
   55:     if ($can_upload) {
   56:         my $groupitem;
   57:         if (defined($group)) {
   58:             $groupitem = '<input type="hidden" name="group" value="'.$group.'" />';
   59:         } 
   60:         my $iconpath= $r->dir_config('lonIconsURL') . "/";
   61:         my %text=&Apache::lonlocal::texthash(
   62: 					 'upload' => 'Upload',
   63: 					 'upload_label' =>  
   64: 					 'Upload file to current directory:',
   65: 					 'createdir' => 'Create Subdirectory',
   66: 					 'createdir_label' => 
   67: 					 'Create subdirectory in current directory:');
   68:         my $escuri = &HTML::Entities::encode($r->uri,'&<>"');
   69:         $r->print(<<"TABLE"); 
   70: <table id="LC_portfolio_actions">
   71:   <tr id="LC_portfolio_upload">
   72:     <td class="LC_label">
   73:       $text{'upload_label'}
   74:     </td>
   75:     <td class="LC_value">
   76:       <form method="post" enctype="multipart/form-data" action="$escuri">
   77:         $groupitem 
   78:         <input name="uploaddoc" type="file" />
   79: 	<input type="hidden" name="currentpath" value="$current_path" />
   80: 	<input type="hidden" name="action" value="$env{"form.action"}" />
   81: 	<input type="hidden" name="fieldname" value="$env{"form.fieldname"}" />
   82: 	<input type="hidden" name="mode" value="$env{"form.mode"}" />
   83: 	<input type="submit" name="storeupl" value="$text{'upload'}" />
   84:       </form>
   85:     </td>
   86:   </tr>
   87:   <tr id="LC_portfolio_createdir">
   88:     <td class="LC_label">
   89:       $text{'createdir_label'}
   90:     </td>
   91:     <td class="LC_value">
   92:       <form method="post" action="$escuri">
   93:         <input name="newdir" type="input" />$groupitem
   94:         <input type="hidden" name="currentpath" value="$current_path" />
   95:         <input type="hidden" name="action" value="$env{"form.action"}" />
   96:         <input type="hidden" name="fieldname" value="$env{"form.fieldname"}" />
   97:         <input type="hidden" name="mode" value="$env{"form.mode"}" />
   98:         <input type="submit" name="createdir" value="$text{'createdir'}" />
   99:       </form>
  100:     </td>
  101:   </tr>
  102: </table>
  103: TABLE
  104:     }
  105:     my @tree = split (/\//,$current_path);
  106:     $r->print('<span class="LC_current_location">'.&make_anchor($url,$port_path,'/',$env{"form.mode"},$env{"form.fieldname"},$env{"form.continue"},$group).'/');
  107:     if (@tree > 1){
  108:         my $newCurrentPath = '';
  109:         for (my $i = 1; $i< @tree; $i++){
  110:             $newCurrentPath .= $tree[$i].'/';
  111:             $r->print(&make_anchor($url,$tree[$i],'/'.$newCurrentPath, $env{"form.mode"},$env{"form.fieldname"}, $env{"form.continue"},$group).'/');
  112:         }
  113:     }
  114:     $r->print('</span>');
  115:     &Apache::lonhtmlcommon::store_recent($namespace,$current_path,$current_path);
  116:     $r->print('<br /><form method="post" action="'.$url.'?mode='.$env{"form.mode"}.'&amp;fieldname='.$env{"form.fieldname"});
  117:     if (defined($group)) {
  118:         $r->print('&amp;group='.$group);
  119:     }
  120:     $r->print('">'.
  121: 	      &Apache::lonhtmlcommon::select_recent($namespace,'currentpath',
  122: 						    'this.form.submit();'));
  123:     $r->print("</form>");
  124: }
  125: sub display_directory {
  126:     my ($r,$url,$current_path,$is_empty,$dir_list,$group,$can_upload,
  127:         $can_modify,$can_delete,$can_setacl)=@_;
  128:     my $iconpath= $r->dir_config('lonIconsURL') . "/";
  129:     my ($groupitem,$groupecho);
  130:     my $display_out;
  131:     my $select_mode;
  132:     my $checked_files;
  133:     my $port_path = &get_port_path($group);
  134:     my ($uname,$udom) = &get_name_dom($group);
  135:     my $access_admin_text = &mt('View Status');
  136:     if ($can_setacl) {
  137:         $access_admin_text = &mt('View/Change Status');
  138:     }
  139:     if ((defined($group)) && (defined($env{'request.course.id'}))) {
  140:        $groupitem = '<input type="hidden" name="group" value="'.$group.'" />'; 
  141:        $groupecho = '&amp;group='.$group;
  142:     }
  143: 
  144:     my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom,
  145:                                                                         $uname);
  146:     my %locked_files = &Apache::lonnet::get_marked_as_readonly_hash(
  147:                                                   $current_permissions,$group);
  148:     my %access_controls = &Apache::lonnet::get_access_controls($current_permissions,$group);
  149:     my $now = time;
  150:     if ($env{"form.mode"} eq 'selectfile'){
  151: 	&select_files($r);
  152: 	$checked_files =&Apache::lonnet::files_in_path($uname,$env{'form.currentpath'});
  153: 	$select_mode = 'true';
  154:     } 
  155:     if ($is_empty && ($current_path ne '/') && $can_delete) {
  156:         $display_out = '<form method="post" action="'.$url.'">'.$groupitem.
  157:         '<input type="hidden" name="action" value="deletedir" />'.
  158:         '<input type="submit" name="deletedir" value="'.&mt("Delete Directory").'" />'.
  159:         '<input type="hidden" name="selectfile" value="" />'.
  160:         '<input type="hidden" name="currentpath" value="'.$current_path.'" />'.
  161:         '</form>';
  162:         
  163:         $r->print($display_out);
  164: 	return;
  165:     }
  166:     if ($select_mode eq 'true') {
  167:         $r->print('<form method="post" name="checkselect" action="'.$url.'">');
  168:         $r->print('<table id="LC_browser">'.
  169:             '<tr><th>Select</th><th>&nbsp;</th><th>Name</th><th>Size</th><th>Last Modified</th></tr>');
  170:     } else {
  171:         $r->print('<form method="post" action="'.$url.'">');
  172:         $r->print('<table id="LC_browser">'.
  173:             '<tr><th colspan="2">Actions</th><th>&nbsp;</th><th>Name</th><th>Size</th><th>Last Modified</th><th>Current Access Status</th></tr>');
  174:     }
  175:     if (defined($group)) {
  176:         $r->print("\n".$groupitem."\n");
  177:     }
  178:     my $href_location="/uploaded/$udom/$uname/$port_path".$current_path;
  179:     my $href_edit_location="/editupload/$udom/$uname/$port_path".$current_path;
  180:     my @dir_lines;
  181:     my %versioned;
  182:     foreach my $line (sort 
  183: 		      { 
  184: 			  my ($afile)=split('&',$a,2);
  185: 			  my ($bfile)=split('&',$b,2);
  186: 			  return (lc($afile) cmp lc($bfile));
  187: 		      } (@$dir_list)) {
  188:     	#$strip holds directory/file name
  189:     	#$dom 
  190:     	my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$line,16); 
  191:     	$filename =~ s/\s+$//;
  192:     	my ($fname,$version,$extension) = &Apache::grades::file_name_version_ext($filename);
  193:     	if ($version) {
  194:     	    $versioned{$fname} .= $version.",";
  195:     	}
  196:         push(@dir_lines, [$filename,$dom,$testdir,$size,$mtime,$obs]);
  197:     }
  198:     foreach my $line (@dir_lines) {
  199:         my ($filename,$dom,$testdir,$size,$mtime,$obs) = @$line;
  200:         my ($fname,$version,$extension) = &Apache::grades::file_name_version_ext($filename);
  201:     	if (($filename ne '.') && ($filename ne '..') && ($filename !~ /\.meta$/ ) && ($filename !~ /(.*)\.(\d+)\.([^\.]*)$/)) {
  202:             if ($dirptr&$testdir) {
  203: 		my $colspan='colspan="2"';
  204:                 if ($select_mode eq 'true'){
  205: 		    undef($colspan);
  206:                 }
  207: 		$r->print('<tr class="LC_browser_folder"><td '.$colspan.'><img alt="'.&mt('closed folder').'" src="'.$iconpath.'folder_closed.gif" /></td>');
  208:                 $r->print('<td>Go to ...</td>');
  209:                 $r->print('<td>'.&make_anchor($url,$filename.'/',$current_path.$filename.'/',$env{'form.mode'},$env{"form.fieldname"},$env{'form.continue'},$group).'</td>'); 
  210:                 $r->print('</tr>'); 
  211:             } else {
  212: 		my $css_class = 'LC_browser_file';
  213: 		my $line;
  214:                 my $version_flag;
  215:                 if (exists($versioned{$fname})) {
  216:                    $version_flag = "*";
  217:                 } else {
  218:                     $version_flag = "";
  219:                 }
  220:                my $fullpath = $current_path.$filename;
  221:                 $fullpath = &prepend_group($fullpath,$group);
  222:                 if ($select_mode eq 'true'){
  223:                     $line='<td><input type="checkbox" name="checkfile" value="'.$filename.'"';
  224: 		    if ($$checked_files{$filename} eq 'selected') {
  225:                         $line.=" checked ";
  226:                     }
  227: 		    $line.=' /></td>';
  228:                 } else {
  229:                     if (exists $locked_files{$fullpath}) {
  230:                         $line.='<td colspan="2"><a href="'.$url.'?lockinfo='.$current_path.$filename.$groupecho.'">Locked</a></td>';
  231: 			$css_class= 'LC_browser_file_locked';
  232:                     } else {
  233:                         if (!$can_modify) {
  234:                             $line .= '<td colspan="2">';
  235:                         } else {
  236:                             $line .= '<td>';
  237:                         }
  238:                         if ($can_delete) {
  239:                             $line .= '<input type="checkbox" name="selectfile" value="'.$filename.'" />';
  240:                         }
  241:                         if ($can_modify) {
  242:                             my $cat='<img alt="'.&mt('Catalog Information').
  243:                             '" src="'.&Apache::loncommon::lonhttpdurl('/res/adm/pages/catalog.gif').'" />';
  244:                             $line .= '<a href="'.$url.'?rename='.$filename.'&amp;currentpath='.$current_path.$groupecho.'">Rename</a>';
  245:                             $line .= '</td><td><a href="'.$href_edit_location.$filename.'.meta">'.$cat.'</a>';
  246:                         }
  247:                         $line .= '</td>';
  248:                     }
  249: 		    $r->print('<tr class="'.$css_class.'">');
  250: 		    $r->print($line);
  251:                 }
  252:                 my $curr_access;
  253:                 my $pub_access = 0;
  254:                 my $guest_access = 0;
  255:                 my $cond_access = 0;
  256:                 foreach my $key (sort(keys(%{$access_controls{$fullpath}}))) {
  257:                     my ($num,$scope,$end,$start) = &unpack_acc_key($key);
  258:                     if (($now > $start) && (!$end || $end > $now)) {
  259:                         if ($scope eq 'public')  {
  260:                             $pub_access = 1;
  261:                         } elsif ($scope eq 'guest') {
  262:                             $guest_access = 1;
  263:                         } else {
  264:                             $cond_access = 1;
  265:                         }
  266:                     }
  267:                 }
  268:                 if (!$pub_access && !$guest_access && !$cond_access) {
  269:                     $curr_access = &mt('Private');
  270:                 } else {
  271:                     my @allaccesses; 
  272:                     if ($pub_access) {
  273:                         push(@allaccesses,&mt('Public'));
  274:                     }
  275:                     if ($guest_access) {
  276:                         push(@allaccesses,&mt('Passphrase-protected'));
  277:                     }
  278:                     if ($cond_access) {
  279:                         push(@allaccesses,&mt('Conditional'));
  280:                     }
  281:                     $curr_access = join('+ ',@allaccesses);
  282:                 }
  283:                 $r->print('<td><img alt="" src="'.&Apache::loncommon::icon($filename).'" /></td>');
  284:                 $r->print('<td><a href="'.$href_location.$filename.'">'.
  285: 			    $filename.'</a></td>'); 
  286:                 $r->print('<td>'.$size.'</td>');
  287:                 $r->print('<td>'.&Apache::lonlocal::locallocaltime($mtime).'</td>');
  288:                 $r->print('<td><span style="white-space: nowrap">'.
  289:                           &mt($curr_access).'&nbsp;&nbsp;&nbsp;');
  290:                 $r->print('<a href="'.$url.'?access='.$filename.
  291:                               '&amp;currentpath='.$current_path.$groupecho.
  292:                               '">'.$access_admin_text.'</a>');
  293:                 $r->print('</span></td></tr>');
  294:             }
  295:         }
  296:     }
  297:     if ($select_mode eq 'true') {
  298:         $r->print('</table>
  299:             <input type="hidden" name="continue" value="true">
  300:             <input type="hidden" name="fieldname" value="'.$env{'form.fieldname'}.'">
  301:             <input type="hidden" name="mode" value="selectfile">
  302:             <input type="submit" name="submit" value="Select checked files, and continue selecting." /><br />
  303:             <input type="button" name="doit" onClick= "finishSelect();" value="Select checked files, and close window" />
  304:             <input type="hidden" name="currentpath" value="'.$current_path.'" />
  305:         </form>');        
  306:     } else {
  307:         $r->print('</table>');
  308:         if ($can_delete) {
  309:             $r->print('
  310:         <input type="submit" name="doit" value="Delete Checked Files" />
  311:         <input type="hidden" name="action" value="delete" />
  312:         <input type="hidden" name="currentpath" value="'.$current_path.'" />
  313:         </form>'
  314:             );
  315:         }
  316:     }
  317: }
  318: 
  319: sub open_form {
  320:     my ($r,$url)=@_;
  321:     my @files=&Apache::loncommon::get_env_multiple('form.selectfile');
  322:     $r->print('<form name="portform" method="post" action="'.$url.'">');
  323:     $r->print('<input type="hidden" name="action" value="'.
  324: 	      $env{'form.action'}.'" />');
  325:     $r->print('<input type="hidden" name="confirmed" value="1" />');
  326:     foreach (@files) {
  327:         $r->print('<input type="hidden" name="selectfile" value="'.
  328: 	      $_.'" />');
  329:     }
  330:     $r->print('<input type="hidden" name="currentpath" value="'.
  331: 	      $env{'form.currentpath'}.'" />');
  332: }
  333: 
  334: sub close_form {
  335:     my ($r,$url,$group,$button_text)=@_;
  336:     if (!defined($button_text)) {
  337:         $button_text = {
  338:                          'continue' => &mt('Continue'),
  339:                          'cancel'   => &mt('Cancel'),
  340:                        };
  341:     }
  342:     $r->print('<p><input type="submit" value="'.$button_text->{'continue'}.'" />');
  343:     if (defined($group)) {
  344:        $r->print("\n".'<input type="hidden" name="group" value="'.
  345:               $group.'" />');
  346:     }
  347:     $r->print('</p></form>');
  348:     $r->print('<form action="'.$url.'" method="post">
  349:                <p>
  350:               <input type="hidden" name="currentpath" value="'.
  351: 	      $env{'form.currentpath'}.'" />');
  352:     if (defined($group)) {
  353:        $r->print("\n".'<input type="hidden" name="group" value="'.
  354:               $group.'" />');
  355:     }
  356:     $r->print("\n".'   <input type="submit" value="'.$button_text->{'cancel'}.'" />
  357:                </p></form>'); 
  358: }
  359: 
  360: sub display_file {
  361:     my ($path,$filename)=@_;
  362:     my $display_file_text;
  363:     my $file_start='<span class="LC_filename">';
  364:     my $file_end='</span>';
  365:     if (!defined($path)) { $path=$env{'form.currentpath'}; }
  366:     if (!defined($filename)) { 
  367:         $filename=$env{'form.selectfile'};
  368:         $display_file_text = $file_start.$path.$filename.$file_end;
  369:     } elsif (ref($filename) eq "ARRAY") {
  370:         foreach my $file (@$filename) {
  371:             $display_file_text .= $file_start.$path.$file.$file_end.'<br />';
  372:         }
  373:     } elsif (ref($filename) eq "SCALAR") {
  374:         $display_file_text = $file_start.$path.$$filename.$file_end;
  375:     } else {
  376: 	$display_file_text = $file_start.$path.$filename.$file_end;
  377:     }
  378:     return $display_file_text;
  379: }
  380: 
  381: sub done {
  382:     my ($message,$url,$group)=@_;
  383:     unless (defined $message) {
  384:         $message='Done';
  385:     }
  386:     my $result = '<h3><a href="'.$url.'?currentpath='.
  387: 	         $env{'form.currentpath'}.
  388: 	         '&fieldname='.$env{'form.fieldname'}.
  389: 	         '&mode='.$env{'form.mode'};
  390:     if (defined($group)) {
  391:         $result .= '&group='.$group;
  392:     }
  393:     $result .= '">'.&mt($message).'</a></h3>';
  394:     return $result;
  395: }
  396: 
  397: sub delete {
  398:     my ($r,$url,$group)=@_;
  399:     my @check;
  400:     my $file_name = $env{'form.currentpath'}.$env{'form.selectfile'};
  401:     $file_name = &prepend_group($file_name,$group);
  402:     my @files=&Apache::loncommon::get_env_multiple('form.selectfile');
  403:     my ($uname,$udom) = &get_name_dom($group);
  404:     if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') {
  405:         $r->print ("The file is locked and cannot be deleted.<br />");
  406:         $r->print(&done('Back',$url,$group));
  407:     } else {
  408:         if (scalar(@files)) {
  409:             &open_form($r,$url);
  410:             $r->print('<p>'.&mt('Delete').' '.&display_file(undef,\@files).'?</p>');
  411:             &close_form($r,$url,$group);
  412:         } else {
  413:             $r->print("No file was checked to delete.<br />");
  414:             $r->print(&done(undef,$url,$group));
  415:         }
  416:     }
  417: } 
  418: 
  419: sub delete_confirmed {
  420:     my ($r,$url,$group)=@_;
  421:     my @files=&Apache::loncommon::get_env_multiple('form.selectfile');
  422:     my $result;
  423:     my ($uname,$udom) = &get_name_dom($group);
  424:     my $port_path = &get_port_path($group);
  425:     foreach my $delete_file (@files) {
  426:         $result=&Apache::lonnet::removeuserfile($uname,$udom,$port_path.
  427: 					       $env{'form.currentpath'}.
  428: 					       $delete_file);
  429:         if ($result ne 'ok') {
  430: 	$r->print('<span class="LC_error"> An error occured ('.$result.
  431: 		  ') while trying to delete '.&display_file(undef, $delete_file).'</span><br />');
  432:         }
  433:     }
  434:     $r->print(&done(undef,$url,$group));
  435: }
  436: 
  437: sub delete_dir {
  438:     my ($r,$url,$group)=@_;
  439:     &open_form($r,$url);
  440:     $r->print('<p>'.&mt('Delete').' '.&display_file().'?</p>');
  441:     &close_form($r,$url,$group);
  442: } 
  443: 
  444: sub delete_dir_confirmed {
  445:     my ($r,$url,$group)=@_;
  446:     my $directory_name = $env{'form.currentpath'};
  447:     $directory_name =~ s|/$||; # remove any trailing slash
  448:     my ($uname,$udom) = &get_name_dom($group);
  449:     my $namespace = &get_namespace($group);
  450:     my $port_path = &get_port_path($group);
  451:     my $result=&Apache::lonnet::removeuserfile($uname,$udom,$port_path.
  452: 					       $directory_name);
  453: 					       
  454:     if ($result ne 'ok') {
  455: 	$r->print('<span class="LC_error"> An error occured (dir) ('.$result.
  456: 		  ') while trying to delete '.$directory_name.'</span><br />');
  457:     } else {
  458:         # now remove from recent
  459: #        $r->print('<br /> removing '.$directory_name.'<br /');
  460:         &Apache::lonhtmlcommon::remove_recent($namespace,[$directory_name.'/']);
  461:         my @dirs = split m!/!, $directory_name;
  462:         
  463: #        $directory_name =~ m/^(\/*\/)(\/*.)$/;
  464:         $directory_name='/';
  465:         for (my $i=1; $i < (@dirs - 1); $i ++){
  466:             $directory_name .= $dirs[$i].'/';
  467:         }
  468:         $env{'form.currentpath'} = $directory_name;
  469:     }
  470:     $r->print(&done(undef,$url,$group));
  471: }
  472: 
  473: sub rename {
  474:     my ($r,$url,$group)=@_;
  475:     my $file_name = $env{'form.currentpath'}.$env{'form.rename'};
  476:     my ($uname,$udom) = &get_name_dom($group);
  477:     $file_name = &prepend_group($file_name,$group);
  478:     if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') {
  479:         $r->print ("The file is locked and cannot be renamed.<br />");
  480:         $r->print(&done(undef,$url,$group));
  481:     } else {
  482:         &open_form($r,$url);
  483:         $r->print('<p>'.&mt('Rename').' '.&display_file().' to 
  484:                    <input name="filenewname" type="input" size="50" />?</p>');
  485:         &close_form($r,$url,$group);
  486:     }
  487: }
  488: 
  489: sub rename_confirmed {
  490:     my ($r,$url,$group)=@_;
  491:     my $filenewname=&Apache::lonnet::clean_filename($env{'form.filenewname'});
  492:     my ($uname,$udom) = &get_name_dom($group);
  493:     my $port_path = &get_port_path($group);
  494:     if ($filenewname eq '') {
  495: 	$r->print('<span class="LC_error">'.
  496: 		  &mt("Error: no valid filename was provided to rename to.").
  497: 		  '</span><br />');
  498: 	$r->print(&done(undef,$url,$group));
  499: 	return;
  500:     } 
  501:     my $result=
  502: 	&Apache::lonnet::renameuserfile($uname,$udom,
  503:             $port_path.$env{'form.currentpath'}.$env{'form.selectfile'},
  504:             $port_path.$env{'form.currentpath'}.$filenewname);
  505:     if ($result ne 'ok') {
  506: 	$r->print('<span class="LC_error">'.
  507: 		  &mt('An errror occured ([_1]) while trying to rename [_2]'
  508: 		      .' to [_3]',$result,&display_file(),
  509: 		      &display_file('',$filenewname)).'</span><br />');
  510:     }
  511:     if ($filenewname ne $env{'form.filenewname'}) {
  512:         $r->print(&mt("The new file name was changed from:<br />[_1] to [_2]",
  513: 		      '<strong>'.&display_file('',$env{'form.filenewname'}).'</strong>',
  514: 		      '<strong>'.&display_file('',$filenewname).'</strong>'));
  515:     }
  516:     $r->print(&done(undef,$url,$group));
  517: }
  518: 
  519: sub display_access {
  520:     my ($r,$url,$group,$can_setacl) = @_;
  521:     my ($uname,$udom) = &get_name_dom($group);
  522:     my $file_name = $env{'form.currentpath'}.$env{'form.access'};
  523:     $file_name = &prepend_group($file_name,$group);
  524:     my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom,
  525:                                                                         $uname);
  526:     my %access_controls = &Apache::lonnet::get_access_controls($current_permissions,$group,$file_name);
  527:     my $aclcount = keys(%access_controls);
  528:     my $header = '<h3>'.&mt('Allowing others to retrieve portfolio file: [_1]',$env{'form.currentpath'}.$env{'form.access'}).'</h3>';
  529:     my $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.').'<br /><ul><li>'.&mt('Public files are available to anyone without the need for login.').'</li><li>'.&mt('Passphrase-protected files do not require log-in, but will require the viewer to enter the passphrase you set.').'</li><li>'.&mt('Conditional files are accessible to logged-in users with accounts in the LON-CAPA network, who satisfy the conditions you set.').'<br />'.&mt('The conditions can include affiliation with a particular course or group, or a user account in a specific domain.').'<br />'.&mt('Alternatively access can be granted to people with specific LON-CAPA usernames and domains.').'</li></ul>';
  530:     if ($can_setacl) {
  531:         &open_form($r,$url);
  532:         $r->print($header.$info);
  533:         &access_setting_table($r,$access_controls{$file_name});
  534:         my $button_text = {
  535:                         'continue' => &mt('Proceed'),
  536:                         'cancel' => &mt('Back to directory listing'),
  537:                       };
  538:         &close_form($r,$url,$group,$button_text);
  539:     } else {
  540:         $r->print($header);
  541:         if ($aclcount) {  
  542:             $r->print($info);
  543:         }
  544:         &view_access_settings($r,$url,$group,$access_controls{$file_name},
  545:                               $aclcount);
  546:     }
  547: }
  548: 
  549: sub view_access_settings {
  550:     my ($r,$url,$group,$access_controls,$aclcount) = @_;
  551:     my ($showstart,$showend);
  552:     my %todisplay;
  553:     foreach my $key (sort(keys(%{$access_controls}))) {
  554:         my ($num,$scope,$end,$start) = &unpack_acc_key($key);
  555:         $todisplay{$scope}{$key} = $$access_controls{$key};
  556:     }
  557:     if ($aclcount) {
  558:         $r->print(&mt('<h4>Current access controls defined for this file:</h4>'));
  559:         $r->print(&Apache::loncommon::start_data_table());
  560:         $r->print(&Apache::loncommon::start_data_table_header_row());
  561:         $r->print('<th>'.&mt('Access control').'</th><th>'.&mt('Dates available').
  562:                   '</th><th>'.&mt('Additional information').'</th>');
  563:         $r->print(&Apache::loncommon::end_data_table_header_row());
  564:         my $count = 1;
  565:         my $chg = 'none';
  566:         &build_access_summary($r,$count,$chg,%todisplay);
  567:         $r->print(&Apache::loncommon::end_data_table());
  568:     } else {
  569:         $r->print(&mt('No access control settings currently exist for this file.<br />' ));
  570:     }
  571:     my $group_arg;
  572:     if ($group) {
  573:         $group_arg = '&amp;group='.$group;
  574:     }
  575:     $r->print('<br /><a href="'.$url.'?currentpath='.$env{'form.currentpath'}.
  576:               $group_arg.'">'.&mt('Return to directory listing').'</a>');
  577:     return;
  578: }
  579: 
  580: sub build_access_summary {
  581:     my ($r,$count,$chg,%todisplay) = @_; 
  582:     my ($showstart,$showend);
  583:     my %scope_desc = (
  584:                       public => 'Public',
  585:                       guest => 'Passphrase-protected',
  586:                       domains => 'Conditional: domain-based',
  587:                       users => 'Conditional: user-based',
  588:                       course => 'Conditional: course-based',
  589:                       group => 'Conditional: group-based',
  590:                      );
  591:     my @allscopes = ('public','guest','domains','users','course','group');
  592:     foreach my $scope (@allscopes) {
  593:         if ((!(exists($todisplay{$scope}))) || (ref($todisplay{$scope}) ne 'HASH')) {
  594:             next;
  595:         }
  596:         foreach my $key (sort(keys(%{$todisplay{$scope}}))) {
  597:             if ($count) {
  598:                 $r->print(&Apache::loncommon::start_data_table_row());
  599:             }
  600:             my ($num,$scope,$end,$start) = &unpack_acc_key($key);
  601:             my $content = $todisplay{$scope}{$key};
  602:             if ($chg eq 'delete') {
  603:                 $showstart = &mt('Deleted');
  604:                 $showend = $showstart;
  605:             } else {
  606:                 $showstart = localtime($start);
  607:                 if ($end == 0) {
  608:                     $showend = &mt('No end date');
  609:                 } else {
  610:                     $showend = localtime($end);
  611:                 }
  612:             }
  613:             $r->print('<td>'.&mt($scope_desc{$scope}));
  614:             if (($scope eq 'course') || ($scope eq 'group')) {
  615:                 if ($chg ne 'delete') {
  616:                     my $cid = $content->{'domain'}.'_'.$content->{'number'};
  617:                     my %course_description = &Apache::lonnet::coursedescription($cid);
  618:                     $r->print('<br />('.$course_description{'description'}.')');
  619:                 }
  620:             }
  621:             $r->print('</td><td>'.&mt('Start: ').$showstart.
  622:                   '<br />'.&mt('End: ').$showend.'</td><td>');
  623:             if ($chg ne 'delete') {
  624:                 if ($scope eq 'guest') {
  625:                     $r->print(&mt('Passphrase').': '.$content->{'password'});
  626:                 } elsif ($scope eq 'course' || $scope eq 'group') {
  627:                     $r->print('<table><tr>');
  628:                     $r->print('<th>'.&mt('Roles').'</th><th>'.
  629:                           &mt('Access').'</th><th>'.
  630:                                           &mt('Sections').'</th>');
  631:                     if ($scope eq 'course') {
  632:                         $r->print('<th>'.&mt('Groups').'</th>');
  633:                     } else {
  634:                         $r->print('<th>'.&mt('Teams').'</th>');
  635:                     }
  636:                     $r->print('</tr>');
  637:                     foreach my $id (sort(keys(%{$content->{'roles'}}))) {
  638:                         $r->print('<tr>');
  639:                         foreach my $item ('role','access','section','group') {
  640:                             $r->print('<td>');
  641:                             if ($item eq 'role') {
  642:                                 my $ucscope = $scope;
  643:                                 $ucscope =~ s/^(\w)/uc($1)/e;
  644:                                 my $role_output;
  645:                                 foreach my $role (@{$content->{'roles'}{$id}{$item}}) {
  646:                                     if ($role eq 'all') {
  647:                                         $role_output .= $role.',';
  648:                                     } elsif ($role =~ /^cr/) {
  649:                                         $role_output .= (split('/',$role))[3].',';
  650:                                     } else {
  651:                                         $role_output .= &Apache::lonnet::plaintext($role,$ucscope).',';
  652:                                     }
  653:                                 }
  654:                                 $role_output =~ s/,$//;
  655:                                 $r->print($role_output);
  656:                             } else {
  657:                                 $r->print(join(',',@{$content->{'roles'}{$id}{$item}}));
  658:                             }
  659:                             $r->print('</td>');
  660:                         }
  661:                     }
  662:                     $r->print(&Apache::loncommon::end_data_table_row());
  663:                     $r->print(&Apache::loncommon::end_data_table());
  664:                 } elsif ($scope eq 'domains') {
  665:                     $r->print(&mt('Domains: ').join(',',@{$content->{'dom'}}));
  666:                 } elsif ($scope eq 'users') {
  667:                     my $curr_user_list = &sort_users($content->{'users'});
  668:                     $r->print(&mt('Users: ').$curr_user_list);
  669:                 } else {
  670:                     $r->print('&nbsp;');
  671:                 }
  672:             } else {
  673:                 $r->print('&nbsp;');
  674:             }
  675:             $r->print('</td>');
  676:             $r->print(&Apache::loncommon::end_data_table_row());
  677:             $count ++;
  678:         }
  679:     }
  680: }
  681: 
  682: 
  683: sub update_access {
  684:     my ($r,$url,$group) = @_;
  685:     my $totalprocessed = 0;
  686:     my %processing;
  687:     my %title  = (
  688:                          'activate' => 'New control(s) added',
  689:                          'delete'   => 'Existing control(s) deleted',
  690:                          'update'   => 'Existing control(s) modified',
  691:                      );
  692:     my $changes;
  693:     foreach my $chg (sort(keys(%title))) {     
  694:         @{$processing{$chg}} = &Apache::loncommon::get_env_multiple('form.'.$chg);
  695:         $totalprocessed += @{$processing{$chg}};
  696:         foreach my $num (@{$processing{$chg}}) {
  697:             my $scope = $env{'form.scope_'.$num};
  698:             my ($start,$end) = &get_dates_from_form($num);
  699:             my $newkey = $num.':'.$scope.'_'.$end.'_'.$start;
  700:             if ($chg eq 'delete') {
  701:                 $$changes{$chg}{$newkey} = 1;
  702:             } else {
  703:                 $$changes{$chg}{$newkey} = 
  704:                             &build_access_record($num,$scope,$start,$end,$chg);
  705:             }
  706:         }
  707:     }
  708:     my $file_name = $env{'form.currentpath'}.$env{'form.selectfile'};
  709:     $r->print('<h3>'.&mt('Allowing others to retrieve portfolio file: [_1]',
  710:               $file_name).'</h3>'."\n");
  711:     $file_name = &prepend_group($file_name,$group);
  712:     my ($uname,$udom) = &get_name_dom($group);
  713:     my ($errors,$outcome,$deloutcome,$new_values,$translation);
  714:     if ($totalprocessed) {
  715:         ($outcome,$deloutcome,$new_values,$translation) =
  716:         &Apache::lonnet::modify_access_controls($file_name,$changes,$udom,
  717:                                                 $uname);
  718:     }
  719:     my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom,
  720:                                                                        $uname);
  721:     my %access_controls = 
  722: 	&Apache::lonnet::get_access_controls($current_permissions,
  723: 					     $group,$file_name);
  724:     if ($totalprocessed) {
  725:         if ($outcome eq 'ok') {
  726:             my $updated_controls = $access_controls{$file_name};
  727:             my ($showstart,$showend);
  728:             $r->print(&Apache::loncommon::start_data_table());
  729:             $r->print(&Apache::loncommon::start_data_table_header_row());
  730:             $r->print('<th>'.&mt('Type of change').'</th><th>'.
  731:                       &mt('Access control').'</th><th>'.&mt('Dates available').
  732:                       '</th><th>'.&mt('Additional information').'</th>');
  733:             $r->print(&Apache::loncommon::end_data_table_header_row());
  734:             foreach my $chg (sort(keys(%processing))) {
  735:                 if (@{$processing{$chg}} > 0) {
  736:                     if ($chg eq 'delete') {
  737:                         if (!($deloutcome eq 'ok')) {
  738:                             $errors .='<span class="LC_error">'.
  739: 				&mt('A problem occurred deleting access controls: [_1]',$deloutcome).
  740: 				'</span>';
  741:                             next;
  742:                         }
  743:                     }
  744:                     my $numchgs = @{$processing{$chg}};
  745:                     $r->print(&Apache::loncommon::start_data_table_row());
  746:                     $r->print('<td rowspan="'.$numchgs.'">'.&mt($title{$chg}).
  747:                               '.</td>');
  748:                     my $count = 0;
  749:                     my %todisplay;
  750:                     foreach my $key (sort(keys(%{$$changes{$chg}}))) {
  751:                         my ($num,$scope,$end,$start) = &unpack_acc_key($key);
  752:                         my $newkey = $key;
  753:                         if ($chg eq 'activate') {
  754:                             $newkey =~ s/^(\d+)/$$translation{$1}/;
  755:                         }
  756:                         $todisplay{$scope}{$newkey} = $$updated_controls{$newkey};
  757:                     }
  758:                     &build_access_summary($r,$count,$chg,%todisplay);  
  759:                 }
  760:             }
  761:             $r->print(&Apache::loncommon::end_data_table());
  762:         } else {
  763:             if ((@{$processing{'activate'}} > 0) || (@{$processing{'update'}} > 0)) {
  764:                 $errors .= '<span class="LC_error">'.
  765: 		    &mt('A problem occurred storing access control settings: [_1]',$outcome).
  766: 		    '</span>';
  767:             }
  768:         }
  769:         if ($errors) { 
  770:             $r->print($errors);
  771:         }
  772:     }
  773:     my $allnew = 0;
  774:     my $totalnew = 0;
  775:     my $status = 'new';
  776:     my ($firstitem,$lastitem);
  777:     foreach my $newitem ('course','group','domains','users') {
  778:         $allnew += $env{'form.new'.$newitem};
  779:     }
  780:     if ($allnew > 0) {
  781:         my $now = time;
  782:         my $then = $now + (60*60*24*180); # six months approx.
  783:         &open_form($r,$url,$group);
  784:         foreach my $newitem ('course','group','domains','users') {
  785:             if ($env{'form.new'.$newitem} > 0) {
  786:                 $r->print('<br />'.&mt('Add new <b>[_1]-based</b> access control for portfolio file: <b>[_2]</b>',$newitem,$env{'form.currentpath'}.$env{'form.selectfile'}).'<br /><br />');
  787:                 $firstitem = $totalnew;
  788:                 $lastitem = $totalnew + $env{'form.new'.$newitem};
  789:                 $totalnew = $lastitem;
  790:                 my @numbers;   
  791:                 for (my $i=$firstitem; $i<$lastitem; $i++) {
  792:                     push (@numbers,$i);
  793:                 }
  794:                 &display_access_row($r,$status,$newitem,\@numbers,
  795:                                     $access_controls{$file_name},$now,$then);
  796:             }
  797:         }
  798:         &close_form($r,$url,$group);
  799:     } else {
  800:         my $group_arg;
  801:         if ($group) {
  802:             $group_arg = '&amp;group='.$group;
  803:         }
  804:         $r->print('<br /><a href="'.$url.'?access='.$env{'form.selectfile'}.
  805:                   '&amp;currentpath='.$env{'form.currentpath'}.$group_arg.'">'.
  806:                    &mt('Display all access settings for this file').'</a>');
  807:     }
  808:     return;
  809: }
  810: 
  811: sub build_access_record {
  812:     my ($num,$scope,$start,$end,$chg) = @_;
  813:     my $record = {
  814: 	type => $scope,
  815: 	time => {
  816: 	    start => $start,
  817: 	    end   => $end
  818: 	    },
  819: 	    };
  820: 		
  821:     if ($scope eq 'guest') {	
  822:         $record->{'password'} = $env{'form.password'};
  823:     } elsif (($scope eq 'course') || ($scope eq 'group')) {
  824:         $record->{'domain'} = $env{'form.crsdom_'.$num};
  825: 	$record->{'number'} = $env{'form.crsnum_'.$num};
  826:         my @role_ids;
  827:         my @delete_role_ids =
  828:             &Apache::loncommon::get_env_multiple('form.delete_role_'.$num);
  829: 	my @preserves =
  830: 	    &Apache::loncommon::get_env_multiple('form.preserve_role_'.$num);
  831: 	if (@delete_role_ids) {
  832: 	    foreach my $id (@preserves) {
  833: 		if (grep {$_ = $id} (@delete_role_ids)) {
  834: 		    next;
  835: 		}
  836: 		push(@role_ids,$id); 
  837: 	    }
  838: 	} else {
  839: 	    push(@role_ids,@preserves);
  840: 	}
  841: 
  842: 	my $next_id = $env{'form.add_role_'.$num};
  843: 	if ($next_id) {
  844: 	    push(@role_ids,$next_id);
  845: 	}
  846: 
  847:         foreach my $id (@role_ids) {
  848:             my (@roles,@accesses,@sections,@groups);
  849:             if (($id == $next_id) && ($chg eq 'update')) {
  850:                 @roles    = split(/,/,$env{'form.role_'.$num.'_'.$next_id});
  851:                 @accesses = split(/,/,$env{'form.access_'.$num.'_'.$next_id});
  852:                 @sections = split(/,/,$env{'form.section_'.$num.'_'.$next_id});
  853:                 @groups   = split(/,/,$env{'form.group_'.$num.'_'.$next_id});
  854:             } else {
  855:                 @roles = &Apache::loncommon::get_env_multiple('form.role_'.$num.'_'.$id);
  856:                 @accesses = &Apache::loncommon::get_env_multiple('form.access_'.$num.'_'.$id);
  857:                 @sections = &Apache::loncommon::get_env_multiple('form.section_'.$num.'_'.$id);
  858:                 @groups = &Apache::loncommon::get_env_multiple('form.group_'.$num.'_'.$id);
  859:             }
  860: 	    $record->{'roles'}{$id}{'role'}    = \@roles;
  861: 	    $record->{'roles'}{$id}{'access'}  = \@accesses;
  862: 	    $record->{'roles'}{$id}{'section'} = \@sections;
  863: 	    $record->{'roles'}{$id}{'group'}   = \@groups;
  864:         }
  865:     } elsif ($scope eq 'domains') {
  866:         my @doms = &Apache::loncommon::get_env_multiple('form.dom_'.$num);
  867: 	$record->{'dom'} = \@doms;
  868:     } elsif ($scope eq 'users') {
  869:         my $userlist = $env{'form.users_'.$num};
  870:         $userlist =~ s/\s+//sg;
  871: 	my %userhash = map { ($_,1) } (split(/,/,$userlist));
  872:         foreach my $user (keys(%userhash)) {
  873:             my ($uname,$udom) = split(/:/,$user);
  874: 	    push(@{$record->{'users'}}, {
  875: 		'uname' => $uname,
  876: 		'udom'  => $udom
  877: 		});
  878: 	}
  879:     }
  880:     return $record;
  881: }
  882: 
  883: sub get_dates_from_form {
  884:     my ($id) = @_;
  885:     my $startdate;
  886:     my $enddate;
  887:     $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate_'.$id);
  888:     $enddate   = &Apache::lonhtmlcommon::get_date_from_form('enddate_'.$id);
  889:     if ( exists ($env{'form.noend_'.$id}) ) {
  890:         $enddate = 0;
  891:     }
  892:     return ($startdate,$enddate);
  893: }
  894: 
  895: sub sort_users {
  896:     my ($users) = @_; 
  897:     my @curr_users = map {
  898: 	$_->{'uname'}.':'.$_->{'udom'}
  899:     } (@{$users});
  900:     my $curr_user_list = join(",\n",sort(@curr_users));
  901:     return $curr_user_list;
  902: }
  903: 
  904: sub access_setting_table {
  905:     my ($r,$access_controls) = @_;
  906:     my ($public,$publictext);
  907:     $publictext = &mt('Off');
  908:     my ($guest,$guesttext);
  909:     $guesttext = &mt('Off');
  910:     my @courses = ();
  911:     my @groups = ();
  912:     my @domains = ();
  913:     my @users = ();
  914:     my $now = time;
  915:     my $then = $now + (60*60*24*180); # six months approx.
  916:     my ($num,$scope,$publicnum,$guestnum);
  917:     my (%acl_count,%end,%start);
  918:     foreach my $key (sort(keys(%{$access_controls}))) {
  919:         ($num,$scope,$end{$key},$start{$key}) = &unpack_acc_key($key);
  920:         if ($scope eq 'public') {
  921:             $public = $key;
  922:             $publicnum = $num;
  923:             $publictext = &acl_status($start{$key},$end{$key},$now);
  924:         } elsif ($scope eq 'guest') {
  925:             $guest=$key;
  926:             $guestnum = $num;  
  927:             $guesttext = &acl_status($start{$key},$end{$key},$now);
  928:         } elsif ($scope eq 'course') {
  929:             push(@courses,$key);
  930:         } elsif ($scope eq 'group') {
  931:             push(@groups,$key);
  932:         } elsif ($scope eq 'domains') {
  933:             push(@domains,$key);
  934:         } elsif ($scope eq 'users') {
  935:             push(@users,$key);
  936:         }
  937:         $acl_count{$scope} ++;
  938:     }
  939:     $r->print('<table border="0"><tr><td valign="top">');
  940:     $r->print('<h3>'.&mt('Public access:').' '.$publictext.'</h3>');
  941:     $r->print(&Apache::loncommon::start_data_table());
  942:     $r->print(&Apache::loncommon::start_data_table_header_row());
  943:     $r->print('<th>'.&mt('Action').'</th><th>'.&mt('Dates available').'</th>');
  944:     $r->print(&Apache::loncommon::end_data_table_header_row());
  945:     $r->print(&Apache::loncommon::start_data_table_row());
  946:     if ($public) {
  947:         $r->print('<td>'.&actionbox('old',$publicnum,'public').'</td><td>'.
  948:                   &dateboxes($publicnum,$start{$public},$end{$public}).'</td>');
  949:     } else {
  950:         $r->print('<td>'.&actionbox('new','0','public').'</td><td>'.
  951:                   &dateboxes('0',$now,$then).'</td>');
  952:     }
  953:     $r->print(&Apache::loncommon::end_data_table_row());
  954:     $r->print(&Apache::loncommon::end_data_table());
  955:     $r->print('</td><td width="40">&nbsp;</td><td valign="top">');
  956:     $r->print('<h3>'.&mt('Passphrase-protected access:').' '.$guesttext.'</h3>');
  957:     $r->print(&Apache::loncommon::start_data_table());
  958:     $r->print(&Apache::loncommon::start_data_table_header_row());
  959:     $r->print('<th>'.&mt('Action').'</th><th>'.&mt('Dates available').
  960:               '</th><th>'. &mt('Passphrase').'</th>');
  961:     $r->print(&Apache::loncommon::end_data_table_header_row());
  962:     $r->print(&Apache::loncommon::start_data_table_row());
  963:     my $passwd;
  964:     if ($guest) {
  965:         $passwd = $$access_controls{$guest}{'password'};
  966:         $r->print('<td>'.&actionbox('old',$guestnum,'guest').'</td><td>'.
  967:                   &dateboxes($guestnum,$start{$guest},$end{$guest}).'</td>');
  968:     } else {
  969:         $r->print('<td>'.&actionbox('new','1','guest').'</td><td>'.
  970:                   &dateboxes('1',$now,$then).'</td>');
  971:     }
  972:     $r->print('<td><input type="text" size="15" name="password" value="'.
  973:               $passwd.'" /></td>');
  974:     $r->print(&Apache::loncommon::end_data_table_row());
  975:     $r->print(&Apache::loncommon::end_data_table());
  976:     $r->print('</td></tr><tr><td colspan="3">&nbsp;</td></tr><tr><td valign="top">');
  977:     &access_element($r,'domains',\%acl_count,\@domains,$access_controls,$now,$then);
  978:     $r->print('</td><td>&nbsp;</td><td valign="top">');
  979:     &access_element($r,'users',\%acl_count,\@users,$access_controls,$now,$then);
  980:     $r->print('</td></tr><tr><td colspan="3"></td></tr><tr>');
  981:     if (@courses > 0 || @groups > 0) {
  982:         $r->print('<td colspan="3" valign="top">');
  983:     } else {
  984:         $r->print('<td valign="top">');
  985:     }
  986:     &access_element($r,'course',\%acl_count,\@courses,$access_controls,$now,$then);
  987:     $r->print('</td>');
  988:     if (@courses > 0 || @groups > 0) {
  989:         $r->print('</tr><tr><td colspan="3">&nbsp;</td></tr><tr><td colspan="3" valign="top">');
  990:     } else {
  991:         $r->print('<td>&nbsp;</td><td valign="top">');
  992:     }
  993:     &access_element($r,'group',\%acl_count,\@groups,$access_controls,$now,$then);
  994:     $r->print('</td></tr></table>');
  995: }
  996: 
  997: sub acl_status {
  998:     my ($start,$end,$now) = @_;
  999:     if ($start > $now) {
 1000:         return &mt('Inactive');
 1001:     }
 1002:     if ($end && $end<$now) {
 1003:         return &mt('Inactive');
 1004:     }
 1005:     return &mt('Active');
 1006: }
 1007: 
 1008: sub access_element {
 1009:     my ($r,$type,$acl_count,$items,$access_controls,$now,$then) = @_;
 1010:     my $title = $type;
 1011:     $title =~ s/s$//;
 1012:     $title =~ s/^(\w)/uc($1)/e;
 1013:     $r->print('<h3>'.&mt('[_1]-based conditional access: ',$title));
 1014:     if ($$acl_count{$type}) {
 1015:         $r->print($$acl_count{$type}.' ');
 1016:         if ($$acl_count{$type} > 1) {
 1017:             $r->print(&mt('conditions'));
 1018:         } else {
 1019:             $r->print(&mt('condition'));
 1020:         }
 1021:     } else {
 1022:         $r->print(&mt('Off'));
 1023:     }
 1024:     $r->print('</h3>');
 1025:     &display_access_row($r,'old',$type,$items,$access_controls,$now,$then);
 1026:     return;
 1027: }
 1028: 
 1029: sub display_access_row {
 1030:     my ($r,$status,$type,$items,$access_controls,$now,$then) = @_;
 1031:     if (@{$items} > 0) {
 1032:         my @all_doms;
 1033:         my $colspan = 3;
 1034:         my $uctype = $type;
 1035:         $uctype =~ s/^(\w)/uc($1)/e;
 1036:         $r->print(&Apache::loncommon::start_data_table());
 1037:         $r->print(&Apache::loncommon::start_data_table_header_row());
 1038:         $r->print('<th>'.&mt('Action?').'</th><th>'.&mt($uctype).'</th><th>'.
 1039:               &mt('Dates available').'</th>');
 1040:         if (($type eq 'course') || ($type eq 'group')) {
 1041:             $r->print('<th>'.&mt('Allowed [_1] member affiliations',$type).
 1042:                       '</th>');
 1043:             $colspan ++;
 1044:         } elsif ($type eq 'domains') {
 1045:             @all_doms = &Apache::loncommon::get_domains();
 1046:         }
 1047:         $r->print(&Apache::loncommon::end_data_table_header_row());
 1048:         foreach my $key (@{$items}) {
 1049: 	    $r->print(&Apache::loncommon::start_data_table_row());
 1050:             if (($type eq 'course') || ($type eq 'group')) {
 1051:                 &course_row($r,$status,$type,$key,$access_controls,$now,$then);
 1052:             } elsif ($type eq 'domains') {
 1053:                 &domains_row($r,$status,$key,\@all_doms,$access_controls,$now,
 1054:                             $then);
 1055:             } elsif ($type eq 'users') {
 1056:                 &users_row($r,$status,$key,$access_controls,$now,$then);
 1057:             }
 1058: 	    $r->print(&Apache::loncommon::end_data_table_row());
 1059:         }
 1060:         if ($status eq 'old') {
 1061: 	    $r->print(&Apache::loncommon::start_data_table_row());
 1062:             $r->print('<td colspan="',$colspan.'">'.&additional_item($type).
 1063:                       '</td>');
 1064: 	    $r->print(&Apache::loncommon::end_data_table_row());
 1065:         }
 1066:         $r->print(&Apache::loncommon::end_data_table());
 1067:     } else {
 1068:         $r->print(&mt('No [_1]-based conditions defined.<br />',$type).
 1069:                   &additional_item($type));
 1070:     }
 1071:     return;
 1072: }
 1073: 
 1074: sub course_js {
 1075:     return qq|
 1076: <script type="text/javascript">
 1077: function setRoleOptions(caller,num,cdom,cnum,type) {
 1078:     addIndexnum = getCallerIndex(caller);
 1079:     updateIndexnum = getIndex('update',num);
 1080:     if (caller.checked) {
 1081:         document.portform.elements[updateIndexnum].checked = true;
 1082:         var url = '/adm/portfolio?action=rolepicker&setroles='+addIndexnum+'&cnum='+cnum+'&cdom='+cdom+'&type='+type;
 1083:         var title = 'Roles_Chooser';
 1084:         var options = 'scrollbars=1,resizable=1,menubar=0';
 1085:         options += ',width=700,height=600';
 1086:         rolebrowser = open(url,title,options,'1');
 1087:         rolebrowser.focus();
 1088:     } else {
 1089:         for (var j=0;j<5;j++) {
 1090:             document.portform.elements[addIndexnum+j].value = '';
 1091:         }
 1092:     }
 1093: }
 1094: 
 1095: function getCallerIndex(caller) {
 1096:     for (var i=0;i<document.portform.elements.length;i++) {
 1097:         if (document.portform.elements[i] == caller) {
 1098:             return i;
 1099:         }
 1100:     }
 1101:     return -1;
 1102: }
 1103: 
 1104: function getIndex(name,value) {
 1105:     for (var i=0;i<document.portform.elements.length;i++) {
 1106:         if (document.portform.elements[i].name == name && document.portform.elements[i].value == value) {
 1107:             return i;
 1108:         }
 1109:     }
 1110:     return -1;
 1111: }
 1112: 
 1113: </script>
 1114: |;
 1115: }
 1116: 
 1117: sub course_row {
 1118:     my ($r,$status,$type,$item,$access_controls,$now,$then) = @_;
 1119:     my $content;
 1120:     my $defdom = $env{'user.domain'};
 1121:     if ($status eq 'old') {
 1122:         $content = $$access_controls{$item}; 
 1123:         $defdom =  $content->{'domain'};
 1124:     }
 1125:     my $js = &Apache::loncommon::coursebrowser_javascript($defdom)
 1126: 	.&course_js();
 1127:     my $crsgrptext = 'Groups';
 1128:     if ($type eq 'group') {
 1129:         $crsgrptext = 'Teams';
 1130:     }
 1131:     my $uctype = $type;
 1132:     $uctype =~ s/^(\w)/uc($1)/e;
 1133:     my ($num,$scope,$end,$start) = &set_identifiers($status,$item,$now,$then,
 1134:                                                     $type);
 1135:     $r->print('<td>'.$js.&actionbox($status,$num,$scope).'</td>');
 1136:     if ($status eq 'old') {
 1137:         my $cid = $content->{'domain'}.'_'.$content->{'number'};
 1138:         my %course_description = &Apache::lonnet::coursedescription($cid);
 1139:         $r->print('<td><input type="hidden" name="crsdom_'.$num.'" value="'.$content->{'domain'}.'" /><input type="hidden" name="crsnum_'.$num.'" value="'.$content->{'number'}.'" />'.$course_description{'description'}.'</td>');
 1140:     } elsif ($status eq 'new') {
 1141:         $r->print('<td>'.&Apache::loncommon::selectcourse_link('portform','crsnum_'.$num,'crsdom_'.$num,'description_'.$num,undef,undef,$uctype).'&nbsp;&nbsp;<input type="text" name="description_'.$num.'" size="30" /><input type="hidden" name="crsdom_'.$num.'" /><input type="hidden" name="crsnum_'.$num.'" /></td>');
 1142:     }
 1143:     $r->print('<td>'.&dateboxes($num,$start,$end).'</td>');
 1144:     $r->print('<td><table><tr>');
 1145:     $r->print('<th>'.&mt('Action').'</th><th>'.&mt('Roles').'</th><th>'.
 1146:               &mt('Access').'</th><th>'.&mt('Sections').'</th><th>'.
 1147:               &mt($crsgrptext).'</th></tr>');
 1148:     if ($status eq 'old') {
 1149:         my $max_id = 0;
 1150:         foreach my $role_id (sort(keys(%{$content->{'roles'}}))) {
 1151:             if ($role_id > $max_id) {
 1152:                 $max_id = $role_id;
 1153:             }
 1154:             $max_id ++;
 1155:             my $role_selects = &role_selectors($num,$role_id,$status,$type,$content,'display');
 1156:             $r->print('<tr><td><span style="white-space: nowrap"><label><input type="checkbox" name="delete_role_'.$num.'" value="'.$role_id.'" />'.&mt('Delete').'</label></span><br /><input type="hidden" name="preserve_role_'.$num.'" value="'.$role_id.'" /></td>'.$role_selects.'</tr>');
 1157:         }
 1158:         $r->print('</table><br />'.&mt('Add a roles-based condition').'&nbsp;<input type="checkbox" name ="add_role_'.$num.'" onClick="javascript:setRoleOptions(this,'."'$num','$content->{'domain'}','$content->{'number'}','$uctype'".')" value="'.$max_id.'" /><input type="hidden" name="role_'.$num.'_'.$max_id.'" /><input type="hidden" name="access_'.$num.'_'.$max_id.'" /><input type="hidden" name="section_'.$num.'_'.$max_id.'" /><input type="hidden" name="group_'.$num.'_'.$max_id.'" /></td>');
 1159:     } elsif ($status eq 'new') {
 1160:         my $role_id = 1;
 1161:         my $role_selects = &role_selectors($num,$role_id,$status,$type,undef,'display');
 1162:         $r->print('<tr><td><input type="checkbox" name="add_role_'.$num.'" value="'.$role_id.'" checked="checked" />'.&mt('Add').'<input type="hidden" name="grplist_'.$num.'_'.$role_id.'" /></td>'.$role_selects);
 1163:         $r->print('</tr></table></td>');
 1164:     }
 1165:     return;
 1166: }
 1167: 
 1168: sub domains_row {
 1169:     my ($r,$status,$item,$all_doms,$access_controls,$now,$then) = @_;
 1170:     my ($num,$scope,$end,$start) = &set_identifiers($status,$item,$now,$then,
 1171:                                                     'domains');
 1172:     my $dom_select = '<select name="dom_'.$num.'" size="4" multiple="true">'.
 1173:                      ' <option value="">'.&mt('Please select').'</option>';
 1174:     if ($status eq 'old') {
 1175:         my $content =  $$access_controls{$item};
 1176: 	foreach my $dom (@{$all_doms}) {
 1177:             if ((@{$content->{'dom'}} > 0) 
 1178: 		&& (grep(/^\Q$dom\E$/,@{$content->{'dom'}}))) {
 1179:                 $dom_select .= '<option value="'.$dom.'" selected>'.
 1180:                                $dom.'</option>';
 1181:             } else {
 1182:                 $dom_select .= '<option value="'.$dom.'">'.$dom.'</option>';
 1183:             }
 1184:         }
 1185:     } else {
 1186:         foreach my $dom (@{$all_doms}) {
 1187:             $dom_select .= '<option value="'.$dom.'">'.$dom.'</option>';
 1188:         }
 1189:     }
 1190:     $dom_select .= '</select>';
 1191:     $r->print('<td>'.&actionbox($status,$num,$scope).'</td><td>'.$dom_select.
 1192:               '</td><td>'.&dateboxes($num,$start,$end).'</td>');
 1193: }
 1194: 
 1195: sub users_row {
 1196:     my ($r,$status,$item,$access_controls,$now,$then) = @_;
 1197:     my ($num,$scope,$end,$start) = &set_identifiers($status,$item,$now,$then,
 1198:                                                     'users');
 1199:     my $curr_user_list;
 1200:     if ($status eq 'old') {
 1201:         my $content = $$access_controls{$item};
 1202:         $curr_user_list = &sort_users($content->{'users'});
 1203:     }
 1204:     $r->print('<td>'.&actionbox($status,$num,$scope).'</td><td>'.&mt("Format for users' username:domain information:").'<br /><tt>sparty:msu,illini:uiuc  ... etc.</tt><br /><textarea name="users_'.$num.'" cols="30"  rows="5">'.$curr_user_list.'</textarea></td><td>'.&dateboxes($num,$start,$end).'</td>');
 1205: }
 1206: 
 1207: sub additional_item {
 1208:     my ($type) = @_;
 1209:     my $output = &mt('Add new [_1] condition(s)?',$type).'&nbsp;'.&mt('Number to add: ').'<input type="text" name="new'.$type.'" size="3" value="0" />';
 1210:     return $output;
 1211: }
 1212: 
 1213: sub actionbox {
 1214:     my ($status,$num,$scope) = @_;
 1215:     my $output = '<span style="white-space: nowrap"><label>';
 1216:     if ($status eq 'new') {
 1217:         $output .= '<input type="checkbox" name="activate" value="'.$num.'" />'.
 1218:         &mt('Activate');
 1219:     } else {
 1220:         $output .= '<input type="checkbox" name="delete" value="'.$num.
 1221:                    '" />'.&mt('Delete').'</label></span><br /><span style="white-space: nowrap">'.
 1222:                    '<label><input type="checkbox" name="update" value="'.
 1223:                    $num.'" />'.&mt('Update');
 1224:     }
 1225:     $output .= '</label></span><input type="hidden" name="scope_'.$num.                '" value="'.$scope.'" />';
 1226:     return $output;
 1227: }
 1228:                                                                                    
 1229: sub dateboxes {
 1230:     my ($num,$start,$end) = @_;
 1231:     my $noend;
 1232:     if ($end == 0) {
 1233:         $noend = 'checked="checked"';
 1234:     }
 1235:     my $startdate = &Apache::lonhtmlcommon::date_setter('portform',
 1236:                            'startdate_'.$num,$start,undef,undef,undef,1,undef,
 1237:                             undef,undef,1);
 1238:     my $enddate = &Apache::lonhtmlcommon::date_setter('portform',
 1239:                                'enddate_'.$num,$end,undef,undef,undef,1,undef,
 1240:                                 undef,undef,1). '&nbsp;&nbsp;<span style="white-space: nowrap"><label>'.
 1241:                                 '<input type="checkbox" name="noend_'.
 1242:                                 $num.'" '.$noend.' />'.&mt('No end date').
 1243:                                 '</label></span>';
 1244:                                                                                    
 1245:     my $output = &mt('Start: ').$startdate.'<br />'.&mt('End: ').$enddate;
 1246:     return $output;
 1247: }
 1248: 
 1249: sub unpack_acc_key {
 1250:     my ($acc_key) = @_;
 1251:     my ($num,$scope,$end,$start) = ($acc_key =~ /^([^:]+):([a-z]+)_(\d*)_?(\d*)$/);
 1252:     return ($num,$scope,$end,$start);
 1253: }
 1254: 
 1255: sub set_identifiers {
 1256:     my ($status,$item,$now,$then,$scope) = @_;
 1257:     if ($status eq 'old') {
 1258:         return(&unpack_acc_key($item));
 1259:     } else {
 1260:         return($item,$scope,$then,$now);
 1261:     }
 1262: } 
 1263: 
 1264: sub role_selectors {
 1265:     my ($num,$role_id,$status,$type,$content,$caller) = @_;
 1266:     my ($output,$cdom,$cnum,$longid);
 1267:     if ($caller eq 'display') {
 1268:         $longid = '_'.$num.'_'.$role_id;
 1269:         if ($status eq 'new') {
 1270:             foreach my $item ('role','access','section','group') {
 1271:                 $output .= '<td><select name="'.$item.$longid.'">'.
 1272:                            '<option value="">'.&mt('Pick [_1] first',$type).
 1273:                            '</option></select></td>';
 1274:             }
 1275:             return $output;
 1276:         } else {
 1277:             $cdom = $$content{'domain'};
 1278:             $cnum = $$content{'number'};
 1279:         }
 1280:     } elsif ($caller eq 'rolepicker') {
 1281:          $cdom = $env{'form.cdom'};
 1282:          $cnum = $env{'form.cnum'};
 1283:     }
 1284:     my $uctype = $type;
 1285:     $uctype =~ s/^(\w)/uc($1)/e;
 1286:     my ($sections,$groups,$allroles,$rolehash,$accesshash) =
 1287:             &Apache::loncommon::get_secgrprole_info($cdom,$cnum,1,$uctype);
 1288:     if (!@{$sections}) {
 1289:         @{$sections} = ('none');
 1290:     } else {
 1291:         unshift(@{$sections},('all','none'));
 1292:     }
 1293:     if (!@{$groups}) {
 1294:         @{$groups} = ('none');
 1295:     } else {
 1296:         unshift(@{$groups},('all','none'));
 1297:     }
 1298:     my @allacesses = sort(keys(%{$accesshash}));
 1299:     my (%sectionhash,%grouphash);
 1300:     foreach my $sec (@{$sections}) {
 1301:         $sectionhash{$sec} = $sec;
 1302:     }
 1303:     foreach my $grp (@{$groups}) {
 1304:         $grouphash{$grp} = $grp;
 1305:     }
 1306:     my %lookup = (
 1307:                    'role' => $rolehash,
 1308:                    'access' => $accesshash,
 1309:                    'section' => \%sectionhash,
 1310:                    'group' => \%grouphash,
 1311:                  );
 1312:     my @allaccesses = sort(keys(%{$accesshash}));
 1313:     my %allitems = (
 1314:                     'role' => $allroles,
 1315:                     'access' => \@allaccesses,
 1316:                     'section' => $sections,
 1317:                     'group' => $groups, 
 1318:                    );
 1319:     foreach my $item ('role','access','section','group') {
 1320:         $output .= '<td><select name="'.$item.$longid.'" multiple="true" size="4">'."\n";
 1321:         foreach my $entry (@{$allitems{$item}}) {
 1322:             if ($caller eq 'display') {
 1323:                 if ((@{$$content{'roles'}{$role_id}{$item}} > 0) && 
 1324:                     (grep(/^\Q$entry\E$/,@{$$content{'roles'}{$role_id}{$item}}))) {
 1325:                     $output .= '  <option value="'.$entry.'" selected>'.
 1326:                                   $lookup{$item}{$entry}.'</option>';
 1327:                     next;
 1328:                 }
 1329:             }
 1330:             $output .= '  <option value="'.$entry.'">'.
 1331:                        $lookup{$item}{$entry}.'</option>';
 1332:         }
 1333:         $output .= '</select>';
 1334:     }
 1335:     $output .= '</td>';
 1336:     return $output;
 1337: }
 1338: 
 1339: sub role_options_window {
 1340:     my ($r) = @_;
 1341:     my $cdom = $env{'form.cdom'};
 1342:     my $cnum = $env{'form.cnum'};
 1343:     my $type = $env{'form.type'};
 1344:     my $addindex = $env{'form.setroles'};
 1345:     my $grouptitle = 'Groups';
 1346:     if ($type eq 'Group') {
 1347:          $grouptitle = 'Teams';
 1348:     } 
 1349:     my $role_selects = &role_selectors(1,1,'new',$type,undef,'rolepicker');
 1350:     $r->print(<<"END_SCRIPT");
 1351: <script type="text/javascript">
 1352: function setRoles() {
 1353:     var addidx = $addindex+1;
 1354:     for (var i=0; i<4; i++) {
 1355:         var copylist = '';
 1356:         for (var j=0; j<document.rolepicker.elements[i].length; j++) {
 1357:             if (document.rolepicker.elements[i].options[j].selected) {
 1358:                 copylist = copylist + document.rolepicker.elements[i].options[j].value + ',';
 1359:             }
 1360:         }
 1361:         copylist = copylist.substr(0,copylist.length-1);
 1362:         opener.document.portform.elements[addidx+i].value = copylist;
 1363:     }
 1364:     self.close();
 1365: }
 1366: </script>
 1367: END_SCRIPT
 1368:     $r->print(&mt('Select roles, course status, section(s) and group(s) for users who will be able to access the portfolio file.'));
 1369:     $r->print('<form name="rolepicker" action="/adm/portfolio" method="post"><table><tr><th>'.&mt('Roles').'</th><th>'.&mt('[_1] status',$type).'</th><th>'.&mt('Sections').'</th><th>'.&mt($grouptitle).'</th></tr><tr>'.$role_selects.'</tr></table><br /><input type="button" name="rolepickbutton" value="Save selections" onclick="setRoles()" />');
 1370:     return;
 1371: }
 1372: 
 1373: sub select_files {
 1374:     my ($r,$group) = @_;
 1375:     if ($env{'form.continue'} eq 'true') {
 1376:         # here we update the selections for the currentpath
 1377:         # eventually, have to handle removing those not checked, but . . . 
 1378:         my @items=&Apache::loncommon::get_env_multiple('form.checkfile');
 1379:         if (scalar(@items)){
 1380:              &Apache::lonnet::save_selected_files($env{'user.name'}, $env{'form.currentpath'}, @items);
 1381:         }
 1382:     } else {
 1383:             #empty the file for a fresh start
 1384:             &Apache::lonnet::clear_selected_files($env{'user.name'});
 1385:     }
 1386:     my @files = &Apache::lonnet::files_not_in_path($env{'user.name'}, $env{'form.currentpath'});
 1387:     my $java_files = join ",", @files;
 1388:     if ($java_files) {
 1389:         $java_files.=',';
 1390:     }
 1391:     my $javascript =(<<ENDSMP);
 1392:         <script type="text/javascript">
 1393:         function finishSelect() {
 1394: ENDSMP
 1395:     $javascript .= 'fileList = "'.$java_files.'";';
 1396:     $javascript .= (<<ENDSMP);
 1397:             for (i=0;i<document.forms.checkselect.length;i++) { 
 1398:                 if (document.forms.checkselect[i].checked){
 1399:                     fileList = fileList + document.forms.checkselect.currentpath.value + document.forms.checkselect[i].value + "," ;
 1400:                 }
 1401:             }
 1402:             opener.document.forms.lonhomework.
 1403: ENDSMP
 1404:     $javascript .= $env{'form.fieldname'};
 1405:     $javascript .= (<<ENDSMP);
 1406:         .value=fileList;
 1407:             self.close();
 1408:         }
 1409:         </script>
 1410: ENDSMP
 1411:     $r->print($javascript);
 1412:     $r->print("<h1>Select portfolio files</h1>
 1413:                 Check as many as you wish in response to the problem.<br />");
 1414:     my @otherfiles=&Apache::lonnet::files_not_in_path($env{'user.name'}, $env{'form.currentpath'});
 1415:     if (@otherfiles) {
 1416: 	$r->print("<strong>Files selected from other directories:</strong><br />");
 1417: 	foreach my $file (@otherfiles) {
 1418: 	    $r->print($file."<br />");
 1419: 	}
 1420:     }
 1421: }
 1422: sub upload {
 1423:     my ($r,$url,$group)=@_;
 1424:     my $fname=$env{'form.uploaddoc.filename'};
 1425:     my $filesize = (length($env{'form.uploaddoc'})) / 1000; #express in k (1024?)
 1426:     my $disk_quota = 20000; # expressed in k
 1427:     $fname=&Apache::lonnet::clean_filename($fname);
 1428: 
 1429:     my $portfolio_root=&get_portfolio_root($group);
 1430:     my ($uname,$udom) = &get_name_dom($group);
 1431:     my $port_path = &get_port_path($group);
 1432:     # Fixme --- Move the checking for existing file to LOND error return
 1433:     my @dir_list=&get_dir_list($portfolio_root,$group);
 1434:     my $found_file = 0;
 1435:     my $locked_file = 0;
 1436:     foreach my $line (@dir_list) {
 1437:         my ($file_name)=split(/\&/,$line,2);
 1438:         if ($file_name eq $fname){
 1439:             $file_name = $env{'form.currentpath'}.$file_name;
 1440:             $file_name = &prepend_group($file_name,$group);
 1441:             $found_file = 1;
 1442:             if (defined($group)) {
 1443:                 $file_name = $group.'/'.$file_name;
 1444:             }
 1445:             if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') {
 1446:                 $locked_file = 1;
 1447:             } 
 1448:         }
 1449:     }
 1450:     my $current_disk_usage = &Apache::lonnet::diskusage($udom,$uname,$portfolio_root);
 1451:     if (($current_disk_usage + $filesize) > $disk_quota){
 1452:         $r->print('<span class="LC_error">Unable to upload <strong>'.$fname.' (size = '.$filesize.' kilobytes)</strong>. Disk quota will be exceeded.</span>'.
 1453:                   '<br />Disk quota is '.$disk_quota.' kilobytes. Your current disk usage is '.$current_disk_usage.' kilobytes.');
 1454:         $r->print(&done('Back',$url,$group));
 1455:     } 
 1456:     elsif ($found_file){
 1457:         if ($locked_file){
 1458:             $r->print('<span class="LC_error">'.'Unable to upload <strong>'.$fname.'</strong>, a <strong>locked</strong> file by that name was found in <strong>'.$port_path.$env{'form.currentpath'}.'</strong></span>'.
 1459:                   '<br />You will be able to rename or delete existing '.$fname.' after a grade has been assigned.');
 1460:             $r->print(&done('Back',$url,$group));      
 1461:         } else {   
 1462:             $r->print('<span class="LC_error">'.'Unable to upload <strong>'.$fname.'</strong>, a file by that name was found in <strong>'.$port_path.$env{'form.currentpath'}.'</strong></span>'.
 1463:                   '<br />To upload, rename or delete existing '.$fname.' in '.$port_path.$env{'form.currentpath'});
 1464:             $r->print(&done('Back',$url,$group));
 1465:         }
 1466:     } else {
 1467:         my $result=&Apache::lonnet::userfileupload('uploaddoc','',
 1468: 	        	 $port_path.$env{'form.currentpath'});
 1469:         if ($result !~ m|^/uploaded/|) {
 1470:             $r->print('<span class="LC_error">'.'An errror occured ('.$result.
 1471: 	              ') while trying to upload '.&display_file().'</span><br />');
 1472: 	    $r->print(&done('Back',$url,$group));
 1473:         } else {
 1474:             $r->print(&done(undef,$url,$group));
 1475:         }
 1476:     }
 1477: }
 1478: sub lock_info {
 1479:     my ($r,$url,$group) = @_;
 1480:     my ($uname,$udom) = &get_name_dom($group);
 1481:     my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom,
 1482:                                                                        $uname);
 1483:     my $file_name = $env{'form.lockinfo'};
 1484:     $file_name = &prepend_group($file_name,$group);
 1485:     if (defined($file_name) && defined($$current_permissions{$file_name})) {
 1486:         foreach my $array_item (@{$$current_permissions{$file_name}}) {
 1487:             if (ref($array_item) eq 'ARRAY') {
 1488:                 my $filetext;
 1489:                 if (defined($group)) {
 1490:                     $filetext = '<strong>'.$env{'form.lockinfo'}.
 1491:                                     '</strong> (group: '.$group.')'; 
 1492:                 } else {
 1493:                     $filetext = '<strong>'.$file_name.'</strong>';
 1494:                 } 
 1495:                 $r->print(&mt('[_1] was submitted in response to problem: ',
 1496:                               $filetext).
 1497:                           '<strong>'.&Apache::lonnet::gettitle($$array_item[0]).
 1498:                           '</strong><br />');
 1499:                 my %course_description = &Apache::lonnet::coursedescription($$array_item[1]);
 1500:                 $r->print(&mt('In the course: <strong>[_1]</strong><br />',
 1501:                               $course_description{'description'}));
 1502:                 # $r->print('the third is '.$$array_item[2].'<br>');
 1503:                 # $r->print("item is $$array_item[0]<br> and $$array_item[0]");
 1504:             }
 1505:         }
 1506:     }
 1507:     $r->print(&done('Back',$url,$group));
 1508:     return 'ok';
 1509: }
 1510: sub createdir {
 1511:     my ($r,$url,$group)=@_;
 1512:     my $newdir=&Apache::lonnet::clean_filename($env{'form.newdir'});
 1513:     if ($newdir eq '') {
 1514:     	$r->print('<span class="LC_error">'.
 1515: 	    	  &mt("Error: no directory name was provided.").
 1516: 		      '</span><br />');
 1517: 	    $r->print(&done(undef,$url,$group));
 1518: 	    return;
 1519:     }
 1520:     my $portfolio_root = &get_portfolio_root($group); 
 1521:     my @dir_list=&get_dir_list($portfolio_root,$group);
 1522:     my $found_file = 0;
 1523:     foreach my $line (@dir_list) {
 1524:         my ($filename)=split(/\&/,$line,2);
 1525:         if ($filename eq $newdir){
 1526:             $found_file = 1;
 1527:         }
 1528:     }
 1529:     if ($found_file){
 1530:     	    $r->print('<span class="LC_error">'.'Unable to create a directory named <strong>'.$newdir.
 1531:     	            ' </strong>a file or directory by that name already exists.</span><br />');
 1532:     } else {
 1533:         my ($uname,$udom) = &get_name_dom($group);
 1534:         my $port_path = &get_port_path($group);
 1535:         my $result=&Apache::lonnet::mkdiruserfile($uname,$udom,
 1536: 	         $port_path.$env{'form.currentpath'}.$newdir);
 1537:         if ($result ne 'ok') {
 1538:     	    $r->print('<span class="LC_error">'.'An errror occured ('.$result.
 1539: 	    	      ') while trying to create a new directory '.&display_file().'</span><br />');
 1540:         }
 1541:     }
 1542:     if ($newdir ne $env{'form.newdir'}) {
 1543:         $r->print("The new directory name was changed from:<br /><strong>".$env{'form.newdir'}."</strong> to <strong>$newdir </strong>");  
 1544:     }
 1545:     $r->print(&done(undef,$url,$group));
 1546: }
 1547: 
 1548: sub get_portfolio_root {
 1549:     my ($group) = @_;
 1550:     my ($portfolio_root,$udom,$uname,$path);
 1551:     ($uname,$udom) = &get_name_dom($group);
 1552:     if (defined($group)) {
 1553:         $path = '/userfiles/groups/'.$group.'/portfolio';
 1554:     } else {
 1555:         $path = '/userfiles/portfolio';
 1556:     }
 1557:     return (&Apache::loncommon::propath($udom,$uname).$path);
 1558: }
 1559: 
 1560: sub get_dir_list {
 1561:     my ($portfolio_root,$group) = @_;
 1562:     my ($uname,$udom) = &get_name_dom($group);
 1563:     return &Apache::lonnet::dirlist($env{'form.currentpath'},
 1564:                                           $udom,$uname,$portfolio_root);
 1565: }
 1566: 
 1567: sub get_name_dom {
 1568:     my ($group) = @_;
 1569:     my ($uname,$udom);
 1570:     if (defined($group)) {
 1571:         $udom = $env{'course.'.$env{'request.course.id'}.'.domain'};
 1572:         $uname = $env{'course.'.$env{'request.course.id'}.'.num'};
 1573:     } else {
 1574:         $udom = $env{'user.domain'};
 1575:         $uname = $env{'user.name'};
 1576:     }
 1577:     return ($uname,$udom);
 1578: }
 1579: 
 1580: sub prepend_group {
 1581:     my ($filename,$group) = @_;
 1582:     if (defined($group)) {
 1583:         $filename = $group.$filename;
 1584:     }
 1585:     return $filename;
 1586: }
 1587: 
 1588: sub get_namespace {
 1589:     my ($group) = @_;
 1590:     my $namespace = 'portfolio';
 1591:     if (defined($group)) {
 1592:         my ($uname,$udom) = &get_name_dom($group);
 1593:         $namespace .= '_'.$udom.'_'.$uname.'_'.$group;
 1594:     }
 1595:     return $namespace;
 1596: }
 1597: 
 1598: sub get_port_path {
 1599:     my ($group) = @_;
 1600:     my $port_path;
 1601:     if (defined($group)) {
 1602:        $port_path = "groups/$group/portfolio";
 1603:     } else {
 1604:        $port_path = 'portfolio';
 1605:     }
 1606:     return $port_path;
 1607: }
 1608: 
 1609: sub missing_priv {
 1610:     my ($r,$url,$priv,$group) = @_;
 1611:     my $longtext = {
 1612:                       upload => 'upload files',
 1613:                       delete => 'delete files',
 1614:                       rename => 'rename files',
 1615:                       setacl => 'set access controls for files',
 1616:                    };
 1617:     my $escpath = &HTML::Entities::encode($env{'form.currentpath'},'&<>"');
 1618:     my $rtnlink = '<a href="'.$url;
 1619:     if ($url =~ /\?/) {
 1620:         $rtnlink .= '&';
 1621:     } else {
 1622:         $rtnlink .= '?';
 1623:     }
 1624:     $rtnlink .= 'currentpath='.$escpath;
 1625:     $r->print(&mt('<h3>Action disallowed</h3>'));
 1626:     $r->print(&mt('You do not have sufficient privileges to [_1] ',
 1627:                   $longtext->{$priv}));
 1628:     if ($group) {
 1629:         $r->print(&mt("in the group's file repository."));
 1630:         $rtnlink .= '&group='.$group;
 1631:     } else {
 1632:         $r->print(&mt('in this portfolio.'));
 1633:     }
 1634:     $rtnlink .= '">'.&mt('Return to directory listing page').'</a>';
 1635:     $r->print('<br />'.$rtnlink);
 1636:     $r->print(&Apache::loncommon::end_page());
 1637:     return;
 1638: }
 1639: 
 1640: sub handler {
 1641:     # this handles file management
 1642:     my $r = shift;
 1643:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
 1644:          ['selectfile','currentpath','meta','lockinfo','currentfile','action',
 1645: 	  'fieldname','mode','rename','continue','group','access','setnum',
 1646:           'cnum','cdom','type','setroles']);
 1647:     my ($uname,$udom,$portfolio_root,$url,$group,$caller,$title);
 1648:     if ($r->uri =~ m|^(/adm/)([^/]+)|) {
 1649:         $url = $1.$2;
 1650:         $caller = $2;
 1651:     }
 1652:     my ($can_modify,$can_delete,$can_upload,$can_setacl);
 1653:     if ($caller eq 'coursegrp_portfolio') {
 1654:     #  Needs to be in a course
 1655:         if (! ($env{'request.course.fn'})) {
 1656:         # Not in a course
 1657:             $env{'user.error.msg'}=
 1658:      "/adm/coursegrp_portfolio:rgf:0:0:Cannot view group portfolio";
 1659:             return HTTP_NOT_ACCEPTABLE;
 1660:         }
 1661:         my $earlyout = 0;
 1662:         my $view_permission = &Apache::lonnet::allowed('vcg',
 1663:                                                 $env{'request.course.id'});
 1664:         $group = $env{'form.group'};
 1665:         $group =~ s/\W//g;
 1666:         if ($group) {
 1667:             ($uname,$udom) = &get_name_dom($group);
 1668:             my %curr_groups = &Apache::longroup::coursegroups($udom,$uname,
 1669: 							       $group); 
 1670:             if (%curr_groups) {
 1671:                 if (($view_permission) || (&Apache::lonnet::allowed('rgf',
 1672:                                       $env{'request.course.id'}.'/'.$group))) {
 1673:                     $portfolio_root = &get_portfolio_root($group);
 1674:                 } else {
 1675:                     $r->print('You do not have the privileges required to access the shared files space for this group.');
 1676:                     $earlyout = 1;
 1677:                 }
 1678:             } else {
 1679:                 $r->print('Not a valid group for this course');
 1680:                 $earlyout = 1;
 1681:             }
 1682:             $title = &mt('Group files').' for '.$group; 
 1683:         } else {
 1684:             $r->print('Invalid group');
 1685:             $earlyout = 1;
 1686:         }
 1687:         if ($earlyout) { return OK; }
 1688:         if (&Apache::lonnet::allowed('agf',$env{'request.course.id'}.'/'.$group)) {
 1689:             $can_setacl = 1;
 1690:         }
 1691:         if (&Apache::lonnet::allowed('ugf',$env{'request.course.id'}.'/'.$group)) {
 1692:             $can_upload = 1;
 1693:         }
 1694:         if (&Apache::lonnet::allowed('mgf',$env{'request.course.id'}.'/'.$group)) {
 1695:             $can_modify = 1;
 1696:         }
 1697:         if (&Apache::lonnet::allowed('dgf',$env{'request.course.id'}.'/'.$group)) {
 1698:             $can_delete = 1;
 1699:         }
 1700:     } else {
 1701:         ($uname,$udom) = &get_name_dom();
 1702:         $portfolio_root = &get_portfolio_root();
 1703:         $title = &mt('Portfolio Manager');
 1704:         $can_modify = 1;
 1705:         $can_delete = 1;
 1706:         $can_upload = 1;
 1707:         $can_setacl = 1;
 1708:     }
 1709: 
 1710:     &Apache::loncommon::no_cache($r);
 1711:     &Apache::loncommon::content_type($r,'text/html');
 1712:     $r->send_http_header;
 1713:     # Give the LON-CAPA page header
 1714:     if ($env{"form.mode"} eq 'selectfile'){
 1715:         $r->print(&Apache::loncommon::start_page($title,undef,
 1716: 						 {'only_body' => 1}));
 1717:     } elsif ($env{'form.action'} eq 'rolepicker') {
 1718:         $r->print(&Apache::loncommon::start_page('New role-based condition',undef,
 1719:                                                  {'no_nav_bar'  => 1, }));
 1720:     } else {
 1721:         $r->print(&Apache::loncommon::start_page($title));
 1722:     }
 1723:     $r->rflush();
 1724: 	if (($env{'form.storeupl'}) & (!$env{'form.uploaddoc.filename'})){
 1725:    	    $r->print('<span class="LC_error">'.
 1726: 		      'No file was selected to upload.'.
 1727: 		      'To upload a file, click <strong>Browse...</strong>'.
 1728: 		      ', select a file, then click <strong>Upload</strong>.'.
 1729: 		      '</span>');
 1730: 	}
 1731:     if ($env{'form.meta'}) {
 1732:         &open_form($r,$url);
 1733: #        $r->print(&edit_meta_data($r, $env{'form.currentpath'}.$env{'form.selectfile'}));
 1734:         $r->print('Edit the meta data<br />');
 1735:         &close_form($r,$url,$group);
 1736:     }
 1737:     if ($env{'form.store'}) {
 1738:     }
 1739: 
 1740:     if ($env{'form.uploaddoc.filename'}) {
 1741:         if ($can_upload) {
 1742: 	    &upload($r,$url,$group);
 1743:         } else {
 1744:             &missing_priv($r,$url,'upload',$group),
 1745:         }
 1746:     } elsif ($env{'form.action'} eq 'delete' && $env{'form.confirmed'}) {
 1747:         if ($can_delete) {
 1748: 	    &delete_confirmed($r,$url,$group);
 1749:         } else {
 1750:             &missing_priv($r,$url,'delete',$group);
 1751:         }
 1752:     } elsif ($env{'form.action'} eq 'delete') {
 1753:         if ($can_delete) {
 1754: 	    &delete($r,$url,$group);
 1755:         } else {
 1756:             &missing_priv($r,$url,'delete',$group);
 1757:         }
 1758:     } elsif ($env{'form.action'} eq 'deletedir' && $env{'form.confirmed'}) {
 1759:         if ($can_delete) {
 1760: 	    &delete_dir_confirmed($r,$url,$group);
 1761:         } else {
 1762:             &missing_priv($r,$url,'delete',$group);
 1763:         }
 1764:     } elsif ($env{'form.action'} eq 'deletedir') {
 1765:         if ($can_delete) {
 1766: 	    &delete_dir($r,$url,$group);
 1767:         } else {
 1768:             &missing_priv($r,$url,'delete',$group);
 1769:         }
 1770:     } elsif ($env{'form.action'} eq 'rename' && $env{'form.confirmed'}) {
 1771:         if ($can_modify) {
 1772: 	    &rename_confirmed($r,$url,$group);
 1773:         } else {
 1774:             &missing_priv($r,$url,'rename',$group);
 1775:         }
 1776:     } elsif ($env{'form.rename'}) {
 1777:         $env{'form.selectfile'} = $env{'form.rename'};
 1778:         $env{'form.action'} = 'rename';
 1779:         if ($can_modify) {
 1780: 	    &rename($r,$url,$group);
 1781:         } else {
 1782:             &missing_priv($r,$url,'rename',$group);
 1783:         }
 1784:     } elsif ($env{'form.access'}) {
 1785:         $env{'form.selectfile'} = $env{'form.access'};
 1786:         $env{'form.action'} = 'chgaccess';
 1787:         &display_access($r,$url,$group,$can_setacl);
 1788:     } elsif ($env{'form.action'} eq 'chgaccess') {
 1789:         if ($can_setacl) {
 1790:             &update_access($r,$url,$group);
 1791:         } else {
 1792:             &missing_priv($r,$url,'setacl',$group);
 1793:         }
 1794:     } elsif ($env{'form.action'} eq 'rolepicker') {
 1795:         if ($can_setacl) { 
 1796:             &role_options_window($r);
 1797:         } else {
 1798:             &missing_priv($r,$url,'setacl',$group);
 1799:         }
 1800:     } elsif ($env{'form.createdir'}) {
 1801:         if ($can_upload) {
 1802: 	    &createdir($r,$url,$group);
 1803:         } else {
 1804:             &missing_priv($r,$url,'upload',$group);
 1805:         }
 1806:     } elsif ($env{'form.lockinfo'}) {
 1807:         &lock_info($r,$url,$group);
 1808:     } else {
 1809: 	my $current_path='/';
 1810: 	if ($env{'form.currentpath'}) {
 1811: 	    $current_path = $env{'form.currentpath'};
 1812: 	}
 1813:         my @dir_list=&get_dir_list($portfolio_root,$group);
 1814: 	if ($dir_list[0] eq 'no_such_dir'){
 1815: 	    # two main reasons for this:
 1816:             #    1) never been here, so directory structure not created
 1817: 	    #    2) back-button navigation after deleting a directory
 1818: 	    if ($current_path eq '/'){
 1819: 	        &Apache::lonnet::mkdiruserfile($uname,$udom,
 1820: 					       &get_port_path($group));
 1821: 	    } else {
 1822:                 # some directory that snuck in get rid of the directory
 1823:                 # from the recent pulldown, just in case
 1824: 		&Apache::lonhtmlcommon::remove_recent('portfolio',
 1825: 						      [$current_path]);
 1826: 		$current_path = '/'; # force it back to the root        
 1827: 	    }
 1828: 	    # now grab the directory list again, for the first time
 1829: 	    @dir_list=&Apache::lonnet::dirlist($current_path,
 1830: 					    $udom,$uname,$portfolio_root);
 1831:         }
 1832: 	# need to know if directory is empty so it can be removed if desired
 1833: 	my $is_empty=(@dir_list == 2);
 1834: 	&display_common($r,$url,$current_path,$is_empty,\@dir_list,$group,
 1835:                         $can_upload);
 1836:         &display_directory($r,$url,$current_path,$is_empty,\@dir_list,$group,
 1837:                            $can_upload,$can_modify,$can_delete,$can_setacl);
 1838: 	$r->print(&Apache::loncommon::end_page());
 1839:     }
 1840:     return OK;
 1841: }
 1842: 
 1843: 1;
 1844: __END__

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
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.