--- loncom/interface/lonpreferences.pm 2021/03/06 19:44:54 1.196.4.27 +++ loncom/interface/lonpreferences.pm 2022/09/08 01:41:13 1.241 @@ -1,7 +1,7 @@ # The LearningOnline Network # Preferences # -# $Id: lonpreferences.pm,v 1.196.4.27 2021/03/06 19:44:54 raeburn Exp $ +# $Id: lonpreferences.pm,v 1.241 2022/09/08 01:41:13 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -31,7 +31,6 @@ package Apache::lonpreferences; use strict; -use LONCAPA; use Apache::Constants qw(:common); use Apache::File; use Apache::loncommon(); @@ -40,6 +39,7 @@ use Apache::lonlocal; use Apache::lonnet; use LONCAPA::lonauthcgi(); use LONCAPA(); +use DateTime::TimeZone(); ################################################################ # Handler subroutines # @@ -165,7 +165,7 @@ sub texenginechanger { my %mathchoices=('' => 'Default', 'tth' => 'tth (TeX to HTML)', #'ttm' => 'TeX to MathML', - 'MathJax' => 'MathJax', + 'MathJax' => 'MathJax', 'mimetex' => 'mimetex (Convert to Images)', 'raw' => 'Raw (Screen Reader)' ); @@ -182,7 +182,7 @@ sub texenginechanger { 'change' => 'Save', 'exmpl' => 'Examples', 'mathjax' => 'MathJax:', - 'mathjaxinfo' => 'MathJax provides rendered equations whose source code can be extracted in TeX and MathML formats by right clicking the equation.', + 'mathjaxinfo' => 'MathJax provides rendered equations whose source code can be extracted in TeX and MathML formats by right clicking the equation.', 'tth' => 'tth (TeX to HTML):', 'mimetex' => 'mimetex (Convert to Images):', ); @@ -280,7 +280,7 @@ sub rolesprefchanger { my $hotlist_n=$userenv{'recentrolesn'}; my ($checkedon,$checkedoff); if ($hotlist_flag) { - $checkedon = 'checked="checked"'; + $checkedon = 'checked="checked"'; } else { $checkedoff = 'checked="checked"'; } @@ -683,16 +683,51 @@ sub verify_and_change_clicker { my $r = shift; my $user = $env{'user.name'}; my $domain = $env{'user.domain'}; + my $uhome = $env{'user.home'}; my $newclickers = $env{'form.clickers'}; + my $message; $newclickers=~s/[^\w\:\-]+/\,/gs; $newclickers=~tr/a-z/A-Z/; $newclickers=~s/[\:\-]+/\-/g; $newclickers=~s/\,+/\,/g; $newclickers=~s/^\,//; $newclickers=~s/\,$//; - &Apache::lonnet::put('environment',{'clickers' => $newclickers}); - &Apache::lonnet::appenv({'environment.clickers' => $newclickers}); - my $message=&Apache::lonhtmlcommon::confirm_success(&mt('Registering clickers: [_1]',$newclickers)); + my @oldclickers = split(/,/,$env{'environment.clickers'}); + my @newclickers = split(/,/,$newclickers); + my %newuniq; + map { $newuniq{$_} = 1; } @newclickers; + @newclickers = sort(keys(%newuniq)); + my @differences = &Apache::loncommon::compare_arrays(\@oldclickers,\@newclickers); + if (@differences) { + my $putres = &Apache::lonnet::put('environment',{'clickers' => $newclickers}); + if ($putres eq 'ok') { + my @adds = (); + my @dels = (); + foreach my $item (@differences) { + if (grep(/^\Q$item\E$/,@newclickers)) { + push(@adds,$item); + } else { + push(@dels,$item); + } + } + if (@dels) { + my %delclicker; + map { $delclicker{$_} = $user; } @dels; + my $putresult = &Apache::lonnet::iddel($domain,\%delclicker,$uhome,'clickers'); + } + if (@adds) { + my %addclicker; + map { $addclicker{$_} = $user; } @adds; + my $putresult = &Apache::lonnet::updateclickers($domain,'add',\%addclicker,$uhome,1); + } + &Apache::lonnet::appenv({'environment.clickers' => $newclickers}); + $message=&Apache::lonhtmlcommon::confirm_success(&mt('Registering clickers: [_1]',$newclickers)); + } else { + $message=&Apache::lonhtmlcommon::confirm_success(&mt('Error saving clicker ID').1); + } + } else { + $message=''.&mt('Clicker information unchanged').''; + } $message=&Apache::loncommon::confirmwrapper($message); &print_main_menu($r, $message); } @@ -1142,10 +1177,10 @@ sub colorschanger { foreach my $item (sort(keys(%colortypes))) { my $curcol=&Apache::loncommon::designparm($function.'.'.$item,$domain); $chtable.=&Apache::loncommon::start_data_table_row(). - '
'.$blocktext.'
'); return; @@ -1267,7 +1303,7 @@ sub passwordchanger { $domain = $data{'domain'}; $currentpass = $data{'temppasswd'}; my ($blocked,$blocktext) = - &Apache::loncommon::blocking_status('passwd',$user,$domain); + &Apache::loncommon::blocking_status('passwd',$clientip,$user,$domain); if ($blocked) { $r->print(''.$blocktext.'
'); return; @@ -1284,9 +1320,9 @@ sub passwordchanger { } else { $r->print( '' - .&mt('Sorry, the URL generated when you requested reset of' - .' your password contained incomplete information.') - .'
' + .&mt('Sorry, the URL generated when you requested reset of' + .' your password contained incomplete information.') + .'' ); return; } @@ -1401,7 +1437,7 @@ sub jscript_send { var posspass = this.document.client.elements.newpass_1.value; if (min > 0) { if (posspass.length < min) { - errors.push("$js_lt{'short'}"); + errors.push("$js_lt{'short'}"); } } if (currauth == 'internal:') { @@ -1430,7 +1466,7 @@ sub jscript_send { } else if (rules[i] == 'spec') { var pattern = /^[!@#$%^&*()_+\\-=\\[\\]{};':"\\\|,.\\/?]/; if (!posspass.match(pattern)) { - errors.push("$js_lt{'spec'}"); + errors.push("$js_lt{'spec'}"); } } } @@ -1588,7 +1624,7 @@ sub server_form { sub verify_and_change_password { my ($r,$caller,$mailtoken,$timelimit,$extrafields,$ended) = @_; - my ($user,$domain,$homeserver); + my ($user,$domain,$homeserver,$clientip); if ($caller eq 'reset_by_email') { $user = $env{'form.uname'}; $domain = $env{'form.udom'}; @@ -1611,8 +1647,9 @@ sub verify_and_change_password { $domain = $env{'user.domain'}; $homeserver = $env{'user.home'}; } + $clientip = &Apache::lonnet::get_requestor_ip($r); my ($blocked,$blocktext) = - &Apache::loncommon::blocking_status('passwd',$user,$domain); + &Apache::loncommon::blocking_status('passwd',$clientip,$user,$domain); if ($blocked) { $r->print(''.$blocktext.'
'); if ($caller eq 'reset_by_email') { @@ -1723,10 +1760,10 @@ ENDERROR } else { my $warning = &Apache::loncommon::check_passwd_rules($domain,$newpass1); if ($warning) { - &passwordchanger($r,''. - $warning. - &mt('Please try again.').'', - $caller,$mailtoken,$timelimit,$extrafields); + &passwordchanger($r,''. + $warning. + &mt('Please try again.').'', + $caller,$mailtoken,$timelimit,$extrafields); if ($caller eq 'reset_by_email') { return 'rules'; } else { @@ -2092,13 +2129,9 @@ sub change_authoring_settings { sub lockednameschanger { my $r = shift; - &Apache::lonhtmlcommon::add_breadcrumb( - { href => '/adm/preferences?action=changelockednames', - text => 'Automatic name changes'}); - $r->print(Apache::loncommon::start_page('Automatic name changes')); - $r->print(Apache::lonhtmlcommon::breadcrumbs('Allow/disallow name updates')); my %userenv = &Apache::lonnet::get('environment',['lockedname']); my $lockedname=''; + my $ended; if (&can_toggle_namelocking()) { if ($userenv{'lockedname'}) { $lockedname = ' checked="checked"'; @@ -2116,6 +2149,11 @@ sub lockednameschanger { } } if (keys(%updateable)) { + &Apache::lonhtmlcommon::add_breadcrumb( + { href => '/adm/preferences?action=changelockednames', + text => 'Automatic name changes'}); + $r->print(Apache::loncommon::start_page('Automatic name changes')); + $r->print(Apache::lonhtmlcommon::breadcrumbs('Allow/disallow name updates')); my %longnames = &Apache::lonlocal::texthash ( firstname => 'First Name', middlename => 'Middle Name', @@ -2142,11 +2180,14 @@ ENDSCREEN } else { my $message = &mt('Based on your institutional affiliation no name information is automatically updated for your LON-CAPA account.'); &print_main_menu($r,$message); + $ended = 1; } } else { my $message = &mt('You are not permitted to set a user preference for automatic name updates for your LON-CAPA account.'); &print_main_menu($r,$message); + $ended = 1; } + return $ended; } sub verify_and_change_lockednames { @@ -2177,6 +2218,120 @@ sub verify_and_change_lockednames { &print_main_menu($r,$message); } +sub timezonechanger { + my $r = shift; + my $uname = $env{'user.name'}; + my $udom = $env{'user.domain'}; + if (&Apache::lonnet::usertools_access($uname,$udom,'timezone')) { + my $js = <<"ENDSCRIPT"; + +ENDSCRIPT + my %loaditems = ( + onload => 'javascript:toggleTZdisplay(document.prefs);', + ); + my $args = { 'add_entries' => \%loaditems }; + &Apache::lonhtmlcommon::add_breadcrumb( + { href => '/adm/preferences?action=', + text => 'Set Your Time Zone'}); + $r->print(Apache::loncommon::start_page('Set Your Time Zone',$js,$args)); + $r->print(Apache::lonhtmlcommon::breadcrumbs('Set Your Time Zone')); + my %userenv = &Apache::lonnet::get('environment',['timezone']); + my $timezone = $userenv{'timezone'}; + my %lt = &Apache::lonlocal::texthash( + lctz => 'Use Time Zone set by LON-CAPA', + owntz => 'Use Time Zone set by you', + save => 'Save', + ); + my (%checked,$tzsty); + if ($userenv{'timezone'} ne '') { + $checked{'owntz'} = ' checked="checked"'; + $tzsty = 'inline-block'; + } else { + $checked{'lctz'} = ' checked="checked"'; + $tzsty = 'none'; + } + my $onclick = ' onclick="javascript:toggleTZdisplay(this.form);"'; + my $selector = &Apache::loncommon::select_timezone('timezone',$timezone,undef,1); + $r->print(<<"END"); + +END + } + return; +} + +sub verify_and_change_timezone { + my $r = shift; + my $currtimezone = $env{'environment.timezone'}; + my $newtimezone; + if ($env{'form.settimezone'}) { + $newtimezone = $env{'form.timezone'}; + if (DateTime::TimeZone->is_valid_name($env{'form.timezone'})) { + $newtimezone = $env{'form.timezone'}; + } + } + my $message=''; + if ($newtimezone) { + if ($newtimezone eq $currtimezone) { + $message = &mt('Time Zone settings unchanged'); + } else { + &Apache::lonnet::put('environment',{'timezone' => $newtimezone}); + &Apache::lonnet::appenv({'environment.timezone' => $newtimezone}); + $message=&Apache::lonhtmlcommon::confirm_success( + &mt('Set [_1] to [_2]', + ''.&mt('Your Time Zone').'', + '"'.$newtimezone.'".')). + '