-
- |
+ if (!defined($uname)) {
+ $uname = $env{'user.name'};
+ }
+
+ # If uname and udom are for a course, check for blocks in the course.
+
+ if (&Apache::lonnet::is_course($udom,$uname)) {
+ my %records = &Apache::lonnet::dump('comm_block',$udom,$uname);
+ my ($startblock,$endblock)=&get_blocks($setters,$activity,$udom,$uname);
+ return ($startblock,$endblock);
+ }
+
+ my $startblock = 0;
+ my $endblock = 0;
+ my %live_courses = &findallcourses(undef,$uname,$udom);
+
+ # If uname is for a user, and activity is course-specific, i.e.,
+ # boards, chat or groups, check for blocking in current course only.
+
+ if (($activity eq 'boards' || $activity eq 'chat' ||
+ $activity eq 'groups') && ($env{'request.course.id'})) {
+ foreach my $key (keys(%live_courses)) {
+ if ($key ne $env{'request.course.id'}) {
+ delete($live_courses{$key});
+ }
+ }
+ }
+
+ my $otheruser = 0;
+ my %own_courses;
+ if ((($uname ne $env{'user.name'})) || ($udom ne $env{'user.domain'})) {
+ # Resource belongs to user other than current user.
+ $otheruser = 1;
+ # Gather courses for current user
+ %own_courses =
+ &findallcourses(undef,$env{'user.name'},$env{'user.domain'});
+ }
+
+ # Gather active course roles - course coordinator, instructor,
+ # exam proctor, ta, student, or custom role.
+
+ foreach my $course (keys(%live_courses)) {
+ my ($cdom,$cnum);
+ if ((defined($env{'course.'.$course.'.domain'})) && (defined($env{'course.'.$course.'.num'}))) {
+ $cdom = $env{'course.'.$course.'.domain'};
+ $cnum = $env{'course.'.$course.'.num'};
+ } else {
+ ($cdom,$cnum) = split(/_/,$course);
+ }
+ my $no_ownblock = 0;
+ my $no_userblock = 0;
+ if ($otheruser && $activity ne 'com') {
+ # Check if current user has 'evb' priv for this
+ if (defined($own_courses{$course})) {
+ foreach my $sec (keys(%{$own_courses{$course}})) {
+ my $checkrole = 'cm./'.$cdom.'/'.$cnum;
+ if ($sec ne 'none') {
+ $checkrole .= '/'.$sec;
+ }
+ if (&Apache::lonnet::allowed('evb',undef,undef,$checkrole)) {
+ $no_ownblock = 1;
+ last;
+ }
+ }
+ }
+ # if they have 'evb' priv and are currently not playing student
+ next if (($no_ownblock) &&
+ ($env{'request.role'} !~ m{^st\./$cdom/$cnum}));
+ }
+ foreach my $sec (keys(%{$live_courses{$course}})) {
+ my $checkrole = 'cm./'.$cdom.'/'.$cnum;
+ if ($sec ne 'none') {
+ $checkrole .= '/'.$sec;
+ }
+ if ($otheruser) {
+ # Resource belongs to user other than current user.
+ # Assemble privs for that user, and check for 'evb' priv.
+ my ($trole,$tdom,$tnum,$tsec);
+ my $entry = $live_courses{$course}{$sec};
+ if ($entry =~ /^cr/) {
+ ($trole,$tdom,$tnum,$tsec) =
+ ($entry =~ m|^(cr/$match_domain/$match_username/\w+)\./($match_domain)/($match_username)/?(\w*)$|);
+ } else {
+ ($trole,$tdom,$tnum,$tsec) = split(/\//,$entry);
+ }
+ my ($spec,$area,$trest,%allroles,%userroles);
+ $area = '/'.$tdom.'/'.$tnum;
+ $trest = $tnum;
+ if ($tsec ne '') {
+ $area .= '/'.$tsec;
+ $trest .= '/'.$tsec;
+ }
+ $spec = $trole.'.'.$area;
+ if ($trole =~ /^cr/) {
+ &Apache::lonnet::custom_roleprivs(\%allroles,$trole,
+ $tdom,$spec,$trest,$area);
+ } else {
+ &Apache::lonnet::standard_roleprivs(\%allroles,$trole,
+ $tdom,$spec,$trest,$area);
+ }
+ my ($author,$adv) = &Apache::lonnet::set_userprivs(\%userroles,\%allroles);
+ if ($userroles{'user.priv.'.$checkrole} =~ /evb\&([^\:]*)/) {
+ if ($1) {
+ $no_userblock = 1;
+ last;
+ }
+ }
+ } else {
+ # Resource belongs to current user
+ # Check for 'evb' priv via lonnet::allowed().
+ if (&Apache::lonnet::allowed('evb',undef,undef,$checkrole)) {
+ $no_ownblock = 1;
+ last;
+ }
+ }
+ }
+ # if they have the evb priv and are currently not playing student
+ next if (($no_ownblock) &&
+ ($env{'request.role'} !~ m{^st\./\Q$cdom\E/\Q$cnum\E}));
+ next if ($no_userblock);
+
+ # Retrieve blocking times and identity of blocker for course
+ # of specified user, unless user has 'evb' privilege.
+
+ my ($start,$end)=&get_blocks($setters,$activity,$cdom,$cnum);
+ if (($start != 0) &&
+ (($startblock == 0) || ($startblock > $start))) {
+ $startblock = $start;
+ }
+ if (($end != 0) &&
+ (($endblock == 0) || ($endblock < $end))) {
+ $endblock = $end;
+ }
+ }
+ return ($startblock,$endblock);
+}
+
+sub get_blocks {
+ my ($setters,$activity,$cdom,$cnum) = @_;
+ my $startblock = 0;
+ my $endblock = 0;
+ my $course = $cdom.'_'.$cnum;
+ $setters->{$course} = {};
+ $setters->{$course}{'staff'} = [];
+ $setters->{$course}{'times'} = [];
+ my %records = &Apache::lonnet::dump('comm_block',$cdom,$cnum);
+ foreach my $record (keys(%records)) {
+ my ($start,$end) = ($record =~ m/^(\d+)____(\d+)$/);
+ if ($start <= time && $end >= time) {
+ my ($staff_name,$staff_dom,$title,$blocks) =
+ &parse_block_record($records{$record});
+ if ($blocks->{$activity} eq 'on') {
+ push(@{$$setters{$course}{'staff'}},[$staff_name,$staff_dom]);
+ push(@{$$setters{$course}{'times'}}, [$start,$end]);
+ if ( ($startblock == 0) || ($startblock > $start) ) {
+ $startblock = $start;
+ }
+ if ( ($endblock == 0) || ($endblock < $end) ) {
+ $endblock = $end;
+ }
+ }
+ }
+ }
+ return ($startblock,$endblock);
+}
+
+sub parse_block_record {
+ my ($record) = @_;
+ my ($setuname,$setudom,$title,$blocks);
+ if (ref($record) eq 'HASH') {
+ ($setuname,$setudom) = split(/:/,$record->{'setter'});
+ $title = &unescape($record->{'event'});
+ $blocks = $record->{'blocks'};
+ } else {
+ my @data = split(/:/,$record,3);
+ if (scalar(@data) eq 2) {
+ $title = $data[1];
+ ($setuname,$setudom) = split(/@/,$data[0]);
+ } else {
+ ($setuname,$setudom,$title) = @data;
+ }
+ $blocks = { 'com' => 'on' };
+ }
+ return ($setuname,$setudom,$title,$blocks);
+}
+
+sub build_block_table {
+ my ($startblock,$endblock,$setters) = @_;
+ my %lt = &Apache::lonlocal::texthash(
+ 'cacb' => 'Currently active communication blocks',
+ 'cour' => 'Course',
+ 'dura' => 'Duration',
+ 'blse' => 'Block set by'
+ );
+ my $output;
+ $output = '
'.$lt{'cacb'}.':
';
+ $output .= &start_data_table();
+ $output .= '
-
-$title
- |
-
- $ENV{'environment.firstname'}
- $ENV{'environment.middlename'}
- $ENV{'environment.lastname'}
- $ENV{'environment.generation'}
-
+ | '.$lt{'cour'}.' |
+ '.$lt{'dura'}.' |
+ '.$lt{'blse'}.' |
+
+';
+ foreach my $course (keys(%{$setters})) {
+ my %courseinfo=&Apache::lonnet::coursedescription($course);
+ for (my $i=0; $i<@{$$setters{$course}{staff}}; $i++) {
+ my ($uname,$udom) = @{$$setters{$course}{staff}[$i]};
+ my $fullname = &plainname($uname,$udom);
+ if (defined($env{'user.name'}) && defined($env{'user.domain'})
+ && $env{'user.name'} ne 'public'
+ && $env{'user.domain'} ne 'public') {
+ $fullname = &aboutmewrapper($fullname,$uname,$udom);
+ }
+ my ($openblock,$closeblock) = @{$$setters{$course}{times}[$i]};
+ $openblock = &Apache::lonlocal::locallocaltime($openblock);
+ $closeblock= &Apache::lonlocal::locallocaltime($closeblock);
+ $output .= &Apache::loncommon::start_data_table_row().
+ ''.$courseinfo{'description'}.' | '.
+ ''.$openblock.' to '.$closeblock.' | '.
+ ''.$fullname.' | '.
+ &Apache::loncommon::end_data_table_row();
+ }
+ }
+ $output .= &end_data_table();
+}
+
+sub blocking_status {
+ my ($activity,$uname,$udom) = @_;
+ my %setters;
+ my ($blocked,$output,$ownitem,$is_course);
+ my ($startblock,$endblock)=&blockcheck(\%setters,$activity,$uname,$udom);
+ if ($startblock && $endblock) {
+ $blocked = 1;
+ if (wantarray) {
+ my $category;
+ if ($activity eq 'boards') {
+ $category = 'Discussion posts in this course';
+ } elsif ($activity eq 'blogs') {
+ $category = 'Blogs';
+ } elsif ($activity eq 'port') {
+ if (defined($uname) && defined($udom)) {
+ if ($uname eq $env{'user.name'} &&
+ $udom eq $env{'user.domain'}) {
+ $ownitem = 1;
+ }
+ }
+ $is_course = &Apache::lonnet::is_course($udom,$uname);
+ if ($ownitem) {
+ $category = 'Your portfolio files';
+ } elsif ($is_course) {
+ my $coursedesc;
+ foreach my $course (keys(%setters)) {
+ my %courseinfo =
+ &Apache::lonnet::coursedescription($course);
+ $coursedesc = $courseinfo{'description'};
+ }
+ $category = "Group portfolio in the course '$coursedesc'";
+ } else {
+ $category = 'Portfolio files belonging to ';
+ if ($env{'user.name'} eq 'public' &&
+ $env{'user.domain'} eq 'public') {
+ $category .= &plainname($uname,$udom);
+ } else {
+ $category .= &aboutmewrapper(&plainname($uname,$udom),$uname,$udom);
+ }
+ }
+ } elsif ($activity eq 'groups') {
+ $category = 'Groups in this course';
+ }
+ my $showstart = &Apache::lonlocal::locallocaltime($startblock);
+ my $showend = &Apache::lonlocal::locallocaltime($endblock);
+ $output = '
'.&mt('[_1] will be inaccessible between [_2] and [_3] because communication is being blocked.',$category,$showstart,$showend).'
';
+ if (!($activity eq 'port' && !($ownitem) && !($is_course))) {
+ $output .= &build_block_table($startblock,$endblock,\%setters);
+ }
+ }
+ }
+ if (wantarray) {
+ return ($blocked,$output);
+ } else {
+ return $blocked;
+ }
+}
+
+###############################################
+
+sub check_ip_acc {
+ my ($acc)=@_;
+ &Apache::lonxml::debug("acc is $acc");
+ if (!defined($acc) || $acc =~ /^\s*$/ || $acc =~/^\s*no\s*$/i) {
+ return 1;
+ }
+ my $allowed=0;
+ my $ip=$env{'request.host'} || $ENV{'REMOTE_ADDR'};
+
+ my $name;
+ foreach my $pattern (split(',',$acc)) {
+ $pattern =~ s/^\s*//;
+ $pattern =~ s/\s*$//;
+ if ($pattern =~ /\*$/) {
+ #35.8.*
+ $pattern=~s/\*//;
+ if ($ip =~ /^\Q$pattern\E/) { $allowed=1; }
+ } elsif ($pattern =~ /(\d+\.\d+\.\d+)\.\[(\d+)-(\d+)\]$/) {
+ #35.8.3.[34-56]
+ my $low=$2;
+ my $high=$3;
+ $pattern=$1;
+ if ($ip =~ /^\Q$pattern\E/) {
+ my $last=(split(/\./,$ip))[3];
+ if ($last <=$high && $last >=$low) { $allowed=1; }
+ }
+ } elsif ($pattern =~ /^\*/) {
+ #*.msu.edu
+ $pattern=~s/\*//;
+ if (!defined($name)) {
+ use Socket;
+ my $netaddr=inet_aton($ip);
+ ($name)=gethostbyaddr($netaddr,AF_INET);
+ }
+ if ($name =~ /\Q$pattern\E$/i) { $allowed=1; }
+ } elsif ($pattern =~ /\d+\.\d+\.\d+\.\d+/) {
+ #127.0.0.1
+ if ($ip =~ /^\Q$pattern\E/) { $allowed=1; }
+ } else {
+ #some.name.com
+ if (!defined($name)) {
+ use Socket;
+ my $netaddr=inet_aton($ip);
+ ($name)=gethostbyaddr($netaddr,AF_INET);
+ }
+ if ($name =~ /\Q$pattern\E$/i) { $allowed=1; }
+ }
+ if ($allowed) { last; }
+ }
+ return $allowed;
+}
+
+###############################################
+
+=pod
+
+=head1 Domain Template Functions
+
+=over 4
+
+=item * &determinedomain()
+
+Inputs: $domain (usually will be undef)
+
+Returns: Determines which domain should be used for designs
+
+=cut
+
+###############################################
+sub determinedomain {
+ my $domain=shift;
+ if (! $domain) {
+ # Determine domain if we have not been given one
+ $domain = $Apache::lonnet::perlvar{'lonDefDomain'};
+ if ($env{'user.domain'}) { $domain=$env{'user.domain'}; }
+ if ($env{'request.role.domain'}) {
+ $domain=$env{'request.role.domain'};
+ }
+ }
+ return $domain;
+}
+###############################################
+
+sub devalidate_domconfig_cache {
+ my ($udom)=@_;
+ &Apache::lonnet::devalidate_cache_new('domainconfig',$udom);
+}
+
+# ---------------------- Get domain configuration for a domain
+sub get_domainconf {
+ my ($udom) = @_;
+ my $cachetime=1800;
+ my ($result,$cached)=&Apache::lonnet::is_cached_new('domainconfig',$udom);
+ if (defined($cached)) { return %{$result}; }
+
+ my %domconfig = &Apache::lonnet::get_dom('configuration',
+ ['login','rolecolors'],$udom);
+ my (%designhash,%legacy);
+ if (keys(%domconfig) > 0) {
+ if (ref($domconfig{'login'}) eq 'HASH') {
+ if (keys(%{$domconfig{'login'}})) {
+ foreach my $key (keys(%{$domconfig{'login'}})) {
+ if (ref($domconfig{'login'}{$key}) eq 'HASH') {
+ foreach my $img (keys(%{$domconfig{'login'}{$key}})) {
+ $designhash{$udom.'.login.'.$key.'_'.$img} =
+ $domconfig{'login'}{$key}{$img};
+ }
+ } else {
+ $designhash{$udom.'.login.'.$key}=$domconfig{'login'}{$key};
+ }
+ }
+ } else {
+ $legacy{'login'} = 1;
+ }
+ } else {
+ $legacy{'login'} = 1;
+ }
+ if (ref($domconfig{'rolecolors'}) eq 'HASH') {
+ if (keys(%{$domconfig{'rolecolors'}})) {
+ foreach my $role (keys(%{$domconfig{'rolecolors'}})) {
+ if (ref($domconfig{'rolecolors'}{$role}) eq 'HASH') {
+ foreach my $item (keys(%{$domconfig{'rolecolors'}{$role}})) {
+ $designhash{$udom.'.'.$role.'.'.$item}=$domconfig{'rolecolors'}{$role}{$item};
+ }
+ }
+ }
+ } else {
+ $legacy{'rolecolors'} = 1;
+ }
+ } else {
+ $legacy{'rolecolors'} = 1;
+ }
+ if (keys(%legacy) > 0) {
+ my %legacyhash = &get_legacy_domconf($udom);
+ foreach my $item (keys(%legacyhash)) {
+ if ($item =~ /^\Q$udom\E\.login/) {
+ if ($legacy{'login'}) {
+ $designhash{$item} = $legacyhash{$item};
+ }
+ } else {
+ if ($legacy{'rolecolors'}) {
+ $designhash{$item} = $legacyhash{$item};
+ }
+ }
+ }
+ }
+ } else {
+ %designhash = &get_legacy_domconf($udom);
+ }
+ &Apache::lonnet::do_cache_new('domainconfig',$udom,\%designhash,
+ $cachetime);
+ return %designhash;
+}
+
+sub get_legacy_domconf {
+ my ($udom) = @_;
+ my %legacyhash;
+ my $designdir=$Apache::lonnet::perlvar{'lonTabDir'}.'/lonDomColors';
+ my $designfile = $designdir.'/'.$udom.'.tab';
+ if (-e $designfile) {
+ if ( open (my $fh,"<$designfile") ) {
+ while (my $line = <$fh>) {
+ next if ($line =~ /^\#/);
+ chomp($line);
+ my ($key,$val)=(split(/\=/,$line));
+ if ($val) { $legacyhash{$udom.'.'.$key}=$val; }
+ }
+ close($fh);
+ }
+ }
+ if (-e '/home/httpd/html/adm/lonDomLogos/'.$udom.'.gif') {
+ $legacyhash{$udom.'.login.domlogo'} = "/adm/lonDomLogos/$udom.gif";
+ }
+ return %legacyhash;
+}
+
+=pod
+
+=item * &domainlogo()
+
+Inputs: $domain (usually will be undef)
+
+Returns: A link to a domain logo, if the domain logo exists.
+If the domain logo does not exist, a description of the domain.
+
+=cut
+
+###############################################
+sub domainlogo {
+ my $domain = &determinedomain(shift);
+ my %designhash = &get_domainconf($domain);
+ # See if there is a logo
+ if ($designhash{$domain.'.login.domlogo'} ne '') {
+ my $imgsrc = $designhash{$domain.'.login.domlogo'};
+ if ($imgsrc =~ m{^/(adm|res)/}) {
+ if ($imgsrc =~ m{^/res/}) {
+ my $local_name = &Apache::lonnet::filelocation('',$imgsrc);
+ &Apache::lonnet::repcopy($local_name);
+ }
+ $imgsrc = &lonhttpdurl($imgsrc);
+ }
+ return '';
+ } elsif (defined(&Apache::lonnet::domain($domain,'description'))) {
+ return &Apache::lonnet::domain($domain,'description');
+ } else {
+ return '';
+ }
+}
+##############################################
+
+=pod
+
+=item * &designparm()
+
+Inputs: $which parameter; $domain (usually will be undef)
+
+Returns: value of designparamter $which
+
+=cut
+
+
+##############################################
+sub designparm {
+ my ($which,$domain)=@_;
+ if (exists($env{'environment.color.'.$which})) {
+ return $env{'environment.color.'.$which};
+ }
+ $domain=&determinedomain($domain);
+ my %domdesign = &get_domainconf($domain);
+ my $output;
+ if ($domdesign{$domain.'.'.$which} ne '') {
+ $output = $domdesign{$domain.'.'.$which};
+ } else {
+ $output = $defaultdesign{$which};
+ }
+ if (($which =~ /^(student|coordinator|author|admin)\.img$/) ||
+ ($which =~ /login\.(img|logo|domlogo|login)/)) {
+ if ($output =~ m{^/(adm|res)/}) {
+ if ($output =~ m{^/res/}) {
+ my $local_name = &Apache::lonnet::filelocation('',$output);
+ &Apache::lonnet::repcopy($local_name);
+ }
+ $output = &lonhttpdurl($output);
+ }
+ }
+ return $output;
+}
+
+##############################################
+=pod
+
+=item * &head_subbox()
+
+Inputs: $content (contains HTML code with page functions, etc.)
+
+Returns: HTML div with $content
+ To be included in page header
+
+=cut
+
+sub head_subbox {
+ my ($content)=@_;
+ my $output =
+ '' #FIXME: solve conflicts with lonhtmlcommon:breadcrumbs LC_head_subbox
+ .$content
+ .'
'
+}
+
+##############################################
+=pod
+
+=item * &CSTR_pageheader()
+
+Inputs: ./.
+
+Returns: HTML div with CSTR path and recent box
+ To be included on Construction Space pages
+
+=cut
+
+sub CSTR_pageheader {
+ # this is for resources; directories have customtitle, and crumbs
+ # and select recent are created in lonpubdir.pm
+ my ($uname,$thisdisfn)=
+ ($env{'request.filename'} =~ m|^/home/([^/]+)/public_html/(.*)|);
+ my $formaction='/priv/'.$uname.'/'.$thisdisfn;
+ $formaction=~s/\/+/\//g;
+
+ my $parentpath = '';
+ my $lastitem = '';
+ if ($thisdisfn =~ m-(.+/)([^/]*)$-) {
+ $parentpath = $1;
+ $lastitem = $2;
+ } else {
+ $lastitem = $thisdisfn;
+ }
+ return
+ ''
+ .&Apache::loncommon::help_open_menu('','',3,'Authoring') #FIXME: Broken? Where is it?
+ .''.&mt('Construction Space:').' '
+ .''
+ .&Apache::lonmenu::constspaceform()
+ .'
';
+}
+
+###############################################
+###############################################
+
+=pod
+
+=back
+
+=head1 HTML Helpers
+
+=over 4
+
+=item * &bodytag()
+
+Returns a uniform header for LON-CAPA web pages.
+
+Inputs:
+
+=over 4
+
+=item * $title, A title to be displayed on the page.
+
+=item * $function, the current role (can be undef).
+
+=item * $addentries, extra parameters for the tag.
+
+=item * $bodyonly, if defined, only return the tag.
+
+=item * $domain, if defined, force a given domain.
+
+=item * $forcereg, if page should register as content page (relevant for
+ text interface only)
+
+=item * $customtitle, alternate text to use instead of $title
+ in the title box that appears, this text
+ is not auto translated like the $title is
+
+=item * $no_nav_bar, if true, keep the 'what is this' info but remove the
+ navigational links
+
+=item * $bgcolor, used to override the bgcolor on a webpage to a specific value
+
+=item * $no_inline_link, if true and in remote mode, don't show the
+ 'Switch To Inline Menu' link
+
+=item * $args, optional argument valid values are
+ no_auto_mt_title -> prevents &mt()ing the title arg
+ inherit_jsmath -> when creating popup window in a page,
+ should it have jsmath forced on by the
+ current page
+
+=back
+
+Returns: A uniform header for LON-CAPA web pages.
+If $bodyonly is nonzero, a string containing a tag will be returned.
+If $bodyonly is undef or zero, an html string containing a tag and
+other decorations will be returned.
+
+=cut
+
+sub bodytag {
+ my ($title,$function,$addentries,$bodyonly,$domain,$forcereg,$customtitle,
+ $no_nav_bar,$bgcolor,$no_inline_link,$args)=@_;
+
+ if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); }
+
+ $function = &get_users_function() if (!$function);
+ my $img = &designparm($function.'.img',$domain);
+ my $font = &designparm($function.'.font',$domain);
+ my $pgbg = $bgcolor || &designparm($function.'.pgbg',$domain);
+
+ my %design = ( 'style' => 'margin-top: 0',
+ 'bgcolor' => $pgbg,
+ 'text' => $font,
+ 'alink' => &designparm($function.'.alink',$domain),
+ 'vlink' => &designparm($function.'.vlink',$domain),
+ 'link' => &designparm($function.'.link',$domain),);
+ @design{keys(%$addentries)} = @$addentries{keys(%$addentries)};
+
+ # role and realm
+ my ($role,$realm) = split(/\./,$env{'request.role'},2);
+ if ($role eq 'ca') {
+ my ($rdom,$rname) = ($realm =~ m{^/($match_domain)/($match_username)$});
+ $realm = &plainname($rname,$rdom);
+ }
+# realm
+ if ($env{'request.course.id'}) {
+ if ($env{'request.role'} !~ /^cr/) {
+ $role = &Apache::lonnet::plaintext($role,&course_type());
+ }
+ $realm = $env{'course.'.$env{'request.course.id'}.'.description'};
+ } else {
+ $role = &Apache::lonnet::plaintext($role);
+ }
+
+ if (!$realm) { $realm=' '; }
+# Set messages
+ my $messages=&domainlogo($domain);
+
+ my $extra_body_attr = &make_attr_string($forcereg,\%design);
+
+# construct main body tag
+ my $bodytag = "".
+ &Apache::lontexconvert::init_math_support($args->{'inherit_jsmath'});
+
+ if ($bodyonly) {
+ return $bodytag;
+ }
+
+ my $name = &plainname($env{'user.name'},$env{'user.domain'});
+ if ($env{'user.name'} eq 'public' && $env{'user.domain'} eq 'public') {
+ undef($role);
+ } else {
+ $name = &aboutmewrapper($name,$env{'user.name'},$env{'user.domain'});
+ }
+
+ my $roleinfo=(<
+
+ $name
+
+
+
+$role
+
+
+$realm
+
+ENDROLE
+
+ my $titleinfo = ''.$title.'
';
+ if ($customtitle) {
+ $titleinfo = $customtitle;
+ }
+ #
+ # Extra info if you are the DC
+ my $dc_info = '';
+ if ($env{'user.adv'} && exists($env{'user.role.dc./'.
+ $env{'course.'.$env{'request.course.id'}.
+ '.domain'}.'/'})) {
+ my $cid = $env{'request.course.id'};
+ $dc_info.= $cid.' '.$env{'course.'.$cid.'.internal.coursecode'};
+ $dc_info =~ s/\s+$//;
+ $dc_info = '('.$dc_info.')';
+ }
+
+ if (($env{'environment.remote'} eq 'off') || ($args->{'suppress_header_logos'})) {
+ # No Remote
+ if ($env{'request.state'} eq 'construct') {
+ $forcereg=1;
+ }
+
+ if (!$customtitle && $env{'request.state'} eq 'construct') {
+ $titleinfo = &CSTR_pageheader(); #FIXME: Will be removed once all scripts have their own calls
+ }
+
+ my $titletable = ''
+ ." $titleinfo $dc_info | ".$roleinfo
+ .'
';
+
+ if ($no_nav_bar) {
+ $bodytag .= $titletable;
+ } else {
+ $bodytag .= qq|$name ($role)
+ $realm $dc_info
|;
+ if ($env{'request.state'} eq 'construct') {
+ $bodytag .= &Apache::lonmenu::menubuttons($forcereg,$forcereg,
+ $titletable);
+ } else {
+ $bodytag .= &Apache::lonmenu::menubuttons($forcereg,$forcereg).
+ $titletable;
+ }
+ }
+ return $bodytag;
+ }
+
+#
+# Top frame rendering, Remote is up
+#
+
+ my $imgsrc = $img;
+ if ($img =~ /^\/adm/) {
+ $imgsrc = &lonhttpdurl($img);
+ }
+ my $upperleft='';
+
+ # Explicit link to get inline menu
+ my $menu= ($no_inline_link?''
+ :'
'.&mt('Switch to Inline Menu Mode').'');
+ #
+ return(<
+$upperleft |
+ $messages |
+
+$titleinfo $dc_info $menu |
+$roleinfo
-
-$role
- |
-