--- loncom/interface/loncommon.pm 2005/11/21 21:06:59 1.297
+++ loncom/interface/loncommon.pm 2006/05/01 20:48:55 1.359
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# a pile of common routines
#
-# $Id: loncommon.pm,v 1.297 2005/11/21 21:06:59 raeburn Exp $
+# $Id: loncommon.pm,v 1.359 2006/05/01 20:48:55 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -58,10 +58,12 @@ use strict;
use Apache::lonnet;
use GDBM_File;
use POSIX qw(strftime mktime);
-use Apache::Constants qw(:common :http :methods);
use Apache::lonmenu();
use Apache::lonlocal;
use HTML::Entities;
+use Apache::lonhtmlcommon();
+use Apache::loncoursedata();
+use Apache::lontexconvert();
my $readit;
@@ -74,7 +76,7 @@ my %language;
my %supported_language;
my %cprtag;
my %scprtag;
-my %fe; my %fd;
+my %fe; my %fd; my %fm;
my %category_extensions;
# ---------------------------------------------- Designs
@@ -105,10 +107,10 @@ BEGIN {
my $langtabfile = $Apache::lonnet::perlvar{'lonTabDir'}.
'/language.tab';
if ( open(my $fh,"<$langtabfile") ) {
- while (<$fh>) {
- next if /^\#/;
- chomp;
- my ($key,$two,$country,$three,$enc,$val,$sup)=(split(/\t/,$_));
+ while (my $line = <$fh>) {
+ next if ($line=~/^\#/);
+ chomp($line);
+ my ($key,$two,$country,$three,$enc,$val,$sup)=(split(/\t/,$line));
$language{$key}=$val.' - '.$enc;
if ($sup) {
$supported_language{$key}=$sup;
@@ -122,24 +124,24 @@ BEGIN {
my $copyrightfile = $Apache::lonnet::perlvar{'lonIncludes'}.
'/copyright.tab';
if ( open (my $fh,"<$copyrightfile") ) {
- while (<$fh>) {
- next if /^\#/;
- chomp;
- my ($key,$val)=(split(/\s+/,$_,2));
+ while (my $line = <$fh>) {
+ next if ($line=~/^\#/);
+ chomp($line);
+ my ($key,$val)=(split(/\s+/,$line,2));
$cprtag{$key}=$val;
}
close($fh);
}
}
-# ------------------------------------------------------------------ source copyrights
+# ----------------------------------------------------------- source copyrights
{
my $sourcecopyrightfile = $Apache::lonnet::perlvar{'lonIncludes'}.
'/source_copyright.tab';
if ( open (my $fh,"<$sourcecopyrightfile") ) {
- while (<$fh>) {
- next if /^\#/;
- chomp;
- my ($key,$val)=(split(/\s+/,$_,2));
+ while (my $line = <$fh>) {
+ next if ($line =~ /^\#/);
+ chomp($line);
+ my ($key,$val)=(split(/\s+/,$line,2));
$scprtag{$key}=$val;
}
close($fh);
@@ -157,10 +159,10 @@ BEGIN {
{
my $designfile = $designdir.'/'.$filename;
if ( open (my $fh,"<$designfile") ) {
- while (<$fh>) {
- next if /^\#/;
- chomp;
- my ($key,$val)=(split(/\=/,$_));
+ while (my $line = <$fh>) {
+ next if ($line =~ /^\#/);
+ chomp($line);
+ my ($key,$val)=(split(/\=/,$line));
if ($val) { $designhash{$domain.'.'.$key}=$val; }
}
close($fh);
@@ -176,10 +178,10 @@ BEGIN {
my $categoryfile = $Apache::lonnet::perlvar{'lonTabDir'}.
'/filecategories.tab';
if ( open (my $fh,"<$categoryfile") ) {
- while (<$fh>) {
- next if /^\#/;
- chomp;
- my ($extension,$category)=(split(/\s+/,$_,2));
+ while (my $line = <$fh>) {
+ next if ($line =~ /^\#/);
+ chomp($line);
+ my ($extension,$category)=(split(/\s+/,$line,2));
push @{$category_extensions{lc($category)}},$extension;
}
close($fh);
@@ -191,13 +193,14 @@ BEGIN {
my $typesfile = $Apache::lonnet::perlvar{'lonTabDir'}.
'/filetypes.tab';
if ( open (my $fh,"<$typesfile") ) {
- while (<$fh>) {
- next if (/^\#/);
- chomp;
- my ($ending,$emb,$descr)=split(/\s+/,$_,3);
+ while (my $line = <$fh>) {
+ next if ($line =~ /^\#/);
+ chomp($line);
+ my ($ending,$emb,$mime,$descr)=split(/\s+/,$line,4);
if ($descr ne '') {
$fe{$ending}=lc($emb);
$fd{$ending}=$descr;
+ if ($mime ne 'unk') { $fm{$ending}=$mime; }
}
}
close($fh);
@@ -331,7 +334,10 @@ sub storeresurl {
sub studentbrowser_javascript {
unless (
(($env{'request.course.id'}) &&
- (&Apache::lonnet::allowed('srm',$env{'request.course.id'})))
+ (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
+ || &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
+ '/'.$env{'request.course.sec'})
+ ))
|| ($env{'request.role'}=~/^(au|dc|su)/)
) { return ''; }
return (<<'ENDSTDBRW');
@@ -362,7 +368,9 @@ ENDSTDBRW
sub selectstudent_link {
my ($form,$unameele,$udomele)=@_;
if ($env{'request.course.id'}) {
- unless (&Apache::lonnet::allowed('srm',$env{'request.course.id'})) {
+ if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'})
+ && !&Apache::lonnet::allowed('srm',$env{'request.course.id'}.
+ '/'.$env{'request.course.sec'})) {
return '';
}
return "$text ";
}
my $nothing=&Apache::lonhtmlcommon::javascript_nothing();
- my $html=&Apache::lonxml::xmlbegin();
my $helpicon=&lonhttpdurl("/adm/lonIcons/helpgateway.gif");
+ my $start_page =
+ &Apache::loncommon::start_page('Help Menu', undef,
+ {'frameset' => 1,
+ 'js_ready' => 1,
+ 'add_entries' => {
+ 'border' => '0',
+ 'rows' => "105,*",},});
+ my $end_page =
+ &Apache::loncommon::end_page({'frameset' => 1,
+ 'js_ready' => 1,});
+
$template .= <<"ENDTEMPLATE";
}{}xmsg;
+
+ return $result;
+}
+
+sub validate_page {
+ if ( exists($env{'internal.start_page'})
+ && $env{'internal.start_page'} > 1) {
+ &Apache::lonnet::logthis('start_page called multiple times '.
+ $env{'internal.start_page'}.' '.
+ $ENV{'request.filename'});
+ }
+ if ( exists($env{'internal.end_page'})
+ && $env{'internal.end_page'} > 1) {
+ &Apache::lonnet::logthis('end_page called multiple times '.
+ $env{'internal.end_page'}.' '.
+ $env{'request.filename'});
+ }
+ if ( exists($env{'internal.start_page'})
+ && ! exists($env{'internal.end_page'})) {
+ &Apache::lonnet::logthis('start_page called without end_page '.
+ $env{'request.filename'});
+ }
+ if ( ! exists($env{'internal.start_page'})
+ && exists($env{'internal.end_page'})) {
+ &Apache::lonnet::logthis('end_page called without start_page'.
+ $env{'request.filename'});
+ }
+}
+
+sub simple_error_page {
+ my ($r,$title,$msg) = @_;
+ my $page =
+ &Apache::loncommon::start_page($title).
+ &mt($msg).
+ &Apache::loncommon::end_page();
+ if (ref($r)) {
+ $r->print($page);
+ return;
+ }
+ return $page;
+}
+
+{
+ my $row_count;
+ sub start_data_table {
+ undef($row_count);
+ return '
';
+ }
+
+ sub end_data_table {
+ undef($row_count);
+ return '
';
+ }
+
+ sub start_data_table_row {
+ $row_count++;
+ return '';
+ }
+
+ sub end_data_table_row {
+ return ' ';
+ }
+}
+
###############################################
=pod
+=over 4
+
=item get_users_function
Used by &bodytag to determine the current users primary role.
@@ -3084,6 +3770,61 @@ sub get_sections {
}
###############################################
+
+=pod
+
+=item coursegroups
+
+Retrieve information about groups in a course,
+
+Input:
+1. Reference to hash to populate with group information.
+2. Optional course domain
+3. Optional course number
+4. Optional group name
+
+Course domain and number will be taken from user's
+environment if not supplied. Optional group name will'
+be passed to lonnet::get_coursegroups() as a regexp to
+use in the call to the dump function.
+
+Output
+Returns number of groups in the course (subject to the
+optional group name filter).
+
+Side effects:
+Populates the referenced curr_groups hash, with key,
+value pairs. Keys are group names, corresponding values
+are scalars containing group information in XML. This
+can be sent to &get_group_settings() to be parsed.
+
+=cut
+
+###############################################
+
+sub coursegroups {
+ my ($curr_groups,$cdom,$cnum,$group) = @_;
+ my $numgroups;
+ if (!defined($cdom) || !defined($cnum)) {
+ my $cid = $env{'request.course.id'};
+ $cdom = $env{'course.'.$cid.'.domain'};
+ $cnum = $env{'course.'.$cid.'.num'};
+ }
+ %{$curr_groups} = &Apache::lonnet::get_coursegroups($cdom,$cnum,$group);
+ my ($tmp) = keys(%{$curr_groups});
+ if ($tmp=~/^error:/) {
+ unless ($tmp eq 'error: 2 tie(GDBM) Failed while attempting dump') {
+ &logthis('Error retrieving groups: '.$tmp.' in '.$cnum.':'.
+ $cdom);
+ }
+ $numgroups = 0;
+ } else {
+ $numgroups = keys(%{$curr_groups});
+ }
+ return $numgroups;
+}
+
+###############################################
=pod
@@ -3093,7 +3834,7 @@ Uses TokeParser to extract group informa
XML used to describe course groups.
Input:
-Scalar containing XML (as retrieved from &lonnet::get_coursegroups).
+Scalar containing XML - as retrieved from &coursegroups().
Output:
Hash containing group information as key=values for (a), and
@@ -3110,7 +3851,7 @@ times for group members.
Outer hash key is functions.
Inner hash keys are chat,discussion,email,files,homepage,roster.
Corresponding values are either on or off, depending on
-whther this type of functionality is available for the group.
+whether this type of functionality is available for the group.
=cut
@@ -3121,13 +3862,18 @@ sub get_group_settings {
my $parser=HTML::TokeParser->new(\$groupinfo);
my $token;
my $tool = '';
+ my $role = '';
my %content=();
while ($token=$parser->get_token) {
if ($token->[0] eq 'S') {
my $entry=$token->[1];
- if ($entry eq 'functions') {
+ if ($entry eq 'functions' || $entry eq 'autosec') {
%{$content{$entry}} = ();
$tool = $entry;
+ } elsif ($entry eq 'role') {
+ if ($tool eq 'autosec') {
+ $role = $token->[2]{id};
+ }
} else {
my $value=$parser->get_text('/'.$entry);
if ($entry eq 'name') {
@@ -3137,14 +3883,24 @@ sub get_group_settings {
}
} elsif ($entry eq 'groupname') {
$content{$entry}=&Apache::lonnet::unescape($value);
+ } elsif (($entry eq 'roles') || ($entry eq 'types') ||
+ ($entry eq 'sectionpick') || ($entry eq 'defpriv')) {
+ push(@{$content{$entry}},$value);
+ } elsif ($entry eq 'section') {
+ if ($tool eq 'autosec' && $role ne '') {
+ push(@{$content{$tool}{$role}},$value);
+ }
} else {
$content{$entry}=$value;
}
}
} elsif ($token->[0] eq 'E') {
- if ($token->[1] eq 'functions') {
+ if ($token->[1] eq 'functions' || $token->[1] eq 'autosec') {
$tool = '';
+ } elsif ($token->[1] eq 'role') {
+ $role = '';
}
+
}
}
return %content;
@@ -3293,78 +4049,6 @@ sub get_user_info {
return;
}
-###############################################
-
-sub get_posted_cgi {
- my $r=shift;
-
- my $buffer;
- if ($r->header_in('Content-length')) {
- $r->read($buffer,$r->header_in('Content-length'),0);
- }
- unless ($buffer=~/^(\-+\w+)\s+Content\-Disposition\:\s*form\-data/si) {
- my @pairs=split(/&/,$buffer);
- my $pair;
- foreach $pair (@pairs) {
- my ($name,$value) = split(/=/,$pair);
- $value =~ tr/+/ /;
- $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
- $name =~ tr/+/ /;
- $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
- &add_to_env("form.$name",$value);
- }
- } else {
- my $contentsep=$1;
- my @lines = split (/\n/,$buffer);
- my $name='';
- my $value='';
- my $fname='';
- my $fmime='';
- my $i;
- for ($i=0;$i<=$#lines;$i++) {
- if ($lines[$i]=~/^$contentsep/) {
- if ($name) {
- chomp($value);
- if ($fname) {
- $env{"form.$name.filename"}=$fname;
- $env{"form.$name.mimetype"}=$fmime;
- } else {
- $value=~s/\s+$//s;
- }
- &add_to_env("form.$name",$value);
- }
- if ($i<$#lines) {
- $i++;
- $lines[$i]=~
- /Content\-Disposition\:\s*form\-data\;\s*name\=\"([^\"]+)\"/i;
- $name=$1;
- $value='';
- if ($lines[$i]=~/filename\=\"([^\"]+)\"/i) {
- $fname=$1;
- if
- ($lines[$i+1]=~/Content\-Type\:\s*([\w\-\/]+)/i) {
- $fmime=$1;
- $i++;
- } else {
- $fmime='';
- }
- } else {
- $fname='';
- $fmime='';
- }
- $i++;
- }
- } else {
- $value.=$lines[$i]."\n";
- }
- }
- }
- $env{'request.method'}=$ENV{'REQUEST_METHOD'};
- $r->method_number(M_GET);
- $r->method('GET');
- $r->headers_in->unset('Content-length');
-}
-
=pod
=item * get_unprocessed_cgi($query,$possible_names)
@@ -3383,8 +4067,8 @@ will result in $env{'form.uname'} and $e
sub get_unprocessed_cgi {
my ($query,$possible_names)= @_;
# $Apache::lonxml::debug=1;
- foreach (split(/&/,$query)) {
- my ($name, $value) = split(/=/,$_);
+ foreach my $pair (split(/&/,$query)) {
+ my ($name, $value) = split(/=/,$pair);
$name = &Apache::lonnet::unescape($name);
if (!defined($possible_names) || (grep {$_ eq $name} @$possible_names)) {
$value =~ tr/+/ /;
@@ -3431,7 +4115,10 @@ sub no_cache {
sub content_type {
my ($r,$type,$charset) = @_;
- &no_cache($r);
+ if ($r) {
+ # Note that printout.pl calls this with undef for $r.
+ &no_cache($r);
+ }
if ($env{'browser.mathml'} && $type eq 'text/html') { $type='text/xml'; }
unless ($charset) {
$charset=&Apache::lonlocal::current_encoding;
@@ -3598,8 +4285,7 @@ sub record_sep {
if ($env{'form.upfiletype'} eq 'xml') {
} elsif ($env{'form.upfiletype'} eq 'space') {
my $i=0;
- foreach (split(/\s+/,$record)) {
- my $field=$_;
+ foreach my $field (split(/\s+/,$record)) {
$field=~s/^(\"|\')//;
$field=~s/(\"|\')$//;
$components{&takeleft($i)}=$field;
@@ -3607,8 +4293,7 @@ sub record_sep {
}
} elsif ($env{'form.upfiletype'} eq 'tab') {
my $i=0;
- foreach (split(/\t/,$record)) {
- my $field=$_;
+ foreach my $field (split(/\t/,$record)) {
$field=~s/^(\"|\')//;
$field=~s/(\"|\')$//;
$components{&takeleft($i)}=$field;
@@ -3666,6 +4351,22 @@ sub upfile_select_html {
return $Str;
}
+sub get_samples {
+ my ($records,$toget) = @_;
+ my @samples=({});
+ my $got=0;
+ foreach my $rec (@$records) {
+ my %temp = &record_sep($rec);
+ if (! grep(/\S/, values(%temp))) { next; }
+ if (%temp) {
+ $samples[$got]=\%temp;
+ $got++;
+ if ($got == $toget) { last; }
+ }
+ }
+ return \@samples;
+}
+
######################################################
######################################################
@@ -3683,20 +4384,17 @@ Apache Request ref, $records is an array
######################################################
sub csv_print_samples {
my ($r,$records) = @_;
- my (%sone,%stwo,%sthree);
- %sone=&record_sep($$records[0]);
- if (defined($$records[1])) {%stwo=&record_sep($$records[1]);}
- if (defined($$records[2])) {%sthree=&record_sep($$records[2]);}
- #
+ my $samples = &get_samples($records,3);
+
$r->print(&mt('Samples').'');
- foreach (sort({$a <=> $b} keys(%sone))) {
- $r->print(''.&mt('Column [_1]',($_+1)).' '); }
+ foreach my $sample (sort({$a <=> $b} keys(%{ $samples->[0] }))) {
+ $r->print(''.&mt('Column [_1]',($sample+1)).' '); }
$r->print(' ');
- foreach my $hash (\%sone,\%stwo,\%sthree) {
+ foreach my $hash (@$samples) {
$r->print('');
- foreach (sort({$a <=> $b} keys(%sone))) {
+ foreach my $sample (sort({$a <=> $b} keys(%{ $samples->[0] }))) {
$r->print('');
- if (defined($$hash{$_})) { $r->print($$hash{$_}); }
+ if (defined($$hash{$sample})) { $r->print($$hash{$sample}); }
$r->print(' ');
}
$r->print(' ');
@@ -3723,23 +4421,23 @@ $d is an array of 2 element arrays (inte
######################################################
sub csv_print_select_table {
my ($r,$records,$d) = @_;
- my $i=0;my %sone;
- %sone=&record_sep($$records[0]);
+ my $i=0;
+ my $samples = &get_samples($records,1);
$r->print(&mt('Associate columns with student attributes.')."\n".
''.
''.&mt('Attribute').' '.
''.&mt('Column').' '."\n");
- foreach (@$d) {
- my ($value,$display,$defaultcol)=@{ $_ };
+ foreach my $array_ref (@$d) {
+ my ($value,$display,$defaultcol)=@{ $array_ref };
$r->print(''.$display.' ');
$r->print('');
$r->print(' ');
- foreach (sort({$a <=> $b} keys(%sone))) {
- $r->print('Column '.($_+1).' ');
+ foreach my $sample (sort({$a <=> $b} keys(%{ $samples->[0] }))) {
+ $r->print('Column '.($sample+1).' ');
}
$r->print(' '."\n");
$i++;
@@ -3767,28 +4465,27 @@ $d is an array of 2 element arrays (inte
######################################################
sub csv_samples_select_table {
my ($r,$records,$d) = @_;
- my %sone; my %stwo; my %sthree;
my $i=0;
#
+ my $samples = &get_samples($records,3);
$r->print(''.
&mt('Field').' '.&mt('Samples').' ');
- %sone=&record_sep($$records[0]);
- if (defined($$records[1])) {%stwo=&record_sep($$records[1]);}
- if (defined($$records[2])) {%sthree=&record_sep($$records[2]);}
- #
- foreach (sort keys %sone) {
+
+ foreach my $key (sort(keys(%{ $samples->[0] }))) {
$r->print('');
- foreach (@$d) {
- my ($value,$display,$defaultcol)=@{ $_ };
+ foreach my $option (@$d) {
+ my ($value,$display,$defaultcol)=@{ $option };
$r->print(''.
$display.' ');
}
$r->print(' ');
- if (defined($sone{$_})) { $r->print($sone{$_}." \n"); }
- if (defined($stwo{$_})) { $r->print($stwo{$_}." \n"); }
- if (defined($sthree{$_})) { $r->print($sthree{$_}." \n"); }
+ foreach my $line (0..2) {
+ if (defined($samples->[$line]{$key})) {
+ $r->print($samples->[$line]{$key}." \n");
+ }
+ }
$r->print(' ');
$i++;
}
@@ -4297,13 +4994,14 @@ sub store_course_settings {
# save to the environment
# appenv the same items, just to be safe
my $courseid = $env{'request.course.id'};
- my $coursedom = $env{'course.'.$courseid.'.domain'};
+ my $udom = $env{'user.domain'};
+ my $uname = $env{'user.name'};
my ($prefix,$Settings) = @_;
my %SaveHash;
my %AppHash;
while (my ($setting,$type) = each(%$Settings)) {
- my $basename = 'internal.'.$prefix.'.'.$setting;
- my $envname = 'course.'.$courseid.'.'.$basename;
+ my $basename = join('.','internal',$courseid,$prefix,$setting);
+ my $envname = 'environment.'.$basename;
if (exists($env{'form.'.$setting})) {
# Save this value away
if ($type eq 'scalar' &&
@@ -4331,8 +5029,7 @@ sub store_course_settings {
}
}
my $put_result = &Apache::lonnet::put('environment',\%SaveHash,
- $coursedom,
- $env{'course.'.$courseid.'.num'});
+ $udom,$uname);
if ($put_result !~ /^(ok|delayed)/) {
&Apache::lonnet::logthis('unable to save form parameters, '.
'got error:'.$put_result);
@@ -4347,7 +5044,7 @@ sub restore_course_settings {
my ($prefix,$Settings) = @_;
while (my ($setting,$type) = each(%$Settings)) {
next if (exists($env{'form.'.$setting}));
- my $envname = 'course.'.$courseid.'.internal.'.$prefix.
+ my $envname = 'environment.internal.'.$courseid.'.'.$prefix.
'.'.$setting;
if (exists($env{$envname})) {
if ($type eq 'scalar') {