--- loncom/interface/lonpreferences.pm 2011/10/10 22:38:20 1.186.2.8 +++ loncom/interface/lonpreferences.pm 2019/08/21 22:41:13 1.235 @@ -1,7 +1,7 @@ # The LearningOnline Network # Preferences # -# $Id: lonpreferences.pm,v 1.186.2.8 2011/10/10 22:38:20 raeburn Exp $ +# $Id: lonpreferences.pm,v 1.235 2019/08/21 22:41:13 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -27,8 +27,6 @@ # # This package uses the "londes.js" javascript code. # -# TODOs that have to be completed: -# interface with lonnet to change the password package Apache::lonpreferences; @@ -36,8 +34,6 @@ use strict; use LONCAPA; use Apache::Constants qw(:common); use Apache::File; -use Crypt::DES; -use DynaLoader; # for Crypt::DES version use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::lonlocal; @@ -45,50 +41,6 @@ use Apache::lonnet; use LONCAPA::lonauthcgi(); use LONCAPA(); -# -# Write lonnet::passwd to do the call below. -# Use: -# my $answer=reply("encrypt:passwd:$udom:$uname:$upass",$tryserver); -# -################################################## -# password associated functions # -################################################## -sub des_keys { - # Make a new key for DES encryption. - # Each key has two parts which are returned separately. - # Please note: Each key must be passed through the &hex function - # before it is output to the web browser. The hex versions cannot - # be used to decrypt. - my @hexstr=('0','1','2','3','4','5','6','7', - '8','9','a','b','c','d','e','f'); - my $lkey=''; - for (0..7) { - $lkey.=$hexstr[rand(15)]; - } - my $ukey=''; - for (0..7) { - $ukey.=$hexstr[rand(15)]; - } - return ($lkey,$ukey); -} - -sub des_decrypt { - my ($key,$cyphertext) = @_; - my $keybin=pack("H16",$key); - my $cypher; - if ($Crypt::DES::VERSION>=2.03) { - $cypher=new Crypt::DES $keybin; - } else { - $cypher=new DES $keybin; - } - my $plaintext= - $cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,0,16)))); - $plaintext.= - $cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,16,16)))); - $plaintext=substr($plaintext,1,ord(substr($plaintext,0,1)) ); - return $plaintext; -} - ################################################################ # Handler subroutines # ################################################################ @@ -152,32 +104,16 @@ sub languagechanger { text => 'Change Language'}); $r->print(Apache::loncommon::start_page('Content Display Settings')); $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Language')); - my $user = $env{'user.name'}; - my $domain = $env{'user.domain'}; - my %userenv = &Apache::lonnet::get - ('environment',['languages']); + my %userenv = &Apache::lonnet::get('environment',['languages']); my $language=$userenv{'languages'}; - my $pref=&mt('Preferred language'); - my %langchoices=('' => 'No language preference'); - foreach (&Apache::loncommon::languageids()) { - if (&Apache::loncommon::supportedlanguagecode($_)) { - $langchoices{&Apache::loncommon::supportedlanguagecode($_)} - = &Apache::loncommon::plainlanguagedescription($_); - } - } - %langchoices = &Apache::lonlocal::texthash(%langchoices); - my $selectionbox= - &Apache::loncommon::select_form( - $language, - 'language', - \%langchoices); - $r->print(< - -
$pref: $selectionbox -ENDLSCREEN - $r->print('
'); + $r->print( + '
'."\n". + ''. + '
'.&mt('Preferred language').': '. + &Apache::loncommon::select_language('language',$language,1).''."\n". + '
' + ); } @@ -222,11 +158,14 @@ sub texenginechanger { my $domain = $env{'user.domain'}; my %userenv = &Apache::lonnet::get('environment',['texengine']); my $texengine=$userenv{'texengine'}; + if (lc($texengine) eq 'jsmath') { + $texengine = 'MathJax'; + } my %mathchoices=('' => 'Default', 'tth' => 'tth (TeX to HTML)', #'ttm' => 'TeX to MathML', - 'jsMath' => 'jsMath', + 'MathJax' => 'MathJax', 'mimetex' => 'mimetex (Convert to Images)', 'raw' => 'Raw (Screen Reader)' ); @@ -236,32 +175,18 @@ sub texenginechanger { $texengine, 'texengine', \%mathchoices); - my $jsMath_start=&Apache::lontexconvert::jsMath_header(); + my $MathJax_start=&Apache::lontexconvert::MathJax_header(); my %lt=&Apache::lonlocal::texthash( 'headline' => 'Change how math is displayed', 'preftxt' => 'Preferred method to display math', 'change' => 'Save', 'exmpl' => 'Examples', - 'jsmath' => 'jsMath:', + 'mathjax' => 'MathJax:', + '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):', ); - my $jsMathWarning='

' - .'

' - .&mt("It looks like you don't have the TeX math fonts installed.") - .'
' - .'
' - .&mt('The jsMath example on this page may not look right without them. ' - .'The [_1]jsMath Home Page[_2] has information on how to download the ' - .'needed fonts. In the meantime, jsMath will do the best it can ' - .'with the fonts you have, but it may not be pretty and some equations ' - .'may not be rendered correctly.' - ,'' - ,'') - .'
' - .'

'; - $r->print(<$lt{'headline'}
@@ -276,30 +201,24 @@ $lt{'preftxt'}: $selectionbox
$lt{'exmpl'} -

$lt{'jsmath'}

-

-$jsMath_start - - + +

+

+$lt{'mathjaxinfo'}

$lt{'mimetex'}

- +

$lt{'tth'}

- +

ENDLSCREEN - if ($env{'environment.texengine'} ne 'jsMath') { - $r->print(''); - } } @@ -310,6 +229,9 @@ sub verify_and_change_texengine { # Screenname my $newtexengine = $env{'form.texengine'}; $newtexengine=~s/[^\-\w]//g; + if (lc($newtexengine) eq 'jsmath') { + $newtexengine = 'MathJax'; + } if ($newtexengine eq 'ttm') { &Apache::lonnet::appenv({'browser.mathml' => 1}); } else { @@ -342,16 +264,25 @@ sub rolesprefchanger { my $domain = $env{'user.domain'}; my %userenv = &Apache::lonnet::get ('environment',['recentroles','recentrolesn']); + my $brtext = 'Change '.$role.' Page Pref'; + my $brtitle; + if ($env{'form.returnurl'} eq '/adm/roles') { + $brtext = 'Configure Hotlist'; + } else { + $brtitle = $brtext; + } Apache::lonhtmlcommon::add_breadcrumb( { href => '/adm/preferences?action=changerolespref', - text => 'Change '.$role.' Page Pref'}); + text => $brtext}); $r->print(Apache::loncommon::start_page('Content Display Settings')); - $r->print(Apache::lonhtmlcommon::breadcrumbs('Change '.$role.' Page Pref')); + $r->print(Apache::lonhtmlcommon::breadcrumbs($brtitle)); my $hotlist_flag=$userenv{'recentroles'}; my $hotlist_n=$userenv{'recentrolesn'}; - my $checked; + my ($checkedon,$checkedoff); if ($hotlist_flag) { - $checked = 'checked="checked"'; + $checkedon = 'checked="checked"'; + } else { + $checkedoff = 'checked="checked"'; } if (!$hotlist_n) { $hotlist_n=3; } @@ -378,7 +309,7 @@ sub rolesprefchanger { &Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row(). "".&mt('Freeze '.$role)."". - "".&mt($role)."". + "".&mt($role)."". &Apache::loncommon::end_data_table_header_row(). "\n"; my $count; @@ -401,28 +332,51 @@ sub rolesprefchanger { $roles_check_list .= "\n"; } + my $actionurl = '/adm/preferences'; + if ($env{'form.returnurl'} eq '/adm/roles') { + $actionurl = '/adm/roles'; + } + $r->print('

'.&mt('Recent Roles Hotlist').'

'); + unless ($checkedon) { + $r->print(&mt('LON-CAPA users with several '.$lc_role.'s may wish to enable the Hotlist.').'
'); + } $r->print(' -

'.&mt('Some LON-CAPA users have a long list of '.$lc_role.'s. The Recent '.$role.'s Hotlist feature keeps track of the last N '.$lc_role.'s which have been visited and places a table of these at the top of the '.$lc_role.'s page. People with very few '.$lc_role.'s should leave this feature disabled.').' -

- + -
'. -'

'.&mt('Recent '.$role.'s Hotlist').'

'. + +

'.&mt('Hotlist options').'

+

'. +&mt('When enabled, the Hotlist keeps track of the last N '.$lc_role.'s visited.').'
'. +&mt('Those N '.$lc_role.'s are then shown in a table at the top of the '.$lc_role.'s page.').'

'. &Apache::lonhtmlcommon::start_pick_box(). -&Apache::lonhtmlcommon::row_title(''). -''. +&Apache::lonhtmlcommon::row_title(&mt('Use Recent '.$role.'s Hotlist')). +' +'. +(' 'x2). +' +'. &Apache::lonhtmlcommon::row_closure(). &Apache::lonhtmlcommon::row_title(''). ''. +$options.' +'. &Apache::lonhtmlcommon::row_closure(1). -&Apache::lonhtmlcommon::end_pick_box(). -'

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

'. -'

'.&mt('This list below can be used to freeze '.$lc_role.'s on your screen. Those marked as frozen will not be removed from the list, even if they have not been used recently.').' +&Apache::lonhtmlcommon::end_pick_box().' +

'); + 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.','','').'
'. +&mt('Those '.$lc_role.'s marked frozen will not be removed from the list, even if not recently used.').'

'.$roles_check_list.' -
+
'); + } else { + $r->print('
'. + &mt('Once the Hotlist contains recently visited '.$lc_role.'s you can return to this page to also set frozen roles.')); + } + $r->print(' +
'); } @@ -513,11 +467,14 @@ sub verify_and_change_rolespref { } } $message=&Apache::loncommon::confirmwrapper($message); - &print_main_menu($r, $message); + if ($env{'form.returnurl'} eq '/adm/roles') { + return $message; + } else { + &print_main_menu($r, $message); + } } - ################################################################ # Anonymous Discussion Name Change Subroutines # ################################################################ @@ -620,7 +577,7 @@ sub iconchanger { my ($inlinetools,$toolsorder) = &icon_previews(); if ((ref($inlinetools) eq 'HASH') && (ref($toolsorder) eq 'ARRAY')) { foreach my $tool (@{$toolsorder}) { - my ($command,$row,$col,$img,$top,$bot,$act,$desc) = + my ($command,$row,$col,$img,$top,$bot,$act,$desc) = split(/\&/,$inlinetools->{$tool}); $iconic_preview .= '
  • '.$desc.''.$top.(' ' x 2).'
  • '; $iconsonly_preview .= '
  • '.$desc.' 
  • '; @@ -633,7 +590,7 @@ sub iconchanger { $iconic_preview = ''; + ''; $r->print(< @@ -663,17 +620,16 @@ sub verify_and_change_icons { } sub icon_options { - my %lt = &Apache::lonlocal::texthash( - iconic => 'Use icons and text', - iconsonly => 'Use icons only', - ); - return %lt; + return &Apache::lonlocal::texthash( + iconic => 'Use icons and text', + iconsonly => 'Use icons only', + ); } sub icon_previews { my %icon_text = ( annotate => 'Notes', - bookmark => 'Bookmark', + wishlist => 'Stored Links', catalog => 'Info', evaluate => 'Evaluate', feedback => 'Communicate', @@ -681,13 +637,13 @@ sub icon_previews { ); my %inlinetools = ( printout => "s&8&3&prt.png&$icon_text{'printout'}&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document", - bookmark => "s&9&1&sbkm.png&$icon_text{'bookmark'}&bookmark[_2]&set_bookmark()&Set a bookmark for this resource", + 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 bookmark evaluate feedback printout catalog); + my @toolsorder = qw(annotate wishlist evaluate feedback printout catalog); return (\%inlinetools,\@toolsorder); } @@ -727,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); } @@ -760,11 +751,13 @@ sub domcoordchanger { if ($userenv{'domcoord.author'} eq 'blocked') { $constchecked=' checked="checked"'; } - my $text=&mt('By default, the Domain Coordinator can enter your construction space.'); - my $construction=&mt('Block access to construction space'); + my $text=&mt('By default, the Domain Coordinator can enter your Authoring Space.'); + my $construction=&mt('Block access to Authoring Space'); my $change=&mt('Save'); + my $returnurl = &HTML::Entities::encode($env{'form.returnurl'},'"<>&\''); $r->print(< + $text

    @@ -787,9 +780,13 @@ sub verify_and_change_domcoord { } else { $status=&mt('off'); } - my $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]',''.&mt('Block access to construction space').'',''.$status.'')); + my $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]',''.&mt('Block access to Authoring Space').'',''.$status.'')); $message=&Apache::loncommon::confirmwrapper($message); - &print_main_menu($r,$message); + if ($env{'form.returnurl'}) { + &do_redirect($r,$env{'form.returnurl'},$message); + } else { + &print_main_menu($r,$message); + } } ################################################################# @@ -803,7 +800,7 @@ sub lockwarning { my $textbottom=&mt('Changing roles or logging out may result in data corruption.'); my ($num,%which)=&Apache::lonnet::get_locks(); my $which=''; - foreach my $id (keys %which) { + foreach my $id (keys(%which)) { $which.='
  • '.$which{$id}.'
  • '; } my $change=&mt('Override'); @@ -845,15 +842,15 @@ sub msgforwardchanger { foad => 'Forward to account(s)', fwdm => 'Forward messages to other account(s) in LON-CAPA', noti => 'E-mail notification of LON-CAPA messages', - foad_exmpl => 'e.g. userA:domain1,userB:domain2,...', mnot => 'E-mail address(es) which should be notified about new LON-CAPA messages', - mnot_exmpl => 'e.g. joe@doe.com', chg => 'Save', email => 'The e-mail address entered in row ', notv => 'is not a valid e-mail address', toen => "To enter multiple addresses, enter one address at a time, click 'Change' and then add the next one", prme => 'Back', ); + $lt{'foad_exmpl'} = &mt('e.g. [_1]userA:domain1,userB:domain2,...[_2]','',''); + $lt{'mnot_exmpl'} = &mt('e.g. [_1]joe@doe.com[_2]','',''); Apache::lonhtmlcommon::add_breadcrumb( { href => '/adm/preferences?action=changemsgforward', text => 'Messages & Notifications'}); @@ -957,7 +954,7 @@ ENDMSG '" onclick="javscript:delete_address('."'$num'".')" />'. &mt('Delete').''. ''; my %chk; if (defined($allnot{$item}{'crit'})) { @@ -1006,7 +1003,7 @@ ENDMSG ''.&mt('Add new address').''. ''; + '" onfocus="javascript:new_address('."'$num'".')" />'; foreach my $type ('all','crit','reg') { $output .= '