--- loncom/interface/lonpreferences.pm 2024/02/28 06:28:07 1.196.4.28.2.2 +++ loncom/interface/lonpreferences.pm 2019/04/24 21:12:44 1.230 @@ -1,7 +1,7 @@ # The LearningOnline Network # Preferences # -# $Id: lonpreferences.pm,v 1.196.4.28.2.2 2024/02/28 06:28:07 raeburn Exp $ +# $Id: lonpreferences.pm,v 1.230 2019/04/24 21:12:44 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -31,6 +31,7 @@ package Apache::lonpreferences; use strict; +use LONCAPA; use Apache::Constants qw(:common); use Apache::File; use Apache::loncommon(); @@ -39,7 +40,6 @@ 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"'; } @@ -363,7 +363,7 @@ $options.' &Apache::lonhtmlcommon::row_closure(1). &Apache::lonhtmlcommon::end_pick_box().' '); - if ($roles_check_list) { + if ($roles_check_list) { $r->print('

'.&mt('Freeze Roles').'

'.&mt('The table below can be used to [_1]freeze[_2] '.$lc_role.'s in the Hotlist.','','').'
'. @@ -627,7 +627,7 @@ sub icon_options { } sub icon_previews { - my %icon_text = &Apache::lonlocal::texthash ( + my %icon_text = ( annotate => 'Notes', wishlist => 'Stored Links', catalog => 'Info', @@ -636,12 +636,12 @@ sub icon_previews { printout => 'Print', ); my %inlinetools = ( - printout => "s&8&3&prt.png&$icon_text{'printout'}&printout[_1]&gopost('/adm/printout',currentURL)&".&mt('Prepare a printable document'), - wishlist => "s&9&1&wishlist-link.png&$icon_text{'wishlist'}&wishlistlink[_2]&set_wishlistlink()&".&mt('Save a link for this resource in your personal Stored Links repository'), - evaluate => "s&8&1&eval.png&$icon_text{'evaluate'}&this[_1]&gopost('/adm/evaluate',currentURL,1)&".&mt('Provide my evaluation of this resource'), - feedback => "s&8&2&fdbk.png&$icon_text{'feedback'}&discuss[_1]&gopost('/adm/feedback',currentURL,1)&".&mt('Provide feedback messages or contribute to the course discussion about this resource'), - annotate => "s&9&3&anot.png&$icon_text{'annotate'}&tations[_1]&annotate()&".&mt('Make notes and annotations about this resource'), - catalog => "s&6&3&catalog.png&$icon_text{'catalog'}&info[_1]&catalog_info()&".&mt('Show Metadata'), + printout => "s&8&3&prt.png&$icon_text{'printout'}&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document", + wishlist => "s&9&1&wishlist-link.png&$icon_text{'wishlist'}&wishlistlink[_2]&set_wishlistlink()&Save a link for this resource in your personal Stored Links repository", + evaluate => "s&8&1&eval.png&$icon_text{'evaluate'}&this[_1]&gopost('/adm/evaluate',currentURL,1)&Provide my evaluation of this resource", + feedback => "s&8&2&fdbk.png&$icon_text{'feedback'}&discuss[_1]&gopost('/adm/feedback',currentURL,1)&Provide feedback messages or contribute to the course discussion about this resource", + annotate => "s&9&3&anot.png&$icon_text{'annotate'}&tations[_1]&annotate()&Make notes and annotations about this resource", + catalog => "s&6&3&catalog.png&$icon_text{'catalog'}&info[_1]&catalog_info()&Show Metadata", ); my @toolsorder = qw(annotate wishlist evaluate feedback printout catalog); return (\%inlinetools,\@toolsorder); @@ -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(). - ''.$colortypes{$item}.''. - &Apache::loncommon::end_data_table_row()."\n"; + ''.$colortypes{$item}.''. + &Apache::loncommon::end_data_table_row()."\n"; } my $end_data_table = &Apache::loncommon::end_data_table(); my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition(); @@ -1197,9 +1232,9 @@ sub verify_and_change_colors { my $message=''; foreach my $item (keys(%colortypes)) { my $color=$env{'form.'.$item}; - if (!($color =~ /^#/)) { - $color = '#' . $color; - } + if (!($color =~ /^#/)) { + $color = '#' . $color; + } my $entry='color.'.$function.'.'.$item; if (($color=~/^\#[0-9A-Fa-f]{6}$/) && (!$env{'form.resetall'})) { &Apache::lonnet::put('environment',{$entry => $color}); @@ -1230,8 +1265,7 @@ sub passwordchanger { # This function is a bit of a mess.... # Passwords are encrypted using londes.js (DES encryption) $errormessage = ($errormessage || ''); - my ($user,$domain,$currentpass,$clientip); - $clientip = &Apache::lonnet::get_requestor_ip($r); + my ($user,$domain,$currentpass); &Apache::lonhtmlcommon::add_breadcrumb( { href => '/adm/preferences?action=changepass', text => 'Change Password'}); @@ -1239,18 +1273,18 @@ sub passwordchanger { $r->print(Apache::loncommon::start_page('Personal Data')); $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Password')); } + my ($blocked,$blocktext) = + &Apache::loncommon::blocking_status('passwd'); + if ($blocked) { + $r->print('

'.$blocktext.'

'); + return; + } if ((!defined($caller)) || ($caller eq 'preferences')) { $user = $env{'user.name'}; $domain = $env{'user.domain'}; if (!defined($caller)) { $caller = 'preferences'; } - my ($blocked,$blocktext) = - &Apache::loncommon::blocking_status('passwd',$clientip); - if ($blocked) { - $r->print('

'.$blocktext.'

'); - return; - } } elsif ($caller eq 'reset_by_email') { my %data = &Apache::lonnet::tmpget($mailtoken); if (keys(%data) == 0) { @@ -1267,12 +1301,6 @@ sub passwordchanger { $user = $data{'username'}; $domain = $data{'domain'}; $currentpass = $data{'temppasswd'}; - my ($blocked,$blocktext) = - &Apache::loncommon::blocking_status('passwd',$clientip,$user,$domain); - if ($blocked) { - $r->print('

'.$blocktext.'

'); - return; - } } else { $r->print( '

' @@ -1282,12 +1310,12 @@ sub passwordchanger { ); return; } - } else { + } 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; } @@ -1332,7 +1360,7 @@ sub passwordchanger { my $jsh=Apache::File->new($include."/londes.js"); $r->print(<$jsh>); } - $r->print(&jscript_send($caller,$domain,$currentauth,$extrafields)); + $r->print(&jscript_send($caller,$extrafields)); $r->print(< 'New password needs at least one upper case letter', - lc => 'New password needs at least one lower case letter', - num => 'New password needs at least one number', - spec => 'New password needs at least one non-alphanumeric', - blank1 => 'Empty Password field', - blank2 => 'Empty Confirm Password field', - mismatch => 'Contents of Password and Confirm Password fields must match', - fail => 'Please fix the following:', - ); - &js_escape(\%js_lt); - if ($currentauth eq 'internal:') { - if ($domain ne '') { - my %passwdconf = &Apache::lonnet::get_passwdconf($domain); - if (keys(%passwdconf)) { - if ($passwdconf{min}) { - $min = $passwdconf{min}; - } - if ($passwdconf{max}) { - $max = $passwdconf{max}; - $js_lt{'long'} = &js_escape(&mt('Maximum password length: [_1]',$max)); - } - if (ref($passwdconf{chars}) eq 'ARRAY') { - if (@{$passwdconf{chars}}) { - $rulestr = join('","',@{$passwdconf{chars}}); - $numrules = scalar(@{$passwdconf{chars}}); - } - } - } - } - } - $js_lt{'short'} = &js_escape(&mt('Minimum password length: [_1]',$min)); - - my $passwdcheck = <<"ENDJS"; - var errors = new Array(); - var min = parseInt("$min") || 0; - var currauth = "$currentauth"; - if (this.document.client.elements.newpass_1.value == '') { - errors.push("$js_lt{'blank1'}"); - } - if (this.document.client.elements.newpass_2.value == '') { - errors.push("$js_lt{'blank2'}"); - } - if (errors.length == 0) { - if (this.document.client.elements.newpass_1.value != this.document.client.elements.newpass_2.value) { - errors.push("$js_lt{'mismatch'}"); - } - var posspass = this.document.client.elements.newpass_1.value; - if (min > 0) { - if (posspass.length < min) { - errors.push("$js_lt{'short'}"); - } - } - if (currauth == 'internal:') { - var max = parseInt("$max") || 0; - if (max > 0) { - if (posspass.length > max) { - errors.push("$js_lt{'long'}"); - } - } - var numrules = parseInt("$numrules") || 0; - if (numrules > 0) { - var rules = new Array("$rulestr"); - for (var i=0; i\\/?]/; - if (!posspass.match(pattern)) { - errors.push("$js_lt{'spec'}"); - } - } - } - } - } - } - if (errors.length > 0) { - alert("$js_lt{'fail'}"+"\\n\\n"+errors.join("\\n")); - return; - } -ENDJS + my ($caller,$extrafields) = @_; my $output = qq| -ENDSCRIPT -} - -sub selectbox { - my ($name,$value,$readonly,$functionref,@idlist)=@_; - my $selout = ''; - return $selout; -} - 1; __END__