# The LearningOnline Network with CAPA
# Handler to display the coauthors
#
# $Id: lonviewcoauthors.pm,v 1.6 2024/08/31 21:00:44 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
###############################################################
##############################################################
package Apache::lonviewcoauthors;
use strict;
use Apache::loncommon();
use Apache::lonhtmlcommon();
use Apache::Constants qw(:common :http);
use Apache::lonlocal;
use Apache::lonnet;
use LONCAPA qw(:DEFAULT :match);
###################################################################
###################################################################
###################################################################
###################################################################
=pod
=item &handler
The typical handler you see in all these modules. Takes $r, the
http request, as an argument.
=cut
###################################################################
###################################################################
sub handler {
my $r=shift;
if ($r->header_only) {
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
return OK;
}
my ($role,$audom,$auname,$canview,$canedit,$start_page);
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
['forceedit','state','action','caller']);
# Get permissions
($role,$audom,$auname,$canview,$canedit) = &get_allowable();
unless ($canview) {
$env{'user.error.msg'}=
"/adm/viewcoauthors:not in co-author role";
return HTTP_NOT_ACCEPTABLE;
}
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
# Get view settings
my %viewsettings = &retrieve_view_settings($auname,$audom,$role);
# Get caller
my $caller;
if ($env{'form.caller'} eq '/adm/createuser') {
$caller = $env{'form.caller'};
} else {
$caller = '/adm/viewcoauthors';
}
# Get breadcrumbs
my $brcrum = [{'href' => $caller,
'text' => 'Co-author listing'},];
if (($canedit) && ($env{'form.forceedit'})) {
&get_editor_crumbs($brcrum,$caller);
}
# Print page header
my $args = { 'bread_crumbs' => $brcrum };
$r->print(&Apache::loncommon::start_page('Co-author listing',undef,
$args));
if (($canedit) && ($env{'form.forceedit'})) {
$r->print(&edit_settings($audom,$auname,$role,$caller,\%viewsettings));
} elsif ($viewsettings{'show'} eq 'none') {
$r->print('<h3>'.&mt('Coauthor-viewable listing').'</h3>'.
'<p class="LC_info">'.&mt('Listing of co-authors not enabled for this Authoring Space').'</p>');
} else {
&print_coauthors($r,$auname,$audom,$role,$caller,\%viewsettings);
}
# Print page footer
$r->print(&Apache::loncommon::end_page());
return OK;
}
sub get_allowable {
my ($role,$audom,$auname,$canview,$canedit);
if ($env{'request.role'} =~ m{^(ca|aa)\./($match_domain)/($match_username)$}) {
($role,$audom,$auname) = ($1,$2,$3);
if ((&Apache::lonnet::allowed('vca',"$audom/$auname")) ||
(&Apache::lonnet::allowed('vaa',"$audom/$auname"))) {
if ($env{"environment.internal.manager./$audom/$auname"}) {
$canedit = 1;
}
}
$canview = 1;
} elsif ($env{'request.role'} eq "au./$env{'user.domain'}/") {
$role = 'au';
$auname = $env{'user.name'};
$audom = $env{'user.domain'};
if ((&Apache::lonnet::allowed('cca',"$audom/$auname")) ||
(&Apache::lonnet::allowed('caa',"$audom/$auname"))) {
$canedit = 1;
}
$canview = 1;
}
return ($role,$audom,$auname,$canview,$canedit);
}
sub retrieve_view_settings {
my ($auname,$audom,$role) = @_;
my %viewsettings;
if (($auname ne '') & ($audom ne '')) {
if ($role eq 'au') {
if (exists($env{'environment.coauthorlist'})) {
$viewsettings{'show'} = $env{'environment.coauthorlist'};
}
if (exists($env{'environment.coauthoroptin'})) {
$viewsettings{'optin'} = $env{'environment.coauthoroptin'};
}
} elsif ($env{"environment.internal.coauthorlist./$audom/$auname"} =~ /^(role|all|none)$/) {
$viewsettings{'show'} = $env{"environment.internal.coauthorlist./$audom/$auname"};
$viewsettings{'optin'} = $env{"environment.internal.coauthoroptin./$audom/$auname"};
}
}
unless ((exists($viewsettings{'show'})) && (exists($viewsettings{'optin'}))) {
if ($audom ne '') {
my %domconfig =
&Apache::lonnet::get_dom('configuration',['authordefaults'],$audom);
my %domdefs;
if (ref($domconfig{'authordefaults'}) eq 'HASH') {
if (exists($domconfig{'authordefaults'}{'coauthorlist'})) {
$domdefs{'show'} = $domconfig{'authordefaults'}{'coauthorlist'};
}
if (exists($domconfig{'authordefaults'}{'coauthoroptin'})) {
$domdefs{'optin'} = $domconfig{'authordefaults'}{'coauthoroptin'};
}
}
unless (exists($viewsettings{'show'})) {
if (exists($domdefs{'show'})) {
$viewsettings{'show'} = $domdefs{'show'};
}
}
unless (exists($viewsettings{'optin'})) {
if (exists($domdefs{'optin'})) {
$viewsettings{'optin'} = $domdefs{'optin'};
}
}
}
}
unless (exists($viewsettings{'show'})) {
$viewsettings{'show'} = 'none';
}
unless (exists($viewsettings{'optin'})) {
$viewsettings{'optin'} = '0';
}
return %viewsettings;
}
sub get_editor_crumbs {
my ($brcrum,$caller) = @_;
my $querystr = '?forceedit=1';
if ($caller eq '/adm/createuser') {
$querystr .= '&action=calist';
}
if (ref($brcrum) eq 'ARRAY') {
push(@{$brcrum},
{'href' => $caller.$querystr,
'text' => 'Configure co-author listing'});
if ($env{'form.state'} eq 'setconfig') {
push(@{$brcrum},
{'href' => $caller.$querystr,
'text' => 'Result'});
}
}
return;
}
sub edit_settings {
my ($audom,$auname,$role,$caller,$settingsref) = @_;
my %viewsettings;
if (ref($settingsref) eq 'HASH') {
%viewsettings = %{$settingsref};
} else {
%viewsettings = &retrieve_view_settings($auname,$audom,$role);
}
my %userenv = &Apache::lonnet::userenvironment($audom,$auname,
'coauthorlist','coauthoroptin');
my %titles = &Apache::lonlocal::texthash (
coauthorlist => 'List availability',
coauthoroptin => "Co-author's agreement needed for listing",
);
my %options = &Apache::lonlocal::texthash (
role => "List only same type of co-author role as viewer",
all => "List both co-author(s) and assistant co-author(s)",
none => "No listing",
);
my %lt = &Apache::lonlocal::texthash (
yes => 'Yes',
no => 'No',
slcc => 'Settings for listing of co-authors changed',
ncms => 'No changes made to settings for listing of co-authors',
apos => 'A problem occurred saving your changes.',
cloc => 'Configure listing of co-authors',
set => 'Setting',
vale => 'Value',
sav => 'Save changes'
);
my $output;
if ($env{'form.state'} eq 'setconfig') {
my (%changed,$message);
my ($numchanged,%changes,%disallowed);
foreach my $key ('coauthorlist','coauthoroptin') {
if ($key eq 'coauthorlist') {
next unless ($env{'form.'.$key} =~ /^all|role|none$/);
} elsif ($key eq 'coauthoroptin') {
next unless ($env{'form.'.$key} =~ /^0|1$/);
}
if ($userenv{$key} ne $env{'form.'.$key}) {
$changed{$key} = $env{'form.'.$key};
}
}
if (keys(%changed)) {
my $putres = &Apache::lonnet::put('environment',\%changed,
$audom,$auname);
if ($putres eq 'ok') {
my $author;
if (($audom eq $env{'user.domain'}) && ($auname eq $env{'user.name'})) {
$author = 1;
}
my (%envhash,%newvaltext);
foreach my $key (keys(%changed)) {
if ($author) {
$envhash{"environment.$key"} = $changed{$key};
} else {
$envhash{"environment.internal.$key./$audom/$auname"} = $changed{$key};
}
if ($key eq 'coauthorlist') {
$newvaltext{$key} = $options{$changed{$key}};
} elsif ($key eq 'coauthoroptin') {
$newvaltext{$key} = ($changed{$key}? $lt{'yes'} : $lt{'no'});
}
}
&Apache::lonnet::appenv(\%envhash);
$output = '<h3>'.$lt{'slcc'}.'</h3><ul>';
foreach my $key ('coauthorlist','coauthoroptin') {
if (exists($changed{$key})) {
$output .= '<li>'.
&mt('[_1] set to "[_2]"',
$titles{$key},$newvaltext{$key}).
'</li>';
}
}
$output .= '</ul>';
} else {
$output = '<h3>'.$lt{'ncms'}.'</h3>'.
'<p class="LC_warning">'.$lt{'apos'}.'</p>';
}
} else {
$output = '<h3>'.$lt{'ncms'}.'</h3>';
}
} else {
my %sel;
foreach my $option (keys(%options)) {
if ($option eq $viewsettings{'show'}) {
$sel{$option} = ' selected="selected"';
} else {
$sel{$option} = '';
}
}
my ($checkedon,$checkedoff);
if ($viewsettings{'optin'}) {
$checkedon = ' checked="checked"';
} else {
$checkedoff = ' checked="checked"';
}
my $forceedit;
if ($env{'form.forceedit'}) {
$forceedit = 1;
}
my $hiddenaction;
if ($caller eq '/adm/createuser') {
$hiddenaction = '<input type="hidden" name="action" value="calist" />'."\n";
}
$output = '<h3>'.$lt{'cloc'}.'</h3>'."\n".
'<form method="post" name="display" action="'.$caller.'">'."\n".
'<input type="hidden" name="caller" value="'.$caller.'" />'."\n".
'<input type="hidden" name="state" value="setconfig" />'."\n".
'<input type="hidden" name="forceedit" value="'.$forceedit.'" />'."\n".
$hiddenaction.
&Apache::loncommon::start_data_table().
&Apache::loncommon::start_data_table_header_row().
'<th>'.$lt{'set'}.'</th><th>'.$lt{'val'}.'</th>'.
&Apache::loncommon::end_data_table_header_row().
&Apache::loncommon::start_data_table_row().
'<td>'.
$titles{'coauthorlist'}.'</td>'.
'<td><select name="coauthorlist">'.
'<option value="none"'.$sel{'none'}.'>'.$options{'none'}.'</option>'.
'<option value="role"'.$sel{'role'}.'>'.$options{'role'}.'</option>'.
'<option value="all"'.$sel{'all'}.'>'.$options{'all'}.'</option>'.
'</select></td>'.
&Apache::loncommon::end_data_table_row().
&Apache::loncommon::start_data_table_row().
'<td>'.$titles{'coauthoroptin'}.'</td>'.
'<td><span class="LC_nobreak">'.
'<label><input type="radio" name="coauthoroptin" value="0" '.
$checkedoff.' />'.$lt{'no'}.'</label> '.
'<label><input type="radio" name="coauthoroptin" value="1" '.
$checkedon.' />'.$lt{'yes'}.'</label>'.
'</span></td>'.
&Apache::loncommon::end_data_table_row().
&Apache::loncommon::end_data_table().
'<br clear="all" />'.
'<input type="submit" value="'.$lt{'sav'}.'" />'.
'</form>';
}
return $output;
}
sub print_coauthors {
my ($r,$auname,$audom,$role,$caller,$settingsref) = @_;
my %viewsettings;
if (ref($settingsref) eq 'HASH') {
%viewsettings = %{$settingsref};
} else {
%viewsettings =
&Apache::lonviewcoauthors::&retrieve_view_settings($auname,$audom,$role);
}
my %lt = &Apache::lonlocal::texthash (
cvl => 'Coauthor-viewable listing',
nam => 'Name',
usr => 'Username:Domain',
rol => 'Role(s)',
and => 'and',
utd => 'Unable to determine Authoring Space context',
);
if (($auname ne '') && ($audom ne '')) {
my (%shownstatus,%coauthors);
$r->print("<h3>$lt{'cvl'}</h3>");
if ($env{'form.action'} eq 'setenv') {
$r->print(&process_coauthor_prefs($auname,$audom,$caller));
}
if ($viewsettings{'optin'}) {
if ($env{'request.role'} =~ /^(ca|aa)/) {
$r->print(&coauthor_listing_form($auname,$audom,$caller));
}
%shownstatus = &Apache::lonnet::dump('showncoauthors',$audom,$auname);
}
my $fullcount = 0;
my $viewablecount = 0;
my $displaycount = 0;
my $getmanagers = 1;
my ($output,$roletype);
my @showroles;
if ($env{'request.role'} eq "au./$env{'user.domain'}/") {
@showroles = ('ca','aa');
} elsif ($viewsettings{'show'} eq 'role') {
($roletype) = ($env{'request.role'} =~ m{^(ca|aa)\./$audom/$auname$});
if ($roletype ne '') {
@showroles = ($roletype);
if ($roletype eq 'aa') {
undef($getmanagers);
}
}
} else {
@showroles = ('ca','aa');
}
my %coauthors = &Apache::lonnet::get_my_roles($auname,$audom,undef,undef,
\@showroles);
my (%userinfo,%showuser);
foreach my $item (keys(%coauthors)) {
my ($username,$domain,$userrole) = split(/:/,$item);
next if (($username eq '') && ($domain eq''));
my ($start,$end) = split(/:/,$coauthors{$item});
next if ($start eq '-1' && $end eq '-1');
if (ref($userinfo{$username.':'.$domain}) eq 'HASH') {
if (ref($userinfo{$username.':'.$domain}{roles}) eq 'ARRAY') {
unless (grep(/^$userrole$/,@{$userinfo{$username.':'.$domain}{roles}})) {
push(@{$userinfo{$username.':'.$domain}{roles}},$userrole);
}
} else {
$userinfo{$username.':'.$domain}{roles} = [$userrole];
}
} else {
$userinfo{$username.':'.$domain}{fullname} =
&Apache::loncommon::plainname($username,$domain,'lastname');
$userinfo{$username.':'.$domain}{roles} = [$userrole];
}
if ($viewsettings{'optin'}) {
if ($shownstatus{$username.':'.$domain}) {
$showuser{$username.':'.$domain} = $userinfo{$username.':'.$domain};
}
} else {
$showuser{$username.':'.$domain} = $userinfo{$username.':'.$domain};
}
}
$fullcount = scalar(keys(%userinfo));
$viewablecount = scalar(keys(%showuser));
my @rolenames = map { &Apache::lonnet::plaintext($_); } ('ca','aa');
if ($viewsettings{'optin'}) {
$displaycount = $viewablecount;
if ($fullcount > $viewablecount) {
if ($viewablecount) {
$output = &mt('Only users who have opted to be listed ([_1] out of [_2] users) are shown.',
$viewablecount,$fullcount).'<br />';
} else {
if ($fullcount == 1) {
if ($roletype) {
$output = &mt('The one user with a [_1] role has opted not to be listed.',
&Apache::lonnet::plaintext($roletype));
} else {
$output = &mt('The one user with a [_1] or [_2] role has opted not to be listed.',
$rolenames[0],$rolenames[1]);
}
} else {
if ($roletype) {
$output = &mt('None of the [_1] users with a [_2] role have opted to be listed.',
$fullcount,&Apache::lonnet::plaintext($roletype));
} else {
$output = &mt('None of the [_1] users with a [_2] or [_3] role have opted to be listed.',
$fullcount,$rolenames[0],$rolenames[1]);
}
}
}
} else {
if ($fullcount > 1) {
if ($roletype) {
$output = &mt('All [_1] users with a [_2] role have opted to be listed.',
$fullcount,&Apache::lonnet::plaintext($roletype));
} else {
$output = &mt('All [_1] users with a [_2] or [_3] role have opted to be listed.',
$fullcount,$rolenames[0],$rolenames[1]);
}
} elsif ($fullcount == 1) {
if ($roletype) {
$output = &mt('The one user with a [_1] role has opted to be listed.',
&Apache::lonnet::plaintext($roletype));
} else {
$output = &mt('The one user with a [_1] or [_2] role has opted to be listed.',
$rolenames[0],$rolenames[1]);
}
} else {
if ($roletype) {
$output = &mt('There are no users with a [_1] role.',
&Apache::lonnet::plaintext($roletype));
} else {
$output = &mt('There are no users with a [_1] or [_2] role.',
$rolenames[0],$rolenames[1]);
}
}
}
} else {
$displaycount = $fullcount;
if ($fullcount > 1) {
if ($roletype) {
$output = &mt('All [_1] users with a [_2] role are shown.',
$fullcount,&Apache::lonnet::plaintext($roletype));
} else {
$output = &mt('All [_1] users with a [_2] or [_3] role are shown.',
$fullcount,$rolenames[0],$rolenames[1]);
}
} elsif ($fullcount == 1) {
if ($roletype) {
$output = &mt('The one user with a [_1] role is shown.',
&Apache::lonnet::plaintext($roletype));
} else {
$output = &mt('The one user with a [_1] or [_2] role is shown.',
$rolenames[0],$rolenames[1]);
}
} else {
if ($roletype) {
$output = &mt('There are no users with a [_1] role.',
&Apache::lonnet::plaintext($roletype));
} else {
$output = &mt('There are no users with a [_1] or [_2] role.',
$rolenames[0],$rolenames[1]);
}
}
}
if ($displaycount) {
$r->print('<h4>'.$output.'</h4>');
my $table = '<br />'.&Apache::loncommon::start_data_table()."\n".
&Apache::loncommon::start_data_table_header_row()."\n".
'<th></th>'. # for the count
'<th>'.$lt{'nam'}.'</th>'.
'<th>'.$lt{'usr'}.'</th>';
unless ($roletype) {
$table .= '<th>'.$lt{'rol'}.'</th>';
}
$table .= &Apache::loncommon::end_data_table_header_row()."\n";
my $count = 0;
my %camanagers;
if ($getmanagers) {
my %userenv = &Apache::lonnet::userenvironment($audom,$auname,
'authormanagers');
map { $camanagers{$_} = 1; } split(/,/,$userenv{'authormanagers'});
}
my @sorted = sort {
lc($showuser{$a}{fullname}) cmp lc($showuser{$b}{fullname})
} (keys(%showuser));
foreach my $user (@sorted) {
my ($username,$domain) = split(/:/,$user);
$count ++;
$table .= &Apache::loncommon::start_data_table_row()."\n".
'<td>'.$count.'</td>'.
'<td>';
if ($camanagers{$user}) {
$table .= '<span style="font-face:bold;">*</span>';
} else {
$table .= ' 'x2;
}
$table .= &Apache::loncommon::aboutmewrapper($showuser{$user}{fullname},
$username,$domain).
'</td>'.
'<td>'.&Apache::loncommon::messagewrapper
('<img src="/adm/lonIcons/mailto.gif" border="0" /> '.
$user,$username,$domain).
'</td>';
unless ($roletype) {
$table .= '<td>'.
join(" $lt{'and'} ", map { &Apache::lonnet::plaintext($_); }
@{$showuser{$user}{roles}}).
'</td>';
}
$table .= &Apache::loncommon::end_data_table_row()."\n";
}
$table .= &Apache::loncommon::end_data_table()."\n";
$r->print($table);
if (keys(%camanagers)) {
$r->print('<br /><span class="LC_fontsize_medium">'.
&mt('[_1]*[_2] indicates co-author can add/revoke co-author roles',
'<span style="font-face:bold;">','</span>').
'</span>');
}
} else {
$r->print('<div class="LC_info">'.$output.'</div>');
}
} else {
$r->print('<div class="LC_warning"'.$lt{'utd'}.'</div>');
}
return;
}
sub coauthor_listing_form {
my ($auname,$audom,$caller) = @_;
my $showinlist = $env{"environment.internal.showinlist./$audom/$auname"};
my ($showoff,$showon);
if ($showinlist) {
$showon = ' checked="checked" ';
$showoff = ' ';
} else {
$showoff = ' checked="checked" ';
$showon = ' ';
}
my %lt = &Apache::lonlocal::texthash (
yls => 'Your listing status',
yci => 'You are currently included in the coauthor-viewable listing.',
iyl => 'Include yourself in the listing?',
y => 'Yes',
n => 'No',
sav => 'Save changes',
);
my $output =
'<div class="LC_left_float">'
.'<fieldset><legend>'.$lt{'yls'}.'</legend>';
if ($showinlist) {
$output .= $lt{'yci'};
} else {
$output .= &mt('You are currently [_1]not[_2] included in the coauthor-viewable listing.','<b>','</b>');
}
$output .= '<br />'.$lt{'iyl'}.' '.
'<form name="coauthorparm" method="post" action="'.$caller.'">'.
'<span class="LC_nobreak">'.
'<label><input type="radio" name="showinlist" value="1"'.$showon.'/>'.$lt{'y'}.'</label> <label>'.
'<input type="radio" name="showinlist" value="0"'.$showoff.'/>'.$lt{'n'}.
'</label></span><br /><br />'.
'<input type="hidden" name="action" value="setenv" />'.
'<input type="submit" name="coauthorsubmit" value="'.$lt{'sav'}.'" />'.
'</form></fieldset></div><br clear="all" />';
return $output;
}
sub process_coauthor_prefs {
my ($auname,$audom,$caller) = @_;
my $uname = $env{'user.name'};
my $udom = $env{'user.domain'};
my $user = $uname.':'.$udom;
my %shown = &Apache::lonnet::get('showncoauthors',[$user],$audom,$auname);
my %lt = &Apache::lonlocal::texthash (
on => 'on',
off => 'off',
err => 'Error occurred saving display setting.',
);
my $visibility = $lt{'off'};
my $showinlist = $env{'form.showinlist'};
if ($showinlist) {
$visibility = $lt{'on'};
}
my $listed = 0;
if ($shown{$user}) {
$listed = 1;
}
my $output;
if ($listed ne $showinlist) {
my %changeHash = (
"internal.showinlist./$audom/$auname" => $showinlist,
);
my $putresult = &Apache::lonnet::put('environment',
\%changeHash,$udom,$uname);
if ($putresult eq 'ok') {
&Apache::lonnet::appenv({"environment.internal.showinlist./$audom/$auname" => $showinlist});
my $result = &Apache::lonnet::put('showncoauthors',{$user => $showinlist,},$audom,$auname);
if ($result eq 'ok') {
$output .=
&Apache::lonhtmlcommon::confirm_success(
&mt("Display of your name in the coauthor-viewable listing set to [_1].",'<b>'.$visibility.'</b>'));
} else {
$output .= &Apache::lonhtmlcommon::confirm_success($lt{'err'},1);
}
} else {
$output .= &Apache::lonhtmlcommon::confirm_success($lt{'err'},1);
}
} else {
$output .=
&Apache::lonhtmlcommon::confirm_success(
&mt("Display of your name in the coauthor-viewable listing unchanged (set to [_1]).",'<b>'.$visibility.'</b>'));
}
$output = &Apache::loncommon::confirmwrapper($output);
return $output;
}
1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>