--- loncom/interface/loncommon.pm 2022/01/23 02:02:48 1.1075.2.161.2.4 +++ loncom/interface/loncommon.pm 2024/07/04 23:00:26 1.1075.2.167 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common routines # -# $Id: loncommon.pm,v 1.1075.2.161.2.4 2022/01/23 02:02:48 raeburn Exp $ +# $Id: loncommon.pm,v 1.1075.2.167 2024/07/04 23:00:26 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -61,7 +61,6 @@ use POSIX qw(strftime mktime); use Apache::lonmenu(); use Apache::lonenc(); use Apache::lonlocal; -use Apache::lonnet(); use HTML::Entities; use Apache::lonhtmlcommon(); use Apache::loncoursedata(); @@ -83,8 +82,6 @@ use Crypt::DES; use DynaLoader; # for Crypt::DES version use File::Copy(); use File::Path(); -use String::CRC32(); -use Short::URL(); # ---------------------------------------------- Designs use vars qw(%defaultdesign); @@ -3672,6 +3669,30 @@ sub syllabuswrapper { # ----------------------------------------------------------------------------- +sub aboutme_on { + my ($uname,$udom)=@_; + unless ($uname) { $uname=$env{'user.name'}; } + unless ($udom) { $udom=$env{'user.domain'}; } + return if ($udom eq 'public' && $uname eq 'public'); + my $hashkey=$uname.':'.$udom; + my ($aboutme,$cached)=&Apache::lonnet::is_cached_new('aboutme',$hashkey); + if ($cached) { + return $aboutme; + } + $aboutme = &Apache::lonnet::usertools_access($uname,$udom,'aboutme'); + &Apache::lonnet::do_cache_new('aboutme',$hashkey,$aboutme,3600); + return $aboutme; +} + +sub devalidate_aboutme_cache { + my ($uname,$udom)=@_; + if (!$udom) { $udom =$env{'user.domain'}; } + if (!$uname) { $uname=$env{'user.name'}; } + return if ($udom eq 'public' && $uname eq 'public'); + my $id=$uname.':'.$udom; + &Apache::lonnet::devalidate_cache_new('aboutme',$id); +} + sub track_student_link { my ($linktext,$sname,$sdom,$target,$start,$only_body) = @_; my $link ="/adm/trackstudent?"; @@ -4732,7 +4753,7 @@ sub findallcourses { sub blockcheck { my ($setters,$activity,$clientip,$uname,$udom,$url,$is_course,$symb,$caller) = @_; - unless (($activity eq 'docs') || ($activity eq 'reinit') || ($activity eq 'alert')) { + unless ($activity eq 'docs') { my ($has_evb,$check_ipaccess); my $dom = $env{'user.domain'}; if ($env{'request.course.id'}) { @@ -4839,9 +4860,8 @@ sub blockcheck { # boards, chat or groups, check for blocking in current course only. if (($activity eq 'boards' || $activity eq 'chat' || - $activity eq 'groups' || $activity eq 'printout' || - $activity eq 'search' || $activity eq 'reinit' || - $activity eq 'alert') && ($env{'request.course.id'})) { + $activity eq 'groups' || $activity eq 'printout') && + ($env{'request.course.id'})) { foreach my $key (keys(%live_courses)) { if ($key ne $env{'request.course.id'}) { delete($live_courses{$key}); @@ -5175,10 +5195,6 @@ END_MYBLOCK $text = &mt('Gradebook Blocked'); } elsif ($activity eq 'search') { $text = &mt('Search Blocked'); - } elsif ($activity eq 'alert') { - $text = &mt('Checking Critical Messages Blocked'); - } elsif ($activity eq 'reinit') { - $text = &mt('Checking Course Update Blocked'); } elsif ($activity eq 'about') { $text = &mt('Access to User Information Pages Blocked'); } elsif ($activity eq 'wishlist') { @@ -5219,34 +5235,13 @@ sub check_ip_acc { } my $name; - my %access = ( - allowfrom => 1, - denyfrom => 0, - ); - my @allows; - my @denies; - foreach my $item (split(',',$acc)) { - $item =~ s/^\s*//; - $item =~ s/\s*$//; - if ($item =~ /^\!(.+)$/) { - push(@denies,$1); - } else { - push(@allows,$item); - } - } - my $numdenies = scalar(@denies); - my $numallows = scalar(@allows); - my $count = 0; - foreach my $pattern (@denies,@allows) { - $count ++; - my $acctype = 'allowfrom'; - if ($count <= $numdenies) { - $acctype = 'denyfrom'; - } + foreach my $pattern (split(',',$acc)) { + $pattern =~ s/^\s*//; + $pattern =~ s/\s*$//; if ($pattern =~ /\*$/) { #35.8.* $pattern=~s/\*//; - if ($ip =~ /^\Q$pattern\E/) { $allowed=$access{$acctype}; } + if ($ip =~ /^\Q$pattern\E/) { $allowed=1; } } elsif ($pattern =~ /(\d+\.\d+\.\d+)\.\[(\d+)-(\d+)\]$/) { #35.8.3.[34-56] my $low=$2; @@ -5254,7 +5249,7 @@ sub check_ip_acc { $pattern=$1; if ($ip =~ /^\Q$pattern\E/) { my $last=(split(/\./,$ip))[3]; - if ($last <=$high && $last >=$low) { $allowed=$access{$acctype}; } + if ($last <=$high && $last >=$low) { $allowed=1; } } } elsif ($pattern =~ /^\*/) { #*.msu.edu @@ -5264,10 +5259,10 @@ sub check_ip_acc { my $netaddr=inet_aton($ip); ($name)=gethostbyaddr($netaddr,AF_INET); } - if ($name =~ /\Q$pattern\E$/i) { $allowed=$access{$acctype}; } + if ($name =~ /\Q$pattern\E$/i) { $allowed=1; } } elsif ($pattern =~ /\d+\.\d+\.\d+\.\d+/) { #127.0.0.1 - if ($ip =~ /^\Q$pattern\E/) { $allowed=$access{$acctype}; } + if ($ip =~ /^\Q$pattern\E/) { $allowed=1; } } else { #some.name.com if (!defined($name)) { @@ -5275,16 +5270,9 @@ sub check_ip_acc { my $netaddr=inet_aton($ip); ($name)=gethostbyaddr($netaddr,AF_INET); } - if ($name =~ /\Q$pattern\E$/i) { $allowed=$access{$acctype}; } - } - if ($allowed =~ /^(0|1)$/) { last; } - } - if ($allowed eq '') { - if ($numdenies && !$numallows) { - $allowed = 1; - } else { - $allowed = 0; + if ($name =~ /\Q$pattern\E$/i) { $allowed=1; } } + if ($allowed) { last; } } return $allowed; } @@ -5709,19 +5697,6 @@ Inputs: inlineremote items to be added in "Functions" menu below breadcrumbs. -=item * $ltiscope, optional argument, will be one of: resource, map or - course, if LON-CAPA is in LTI Provider context. Value is - the scope of use, i.e., launch was for access to a single, a map - or the entire course. - -=item * $ltiuri, optional argument, if LON-CAPA is in LTI Provider - context, this will contain the URL for the landing item in - the course, after launch from an LTI Consumer - -=item * $ltimenu, optional argument, if LON-CAPA is in LTI Provider - context, this will contain a reference to hash of items - to be included in the page header and/or inline menu. - =back Returns: A uniform header for LON-CAPA web pages. @@ -5733,8 +5708,7 @@ other decorations will be returned. sub bodytag { my ($title,$function,$addentries,$bodyonly,$domain,$forcereg, - $no_nav_bar,$bgcolor,$no_inline_link,$args,$advtoolsref, - $ltiscope,$ltiuri,$ltimenu,$menucoll,$menuref)=@_; + $no_nav_bar,$bgcolor,$no_inline_link,$args,$advtoolsref)=@_; my $public; if ((($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public')) @@ -5818,46 +5792,16 @@ sub bodytag { undef($role); } - my $showcrstitle = 1; - if (($cid) && ($env{'request.lti.login'})) { - if (ref($ltimenu) eq 'HASH') { - unless ($ltimenu->{'role'}) { - undef($role); - } - unless ($ltimenu->{'coursetitle'}) { - $realm=' '; - $showcrstitle = 0; - } - } - } elsif (($cid) && ($menucoll)) { - if (ref($menuref) eq 'HASH') { - unless ($menuref->{'role'}) { - undef($role); - } - unless ($menuref->{'crs'}) { - $realm=' '; - $showcrstitle = 0; - } - } - } - my $titleinfo = '

'.$title.'

'; # # Extra info if you are the DC my $dc_info = ''; - if (($env{'user.adv'}) && ($env{'request.course.id'}) && $showcrstitle && + if (($env{'user.adv'}) && ($env{'request.course.id'}) && (exists($env{'user.role.dc./'.$env{'course.'.$cid.'.domain'}.'/'}))) { $dc_info = $cid.' '.$env{'course.'.$cid.'.internal.coursecode'}; $dc_info =~ s/\s+$//; } - my $crstype; - if ($cid) { - $crstype = $env{'course.'.$cid.'.type'}; - } elsif ($args->{'crstype'}) { - $crstype = $args->{'crstype'}; - } - $role = '('.$role.')' if ($role && !$env{'browser.mobile'}); if ($env{'request.state'} eq 'construct') { $forcereg=1; } @@ -5885,29 +5829,27 @@ sub bodytag { $bodytag .= Apache::lonhtmlcommon::scripttag( Apache::lonmenu::utilityfunctions($httphost), 'start'); - unless ($args->{'no_primary_menu'}) { - my ($left,$right) = Apache::lonmenu::primary_menu($crstype,$ltimenu,$menucoll,$menuref, - $args->{'links_disabled'}); - if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { - if ($dc_info) { - $dc_info = qq|$dc_info|; - } - $bodytag .= qq|
$left $role
- $realm $dc_info
|; - return $bodytag; - } + my ($left,$right) = Apache::lonmenu::primary_menu($args->{'links_disabled'}); - unless ($env{'request.symb'} =~ m/\.page___\d+___/) { - $bodytag .= qq|
$left $role
|; + if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { + if ($dc_info) { + $dc_info = qq|$dc_info|; } + $bodytag .= qq|
$left $role
+ $realm $dc_info
|; + return $bodytag; + } - $bodytag .= $right; + unless ($env{'request.symb'} =~ m/\.page___\d+___/) { + $bodytag .= qq|
$left $role
|; + } - if ($dc_info) { - $dc_info = &dc_courseid_toggle($dc_info); - } - $bodytag .= qq|
$realm $dc_info
|; + $bodytag .= $right; + + if ($dc_info) { + $dc_info = &dc_courseid_toggle($dc_info); } + $bodytag .= qq|
$realm $dc_info
|; #if directed to not display the secondary menu, don't. if ($args->{'no_secondary_menu'}) { @@ -5915,22 +5857,17 @@ sub bodytag { } #don't show menus for public users if (!$public){ - unless ($args->{'no_inline_menu'}) { - $bodytag .= Apache::lonmenu::secondary_menu($httphost,$ltiscope,$ltimenu, - $args->{'no_primary_menu'}, - $menucoll,$menuref, - $args->{'links_disabled'}); - } + $bodytag .= Apache::lonmenu::secondary_menu($httphost,$args->{'links_disabled'}); $bodytag .= Apache::lonmenu::serverform(); $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end'); if ($env{'request.state'} eq 'construct') { $bodytag .= &Apache::lonmenu::innerregister($forcereg, - $args->{'bread_crumbs'},'','',$hostname,$ltiscope,$ltiuri); + $args->{'bread_crumbs'},'','',$hostname); } elsif ($forcereg) { $bodytag .= &Apache::lonmenu::innerregister($forcereg,undef, $args->{'group'}, $args->{'hide_buttons'}, - $hostname,$ltiscope,$ltiuri); + $hostname); } else { my $forbodytag; &Apache::lonmenu::prepare_functions($env{'request.noversionuri'}, @@ -6079,6 +6016,9 @@ sub endbodytag { $endbodytag; } } + if ((ref($args) eq 'HASH') && ($args->{'dashjs'})) { + $endbodytag = &Apache::lonhtmlcommon::dash_to_minus_js().$endbodytag; + } return $endbodytag; } @@ -8133,6 +8073,7 @@ Inputs: $title - optional title for the (side effect of setting $env{'internal.head.redirect'} to the url redirected too) + 4- whether encrypt check should be skipped domain -> force to color decorate a page for a specific domain function -> force usage of a specific rolish color scheme @@ -8195,8 +8136,10 @@ sub headtag { } } if (ref($args->{'redirect'})) { - my ($time,$url,$inhibit_continue) = @{$args->{'redirect'}}; - $url = &Apache::lonenc::check_encrypt($url); + my ($time,$url,$inhibit_continue,$skip_enc_check) = @{$args->{'redirect'}}; + if (!$skip_enc_check) { + $url = &Apache::lonenc::check_encrypt($url); + } if (!$inhibit_continue) { $env{'internal.head.redirect'} = $url; } @@ -8249,7 +8192,7 @@ ADDMETA my $newserver = &Apache::lonnet::spareserver(undef,30000,undef,1,$dom_in_use); if (($newserver eq '') && ($offloadoth)) { my @domains = &Apache::lonnet::current_machine_domains(); - if (($dom_in_use ne '') && (!grep(/^\Q$dom_in_use\E$/,@domains))) { + if (($dom_in_use ne '') && (!grep(/^\Q$dom_in_use\E$/,@domains))) { ($newserver) = &Apache::lonnet::choose_server($dom_in_use); } } @@ -8565,82 +8508,12 @@ sub start_page { #&Apache::lonnet::logthis("start_page ".join(':',caller(0))); $env{'internal.start_page'}++; - my ($result,@advtools,$ltiscope,$ltiuri,%ltimenu,$menucoll,%menu); + my ($result,@advtools); if (! exists($args->{'skip_phases'}{'head'}) ) { $result .= &xml_begin($args->{'frameset'}) . &headtag($title, $head_extra, $args); } - - if (($env{'request.course.id'}) && ($env{'request.lti.login'})) { - if ($env{'course.'.$env{'request.course.id'}.'.lti.override'}) { - unless ($env{'course.'.$env{'request.course.id'}.'.lti.topmenu'}) { - $args->{'no_primary_menu'} = 1; - } - unless ($env{'course.'.$env{'request.course.id'}.'.lti.inlinemenu'}) { - $args->{'no_inline_menu'} = 1; - } - if ($env{'course.'.$env{'request.course.id'}.'.lti.lcmenu'}) { - map { $ltimenu{$_} = 1; } split(/,/,$env{'course.'.$env{'request.course.id'}.'.lti.lcmenu'}); - } - } else { - my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - my %lti = &Apache::lonnet::get_domain_lti($cdom,'provider'); - if (ref($lti{$env{'request.lti.login'}}) eq 'HASH') { - unless ($lti{$env{'request.lti.login'}}{'topmenu'}) { - $args->{'no_primary_menu'} = 1; - } - unless ($lti{$env{'request.lti.login'}}{'inlinemenu'}) { - $args->{'no_inline_menu'} = 1; - } - if (ref($lti{$env{'request.lti.login'}}{'lcmenu'}) eq 'ARRAY') { - map { $ltimenu{$_} = 1; } @{$lti{$env{'request.lti.login'}}{'lcmenu'}}; - } - } - } - ($ltiscope,$ltiuri) = &LONCAPA::ltiutils::lti_provider_scope($env{'request.lti.uri'}, - $env{'course.'.$env{'request.course.id'}.'.domain'}, - $env{'course.'.$env{'request.course.id'}.'.num'}); - } elsif ($env{'request.course.id'}) { - my $expiretime=600; - if ((time-$env{'course.'.$env{'request.course.id'}.'.last_cache'}) > $expiretime) { - &Apache::lonnet::coursedescription($env{'request.course.id'},{'freshen_cache' => 1}); - } - my ($deeplinkmenu,$menuref); - ($menucoll,$deeplinkmenu,$menuref) = &menucoll_in_effect(); - if ($menucoll) { - if (ref($menuref) eq 'HASH') { - %menu = %{$menuref}; - } - if ($menu{'top'} eq 'n') { - $args->{'no_primary_menu'} = 1; - } - if ($menu{'inline'} eq 'n') { - unless (&Apache::lonnet::allowed('opa')) { - my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; - my $crstype = &course_type(); - my $now = time; - my $ccrole; - if ($crstype eq 'Community') { - $ccrole = 'co'; - } else { - $ccrole = 'cc'; - } - if ($env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum}) { - my ($start,$end) = split(/\./,$env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum}); - if ((($start) && ($start<0)) || - (($end) && ($end<$now)) || - (($start) && ($now<$start))) { - $args->{'no_inline_menu'} = 1; - } - } else { - $args->{'no_inline_menu'} = 1; - } - } - } - } - } - + if (! exists($args->{'skip_phases'}{'body'}) ) { if ($args->{'frameset'}) { my $attr_string = &make_attr_string($args->{'force_register'}, @@ -8653,8 +8526,7 @@ sub start_page { $args->{'only_body'}, $args->{'domain'}, $args->{'force_register'}, $args->{'no_nav_bar'}, $args->{'bgcolor'}, $args->{'no_inline_link'}, - $args, \@advtools, - $ltiscope,$ltiuri,\%ltimenu,$menucoll,\%menu); + $args, \@advtools); } } @@ -8689,8 +8561,7 @@ sub start_page { } my $menulink; # if arg: bread_crumbs_nomenu is true pass 0 as $menulink item. - if ((exists($args->{'bread_crumbs_nomenu'})) || - ($ltiscope eq 'map') || ($ltiscope eq 'resource')) { + if (exists($args->{'bread_crumbs_nomenu'})) { $menulink = 0; } else { undef($menulink); @@ -8698,7 +8569,7 @@ sub start_page { #if bread_crumbs_component exists show it as headline else show only the breadcrumbs if(exists($args->{'bread_crumbs_component'})){ $result .= &Apache::lonhtmlcommon::breadcrumbs($args->{'bread_crumbs_component'},'',$menulink); - } else { + }else{ $result .= &Apache::lonhtmlcommon::breadcrumbs('','',$menulink); } } elsif (($env{'environment.remote'} eq 'on') && @@ -8742,103 +8613,6 @@ sub end_page { return $result; } -sub menucoll_in_effect { - my ($menucoll,$deeplinkmenu,%menu); - if ($env{'request.course.id'}) { - $menucoll = $env{'course.'.$env{'request.course.id'}.'.menudefault'}; - if ($env{'request.deeplink.login'}) { - my ($deeplink_symb,$deeplink,$check_login_symb); - my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; - my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - if ($env{'request.noversionuri'} =~ m{^/(res|uploaded)/}) { - if ($env{'request.noversionuri'} =~ /\.(page|sequence)$/) { - my $navmap = Apache::lonnavmaps::navmap->new(); - if (ref($navmap)) { - $deeplink = $navmap->get_mapparam(undef, - &Apache::lonnet::declutter($env{'request.noversionuri'}), - '0.deeplink'); - } else { - $check_login_symb = 1; - } - } else { - my $symb=&Apache::lonnet::symbread(); - if ($symb) { - $deeplink = &Apache::lonnet::EXT('resource.0.deeplink',$symb); - } else { - $check_login_symb = 1; - } - } - } else { - $check_login_symb = 1; - } - if ($check_login_symb) { - $deeplink_symb = &deeplink_login_symb($cnum,$cdom); - if ($deeplink_symb =~ /\.(page|sequence)$/) { - my $mapname = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($deeplink_symb))[2]); - my $navmap = Apache::lonnavmaps::navmap->new(); - if (ref($navmap)) { - $deeplink = $navmap->get_mapparam(undef,$mapname,'0.deeplink'); - } - } else { - $deeplink = &Apache::lonnet::EXT('resource.0.deeplink',$deeplink_symb); - } - } - if ($deeplink ne '') { - my ($state,$others,$listed,$scope,$protect,$display) = split(/,/,$deeplink); - if ($display =~ /^\d+$/) { - $deeplinkmenu = 1; - $menucoll = $display; - } - } - } - if ($menucoll) { - %menu = &page_menu($env{'course.'.$env{'request.course.id'}.'.menucollections'},$menucoll); - } - } - return ($menucoll,$deeplinkmenu,\%menu); -} - -sub deeplink_login_symb { - my ($cnum,$cdom) = @_; - my $login_symb; - if ($env{'request.deeplink.login'}) { - $login_symb = &symb_from_tinyurl($env{'request.deeplink.login'},$cnum,$cdom); - } - return $login_symb; -} - -sub symb_from_tinyurl { - my ($url,$cnum,$cdom) = @_; - if ($url =~ m{^\Q/tiny/$cdom/\E(\w+)$}) { - my $key = $1; - my ($tinyurl,$login); - my ($result,$cached)=&Apache::lonnet::is_cached_new('tiny',$cdom."\0".$key); - if (defined($cached)) { - $tinyurl = $result; - } else { - my $configuname = &Apache::lonnet::get_domainconfiguser($cdom); - my %currtiny = &Apache::lonnet::get('tiny',[$key],$cdom,$configuname); - if ($currtiny{$key} ne '') { - $tinyurl = $currtiny{$key}; - &Apache::lonnet::do_cache_new('tiny',$cdom."\0".$key,$currtiny{$key},600); - } - } - if ($tinyurl ne '') { - my ($cnumreq,$symb) = split(/\&/,$tinyurl); - if (wantarray) { - return ($cnumreq,$symb); - } elsif ($cnumreq eq $cnum) { - return $symb; - } - } - } - if (wantarray) { - return (); - } else { - return; - } -} - sub wishlist_window { return(<<'ENDWISHLIST');