[LON-CAPA-cvs] cvs: loncom /interface portfolio.pm
raeburn
lon-capa-cvs@mail.lon-capa.org
Thu, 22 Jun 2006 13:27:14 -0000
This is a MIME encoded message
--raeburn1150982834
Content-Type: text/plain
raeburn Thu Jun 22 09:27:14 2006 EDT
Modified files:
/loncom/interface portfolio.pm
Log:
Additional portfolio access control can now be defined: passphrase-protected, or conditional access (requires log-in) based on username/domain, domain, course or group affiliation (possible restriction by role, status, sectio and group).
--raeburn1150982834
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20060622092714.txt"
Index: loncom/interface/portfolio.pm
diff -u loncom/interface/portfolio.pm:1.107 loncom/interface/portfolio.pm:1.108
--- loncom/interface/portfolio.pm:1.107 Mon Jun 19 23:13:08 2006
+++ loncom/interface/portfolio.pm Thu Jun 22 09:27:13 2006
@@ -227,18 +227,34 @@
}
my $curr_access;
my $pub_access = 0;
+ my $guest_access = 0;
+ my $cond_access = 0;
foreach my $key (sort(keys(%{$access_controls{$fullpath}}))) {
- my ($scope,$end,$start) = ($key =~ /^[^:]+:([a-z]+)_(\d*)_?(\d*)$/);
+ my ($num,$scope,$end,$start) = &unpack_acc_key($key);
if (($now > $start) && (!$end || $end > $now)) {
if ($scope eq 'public') {
$pub_access = 1;
+ } elsif ($scope eq 'guest') {
+ $guest_access = 1;
+ } else {
+ $cond_access = 1;
}
}
}
- if (!$pub_access) {
- $curr_access = 'Private'
+ if (!$pub_access && !$guest_access && !$cond_access) {
+ $curr_access = &mt('Private');
} else {
- $curr_access = 'Public';
+ my @allaccesses;
+ if ($pub_access) {
+ push(@allaccesses,&mt('Public'));
+ }
+ if ($guest_access) {
+ push(@allaccesses,&mt('Password-protected'));
+ }
+ if ($cond_access) {
+ push(@allaccesses,&mt('Conditional'));
+ }
+ $curr_access = join('+ ',@allaccesses);
}
$r->print('<td><img src="'.&Apache::loncommon::icon($filename).'"></td>');
$r->print('<td><a href="'.$href_location.$filename.'">'.
@@ -287,8 +303,14 @@
}
sub close_form {
- my ($r,$url,$group)=@_;
- $r->print('<p><input type="submit" value="'.&mt('Continue').'" />');
+ my ($r,$url,$group,$button_text)=@_;
+ if (!defined($button_text)) {
+ $button_text = {
+ 'continue' => &mt('Continue'),
+ 'cancel' => &mt('Cancel'),
+ };
+ }
+ $r->print('<p><input type="submit" value="'.$button_text->{'continue'}.'" />');
if (defined($group)) {
$r->print("\n".'<input type="hidden" name="group" value="'.
$group.'" />');
@@ -302,7 +324,7 @@
$r->print("\n".'<input type="hidden" name="group" value="'.
$group.'" />');
}
- $r->print("\n".' <input type="submit" value="'.&mt('Cancel').'" />
+ $r->print("\n".' <input type="submit" value="'.$button_text->{'cancel'}.'" />
</p></form>');
}
@@ -468,21 +490,27 @@
my %access_controls = &Apache::lonnet::get_access_controls($current_permissions,$group,$file_name);
&open_form($r,$url);
$r->print('<h3>'.&mt('Allowing others to retrieve portfolio file: [_1]',$env{'form.currentpath'}.$env{'form.access'}).'</h3>'."\n");
- $r->print(&mt('Access to this file by others can be set to be one the following types: public.').'<br /><ul><li>'.&mt('Public files are available to anyone without the need for login.').'</li></ul><br />');
+ $r->print(&mt('Access to this file by others can be set to be one or more of the following types: public, password-protected or conditional.').'<br /><ul><li>'.&mt('Public files are available to anyone without the need for login.').'</li><li>'.&mt('Password-protected files do not require log-in, but will require the viewer to enter the password you set.').'</li><li>'.&mt('Conditional files are accessible to logged-in users with accounts in the LON-CAPA network, who satify 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 you can grant access to people with specific LON-CAPA usernames and domains.').'</li></ul>');
&access_setting_table($r,$access_controls{$file_name});
- &close_form($r,$url,$group);
+ my $button_text = {
+ 'continue' => &mt('Proceed'),
+ 'cancel' => &mt('Back to directory listing'),
+ };
+ &close_form($r,$url,$group,$button_text);
}
sub update_access {
my ($r,$url,$group) = @_;
+ my $function = &Apache::loncommon::get_users_function();
+ my $tablecolor = &Apache::loncommon::designparm($function.'.tabbg');
my $totalprocessed = 0;
my %processing;
my %title = (
- 'activate' => 'New controls added',
- 'delete' => 'Existing controls deleted',
- 'update' => 'Existing controls modified',
+ 'activate' => 'New control(s) added',
+ 'delete' => 'Existing control(s) deleted',
+ 'update' => 'Existing control(s) modified',
);
- my $changes;
+ my $changes;
foreach my $chg (sort(keys(%title))) {
@{$processing{$chg}} = &Apache::loncommon::get_env_multiple('form.'.$chg);
$totalprocessed += @{$processing{$chg}};
@@ -494,28 +522,34 @@
$$changes{$chg}{$newkey} = 1;
} else {
$$changes{$chg}{$newkey} =
- &build_access_record($num,$scope,$start,$end);
+ &build_access_record($num,$scope,$start,$end,$chg);
}
}
}
my $file_name = $env{'form.currentpath'}.$env{'form.selectfile'};
- $r->print('<h3>'.&mt('Allowing others to retrieve portfolio file: [_1]',$file_name).'</h3>'."\n");
+ $r->print('<h3>'.&mt('Allowing others to retrieve portfolio file: [_1]',
+ $file_name).'</h3>'."\n");
$file_name = &prepend_group($file_name,$group);
my ($uname,$udom) = &get_name_dom($group);
my ($errors,$outcome,$deloutcome,$new_values,$translation);
if ($totalprocessed) {
($outcome,$deloutcome,$new_values,$translation) =
- &Apache::lonnet::modify_access_controls($file_name,$changes,$udom,$uname);
+ &Apache::lonnet::modify_access_controls($file_name,$changes,$udom,
+ $uname);
}
- my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom, $uname);
- my %access_controls = &Apache::lonnet::get_access_controls($current_permissions,$group,$file_name);
+ my $current_permissions = &Apache::lonnet::get_portfile_permissions($udom,
+ $uname);
+ my %access_controls = &Apache::lonnet::get_access_controls(
+ $current_permissions,$group,$file_name);
if ($totalprocessed) {
if ($outcome eq 'ok') {
my $updated_controls = $access_controls{$file_name};
my ($showstart,$showend);
$r->print(&Apache::loncommon::start_data_table());
$r->print(&Apache::loncommon::start_data_table_row());
- $r->print('<th>'.&mt('Type of change').'</th><th>'.&mt('Access control').'</th><th>'.&mt('Start date').'</th><th>'.&mt('End date').'</th>');
+ $r->print('<th>'.&mt('Type of change').'</th><th>'.
+ &mt('Access control').'</th><th>'.&mt('Dates available').
+ '</th><th>'.&mt('Additional information').'</th>');
$r->print(&Apache::loncommon::end_data_table_row());
foreach my $chg (sort(keys(%processing))) {
if (@{$processing{$chg}} > 0) {
@@ -527,14 +561,14 @@
}
my $numchgs = @{$processing{$chg}};
$r->print(&Apache::loncommon::start_data_table_row());
- $r->print('<td rowspan="'.$numchgs.'">'.&mt($title{$chg}).'.</td>');
+ $r->print('<td rowspan="'.$numchgs.'">'.&mt($title{$chg}).
+ '.</td>');
my $count = 0;
foreach my $key (sort(keys(%{$$changes{$chg}}))) {
if ($count) {
$r->print(&Apache::loncommon::start_data_table_row());
}
- my ($num,$scope,$end,$start) =
- ($key =~ /^([^:]+):([a-z]+)_(\d*)_?(\d*)$/);
+ my ($num,$scope,$end,$start) = &unpack_acc_key($key);
my $newkey = $key;
if ($chg eq 'activate') {
$newkey =~ s/^(\d+)/$$translation{$1}/;
@@ -552,8 +586,70 @@
$showend = localtime($end);
}
}
- $r->print('<td>'.&mt($scope).'</td><td>'.$showstart.
- '</td><td>'. $showend.'</td>');
+ $r->print('<td>'.&mt($scope));
+ if (($scope eq 'course') || ($scope eq 'group')) {
+ if ($chg ne 'delete') {
+ my $cid = $content{'domain'}.'_'.$content{'number'};
+ my %course_description = &Apache::lonnet::coursedescription($cid);
+ $r->print('<br />('.$course_description{'description'}.')');
+ }
+ }
+ $r->print('</td><td>'.&mt('Start: ').$showstart.
+ '<br />'.&mt('End: ').$showend.'</td><td>');
+ if ($chg ne 'delete') {
+ if ($scope eq 'guest') {
+ $r->print(&mt('Password').': '.$content{'password'});
+ } elsif ($scope eq 'course' || $scope eq 'group') {
+ $r->print('<table border="0"><tr bgcol = "'.
+ $tablecolor.'">');
+ $r->print('<th>'.&mt('Roles').'</th><th>'.
+ &mt('Access').'</th><th>'.
+ &mt('Sections').'</th>');
+ if ($scope eq 'course') {
+ $r->print('<th>'.&mt('Groups').'</th>');
+ } else {
+ $r->print('<th>'.&mt('Teams').'</th>');
+ }
+ $r->print('</tr>');
+ foreach my $id (sort(keys(%{$content{'roles'}}))) {
+ $r->print('<tr>');
+ foreach my $item ('role','access','section','group') {
+ $r->print('<td>');
+ if ($item eq 'role') {
+ my $ucscope = $scope;
+ $ucscope =~ s/^(\w)/uc($1)/;
+ my $role_output;
+ foreach my $role (@{$content{'roles'}{$id}{$item}}) {
+ if ($role eq 'all') {
+ $role_output .= $role.',';
+ } elsif ($role =~ /^cr/) {
+ $role_output .= (split('/',$role))[3].',';
+ } else {
+ $role_output .= &Apache::lonnet::plaintext($role,$ucscope).',';
+ }
+ }
+ $role_output =~ s/,$//;
+ $r->print($role_output);
+ } else {
+ $r->print(join(',',@{$content{'roles'}{$id}{$item}}));
+ }
+ $r->print('</td>');
+ }
+ }
+ $r->print(&Apache::loncommon::end_data_table_row());
+ $r->print(&Apache::loncommon::end_data_table());
+ } elsif ($scope eq 'domains') {
+ $r->print(&mt('Domains: ').join(',',@{$content{'dom'}}));
+ } elsif ($scope eq 'users') {
+ my $curr_user_list = &sort_users($content{'users'});
+ $r->print(&mt('Users: ').$curr_user_list);
+ } else {
+ $r->print(' ');
+ }
+ } else {
+ $r->print(' ');
+ }
+ $r->print('</td>');
$r->print(&Apache::loncommon::end_data_table_row());
$count ++;
}
@@ -569,14 +665,131 @@
$r->print($errors);
}
}
- $r->print('<br /><a href="'.$url.'?access='.$env{'form.selectfile'}.'¤tpath='.$env{'form.currentpath'}.'">'.&mt('Display all access settings for this file').'</a>');
+ my $allnew = 0;
+ my $totalnew = 0;
+ my $status = 'new';
+ my ($firstitem,$lastitem);
+ foreach my $newitem ('course','group','domains','users') {
+ $allnew += $env{'form.new'.$newitem};
+ }
+ if ($allnew > 0) {
+ my $now = time;
+ my $then = $now + (60*60*24*180); # six months approx.
+ &open_form($r,$url,$group);
+ foreach my $newitem ('course','group','domains','users') {
+ if ($env{'form.new'.$newitem} > 0) {
+ $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 />');
+ $firstitem = $totalnew;
+ $lastitem = $totalnew + $env{'form.new'.$newitem};
+ $totalnew = $lastitem;
+ my @numbers;
+ for (my $i=$firstitem; $i<$lastitem; $i++) {
+ push (@numbers,$i);
+ }
+ &display_access_row($r,$status,$newitem,\@numbers,
+ $access_controls{$file_name},$now,$then);
+ }
+ }
+ &close_form($r,$url,$group);
+ } else {
+ $r->print('<br /><a href="'.$url.'?access='.$env{'form.selectfile'}.
+ '¤tpath='.$env{'form.currentpath'}.'">'.
+ &mt('Display all access settings for this file').'</a>');
+ }
return;
}
sub build_access_record {
- my ($num,$scope,$start,$end) = @_;
- my $record = '<scope type="'.$scope.'"><start>'.$start.'</start><end>'.$end.
- '</end></scope>';
+ my ($num,$scope,$start,$end,$chg) = @_;
+ my $record = '<scope type="'.$scope.'"><start>'.$start.'</start><end>'.
+ $end.'</end>';
+ if ($scope eq 'guest') {
+ $record .= '<password>'.$env{'form.password'}.'</password>';
+ } elsif (($scope eq 'course') || ($scope eq 'group')) {
+ $record .= '<domain>'.$env{'form.crsdom_'.$num}.'</domain><number>'.
+ $env{'form.crsnum_'.$num}.'</number>';
+ my @role_ids;
+ my @delete_role_ids;
+ if (exists($env{'form.delete_role_'.$num})) {
+ @delete_role_ids = &Apache::loncommon::get_env_multiple('form.delete_role_'.$num);
+ }
+ if (exists($env{'form.preserve_role_'.$num})) {
+ my @preserves = &Apache::loncommon::get_env_multiple('form.preserve_role_'.$num);
+ if (@delete_role_ids > 0) {
+ foreach my $id (@preserves) {
+ if (grep/^\Q$id\E$/,@delete_role_ids) {
+ next;
+ }
+ push(@role_ids,$id);
+ }
+ } else {
+ push(@role_ids,@preserves);
+ }
+ }
+ my $next_id = '';
+ if (exists($env{'form.add_role_'.$num})) {
+ $next_id = $env{'form.add_role_'.$num};
+ if ($next_id) {
+ push(@role_ids,$next_id);
+ }
+ }
+ foreach my $id (@role_ids) {
+ my (@roles,@accesses,@sections,@groups);
+ if (($id == $next_id) && ($chg eq 'update')) {
+ @roles = split(/,/,$env{'form.role_'.$num.'_'.$next_id});
+ @accesses = split(/,/,$env{'form.access_'.$num.'_'.$next_id});
+ @sections = split(/,/,$env{'form.section_'.$num.'_'.$next_id});
+ @groups = split(/,/,$env{'form.group_'.$num.'_'.$next_id});
+ } else {
+ @roles = &Apache::loncommon::get_env_multiple('form.role_'.$num.'_'.$id);
+ @accesses = &Apache::loncommon::get_env_multiple('form.access_'.$num.'_'.$id);
+ @sections = &Apache::loncommon::get_env_multiple('form.section_'.$num.'_'.$id);
+ @groups = &Apache::loncommon::get_env_multiple('form.group_'.$num.'_'.$id);
+ }
+ $record .= '<roles id="'.$id.'">';
+ foreach my $role (@roles) {
+ $record .= '<role>'.$role.'</role>';
+ }
+ foreach my $access (@accesses) {
+ $record .= '<access>'.$access.'</access>';
+ }
+ foreach my $section (@sections) {
+ $record .= '<section>'.$section.'</section>';
+ }
+ foreach my $group (@groups) {
+ $record .= '<group>'.$group.'</group>';
+ }
+ $record .= '</roles>';
+ }
+ } elsif ($scope eq 'domains') {
+ my @doms = &Apache::loncommon::get_env_multiple('form.dom_'.$num);
+ foreach my $dom (@doms) {
+ if ($dom ne '') {
+ $record .= '<dom>'.$dom.'</dom>';
+ }
+ }
+ } elsif ($scope eq 'users') {
+ my $userlist = $env{'form.users_'.$num};
+ $userlist =~ s/[\r\n\f]+//g;
+ $userlist =~ s/\s+//g;
+ my @users = split/,/,$userlist;
+ my %userhash;
+ my @unique_users;
+ foreach my $user (@users) {
+ if (!exists($userhash{$user})) {
+ $userhash{$user} = 1;
+ push(@unique_users,$user);
+ }
+ }
+ $record .= '<users>';
+ foreach my $user (@unique_users) {
+ my ($uname,$udom) = split(/:/,$user);
+ $record .= '<user><uname>'.$uname.'</uname><udom>'.$udom.
+ '</udom></user>';
+ }
+ $record .= '</users>';
+ }
+ $record .= '</scope>';
return $record;
}
@@ -592,82 +805,487 @@
return ($startdate,$enddate);
}
+sub sort_users {
+ my ($users_hash) = @_;
+ my @curr_users;
+ foreach my $user (keys(%{$users_hash})) {
+ $curr_users[$$users_hash{$user}] = $user;
+ }
+ my $curr_user_list = join(",\n",@curr_users);
+ return $curr_user_list;
+}
+
sub access_setting_table {
my ($r,$access_controls) = @_;
my ($public,$publictext);
- $publictext = '<b>'.&mt('Off').'</b>';
+ $publictext = &mt('Off');
my ($guest,$guesttext);
- $guesttext = '<b>'.&mt('Off').'</b>';
+ $guesttext = &mt('Off');
my @courses = ();
my @groups = ();
my @domains = ();
my @users = ();
my $now = time;
my $then = $now + (60*60*24*180); # six months approx.
+ my ($num,$scope,$publicnum,$guestnum);
+ my (%acl_count,%end,%start);
foreach my $key (sort(keys(%{$access_controls}))) {
- my ($scope) = ($key =~ /^[^:]+:([a-z]+)_\d*_?\d*$/);
+ ($num,$scope,$end{$key},$start{$key}) = &unpack_acc_key($key);
if ($scope eq 'public') {
$public = $key;
- $publictext = '<b>'.&mt('On').'</b>';
+ $publicnum = $num;
+ $publictext = &acl_status($start{$key},$end{$key},$now);
+ } elsif ($scope eq 'guest') {
+ $guest=$key;
+ $guestnum = $num;
+ $guesttext = &acl_status($start{$key},$end{$key},$now);
+ } elsif ($scope eq 'course') {
+ push(@courses,$key);
+ } elsif ($scope eq 'group') {
+ push(@groups,$key);
+ } elsif ($scope eq 'domains') {
+ push(@domains,$key);
+ } elsif ($scope eq 'users') {
+ push(@users,$key);
}
+ $acl_count{$scope} ++;
}
+ $r->print('<table border="0"><tr><td valign="top">');
+ $r->print('<h3>'.&mt('Public access:').' '.$publictext.'</h3>');
$r->print(&Apache::loncommon::start_data_table());
$r->print(&Apache::loncommon::start_data_table_row());
- $r->print('<th>'.&mt('Access Type').'</th><th colspan="3">'.
- &mt('Settings').'</th>'."\n");
+ $r->print('<th>'.&mt('Action').'</th><th>'.&mt('Dates available').'</th>');
$r->print(&Apache::loncommon::end_data_table_row());
$r->print(&Apache::loncommon::start_data_table_row());
- $r->print('<td><b>Public</b><br />'.$publictext.'</td><td colspan="3">');
+ if ($public) {
+ $r->print('<td>'.&actionbox('old',$publicnum,'public').'</td><td>'.
+ &dateboxes($publicnum,$start{$public},$end{$public}).'</td>');
+ } else {
+ $r->print('<td>'.&actionbox('new','0','public').'</td><td>'.
+ &dateboxes('0',$now,$then).'</td>');
+ }
+ $r->print(&Apache::loncommon::end_data_table_row());
+ $r->print(&Apache::loncommon::end_data_table());
+ $r->print('</td><td width="40"> </td><td valign="top">');
+ $r->print('<h3>'.&mt('Password-protected access:').' '.$guesttext.'</h3>');
$r->print(&Apache::loncommon::start_data_table());
$r->print(&Apache::loncommon::start_data_table_row());
- my ($pub_startdate,$pub_enddate,$pub_action,$pub_noend);
- if ($public) {
- my ($num,$end,$start) = ($public =~ /^([^:]+):[a-z]+_(\d*)_?(\d*)$/);
- if ($end == 0) {
- $pub_noend = 'checked="checked"';
- }
- $pub_action = '<td><label>
- <input type="checkbox" name="delete" value="'.$num.
- '" />'.&mt('Delete').'
- </label> <br />
- <label><input type="checkbox" name="update" value="'.
- $num.'" />'.&mt('Update').
- '</label>'.
- '<input type="hidden" name="scope_'.$num.'"'.
- ' value="public" /></td>';
- $pub_startdate = &Apache::lonhtmlcommon::date_setter('portform',
- 'startdate_'.$num,$start,undef,undef,undef,1,undef,
- undef,undef,1);
- $pub_enddate = &Apache::lonhtmlcommon::date_setter('portform',
- 'enddate_'.$num,$end,undef,undef,undef,1,undef,
- undef,undef,1).
- ' <nobr><label>
- <input type="checkbox" name="noend_'.
- $num.'" '.$pub_noend.' />'.&mt('No end date').
- '</label></nobr>';
- } else {
- $pub_action = '<label>'.
- '<input type="checkbox" name="activate" value="0" />'.
- &mt('Activate').'</label>'.
- '<input type="hidden" name="scope_0" value="public" />';
- $pub_startdate = &Apache::lonhtmlcommon::date_setter('portform',
- 'startdate_0',$now,undef,undef,undef,1,undef,
- undef,undef,1);
- $pub_enddate = &Apache::lonhtmlcommon::date_setter('portform',
- 'enddate_0',$then,,undef,undef,undef,1,undef,
- undef,undef,1).
- '  <nobr><label><input type="checkbox" '.
- 'name="noend_0" />'.&mt('No end date').
- '</label></nobr>';
-
+ $r->print('<th>'.&mt('Action').'</th><th>'.&mt('Dates available').
+ '</th><th>'. &mt('Password').'</th>');
+ $r->print(&Apache::loncommon::end_data_table_row());
+ $r->print(&Apache::loncommon::start_data_table_row());
+ my $passwd;
+ if ($guest) {
+ my %content = &Apache::lonnet::parse_access_controls(
+ $$access_controls{$guest});
+ $passwd = $content{'password'};
+ $r->print('<td>'.&actionbox('old',$guestnum,'guest').'</td><td>'.
+ &dateboxes($guestnum,$start{$guest},$end{$guest}).'</td>');
+ } else {
+ $r->print('<td>'.&actionbox('new','1','guest').'</td><td>'.
+ &dateboxes('1',$now,$then).'</td>');
}
- $r->print('<td>'.$pub_action.'</td><td>'.&mt('Start: ').$pub_startdate.
- '<br />'.&mt('End: ').$pub_enddate.'</td>');
+ $r->print('<td><input type="text" size="15" name="password" value="'.
+ $passwd.'" /></td>');
$r->print(&Apache::loncommon::end_data_table_row());
$r->print(&Apache::loncommon::end_data_table());
+ $r->print('</td></tr><tr><td colspan="3"> </td></tr><tr><td valign="top">');
+ &access_element($r,'domains',\%acl_count,\@domains,$access_controls,$now,$then);
+ $r->print('</td><td> </td><td valign="top">');
+ &access_element($r,'users',\%acl_count,\@users,$access_controls,$now,$then);
+ $r->print('</td></tr><tr><td colspan="3"></td></tr><tr>');
+ if (@courses > 0 || @groups > 0) {
+ $r->print('<td colspan="3" valign="top">');
+ } else {
+ $r->print('<td valign="top">');
+ }
+ &access_element($r,'course',\%acl_count,\@courses,$access_controls,$now,$then);
$r->print('</td>');
+ if (@courses > 0 || @groups > 0) {
+ $r->print('</tr><tr><td colspan="3"> </td></tr><tr><td colspan="3" valign="top">');
+ } else {
+ $r->print('<td> </td><td valign="top">');
+ }
+ &access_element($r,'group',\%acl_count,\@groups,$access_controls,$now,$then);
+ $r->print('</td></tr></table>');
+}
+
+sub acl_status {
+ my ($start,$end,$now) = @_;
+ if ($start > $now) {
+ return &mt('Inactive');
+ }
+ if ($end && $end<$now) {
+ return &mt('Inactive');
+ }
+ return &mt('Active');
+}
+
+sub access_element {
+ my ($r,$type,$acl_count,$items,$access_controls,$now,$then) = @_;
+ my $title = $type;
+ $title =~ s/s$//;
+ $title =~ s/^(\w)/uc($1)/e;
+ $r->print('<h3>'.&mt('[_1]-based conditional access: ',$title));
+ if ($$acl_count{$type}) {
+ $r->print($$acl_count{$type}.' ');
+ if ($$acl_count{$type} > 1) {
+ $r->print(&mt('conditions'));
+ } else {
+ $r->print(&mt('condition'));
+ }
+ } else {
+ $r->print(&mt('Off'));
+ }
+ $r->print('</h3>');
+ &display_access_row($r,'old',$type,$items,$access_controls,$now,$then);
+ return;
+}
+
+sub display_access_row {
+ my ($r,$status,$type,$items,$access_controls,$now,$then) = @_;
+ if (@{$items} > 0) {
+ my @all_doms;
+ my $tablecolor;
+ my $colspan = 3;
+ my $uctype = $type;
+ $uctype =~ s/^(\w)/uc($1)/e;
+ $r->print(&Apache::loncommon::start_data_table());
+ $r->print(&Apache::loncommon::start_data_table_row());
+ $r->print('<th>'.&mt('Action?').'</th><th>'.&mt($uctype).'</td><th>'.
+ &mt('Dates available').'</th>');
+ if (($type eq 'course') || ($type eq 'group')) {
+ $r->print('<th>'.&mt('Allowed [_1] member affiliations',$type).
+ '</th>');
+ $colspan ++;
+ my $function = &Apache::loncommon::get_users_function();
+ $tablecolor=&Apache::loncommon::designparm($function.'.tabbg');
+ } elsif ($type eq 'domains') {
+ @all_doms = &Apache::loncommon::get_domains();
+ }
+ $r->print(&Apache::loncommon::end_data_table_row());
+ foreach my $key (@{$items}) {
+ if (($type eq 'course') || ($type eq 'group')) {
+ &course_row($r,$status,$type,$key,$access_controls,
+ $tablecolor,$now,$then);
+ } elsif ($type eq 'domains') {
+ &domains_row($r,$status,$key,\@all_doms,$access_controls,$now,
+ $then);
+ } elsif ($type eq 'users') {
+ &users_row($r,$status,$key,$access_controls,$now,$then);
+ }
+ }
+ $r->print(&Apache::loncommon::end_data_table_row());
+ $r->print(&Apache::loncommon::start_data_table_row());
+ if ($status eq 'old') {
+ $r->print('<td colspan="',$colspan.'">'.&additional_item($type).
+ '</td>');
+ }
+ $r->print(&Apache::loncommon::end_data_table());
+ } else {
+ $r->print(&mt('No [_1]-based conditions defined.<br />',$type).
+ &additional_item($type));
+ }
+ return;
+}
+
+sub course_row {
+ my ($r,$status,$type,$item,$access_controls,$tablecolor,$now,$then) = @_;
+ my %content;
+ my $defdom = $env{'user.domain'};
+ if ($status eq 'old') {
+ %content = &Apache::lonnet::parse_access_controls(
+ $$access_controls{$item});
+ $defdom = $content{'domain'};
+ }
+ $r->print(&Apache::loncommon::coursebrowser_javascript($defdom));
+ $r->print(qq|
+<script type="text/javascript">
+function setRoleOptions(caller,num,cdom,cnum,type) {
+ addIndexnum = getCallerIndex(caller);
+ updateIndexnum = getIndex('update',num);
+ if (caller.checked) {
+ document.portform.elements[updateIndexnum].checked = true;
+ var url = '/adm/portfolio?action=rolepicker&setroles='+addIndexnum+'&cnum='+cnum+'&cdom='+cdom+'&type='+type;
+ var title = 'Roles_Chooser';
+ var options = 'scrollbars=1,resizable=1,menubar=0';
+ options += ',width=700,height=600';
+ rolebrowser = open(url,title,options,'1');
+ rolebrowser.focus();
+ } else {
+ for (var j=0;j<5;j++) {
+ document.portform.elements[addIndexnum+j].value = '';
+ }
+ }
+}
+
+function getCallerIndex(caller) {
+ for (var i=0;i<document.portform.elements.length;i++) {
+ if (document.portform.elements[i] == caller) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+function getIndex(name,value) {
+ for (var i=0;i<document.portform.elements.length;i++) {
+ if (document.portform.elements[i].name == name && document.portform.elements[i].value == value) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+</script>
+|);
+ $r->print(&Apache::loncommon::start_data_table_row());
+ my $crsgrptext = 'Groups';
+ if ($type eq 'group') {
+ $crsgrptext = 'Teams';
+ }
+ my ($num,$scope,$end,$start) = &set_identifiers($status,$item,$now,$then,
+ $type);
+ $r->print('<td>'.&actionbox($status,$num,$scope).'</td>');
+ if ($status eq 'old') {
+ my $cid = $content{'domain'}.'_'.$content{'number'};
+ my %course_description = &Apache::lonnet::coursedescription($cid);
+ $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>');
+ } elsif ($status eq 'new') {
+ my $uctype = $type;
+ $uctype =~ s/^(\w)/uc($1)/e;
+ $r->print('<td>'.&Apache::loncommon::selectcourse_link('portform','crsnum_'.$num,'crsdom_'.$num,'description_'.$num,undef,undef,$uctype).' <input type="text" name="description_'.$num.'" size="30" /><input type="hidden" name="crsdom_'.$num.'" /><input type="hidden" name="crsnum_'.$num.'" /></td>');
+ }
+ $r->print('<td>'.&dateboxes($num,$start,$end).'</td>');
+ $r->print('<td><table border="0"><tr bgcolor="'.$tablecolor.'">');
+ $r->print('<th>'.&mt('Action').'</th><th>'.&mt('Roles').'</th><th>'.
+ &mt('Access').'</th><th>'.&mt('Sections').'</th><th>'.
+ &mt($crsgrptext).'</th></tr>');
+ if ($status eq 'old') {
+ my $max_id = 0;
+ foreach my $role_id (sort(keys(%{$content{'roles'}}))) {
+ if ($role_id > $max_id) {
+ $max_id = $role_id;
+ }
+ $max_id ++;
+ my $role_selects = &role_selectors($num,$role_id,$status,$type,\%content,'display');
+ $r->print('<tr><td><nobr><label><input type="checkbox" name="delete_role_'.$num.'" value="'.$role_id.'" />'.&mt('Delete').'</label></nobr><br /><input type="hidden" name="preserve_role_'.$num.'" value="'.$role_id.'" /></td>'.$role_selects.'</tr>');
+ }
+ $r->print('</table><br />'.&mt('Add a roles-based condition').' <input type="checkbox" name ="add_role_'.$num.'" onClick="javascript:setRoleOptions(this,'."'$num','$content{domain}','$content{number}','Course'".')" 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>');
+ } elsif ($status eq 'new') {
+ my $role_id = 1;
+ my $role_selects = &role_selectors($num,$role_id,$status,$type,undef,'display');
+ $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);
+ $r->print('</tr></table></td>');
+ }
$r->print(&Apache::loncommon::end_data_table_row());
- $r->print(&Apache::loncommon::end_data_table());
+ return;
+}
+
+sub domains_row {
+ my ($r,$status,$item,$all_doms,$access_controls,$now,$then) = @_;
+ $r->print(&Apache::loncommon::start_data_table_row());
+ my ($num,$scope,$end,$start) = &set_identifiers($status,$item,$now,$then,
+ 'domains');
+ my $dom_select = '<select name="dom_'.$num.'" size="4" multiple="true"/>'.
+ ' <option value="">'.&mt('Please select').'</option>';
+ $r->print(&Apache::loncommon::start_data_table_row());
+ if ($status eq 'old') {
+ my %content = &Apache::lonnet::parse_access_controls(
+ $$access_controls{$item});
+ my @curr_doms = @{$content{'dom'}};
+ foreach my $dom (@{$all_doms}) {
+ if ((@{$content{'dom'}} > 0) && (grep(/^\Q$dom\E$/,@{$content{'dom'}}))) {
+ $dom_select .= '<option value="'.$dom.'" selected>'.
+ $dom.'</option>';
+ } else {
+ $dom_select .= '<option value="'.$dom.'">'.$dom.'</option>';
+ }
+ }
+ } else {
+ foreach my $dom (@{$all_doms}) {
+ $dom_select .= '<option value="'.$dom.'">'.$dom.'</option>';
+ }
+ }
+ $r->print('<td>'.&actionbox($status,$num,$scope).'</td><td>'.$dom_select.
+ '</td><td>'.&dateboxes($num,$start,$end).'</td>');
+ $r->print(&Apache::loncommon::end_data_table_row());
+ $r->print(&Apache::loncommon::start_data_table_row());
+}
+
+sub users_row {
+ my ($r,$status,$item,$access_controls,$now,$then) = @_;
+ $r->print(&Apache::loncommon::start_data_table_row());
+ my ($num,$scope,$end,$start) = &set_identifiers($status,$item,$now,$then,
+ 'users');
+ my $curr_user_list;
+ if ($status eq 'old') {
+ my %content = &Apache::lonnet::parse_access_controls(
+ $$access_controls{$item});
+ $curr_user_list = &sort_users($content{'users'});
+ }
+ $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>');
+ $r->print(&Apache::loncommon::end_data_table_row());
+}
+
+sub additional_item {
+ my ($type) = @_;
+ my $output = &mt('Add new [_1] condition(s)?',$type).' '.&mt('Number to add: ').'<input type="text" name="new'.$type.'" size="3" value="0" />';
+ return $output;
+}
+
+sub actionbox {
+ my ($status,$num,$scope) = @_;
+ my $output = '<nobr><label>';
+ if ($status eq 'new') {
+ $output .= '<input type="checkbox" name="activate" value="'.$num.'" />'.
+ &mt('Activate');
+ } else {
+ $output .= '<input type="checkbox" name="delete" value="'.$num.
+ '" />'.&mt('Delete').'</label><br /><nobr>'.
+ '<label><input type="checkbox" name="update" value="'.
+ $num.'" />'.&mt('Update');
+ }
+ $output .= '</label></nobr><input type="hidden" name="scope_'.$num. '" value="'.$scope.'" />';
+ return $output;
+}
+
+sub dateboxes {
+ my ($num,$start,$end) = @_;
+ my $noend;
+ if ($end == 0) {
+ $noend = 'checked="checked"';
+ }
+ my $startdate = &Apache::lonhtmlcommon::date_setter('portform',
+ 'startdate_'.$num,$start,undef,undef,undef,1,undef,
+ undef,undef,1);
+ my $enddate = &Apache::lonhtmlcommon::date_setter('portform',
+ 'enddate_'.$num,$end,undef,undef,undef,1,undef,
+ undef,undef,1). ' <nobr><label>'.
+ '<input type="checkbox" name="noend_'.
+ $num.'" '.$noend.' />'.&mt('No end date').
+ '</label></nobr>';
+
+ my $output = &mt('Start: ').$startdate.'<br />'.&mt('End: ').$enddate;
+ return $output;
+}
+
+sub unpack_acc_key {
+ my ($acc_key) = @_;
+ my ($num,$scope,$end,$start) = ($acc_key =~ /^([^:]+):([a-z]+)_(\d*)_?(\d*)$/);
+ return ($num,$scope,$end,$start);
+}
+
+sub set_identifiers {
+ my ($status,$item,$now,$then,$scope) = @_;
+ if ($status eq 'old') {
+ return(&unpack_acc_key($item));
+ } else {
+ return($item,$scope,$then,$now);
+ }
+}
+
+sub role_selectors {
+ my ($num,$role_id,$status,$type,$content,$caller) = @_;
+ my ($output,$cdom,$cnum,$longid);
+ if ($caller eq 'display') {
+ $longid = '_'.$num.'_'.$role_id;
+ if ($status eq 'new') {
+ foreach my $item ('role','access','section','group') {
+ $output .= '<td><select name="'.$item.$longid.'">'.
+ '<option value="">'.&mt('Pick [_1] first',$type).
+ '</option></select></td>';
+ }
+ return $output;
+ } else {
+ $cdom = $$content{'domain'};
+ $cnum = $$content{'number'};
+ }
+ } elsif ($caller eq 'rolepicker') {
+ $cdom = $env{'form.cdom'};
+ $cnum = $env{'form.cnum'};
+ }
+ my ($sections,$groups,$allroles,$rolehash,$accesshash) =
+ &Apache::loncommon::get_secgrprole_info($cdom,$cnum,1,$type);
+ if (!@{$sections}) {
+ @{$sections} = ('none');
+ } else {
+ unshift(@{$sections},('all','none'));
+ }
+ if (!@{$groups}) {
+ @{$groups} = ('none');
+ } else {
+ unshift(@{$groups},('all','none'));
+ }
+ my @allacesses = sort(keys(%{$accesshash}));
+ my (%sectionhash,%grouphash);
+ foreach my $sec (@{$sections}) {
+ $sectionhash{$sec} = $sec;
+ }
+ foreach my $grp (@{$groups}) {
+ $grouphash{$grp} = $grp;
+ }
+ my %lookup = (
+ 'role' => $rolehash,
+ 'access' => $accesshash,
+ 'section' => \%sectionhash,
+ 'group' => \%grouphash,
+ );
+ my @allaccesses = sort(keys(%{$accesshash}));
+ my %allitems = (
+ 'role' => $allroles,
+ 'access' => \@allaccesses,
+ 'section' => $sections,
+ 'group' => $groups,
+ );
+ foreach my $item ('role','access','section','group') {
+ $output .= '<td><select name="'.$item.$longid.'" multiple="true" size="4">'."\n";
+ foreach my $entry (@{$allitems{$item}}) {
+ if ($caller eq 'display') {
+ if ((@{$$content{'roles'}{$role_id}{$item}} > 0) &&
+ (grep(/^\Q$entry\E$/,@{$$content{'roles'}{$role_id}{$item}}))) {
+ $output .= ' <option value="'.$entry.'" selected>'.
+ $lookup{$item}{$entry}.'</option>';
+ next;
+ }
+ }
+ $output .= ' <option value="'.$entry.'">'.
+ $lookup{$item}{$entry}.'</option>';
+ }
+ $output .= '</select>';
+ }
+ $output .= '</td>';
+ return $output;
+}
+
+sub role_options_window {
+ my ($r) = @_;
+ my $cdom = $env{'form.cdom'};
+ my $cnum = $env{'form.cnum'};
+ my $type = $env{'form.type'};
+ my $addindex = $env{'form.setroles'};
+ my $role_selects = &role_selectors(1,1,'new',$type,undef,'rolepicker');
+ $r->print(<<"END_SCRIPT");
+<script type="text/javascript">
+function setRoles() {
+ var addidx = $addindex+1;
+ for (var i=0; i<4; i++) {
+ var copylist = '';
+ for (var j=0; j<document.rolepicker.elements[i].length; j++) {
+ if (document.rolepicker.elements[i].options[j].selected) {
+ copylist = copylist + document.rolepicker.elements[i].options[j].value + ',';
+ }
+ }
+ copylist = copylist.substr(0,copylist.length-1);
+ opener.document.portform.elements[addidx+i].value = copylist;
+ }
+ self.close();
+}
+</script>
+END_SCRIPT
+ $r->print(&mt('Select roles, course status, section(s) and group(s) for users who will be able to access the portfolio file.'));
+ $r->print('<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('Groups').'</th></tr><tr>'.$role_selects.'</tr></table><br /><input type="button" name="rolepickbutton" value="Save selections" onclick="setRoles()" />');
+ return;
}
sub select_files {
@@ -910,8 +1528,9 @@
# this handles file management
my $r = shift;
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
- ['selectfile','currentpath','meta','lockinfo','currentfile',
- 'action','fieldname','mode','rename','continue','group','access']);
+ ['selectfile','currentpath','meta','lockinfo','currentfile','action',
+ 'fieldname','mode','rename','continue','group','access','setnum',
+ 'cnum','cdom','type','setroles']);
my ($uname,$udom,$portfolio_root,$url,$group,$caller,$title);
if ($r->uri =~ m|^(/adm/)([^/]+)|) {
$url = $1.$2;
@@ -965,6 +1584,9 @@
if ($env{"form.mode"} eq 'selectfile'){
$r->print(&Apache::loncommon::start_page($title,undef,
{'only_body' => 1}));
+ } elsif ($env{'form.action'} eq 'rolepicker') {
+ $r->print(&Apache::loncommon::start_page('New role-based condition',undef,
+ {'no_nav_bar' => 1, }));
} else {
$r->print(&Apache::loncommon::start_page($title));
}
@@ -1005,6 +1627,8 @@
&display_access($r,$url,$group);
} elsif ($env{'form.action'} eq 'chgaccess') {
&update_access($r,$url,$group);
+ } elsif ($env{'form.action'} eq 'rolepicker') {
+ &role_options_window($r);
} elsif ($env{'form.createdir'}) {
&createdir($r,$url,$group);
} elsif ($env{'form.lockinfo'}) {
--raeburn1150982834--