--- loncom/interface/loncommon.pm 2005/11/15 16:04:14 1.291
+++ loncom/interface/loncommon.pm 2006/03/21 20:36:15 1.317
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# a pile of common routines
#
-# $Id: loncommon.pm,v 1.291 2005/11/15 16:04:14 albertel Exp $
+# $Id: loncommon.pm,v 1.317 2006/03/21 20:36:15 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -331,7 +331,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 +365,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 "
var stdeditbrowser;
- function opencrsbrowser(formname,uname,udom,desc,extra_element) {
+ function opencrsbrowser(formname,uname,udom,desc,extra_element,multflag) {
var url = '/adm/pickcourse?';
var filter;
if (filter != null) {
@@ -403,6 +408,9 @@ sub coursebrowser_javascript {
url += '&domainfilter='+extra_element;
}
}
+ if (multflag !=null && multflag != '') {
+ url += '&multiple='+multflag;
+ }
var title = 'Course_Browser';
var options = 'scrollbars=1,resizable=1,menubar=0';
options += ',width=700,height=600';
@@ -414,9 +422,9 @@ ENDSTDBRW
}
sub selectcourse_link {
- my ($form,$unameele,$udomele,$desc,$extra_element)=@_;
+ my ($form,$unameele,$udomele,$desc,$extra_element,$multflag)=@_;
return "".&mt('Select Course')."";
+ '","'.$udomele.'","'.$desc.'","'.$extra_element.'","'.$multflag.'");'."'>".&mt('Select Course')."";
}
sub check_uncheck_jscript {
@@ -1917,12 +1925,11 @@ if $first is set to 'lastname' then it r
=cut
+
###############################################################
sub plainname {
my ($uname,$udom,$first)=@_;
- my %names=&Apache::lonnet::get('environment',
- ['firstname','middlename','lastname','generation'],
- $udom,$uname);
+ my %names=&getnames($uname,$udom);
my $name=&Apache::lonnet::format_name($names{'firstname'},
$names{'middlename'},
$names{'lastname'},
@@ -1953,19 +1960,7 @@ if the user does not
sub nickname {
my ($uname,$udom)=@_;
- my %names;
- if ($uname eq $env{'user.name'} &&
- $udom eq $env{'user.domain'}) {
- %names=('nickname' => $env{'environment.nickname'} ,
- 'firstname' => $env{'environment.firstname'} ,
- 'middlename' => $env{'environment.middlename'},
- 'lastname' => $env{'environment.lastname'} ,
- 'generation' => $env{'environment.generation'});
- } else {
- %names=&Apache::lonnet::get('environment',
- ['nickname','firstname','middlename',
- 'lastname','generation'],$udom,$uname);
- }
+ my %names=&getnames($uname,$udom);
my $name=$names{'nickname'};
if ($name) {
$name='"'.$name.'"';
@@ -1978,6 +1973,20 @@ sub nickname {
return $name;
}
+sub getnames {
+ my ($uname,$udom)=@_;
+ my $id=$uname.':'.$udom;
+ my ($names,$cached)=&Apache::lonnet::is_cached_new('namescache',$id);
+ if ($cached) {
+ return %{$names};
+ } else {
+ my %loadnames=&Apache::lonnet::get('environment',
+ ['firstname','middlename','lastname','generation','nickname'],
+ $udom,$uname);
+ &Apache::lonnet::do_cache_new('namescache',$id,\%loadnames);
+ return %loadnames;
+ }
+}
# ------------------------------------------------------------------ Screenname
@@ -2728,6 +2737,13 @@ Inputs:
=item * $forcereg, if page should register as content page (relevant for
text interface only)
+=item * $customtitle, overrides the $title in some way ????
+
+=item * $notopbar, if true, keep the 'what is this' info but remove the
+ navigational links
+
+=item * $bgcolor, used to override the bg coor on a webpage to a specific value
+
=back
Returns: A uniform header for LON-CAPA web pages.
@@ -2738,11 +2754,12 @@ other decorations will be returned.
=cut
sub bodytag {
- my ($title,$function,$addentries,$bodyonly,$domain,$forcereg,$customtitle,$notopbar)=@_;
+ my ($title,$function,$addentries,$bodyonly,$domain,$forcereg,$customtitle,
+ $notopbar,$bgcolor)=@_;
$title=&mt($title);
$function = &get_users_function() if (!$function);
my $img=&designparm($function.'.img',$domain);
- my $pgbg=&designparm($function.'.pgbg',$domain);
+ my $pgbg= $bgcolor || &designparm($function.'.pgbg',$domain);
my $tabbg=&designparm($function.'.tabbg',$domain);
my $font=&designparm($function.'.font',$domain);
my $link=&designparm($function.'.link',$domain);
@@ -2778,6 +2795,7 @@ table.thinborder { border-collapse: coll
table.thinborder tr th, table.thinborder tr td { border-style: solid; border-width: 1px}
form, .inline { display: inline; }
.center { text-align: center; }
+.filename {font-family: monospace;}
@@ -2883,17 +2901,19 @@ ENDROLE
$dc_info.= $cid.' '.$env{'course.'.$cid.'.internal.coursecode'};
$dc_info = '('.$dc_info.')';
}
+ # Explicit link to get inline menu
+ my $menu=' '.&mt('Switch to Inline Menu Mode').'';
#
return(<
+
$upperleft
$messages
-$titleinfo $dc_info
+$titleinfo $dc_info $menu
$env{'environment.firstname'}
@@ -2919,7 +2939,7 @@ ENDBODY
=back
-=head1 HTTP Helpers
+=head1 HTML Helpers
=over 4
@@ -2927,26 +2947,222 @@ ENDBODY
Returns a uniform footer for LON-CAPA web pages.
-Inputs:
-
-=over 4
+Inputs: none
=back
-Returns: A uniform footer for LON-CAPA web pages.
-
=cut
sub endbodytag {
my $endbodytag='';
$endbodytag=&Apache::lontexconvert::jsMath_process()."\n".$endbodytag;
+ if ( exists( $env{'internal.head.redirect'} ) ) {
+ $endbodytag=
+ " ".
+ &mt('Continue').''.
+ $endbodytag;
+ }
return $endbodytag;
}
+=pod
+
+=over 4
+
+=item * &headtag()
+
+Returns a uniform footer for LON-CAPA web pages.
+
+Inputs: $title - optional title for the head
+ $head_extra - optional extra HTML to put inside the
+ $args - optional arguments
+ redirect - array ref of seconds before redirect occurs
+ url to redirect to
+ (side effect of setting
+ $env{'internal.head.redirect'} to the url
+ redirected too)
+=back
+
+=cut
+
+sub headtag {
+ my ($title,$head_extra,$args) = @_;
+
+ my $result =
+ ''.
+ &Apache::lonxml::fontsettings().
+ &Apache::lonhtmlcommon::htmlareaheaders();
+
+ if (ref($args->{'redirect'})) {
+ my ($time,$url) = @{$args->{'redirect'}};
+ $url = &Apache::lonenc::check_encrypt($url);
+ $env{'internal.head.redirect'} = $url;
+ $result.=<
+
+ADDMETA
+ }
+ if (!defined($title)) {
+ $title = 'The LearningOnline Network with CAPA';
+ }
+
+ $result .= ' LON-CAPA '.&mt($title).''.$head_extra;
+
+ return $result;
+}
+
+=pod
+
+=over 4
+
+=item * &endheadtag()
+
+Returns a uniform for LON-CAPA web pages.
+
+Inputs: none
+
+=back
+
+=cut
+
+sub endheadtag {
+ return '';
+}
+
+=pod
+
+=over 4
+
+=item * &head()
+
+Returns a uniform complete .. section for LON-CAPA web pages.
+
+Inputs: $title - optional title for the page
+ $head_extra - optional extra HTML to put inside the
+=back
+
+=cut
+
+sub head {
+ my ($title,$head_extra) = @_;
+ return &headtag($title,$head_extra).&endheadtag();
+}
+
+=pod
+
+=over 4
+
+=item * &start_page()
+
+Returns a complete .. section for LON-CAPA web pages.
+
+Inputs: $title - optional title for the page
+ $head_extra - optional extra HTML to incude inside the
+ $args - additional optional args supported are:
+ only_body -> is true will set &bodytag() onlybodytag
+ arg on
+ no_nav_bar -> is true will set &bodytag() notopbar arg on
+ add_entries -> additional attributes to add to the
+ domain -> force to color decorate a page for a
+ specific domain
+ function -> force usage of a specific rolish color
+ scheme
+ redirect -> see &headtag()
+ bgcolor -> override the default page bg color
+ js_ready -> return a string ready for being used in
+ a javascript writeln
+ force_register -> if is true will turn on the &bodytag()
+ $forcereg arg
+
+=back
+
+=cut
+
+sub start_page {
+ my ($title,$head_extra,$args) = @_;
+ my %head_args;
+ if (defined($args->{'redirect'})) {
+ $head_args{'redirect'} = $args->{'redirect'};
+ }
+ $env{'internal.start_page'}++;
+ my $result =
+ &Apache::lonxml::xmlbegin().
+ &headtag($title,$head_extra,\%head_args).&endheadtag().
+ &bodytag($title,
+ $args->{'function'}, $args->{'add_entries'},
+ $args->{'only_body'}, $args->{'domain'},
+ $args->{'force_register'}, undef,
+ $args->{'no_nav_bar'}, $args->{'bgcolor'});
+ if ($args->{'js_ready'}) {
+ $result = &js_ready($result);
+ }
+ return $result;
+}
+
+=pod
+
+=over 4
+
+=item * &head()
+
+Returns a complete section for LON-CAPA web pages.
+
+Inputs: $args - additional optional args supported are:
+ js_ready -> return a string ready for being used in
+ a javascript writeln
+=back
+
+=cut
+
+sub end_page {
+ my ($args) = @_;
+ $env{'internal.end_page'}++;
+ my $result = &endbodytag()."\n";
+ if ($args->{'js_ready'}) {
+ $result = &js_ready($result);
+ }
+ return $result;
+}
+
+sub js_ready {
+ my ($result) = @_;
+ $result = &HTML::Entities::encode($result,'<>&"');
+
+ $result =~ s/[\n\r]/ /g;
+ $result =~ s/'/\\'/g;
+
+ 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{'request.filename'});
+ }
+ if ( exists($env{'internal.end_page'})
+ && $env{'internal.end_page'} > 1) {
+ &Apache::lonnet::logthis('end_page called multiple times '.
+ $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'});
+ }
+}
+
###############################################
=pod
+=over 4
+
=item get_users_function
Used by &bodytag to determine the current users primary role.
@@ -3080,6 +3296,153 @@ 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
+
+=item get_group_settings
+
+Uses TokeParser to extract group information from the
+XML used to describe course groups.
+
+Input:
+Scalar containing XML - as retrieved from &coursegroups().
+
+Output:
+Hash containing group information as key=values for (a), and
+hash of hashes for (b)
+
+Keys (in two categories):
+(a) groupname, creator, creation, modified, startdate,enddate.
+Corresponding values are name of the group, creator of the group
+(username:domain), UNIX time for date group was created, and
+settings were last modified, and default start and end access
+times for group members.
+
+(b) functions returned in hash of hashes.
+Outer hash key is functions.
+Inner hash keys are chat,discussion,email,files,homepage,roster.
+Corresponding values are either on or off, depending on
+whether this type of functionality is available for the group.
+
+=cut
+
+###############################################
+
+sub get_group_settings {
+ my ($groupinfo)=@_;
+ 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' || $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') {
+ if ($tool eq 'functions') {
+ my $function = $token->[2]{id};
+ $content{$tool}{$function} = $value;
+ }
+ } 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' || $token->[1] eq 'autosec') {
+ $tool = '';
+ } elsif ($token->[1] eq 'role') {
+ $role = '';
+ }
+
+ }
+ }
+ return %content;
+}
+
+sub check_group_access {
+ my ($group) = @_;
+ my $access = 1;
+ my $now = time;
+ my ($start,$end) = split(/\./,$env{'user.role.gr/'.$env{'request.course,id'}.'/'.$group});
+ if (($end!=0) && ($end<$now)) { $access = 0; }
+ if (($start!=0) && ($start>$now)) { $access=0; }
+ return $access;
+}
+
+###############################################
=pod
@@ -3208,7 +3571,7 @@ sub get_user_info {
$$userdata{$uname.':'.$udom}[$$idx{fullname}] =
&plainname($uname,$udom,'lastname');
$$userdata{$uname.':'.$udom}[$$idx{uname}] = $uname;
- $$userdata{$uname.':'.$udom}[$$idx{uname}] = $udom;
+ $$userdata{$uname.':'.$udom}[$$idx{udom}] = $udom;
return;
}
@@ -3350,6 +3713,10 @@ sub no_cache {
sub content_type {
my ($r,$type,$charset) = @_;
+ 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;
@@ -3584,6 +3951,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;
+}
+
######################################################
######################################################
@@ -3601,18 +3984,15 @@ 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').'
');
if (defined($$hash{$_})) { $r->print($$hash{$_}); }
$r->print('
');
@@ -3641,8 +4021,8 @@ $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').'
'.
@@ -3654,7 +4034,7 @@ sub csv_print_select_table {
$r->print('