# The LearningOnline Network with CAPA
# Handler to show and edit custom distribution rights
#
# $Id: lonrights.pm,v 1.36 2023/07/13 22:21:26 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::lonrights;
use strict;
use Apache::Constants qw(:common :http);
use Apache::lonnet;
use Apache::loncommon();
use HTML::LCParser;
use Apache::File;
use Apache::lonlocal;
sub handler {
my $r=shift;
my $target = $env{'form.grade_target'};
if ($target eq 'meta') {
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
$env{'request.uri'}=$r->uri;
my $file = &Apache::lonnet::filelocation("",$r->uri);
my $content=&Apache::lonnet::getfile($file);
my $result=&Apache::lonxml::xmlparse(undef,'meta',$content);
$r->print($result);
return OK;
}
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
my $text = 'Authoring Space';
my $href = &Apache::loncommon::authorspace($r->uri);
my ($crsauthor,$cdom,$cnum);
if ($env{'request.course.id'}) {
$cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
$cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
if ($href eq "/priv/$cdom/$cnum/") {
$crsauthor = 1;
$text = 'Course Authoring Space';
}
}
# Breadcrumbs
&Apache::lonhtmlcommon::clear_breadcrumbs();
&Apache::lonhtmlcommon::add_breadcrumb({
'text' => $text,
'href' => $href,
});
if ($crsauthor) {
&Apache::lonhtmlcommon::add_breadcrumb({
'text' => 'Custom Rights',
'title' => 'Custom Distribution Rights',
'href' => '',});
} else {
&Apache::lonhtmlcommon::add_breadcrumb({
'text' => 'Custom Rights Editor',
'title' => 'Custom Distribution Rights Editor',
'href' => '',});
}
my $js = &Apache::loncommon::coursebrowser_javascript().
&Apache::loncommon::studentbrowser_javascript();
# Breadcrumbs are included by &start_page
$r->print(&Apache::loncommon::start_page('Custom Distribution Rights',$js)
.&Apache::loncommon::head_subbox(
&Apache::loncommon::CSTR_pageheader())
);
$r->rflush();
my $uri=$r->uri;
my $fn=&Apache::lonnet::filelocation('',$uri);
my $contents='';
my $constructmode=($uri=~ m{^/priv/});
if ($constructmode) {
if (($crsauthor) && ($uri eq "/priv/$cdom/$cnum/default.rights")) {
undef($constructmode);
}
}
# ============================================================ Modify and store
if ($constructmode && $env{'form.store'}) {
my @newrules;
# read rules from form
foreach my $key (keys(%env)) {
next if ($key!~/^form\.effect\_(\d+)$/);
my $number=$1;
my %rulehash;
foreach my $action ('effect','type','domain','course','section','role') {
$rulehash{$action}=$env{'form.'.$action.'_'.$number};
}
if ($rulehash{'type'} !~ /^(user|course)$/) {
$rulehash{'type'} = 'course';
}
if ($rulehash{'type'} eq 'user') {
$rulehash{'section'}='';
$rulehash{'role'}='';
}
if ($rulehash{'role'} eq 'au') {
$rulehash{'course'}='';
$rulehash{'section'}='';
}
if ($rulehash{'role'} eq 'cc') {
$rulehash{'section'}='';
}
unless (($rulehash{'effect'} eq 'deny') ||
($rulehash{'effect'} eq 'allow')) {
$rulehash{'effect'}='deny';
}
$rulehash{'domain'} =
&LONCAPA::clean_domain($rulehash{'domain'});
if ($rulehash{'type'} eq 'course') {
$rulehash{'course'} =
&LONCAPA::clean_courseid($rulehash{'course'});
} else {
$rulehash{'course'} =
&LONCAPA::clean_username($rulehash{'course'});
}
$rulehash{'section'}=~s/\W//g;
if (!$rulehash{'domain'}) {
$rulehash{'domain'}=$env{'user.domain'};
}
my $realm='';
my $separator = ($rulehash{'type'} eq 'course') ? '_' : '/';
if ($number) {
$realm=$rulehash{'domain'};
if ($rulehash{'course'}) {
$realm.=$separator.$rulehash{'course'};
}
if ($rulehash{'section'}) {
$realm.=$separator.$rulehash{'section'};
}
}
$newrules[$number]=$rulehash{'effect'}.':'.
$realm.':'.$rulehash{'role'}.':'.$rulehash{'type'};
}
# edit actions?
foreach my $key (keys(%env)) {
next if ($key!~/^form\.action\_(\d+)$/);
my $number=$1;
if ($env{$key} eq 'delete') { splice(@newrules,$number,1); }
if (($env{$key} eq 'moveup') && ($number>1)) {
@newrules[$number-1,$number] = @newrules[$number,$number-1];
}
if (($env{$key} eq 'movedown') && ($number<$#newrules)) {
@newrules[$number+1,$number] = @newrules[$number,$number+1];
}
if ($env{$key} eq 'insertabove') {
splice(@newrules,$number,0,'deny');
}
if ($env{$key} eq 'insertbelow') {
splice(@newrules,$number+1,0,'deny');
}
}
# store file
my $fh=Apache::File->new('>'.$fn);
foreach (my $i=0;$i<=$#newrules;$i++) {
if ($newrules[$i]) {
my ($effect,$realm,$role,$type)=split(/\:/,$newrules[$i]);
print $fh
"<accessrule effect='$effect' realm='$realm' role='$role' type='$type' />\n";
}
}
$fh->close;
}
# ============================================================ Read and display
unless ($constructmode) {
# =========================================== This is not in construction space
$contents=&Apache::lonnet::getfile($fn);
if ($contents==-1) { $contents=''; }
} else {
# =============================================== This is in construction space
if (-e $fn) {
my $fh=Apache::File->new($fn);
$contents=join('',<$fh>);
$fh->close();
}
$r->print('<form name="rules" method="post" action="">');
}
unless ($contents=~/\<accessrule/s) {
$contents='<accessrule effect="deny" />';
}
my $parser=HTML::LCParser->new(\$contents);
my $token;
my $rulecounter=0;
my $colzero=&mt($constructmode?'Edit action':'Rule');
my %lt=&Apache::lonlocal::texthash(
'ef' => 'Effect',
'ty' => 'Type',
'do' => 'Domain',
'co' => 'Course / User',
'se' => 'Section',
'ro' => 'Role');
my %iconimg = ('allow' => '<img src="/adm/lonIcons/navmap.correct.gif"'
.' alt="'.&mt('allow').'" title="'.&mt('allow').'" />',
'deny' => '<img src="/adm/lonIcons/navmap.wrong.gif"'
.' alt="'.&mt('deny').'" title="'.&mt('deny').'" />');
# ---------------------------------------------------------- Start table output
$r->print(&Apache::loncommon::start_data_table().
&Apache::loncommon::start_data_table_header_row().
"<th>$colzero</th><th>$lt{'ef'}</th><th>$lt{'ty'}</th><th>$lt{'do'}</th>".
"<th>$lt{'co'}</th><th>$lt{'se'}</th><th>$lt{'ro'}</th>".
&Apache::loncommon::end_data_table_header_row());
# --------------------------------------------------------------------- Default
# Fast forward to first rule
$token=$parser->get_token;
while ($token->[1] ne 'accessrule') { $token=$parser->get_token; }
# print default
$r->print(&Apache::loncommon::start_data_table_row().'<td align="right">');
if ($constructmode) {
$r->print(&Apache::loncommon::select_form('','action_0',
{'' => '',
'insertbelow' => &mt('Insert rule below')}));
} else {
$r->print(' ');
}
$r->print('</td><td>');
$r->print($iconimg{$token->[2]->{'effect'}});
if ($constructmode) {
my %lt = &Apache::lonlocal::texthash
('allow' => 'allow',
'deny' => 'deny');
$r->print(&Apache::loncommon::select_form
($token->[2]->{'effect'},'effect_0',\%lt));
}
$r->print('</td><td colspan="5">'.&mt('Default'));
if (($token->[2]->{'realm'}) || ($token->[2]->{'role'})) {
$r->print(' - <span class="LC_error">'.&mt('Error! No default set.').
'</span>');
}
$r->print('</td>'.&Apache::loncommon::end_data_table_row());
# Additional roles
while ($token=$parser->get_token) {
if (($token->[0] eq 'S') && ($token->[1] eq 'accessrule')) {
$rulecounter++;
$r->print(&Apache::loncommon::start_data_table_row().
'<td align="right" rowspan="2">');
# insert, delete, etc
$r->print('<span class="LC_nobreak">'.$rulecounter.'. ');
if ($constructmode) {
my %lt = &Apache::lonlocal::texthash
('' => '',
'delete' => 'Delete this rule',
'insertabove' => 'Insert rule above',
'insertbelow' => 'Insert rule below',
'moveup' => 'Move rule up',
'movedown' => 'Move rule down'
);
$r->print(&Apache::loncommon::select_form(
'','action_'.$rulecounter,\%lt));
}
$r->print('</span></td>'.
'<td rowspan="2">');
# effect
$r->print($iconimg{$token->[2]->{'effect'}});
if ($constructmode) {
my %lt = &Apache::lonlocal::texthash
('allow' => 'allow',
'deny' => 'deny');
$r->print(&Apache::loncommon::select_form
($token->[2]->{'effect'},
'effect_'.$rulecounter,\%lt));
}
# type
$r->print('</td><td rowspan="2">');
my $type = ($token->[2]{'type'} || 'course');
if ($constructmode) {
my %lt = &Apache::lonlocal::texthash
('course' => 'Course',
'user' => 'User');
$r->print(&Apache::loncommon::select_form($type,
'type_'.$rulecounter,\%lt));
} else {
$r->print(&mt($type));
}
# ---- realm
my $realm=$token->[2]->{'realm'};
my ($rdom,$rcourse,$rsec);
if ($type eq 'course') {
($rdom,$rcourse,$rsec) = split(m{[/_]},$realm,3);
$rcourse = &LONCAPA::clean_courseid($rcourse);
} else {
($rdom,$rcourse,$rsec) = split(m{/},$realm,3);
$rcourse = &LONCAPA::clean_username($rcourse);
}
$r->print('</td><td>');
# realm domain
if ($constructmode) {
unless ($rdom) { $rdom=$env{'user.domain'}; }
$r->print(&Apache::loncommon::select_dom_form($rdom,
'domain_'.$rulecounter));
} else {
$r->print($rdom);
}
$r->print('</td><td>');
# realm course
if ($constructmode) {
$r->print('<input type="text" size="25" name="course_'.
$rulecounter.'" value="'.$rcourse.'" />');
} else {
$r->print($rcourse);
}
$r->print('</td><td rowspan="2">');
# realm section
if ($type eq 'course') {
if ($constructmode) {
$r->print('<input type="text" size="5" name="section_'.
$rulecounter.'" value="'.$rsec.'" />');
} else {
$r->print($rsec);
}
}
$r->print('</td><td rowspan="2">');
# role
if ($type eq 'course') {
if ($constructmode) {
my %hash=('' => '');
foreach ('au','cc','in','ta','st') {
$hash{$_}=&Apache::lonnet::plaintext($_);
}
my $role=$token->[2]->{'role'};
unless ($role) { $role=''; }
$r->print(&Apache::loncommon::select_form(
$role,'role_'.$rulecounter,\%hash));
} else {
$r->print(&Apache::lonnet::plaintext($token->[2]->{'role'}));
}
}
# course selection link
$r->print('</td>'.
&Apache::loncommon::end_data_table_row().
&Apache::loncommon::continue_data_table_row().
'<td colspan="2" align="right">');
if ($type eq 'course') {
if ($rcourse) {
my %descript=
&Apache::lonnet::coursedescription($rdom.'_'.$rcourse,
{'one_time' => 1});
$r->print($descript{'description'}.' ');
}
if ($constructmode) {
$r->print(&Apache::loncommon::selectcourse_link('rules',
'course_'.$rulecounter,'domain_'.$rulecounter));
}
} else {
if ($rcourse) {
my $name = &Apache::loncommon::plainname($rcourse,$rdom);
$r->print($name.' ');
}
if ($constructmode) {
$r->print(&Apache::loncommon::selectstudent_link('rules','course_'.$rulecounter,'domain_'.$rulecounter));
}
}
# close row
$r->print('</td>'.&Apache::loncommon::end_data_table_row());
}
}
$r->print(&Apache::loncommon::end_data_table());
# ------------------------------------------------------------ End table output
if ($constructmode) {
$r->print('<input type="submit" name="store" value="'.&mt('Save').'" /></form>');
}
$r->print(&Apache::loncommon::end_page());
return OK;
}
1;
__END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>