Annotation of loncom/interface/lonpreferences.pm, revision 1.186.2.7
1.1 www 1: # The LearningOnline Network
2: # Preferences
3: #
1.186.2.7! raeburn 4: # $Id: lonpreferences.pm,v 1.186.2.6 2011/05/16 00:57:08 raeburn Exp $
1.2 albertel 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
1.3 matthew 28: # This package uses the "londes.js" javascript code.
29: #
30: # TODOs that have to be completed:
31: # interface with lonnet to change the password
32:
1.1 www 33: package Apache::lonpreferences;
34:
35: use strict;
1.86 albertel 36: use LONCAPA;
1.1 www 37: use Apache::Constants qw(:common);
1.3 matthew 38: use Apache::File;
39: use Crypt::DES;
40: use DynaLoader; # for Crypt::DES version
1.4 matthew 41: use Apache::loncommon();
1.23 matthew 42: use Apache::lonhtmlcommon();
1.32 www 43: use Apache::lonlocal;
1.59 albertel 44: use Apache::lonnet;
1.174 raeburn 45: use LONCAPA::lonauthcgi();
1.95 albertel 46: use LONCAPA();
1.3 matthew 47:
48: #
49: # Write lonnet::passwd to do the call below.
50: # Use:
51: # my $answer=reply("encrypt:passwd:$udom:$uname:$upass",$tryserver);
52: #
53: ##################################################
54: # password associated functions #
55: ##################################################
56: sub des_keys {
1.4 matthew 57: # Make a new key for DES encryption.
1.36 www 58: # Each key has two parts which are returned separately.
1.4 matthew 59: # Please note: Each key must be passed through the &hex function
60: # before it is output to the web browser. The hex versions cannot
61: # be used to decrypt.
1.3 matthew 62: my @hexstr=('0','1','2','3','4','5','6','7',
63: '8','9','a','b','c','d','e','f');
64: my $lkey='';
65: for (0..7) {
66: $lkey.=$hexstr[rand(15)];
67: }
68: my $ukey='';
69: for (0..7) {
70: $ukey.=$hexstr[rand(15)];
71: }
72: return ($lkey,$ukey);
73: }
74:
75: sub des_decrypt {
76: my ($key,$cyphertext) = @_;
77: my $keybin=pack("H16",$key);
78: my $cypher;
79: if ($Crypt::DES::VERSION>=2.03) {
80: $cypher=new Crypt::DES $keybin;
81: } else {
82: $cypher=new DES $keybin;
83: }
84: my $plaintext=
85: $cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,0,16))));
86: $plaintext.=
87: $cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,16,16))));
1.4 matthew 88: $plaintext=substr($plaintext,1,ord(substr($plaintext,0,1)) );
1.3 matthew 89: return $plaintext;
90: }
91:
1.4 matthew 92: ################################################################
93: # Handler subroutines #
94: ################################################################
1.9 matthew 95:
96: ################################################################
1.28 www 97: # Language Change Subroutines #
98: ################################################################
1.44 www 99:
100: sub wysiwygchanger {
101: my $r = shift;
1.126 droeschl 102: Apache::lonhtmlcommon::add_breadcrumb(
103: { href => '/adm/preferences?action=changewysiwyg',
104: text => 'Change WYSIWYG Preferences'});
1.147 schafran 105: $r->print(Apache::loncommon::start_page('Content Display Settings'));
1.126 droeschl 106: $r->print(Apache::lonhtmlcommon::breadcrumbs('Change WYSIWYG Preferences'));
107:
1.44 www 108: my %userenv = &Apache::lonnet::get
109: ('environment',['wysiwygeditor']);
1.78 albertel 110: my $onselect='checked="checked"';
1.44 www 111: my $offselect='';
1.77 albertel 112: if ($userenv{'wysiwygeditor'} eq 'on') {
1.44 www 113: $onselect='';
1.78 albertel 114: $offselect='checked="checked"';
1.44 www 115: }
116: my $switchoff=&mt('Disable WYSIWYG editor');
117: my $switchon=&mt('Enable WYSIWYG editor');
1.124 www 118: my $warning='';
119: if ($env{'user.adv'}) {
1.185 droeschl 120: $warning.='<p class="LC_warning">'.&mt("The WYSIWYG editor only supports simple HTML and is in many cases unsuited for advanced authoring. In a number of cases, it may destroy advanced authoring involving LaTeX and script function calls.")."</p>";
1.124 www 121: }
1.44 www 122: $r->print(<<ENDLSCREEN);
1.88 albertel 123: <form name="prefs" action="/adm/preferences" method="post">
1.44 www 124: <input type="hidden" name="action" value="set_wysiwyg" />
1.124 www 125: $warning
1.44 www 126: <br />
1.65 albertel 127: <label><input type="radio" name="wysiwyg" value="off" $onselect /> $switchoff</label><br />
128: <label><input type="radio" name="wysiwyg" value="on" $offselect /> $switchon</label>
1.44 www 129: ENDLSCREEN
1.136 schafran 130: $r->print('<br /><input type="submit" value="'.&mt('Save').'" />');
1.44 www 131: }
132:
133:
134: sub verify_and_change_wysiwyg {
135: my $r = shift;
1.59 albertel 136: my $newsetting=$env{'form.wysiwyg'};
1.44 www 137: &Apache::lonnet::put('environment',{'wysiwygeditor' => $newsetting});
1.116 raeburn 138: &Apache::lonnet::appenv({'environment.wysiwygeditor' => $newsetting});
1.158 bisitz 139: my $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('WYSIWYG Editor').'</i>','<tt>'.&mt($newsetting).'</tt>'));
140: $message=&Apache::loncommon::confirmwrapper($message);
141: &print_main_menu($r,$message);
1.44 www 142: }
143:
144: ################################################################
145: # Language Change Subroutines #
146: ################################################################
1.28 www 147: sub languagechanger {
148: my $r = shift;
1.126 droeschl 149:
150: Apache::lonhtmlcommon::add_breadcrumb(
151: { href => '/adm/preferences?action=changelanguages',
1.127 droeschl 152: text => 'Change Language'});
1.147 schafran 153: $r->print(Apache::loncommon::start_page('Content Display Settings'));
1.126 droeschl 154: $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Language'));
1.59 albertel 155: my $user = $env{'user.name'};
156: my $domain = $env{'user.domain'};
1.28 www 157: my %userenv = &Apache::lonnet::get
1.32 www 158: ('environment',['languages']);
1.29 www 159: my $language=$userenv{'languages'};
1.32 www 160:
1.33 www 161: my $pref=&mt('Preferred language');
162: my %langchoices=('' => 'No language preference');
163: foreach (&Apache::loncommon::languageids()) {
164: if (&Apache::loncommon::supportedlanguagecode($_)) {
165: $langchoices{&Apache::loncommon::supportedlanguagecode($_)}
166: = &Apache::loncommon::plainlanguagedescription($_);
167: }
168: }
1.186.2.4 raeburn 169: %langchoices = &Apache::lonlocal::texthash(%langchoices);
1.179 bisitz 170: my $selectionbox=
171: &Apache::loncommon::select_form(
172: $language,
173: 'language',
1.186.2.4 raeburn 174: \%langchoices);
1.28 www 175: $r->print(<<ENDLSCREEN);
1.88 albertel 176: <form name="prefs" action="/adm/preferences" method="post">
1.28 www 177: <input type="hidden" name="action" value="verify_and_change_languages" />
1.33 www 178: <br />$pref: $selectionbox
1.28 www 179: ENDLSCREEN
1.136 schafran 180: $r->print('<br /><input type="submit" value="'.&mt('Save').'" />');
1.28 www 181: }
182:
183:
184: sub verify_and_change_languages {
185: my $r = shift;
1.59 albertel 186: my $user = $env{'user.name'};
187: my $domain = $env{'user.domain'};
1.28 www 188: # Screenname
1.59 albertel 189: my $newlanguage = $env{'form.language'};
1.28 www 190: $newlanguage=~s/[^\-\w]//g;
191: my $message='';
192: if ($newlanguage) {
1.29 www 193: &Apache::lonnet::put('environment',{'languages' => $newlanguage});
1.116 raeburn 194: &Apache::lonnet::appenv({'environment.languages' => $newlanguage});
1.183 bisitz 195: $message=&Apache::lonhtmlcommon::confirm_success(
196: &mt('Set [_1] to [_2]',
197: '<i>'.&mt('Preferred language').'</i>',
198: '<tt>"'.$newlanguage.'"</tt>.'))
199: .'<br />'
200: .&mt('The change will become active on the next page.');
1.28 www 201: } else {
1.29 www 202: &Apache::lonnet::del('environment',['languages']);
1.139 raeburn 203: &Apache::lonnet::delenv('environment.languages');
1.158 bisitz 204: $message=&Apache::lonhtmlcommon::confirm_success(&mt('Reset [_1]','<i>'.&mt('Preferred language').'</i>'));
1.28 www 205: }
1.158 bisitz 206: $message=&Apache::loncommon::confirmwrapper($message);
1.132 raeburn 207: &Apache::loncommon::flush_langs_cache($user,$domain);
1.152 www 208: &print_main_menu($r, $message);
1.28 www 209: }
210:
1.50 albertel 211: ################################################################
1.54 albertel 212: # Tex Engine Change Subroutines #
213: ################################################################
214: sub texenginechanger {
215: my $r = shift;
1.126 droeschl 216: Apache::lonhtmlcommon::add_breadcrumb(
217: { href => '/adm/preferences?action=changetexenginepref',
1.177 raeburn 218: text => 'Math display settings'});
1.147 schafran 219: $r->print(Apache::loncommon::start_page('Content Display Settings'));
1.177 raeburn 220: $r->print(Apache::lonhtmlcommon::breadcrumbs('Math display settings'));
1.59 albertel 221: my $user = $env{'user.name'};
222: my $domain = $env{'user.domain'};
1.54 albertel 223: my %userenv = &Apache::lonnet::get('environment',['texengine']);
224: my $texengine=$userenv{'texengine'};
225:
1.69 albertel 226: my %mathchoices=('' => 'Default',
1.123 bisitz 227: 'tth' => 'tth (TeX to HTML)',
1.64 albertel 228: #'ttm' => 'TeX to MathML',
1.54 albertel 229: 'jsMath' => 'jsMath',
1.168 www 230: 'mimetex' => 'mimetex (Convert to Images)',
231: 'raw' => 'Raw (Screen Reader)'
1.54 albertel 232: );
1.186.2.4 raeburn 233: %mathchoices = &Apache::lonlocal::texthash(%mathchoices);
1.179 bisitz 234: my $selectionbox=
235: &Apache::loncommon::select_form(
236: $texengine,
237: 'texengine',
1.186.2.4 raeburn 238: \%mathchoices);
1.67 albertel 239: my $jsMath_start=&Apache::lontexconvert::jsMath_header();
1.123 bisitz 240: my %lt=&Apache::lonlocal::texthash(
1.177 raeburn 241: 'headline' => 'Change how math is displayed',
242: 'preftxt' => 'Preferred method to display math',
1.136 schafran 243: 'change' => 'Save',
1.123 bisitz 244: 'exmpl' => 'Examples',
245: 'jsmath' => 'jsMath:',
246: 'tth' => 'tth (TeX to HTML):',
247: 'mimetex' => 'mimetex (Convert to Images):',
248: );
249:
1.162 bisitz 250: my $jsMathWarning='<p>'
251: .'<div class="LC_warning">'
252: .&mt("It looks like you don't have the TeX math fonts installed.")
253: .'</div>'
254: .'<div>'
255: .&mt('The jsMath example on this page may not look right without them. '
256: .'The [_1]jsMath Home Page[_2] has information on how to download the '
257: .'needed fonts. In the meantime, jsMath will do the best it can '
258: .'with the fonts you have, but it may not be pretty and some equations '
259: .'may not be rendered correctly.'
260: ,'<a href="http://www.math.union.edu/locate/jsMath/" target="_blank">'
261: ,'</a>')
262: .'</div>'
263: .'</p>';
264:
1.54 albertel 265: $r->print(<<ENDLSCREEN);
1.123 bisitz 266: <h2>$lt{'headline'}</h2>
1.88 albertel 267: <form name="prefs" action="/adm/preferences" method="post">
1.54 albertel 268: <input type="hidden" name="action" value="verify_and_change_texengine" />
1.123 bisitz 269: <p>
1.136 schafran 270: $lt{'preftxt'}: $selectionbox
271: <br />
272: <input type="submit" value="$lt{'change'}" />
1.123 bisitz 273: </p>
1.54 albertel 274: </form>
1.123 bisitz 275: <br />
276: <hr />
277: $lt{'exmpl'}
278:
279: <h3>$lt{'jsmath'}</h3>
280: <p>
1.67 albertel 281: $jsMath_start
1.148 bisitz 282: <script type="text/javascript" language="JavaScript">
1.54 albertel 283: if (jsMath.nofonts == 1) {
1.162 bisitz 284: document.writeln($jsMathWarning);
1.54 albertel 285: }
286: </script>
1.122 www 287: <iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=jsMath" width="400" height="120"></iframe>
1.123 bisitz 288: </p>
1.54 albertel 289:
1.123 bisitz 290: <h3>$lt{'mimetex'}</h3>
291: <p>
292: <iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=mimetex" width="400" height="100"></iframe>
1.67 albertel 293: </p>
1.123 bisitz 294:
295: <h3>$lt{'tth'}</h3>
296: <p>
1.177 raeburn 297: <iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=tth" width="400" height="220"></iframe>
1.67 albertel 298: </p>
1.54 albertel 299: ENDLSCREEN
1.59 albertel 300: if ($env{'environment.texengine'} ne 'jsMath') {
1.148 bisitz 301: $r->print('<script type="text/javascript" language="JavaScript">jsMath.Process()</script>');
1.55 albertel 302: }
1.54 albertel 303: }
304:
305:
306: sub verify_and_change_texengine {
307: my $r = shift;
1.59 albertel 308: my $user = $env{'user.name'};
309: my $domain = $env{'user.domain'};
1.54 albertel 310: # Screenname
1.59 albertel 311: my $newtexengine = $env{'form.texengine'};
1.54 albertel 312: $newtexengine=~s/[^\-\w]//g;
1.56 albertel 313: if ($newtexengine eq 'ttm') {
1.116 raeburn 314: &Apache::lonnet::appenv({'browser.mathml' => 1});
1.56 albertel 315: } else {
1.59 albertel 316: if ($env{'environment.texengine'} eq 'ttm') {
1.116 raeburn 317: &Apache::lonnet::appenv({'browser.mathml' => 0});
1.56 albertel 318: }
319: }
1.54 albertel 320: my $message='';
321: if ($newtexengine) {
322: &Apache::lonnet::put('environment',{'texengine' => $newtexengine});
1.116 raeburn 323: &Apache::lonnet::appenv({'environment.texengine' => $newtexengine});
1.158 bisitz 324: $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('Preferred method to display Math').'</i>','<tt>"'.$newtexengine.'"</tt>'));
1.54 albertel 325: } else {
326: &Apache::lonnet::del('environment',['texengine']);
1.139 raeburn 327: &Apache::lonnet::delenv('environment.texengine');
1.158 bisitz 328: $message=&Apache::lonhtmlcommon::confirm_success(&mt('Reset [_1]','<i>'.&mt('Preferred method to display Math').'</i>'));
1.54 albertel 329: }
1.158 bisitz 330: $message=&Apache::loncommon::confirmwrapper($message);
1.152 www 331: &print_main_menu($r, $message);
1.54 albertel 332: }
333:
334: ################################################################
1.50 albertel 335: # Roles Page Preference Change Subroutines #
336: ################################################################
337: sub rolesprefchanger {
338: my $r = shift;
1.96 albertel 339: my $role = ($env{'user.adv'} ? 'Role' : 'Course');
340: my $lc_role = ($env{'user.adv'} ? 'role' : 'course');
1.59 albertel 341: my $user = $env{'user.name'};
342: my $domain = $env{'user.domain'};
1.50 albertel 343: my %userenv = &Apache::lonnet::get
344: ('environment',['recentroles','recentrolesn']);
1.126 droeschl 345: Apache::lonhtmlcommon::add_breadcrumb(
346: { href => '/adm/preferences?action=changerolespref',
347: text => 'Change '.$role.' Page Pref'});
1.147 schafran 348: $r->print(Apache::loncommon::start_page('Content Display Settings'));
1.126 droeschl 349: $r->print(Apache::lonhtmlcommon::breadcrumbs('Change '.$role.' Page Pref'));
1.50 albertel 350: my $hotlist_flag=$userenv{'recentroles'};
351: my $hotlist_n=$userenv{'recentrolesn'};
352: my $checked;
353: if ($hotlist_flag) {
354: $checked = 'checked="checked"';
355: }
356:
357: if (!$hotlist_n) { $hotlist_n=3; }
358: my $options;
359: for (my $i=1; $i<10; $i++) {
360: my $select;
361: if ($hotlist_n == $i) { $select = 'selected="selected"'; }
362: $options .= "<option $select>$i</option>\n";
363: }
364:
1.89 albertel 365: # Get list of recent roles and display with checkbox in front
366: my $roles_check_list = '';
367: my $role_key='';
368: if ($env{'environment.recentroles'}) {
369: my %recent_roles =
370: &Apache::lonhtmlcommon::get_recent('roles',$env{'environment.recentrolesn'});
1.91 albertel 371: my %frozen_roles =
372: &Apache::lonhtmlcommon::get_recent_frozen('roles',$env{'environment.recentrolesn'});
1.89 albertel 373:
1.93 albertel 374: my %role_text = &rolespref_get_role_text([keys(%recent_roles)]);
1.92 albertel 375: my @sorted_roles = sort {$role_text{$a} cmp $role_text{$b}} keys(%role_text);
376:
1.89 albertel 377: $roles_check_list .=
378: &Apache::loncommon::start_data_table().
379: &Apache::loncommon::start_data_table_header_row().
1.96 albertel 380: "<th>".&mt('Freeze '.$role)."</th>".
381: "<th>".&mt($role)."</td>".
1.89 albertel 382: &Apache::loncommon::end_data_table_header_row().
383: "\n";
384: my $count;
1.92 albertel 385: foreach $role_key (@sorted_roles) {
1.89 albertel 386: my $checked = "";
387: my $value = $recent_roles{$role_key};
1.91 albertel 388: if ($frozen_roles{$role_key}) {
1.159 bisitz 389: $checked = ' checked="checked"';
1.89 albertel 390: }
391: $count++;
392: $roles_check_list .=
393: &Apache::loncommon::start_data_table_row().
394: '<td class="LC_table_cell_checkbox">'.
1.159 bisitz 395: "<input type=\"checkbox\"$checked name=\"freezeroles\"".
1.89 albertel 396: " id=\"freezeroles$count\" value=\"$role_key\" /></td>".
397: "<td><label for=\"freezeroles$count\">".
1.92 albertel 398: "$role_text{$role_key}</label></td>".
1.89 albertel 399: &Apache::loncommon::end_data_table_row(). "\n";
400: }
401: $roles_check_list .= "</table>\n";
402: }
403:
404: $r->print('
1.96 albertel 405: <p>'.&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.').'
1.50 albertel 406: </p>
1.160 bisitz 407: <form name="prefs" action="/adm/preferences" method="post">
1.50 albertel 408: <input type="hidden" name="action" value="verify_and_change_rolespref" />
1.181 wenzelju 409: <br />'.
410: '<h2>'.&mt('Recent '.$role.'s Hotlist').'</h2>'.
411: &Apache::lonhtmlcommon::start_pick_box().
412: &Apache::lonhtmlcommon::row_title('<label for="Hotlist">'.&mt('Enable Recent '.$role.'s Hotlist').'</label>').
413: '<input id="Hotlist" type="checkbox"'.$checked.' name="recentroles" value="true" />'.
414: &Apache::lonhtmlcommon::row_closure().
415: &Apache::lonhtmlcommon::row_title('<label for="NumberOfRoles">'.&mt('Number of '.$role.'s in Hotlist').'</label>').
416: '<select name="recentrolesn" size="1" id ="NumberOfRoles">'.
417: $options.
418: '</select>'.
419: &Apache::lonhtmlcommon::row_closure(1).
420: &Apache::lonhtmlcommon::end_pick_box().
421: '<br/><h2>'.&mt('Freeze Roles').'</h2>'.
422: '<p>'.&mt('This list below can be used to <q>freeze</q> '.$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.').'
1.89 albertel 423: </p>
424: '.$roles_check_list.'
1.50 albertel 425: <br />
1.136 schafran 426: <input type="submit" value="'.&mt('Save').'" />
1.89 albertel 427: </form>');
1.50 albertel 428: }
429:
1.92 albertel 430: sub rolespref_get_role_text {
431: # Get a line of text for each role
432: my ($roles) = @_;
433: my %roletext = ();
434:
435: foreach my $item (@$roles) {
436: # get course information
437: my ($role,$rest) = split(/\./, $item);
1.93 albertel 438: my $trole = "";
439: $trole = &Apache::lonnet::plaintext($role);
1.92 albertel 440: my ($tdomain,$other,$tsection)= split(/\//,Apache::lonnet::declutter($rest));
441: my $tother = '-';
1.93 albertel 442: if ($role =~ /^(cc|st|in|ta|ep|cr)/ ) {
1.92 albertel 443: my %newhash=&Apache::lonnet::coursedescription($tdomain."_".$other);
444: $tother = " - ".$newhash{'description'};
445: } elsif ($role =~ /dc/) {
446: $tother = "";
447: } else {
448: $tother = " - $other";
449: }
450:
451: my $section="";
452: if ($tsection) {
453: $section = " - Section/Group: $tsection";
454: }
455: $roletext{$item} = $tdomain." - ".$trole.$tother.$section;
456: }
457: return %roletext;
458: }
459:
1.50 albertel 460: sub verify_and_change_rolespref {
461: my $r = shift;
1.96 albertel 462: my $role = ($env{'user.adv'} ? 'Role' : 'Course');
1.59 albertel 463: my $user = $env{'user.name'};
464: my $domain = $env{'user.domain'};
1.50 albertel 465: # Recent Roles Hotlist Flag
1.59 albertel 466: my $hotlist_flag = $env{'form.recentroles'};
467: my $hotlist_n = $env{'form.recentrolesn'};
1.89 albertel 468: my $message='<hr />';
1.50 albertel 469: if ($hotlist_flag) {
470: &Apache::lonnet::put('environment',{'recentroles' => $hotlist_flag});
1.116 raeburn 471: &Apache::lonnet::appenv({'environment.recentroles' => $hotlist_flag});
1.180 wenzelju 472: $message=&Apache::lonhtmlcommon::confirm_success(&mt('Recent '.$role.'s Hotlist is Enabled.')." ".&mt('Display [_1] Most Recent '.$role.'s.',$hotlist_n));
1.50 albertel 473: } else {
474: &Apache::lonnet::del('environment',['recentroles']);
1.139 raeburn 475: &Apache::lonnet::delenv('environment.recentroles');
1.180 wenzelju 476: $message=&Apache::lonhtmlcommon::confirm_success(&mt('Recent '.$role.'s Hotlist is Disabled'));
1.50 albertel 477: }
478: if ($hotlist_n) {
479: &Apache::lonnet::put('environment',{'recentrolesn' => $hotlist_n});
1.116 raeburn 480: &Apache::lonnet::appenv({'environment.recentrolesn' => $hotlist_n});
1.89 albertel 481: }
482:
483: # Get list of froze roles and list of recent roles
484: my @freeze_list = &Apache::loncommon::get_env_multiple('form.freezeroles');
485: my %freeze = ();
1.92 albertel 486: my %roletext = ();
487:
1.89 albertel 488: foreach my $key (@freeze_list) {
1.91 albertel 489: $freeze{$key}='1';
1.89 albertel 490: }
1.92 albertel 491:
1.89 albertel 492: my %recent_roles =
493: &Apache::lonhtmlcommon::get_recent('roles',$env{'environment.recentrolesn'});
1.91 albertel 494: my %frozen_roles =
495: &Apache::lonhtmlcommon::get_recent_frozen('roles',$env{'environment.recentrolesn'});
1.92 albertel 496: my %role_text = &rolespref_get_role_text([keys(%recent_roles)]);
1.89 albertel 497:
498: # Unset any roles that were previously frozen but aren't in list
499: foreach my $role_key (sort(keys(%recent_roles))) {
1.91 albertel 500: if (($frozen_roles{$role_key}) && (!exists($freeze{$role_key}))) {
1.158 bisitz 501: $message .= "<br />".&Apache::lonhtmlcommon::confirm_success(&mt('Unfreezing '.$role.': [_1]','<i>'.$role_text{$role_key}.'</i>'));
1.91 albertel 502: &Apache::lonhtmlcommon::store_recent('roles',$role_key,' ',0);
1.89 albertel 503: }
504: }
505:
506: # Freeze selected roles
507: foreach my $role_key (@freeze_list) {
1.91 albertel 508: if (!$frozen_roles{$role_key}) {
1.154 www 509: $message .= "<br />".
1.158 bisitz 510: &Apache::lonhtmlcommon::confirm_success(&mt('Freezing '.$role.': [_1]','<i>'.$role_text{$role_key}.'</i>'));
1.89 albertel 511: &Apache::lonhtmlcommon::store_recent('roles',
1.91 albertel 512: $role_key,' ',1);
1.50 albertel 513: }
514: }
1.158 bisitz 515: $message=&Apache::loncommon::confirmwrapper($message);
1.152 www 516: &print_main_menu($r, $message);
1.50 albertel 517: }
518:
519:
1.28 www 520:
521: ################################################################
1.9 matthew 522: # Anonymous Discussion Name Change Subroutines #
523: ################################################################
1.5 www 524: sub screennamechanger {
525: my $r = shift;
1.59 albertel 526: my $user = $env{'user.name'};
527: my $domain = $env{'user.domain'};
1.14 www 528: my %userenv = &Apache::lonnet::get
529: ('environment',['screenname','nickname']);
1.6 www 530: my $screenname=$userenv{'screenname'};
1.14 www 531: my $nickname=$userenv{'nickname'};
1.126 droeschl 532: Apache::lonhtmlcommon::add_breadcrumb(
533: { href => '/adm/preferences?action=changescreenname',
534: text => 'Change Screen Name'});
1.147 schafran 535: $r->print(Apache::loncommon::start_page('Personal Data'));
1.126 droeschl 536: $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Screen Name'));
1.133 bisitz 537: $r->print('<p>'
538: .&mt('Change the name that is displayed in your posts.')
539: .'</p>'
540: );
541: $r->print('<form name="prefs" action="/adm/preferences" method="post">'
542: .'<input type="hidden" name="action" value="verify_and_change_screenname" />'
543: .&Apache::lonhtmlcommon::start_pick_box()
1.158 bisitz 544: .&Apache::lonhtmlcommon::row_title(&mt('Screenname').' '.&mt('(shown if you post anonymously)'))
1.133 bisitz 545: .'<input type="text" size="20" value="'.$screenname.'" name="screenname" />'
546: .&Apache::lonhtmlcommon::row_closure()
1.158 bisitz 547: .&Apache::lonhtmlcommon::row_title(&mt('Nickname').' '.&mt('(shown if you post non-anonymously)'))
1.133 bisitz 548: .'<input type="text" size="20" value="'.$nickname.'" name="nickname" />'
549: .&Apache::lonhtmlcommon::row_closure()
550: .&Apache::lonhtmlcommon::row_title()
551: .'<input type="submit" value="'.&mt('Save').'" />'
552: .&Apache::lonhtmlcommon::row_closure(1)
553: .&Apache::lonhtmlcommon::end_pick_box()
554: .'</form>'
555: );
1.5 www 556: }
1.6 www 557:
558: sub verify_and_change_screenname {
559: my $r = shift;
1.59 albertel 560: my $user = $env{'user.name'};
561: my $domain = $env{'user.domain'};
1.14 www 562: # Screenname
1.59 albertel 563: my $newscreen = $env{'form.screenname'};
1.14 www 564: $newscreen=~s/[^ \w]//g;
1.6 www 565: my $message='';
566: if ($newscreen) {
1.7 www 567: &Apache::lonnet::put('environment',{'screenname' => $newscreen});
1.116 raeburn 568: &Apache::lonnet::appenv({'environment.screenname' => $newscreen});
1.161 bisitz 569: $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('Screenname').'</i>','<tt>"'.$newscreen.'"</tt>'));
1.6 www 570: } else {
571: &Apache::lonnet::del('environment',['screenname']);
1.139 raeburn 572: &Apache::lonnet::delenv('environment.screenname');
1.158 bisitz 573: $message=&Apache::lonhtmlcommon::confirm_success(&mt('Reset [_1]','<i>'.&mt('Screenname').'</i>'));
1.6 www 574: }
1.14 www 575: # Nickname
576: $message.='<br />';
1.59 albertel 577: $newscreen = $env{'form.nickname'};
1.14 www 578: $newscreen=~s/[^ \w]//g;
579: if ($newscreen) {
580: &Apache::lonnet::put('environment',{'nickname' => $newscreen});
1.116 raeburn 581: &Apache::lonnet::appenv({'environment.nickname' => $newscreen});
1.161 bisitz 582: $message.=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('Nickname').'</i>','<tt>"'.$newscreen.'"</tt>'));
1.14 www 583: } else {
584: &Apache::lonnet::del('environment',['nickname']);
1.139 raeburn 585: &Apache::lonnet::delenv('environment.nickname');
1.158 bisitz 586: $message.=&Apache::lonhtmlcommon::confirm_success(&mt('Reset [_1]','<i>'.&mt('Nickname').'</i>'));
1.14 www 587: }
1.68 www 588: &Apache::lonnet::devalidate_cache_new('namescache',$user.':'.$domain);
1.158 bisitz 589: $message=&Apache::loncommon::confirmwrapper($message);
1.152 www 590: &print_main_menu($r, $message);
1.20 www 591: }
592:
593: ################################################################
1.186.2.6 raeburn 594: # Icon Subroutines #
595: ################################################################
596: sub iconchanger {
597: my $r = shift;
598: &Apache::lonhtmlcommon::add_breadcrumb(
599: { href => '/adm/preferences?action=changeicons',
600: text => 'Change Menu Display'});
601: $r->print(Apache::loncommon::start_page('Page Display Settings'));
602: $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Menu Display'));
603:
604: my $user = $env{'user.name'};
605: my $domain = $env{'user.domain'};
606: my %userenv = &Apache::lonnet::get('environment',['icons']);
607: my $iconic='checked="checked"';
608: my ($classic,$onlyicon,$iconic_preview,$iconsonly_preview);
609: if ($userenv{'icons'} eq 'classic') {
610: $iconic='';
611: $classic='<div class="LC_info">'.
612: &mt('Your current selection: "Use buttons and text" is deprecated - it is recommended that you change this to "Use icons and text".').'</div>';
613: }
614: if ($userenv{'icons'} eq 'iconsonly') {
615: $onlyicon='checked="checked"';
616: $iconic='';
617: }
618: my $change=&mt('Save');
619: my %lt = &icon_options();
620: my ($inlinetools,$toolsorder) = &icon_previews();
621: if ((ref($inlinetools) eq 'HASH') && (ref($toolsorder) eq 'ARRAY')) {
622: foreach my $tool (@{$toolsorder}) {
623: my ($command,$row,$col,$img,$top,$bot,$act,$desc) =
624: split(/\&/,$inlinetools->{$tool});
625: $iconic_preview .= '<li><a title="'.$desc.'" class="LC_menubuttons_link" href=""><img alt="'.$desc.'" src="/res/adm/pages/'.$img.'" class="LC_icon" /><span class="LC_menubuttons_inline_text">'.$top.(' ' x 2).'</span></a></li>';
626: $iconsonly_preview .= '<li><a title="'.$desc.'" class="LC_menubuttons_link" href=""><img alt="'.$desc.'" src="/res/adm/pages/'.$img.'" class="LC_icon" /> </a></li>';
627: }
628: }
629: $iconsonly_preview = '<ul class="LC_breadcrumb_tools_outerlist"><li>'.
630: '<ul>'.
631: $iconsonly_preview.
632: '</ul></li></ul>';
633: $iconic_preview = '<ul class="LC_breadcrumb_tools_outerlist"><li>'.
634: '<ul>'.
635: $iconic_preview.
636: '</ul></li></ul>';
637: $r->print(<<ENDSCREEN);
638: $classic
639: <form name="prefs" action="/adm/preferences" method="post">
640: <input type="hidden" name="action" value="verify_and_change_icons" />
641: <label><input type="radio" name="menumode" value="iconic" $iconic /> $lt{'iconic'}</label>$iconic_preview<br />
642: <label><input type="radio" name="menumode" value="iconsonly" $onlyicon /> $lt{'iconsonly'}</label>$iconsonly_preview<br />
643: <input type="submit" value="$change" />
644: </form>
645: ENDSCREEN
646: }
647:
648: sub verify_and_change_icons {
649: my $r = shift;
650: my $user = $env{'user.name'};
651: my $domain = $env{'user.domain'};
652: my $newicons = $env{'form.menumode'};
653: my %lt = &icon_options();
654: my $newchoice = $newicons;
655: if ($lt{$newicons}) {
656: $newchoice = $lt{$newicons};
657: }
658: &Apache::lonnet::put('environment',{'icons' => $newicons});
659: &Apache::lonnet::appenv({'environment.icons' => $newicons});
660: my $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('Menu Display').'</i>','<tt>'.$newchoice.'</tt>'));
661: $message=&Apache::loncommon::confirmwrapper($message);
662: &print_main_menu($r, $message);
663: }
664:
665: sub icon_options {
666: my %lt = &Apache::lonlocal::texthash(
667: iconic => 'Use icons and text',
668: iconsonly => 'Use icons only',
669: );
670: return %lt;
671: }
672:
673: sub icon_previews {
674: my %icon_text = (
675: annotate => 'Notes',
676: bookmark => 'Bookmark',
677: catalog => 'Info',
678: evaluate => 'Evaluate',
679: feedback => 'Communicate',
680: printout => 'Print',
681: );
682: my %inlinetools = (
683: printout => "s&8&3&prt.png&$icon_text{'printout'}&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document",
684: bookmark => "s&9&1&sbkm.png&$icon_text{'bookmark'}&bookmark[_2]&set_bookmark()&Set a bookmark for this resource",
685: evaluate => "s&8&1&eval.png&$icon_text{'evaluate'}&this[_1]&gopost('/adm/evaluate',currentURL,1)&Provide my evaluation of this resource",
686: 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",
687: annotate => "s&9&3&anot.png&$icon_text{'annotate'}&tations[_1]&annotate()&Make notes and annotations about this resource",
688: catalog => "s&6&3&catalog.png&$icon_text{'catalog'}&info[_1]&catalog_info()&Show Metadata",
689: );
690: my @toolsorder = qw(annotate bookmark evaluate feedback printout catalog);
691: return (\%inlinetools,\@toolsorder);
692: }
693:
694: ################################################################
1.105 www 695: # Clicker Subroutines #
696: ################################################################
697:
698: sub clickerchanger {
699: my $r = shift;
1.152 www 700: &Apache::lonhtmlcommon::add_breadcrumb(
1.126 droeschl 701: { href => '/adm/preferences?action=changeclicker',
702: text => 'Register Clicker'});
1.147 schafran 703: $r->print(Apache::loncommon::start_page('Other'));
1.126 droeschl 704: $r->print(Apache::lonhtmlcommon::breadcrumbs('Register Clicker'));
1.105 www 705: my $user = $env{'user.name'};
706: my $domain = $env{'user.domain'};
707: my %userenv = &Apache::lonnet::get
708: ('environment',['clickers']);
709: my $clickers=$userenv{'clickers'};
710: $clickers=~s/\,/\n/gs;
711: my $text=&mt('Enter response device ("clicker") numbers');
1.151 bisitz 712: my $change=&mt('Save');
1.114 bisitz 713: my $helplink=&Apache::loncommon::help_open_topic('Clicker_Registration',&mt('Locating your clicker ID'));
1.105 www 714: $r->print(<<ENDSCREEN);
715: <form name="prefs" action="/adm/preferences" method="post">
716: <input type="hidden" name="action" value="verify_and_change_clicker" />
1.151 bisitz 717: <label>$helplink<br /><br />$text<br />
1.108 www 718: <textarea name="clickers" rows="5" cols="20">$clickers</textarea>
1.105 www 719: </label>
1.151 bisitz 720: <br />
1.105 www 721: <input type="submit" value="$change" />
722: </form>
723: ENDSCREEN
724: }
725:
726: sub verify_and_change_clicker {
727: my $r = shift;
728: my $user = $env{'user.name'};
729: my $domain = $env{'user.domain'};
730: my $newclickers = $env{'form.clickers'};
1.108 www 731: $newclickers=~s/[^\w\:\-]+/\,/gs;
1.105 www 732: $newclickers=~tr/a-z/A-Z/;
1.108 www 733: $newclickers=~s/[\:\-]+/\-/g;
734: $newclickers=~s/\,+/\,/g;
1.105 www 735: $newclickers=~s/^\,//;
736: $newclickers=~s/\,$//;
737: &Apache::lonnet::put('environment',{'clickers' => $newclickers});
1.116 raeburn 738: &Apache::lonnet::appenv({'environment.clickers' => $newclickers});
1.158 bisitz 739: my $message=&Apache::lonhtmlcommon::confirm_success(&mt('Registering clickers: [_1]',$newclickers));
740: $message=&Apache::loncommon::confirmwrapper($message);
741: &print_main_menu($r, $message);
1.105 www 742: }
743:
1.119 www 744: ################################################################
745: # Domcoord Access Subroutines #
746: ################################################################
747:
748: sub domcoordchanger {
749: my $r = shift;
1.154 www 750: &Apache::lonhtmlcommon::add_breadcrumb(
1.126 droeschl 751: { href => '/adm/preferences?action=changedomcoord',
752: text => 'Restrict Domain Coordinator Access'});
753: $r->print(Apache::loncommon::start_page('Restrict Domain Coordinator Access'));
754: $r->print(Apache::lonhtmlcommon::breadcrumbs('Restrict Domain Coordinator Access'));
1.119 www 755: my $user = $env{'user.name'};
756: my $domain = $env{'user.domain'};
757: my %userenv = &Apache::lonnet::get
1.120 www 758: ('environment',['domcoord.author']);
1.119 www 759: my $constchecked='';
760: if ($userenv{'domcoord.author'} eq 'blocked') {
1.159 bisitz 761: $constchecked=' checked="checked"';
1.119 www 762: }
1.120 www 763: my $text=&mt('By default, the Domain Coordinator can enter your construction space.');
1.119 www 764: my $construction=&mt('Block access to construction space');
1.136 schafran 765: my $change=&mt('Save');
1.119 www 766: $r->print(<<ENDSCREEN);
767: <form name="prefs" action="/adm/preferences" method="post">
768: <input type="hidden" name="action" value="verify_and_change_domcoord" />
769: $text<br />
1.159 bisitz 770: <label><input type="checkbox" name="construction"$constchecked />$construction</label><br />
1.119 www 771: <input type="submit" value="$change" />
772: </form>
773: ENDSCREEN
774: }
775:
776: sub verify_and_change_domcoord {
777: my $r = shift;
778: my $user = $env{'user.name'};
779: my $domain = $env{'user.domain'};
1.120 www 780: my %domcoord=('domcoord.author' => '');
1.119 www 781: if ($env{'form.construction'}) { $domcoord{'domcoord.author'}='blocked'; }
782: &Apache::lonnet::put('environment',\%domcoord);
1.120 www 783: &Apache::lonnet::appenv({'environment.domcoord.author' => $domcoord{'domcoord.author'}});
1.158 bisitz 784: my $status='';
785: if ($domcoord{'domcoord.author'} eq 'blocked') {
786: $status=&mt('on');
787: } else {
788: $status=&mt('off');
789: }
790: my $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('Block access to construction space').'</i>','<tt>'.$status.'</tt>'));
791: $message=&Apache::loncommon::confirmwrapper($message);
792: &print_main_menu($r,$message);
1.119 www 793: }
794:
1.118 www 795: #################################################################
796: ## Lock Subroutines #
797: #################################################################
798:
799: sub lockwarning {
800: my $r = shift;
801: my $title=&mt('Action locked');
802: my $texttop=&mt('LON-CAPA is currently performing the following actions:');
803: my $textbottom=&mt('Changing roles or logging out may result in data corruption.');
804: my ($num,%which)=&Apache::lonnet::get_locks();
805: my $which='';
806: foreach my $id (keys %which) {
807: $which.='<li>'.$which{$id}.'</li>';
808: }
809: my $change=&mt('Override');
810: $r->print(<<ENDSCREEN);
811: <form name="prefs" action="/adm/preferences" method="post">
812: <input type="hidden" name="action" value="verify_and_change_locks" />
813: <h1>$title</h1>
814: $texttop
815: <ul>
816: $which
817: </ul>
818: $textbottom
819: <input type="submit" value="$change" />
820: </form>
821: ENDSCREEN
822: }
823:
824: sub verify_and_change_lockwarning {
825: my $r = shift;
826: &Apache::lonnet::remove_all_locks();
827: $r->print(&mt('Cleared locks.'));
828: }
829:
830:
1.105 www 831: ################################################################
1.20 www 832: # Message Forward #
833: ################################################################
834:
835: sub msgforwardchanger {
1.102 raeburn 836: my ($r,$message) = @_;
1.59 albertel 837: my $user = $env{'user.name'};
838: my $domain = $env{'user.domain'};
1.102 raeburn 839: my %userenv = &Apache::lonnet::get('environment',['msgforward','notification','critnotification','notifywithhtml']);
1.20 www 840: my $msgforward=$userenv{'msgforward'};
1.102 raeburn 841: my %lt = &Apache::lonlocal::texthash(
842: all => 'All',
843: crit => 'Critical only',
844: reg => 'Non-critical only',
1.175 raeburn 845: foad => 'Forward to account(s)',
846: fwdm => 'Forward messages to other account(s) in LON-CAPA',
847: noti => 'E-mail notification of LON-CAPA messages',
1.110 bisitz 848: foad_exmpl => 'e.g. <tt>userA:domain1,userB:domain2,...</tt>',
1.175 raeburn 849: mnot => 'E-mail address(es) which should be notified about new LON-CAPA messages',
1.110 bisitz 850: mnot_exmpl => 'e.g. <tt>joe@doe.com</tt>',
1.136 schafran 851: chg => 'Save',
1.104 raeburn 852: email => 'The e-mail address entered in row ',
1.102 raeburn 853: notv => 'is not a valid e-mail address',
1.103 raeburn 854: toen => "To enter multiple addresses, enter one address at a time, click 'Change' and then add the next one",
1.136 schafran 855: prme => 'Back',
1.102 raeburn 856: );
1.126 droeschl 857: Apache::lonhtmlcommon::add_breadcrumb(
858: { href => '/adm/preferences?action=changemsgforward',
1.176 raeburn 859: text => 'Messages & Notifications'});
1.178 bisitz 860: $r->print(Apache::loncommon::start_page('Messages & Notifications'));
861: $r->print(Apache::lonhtmlcommon::breadcrumbs('Messages & Notifications'));
1.113 raeburn 862: my $forwardingHelp = &Apache::loncommon::help_open_topic("Prefs_Forwarding");
863: my $notificationHelp = &Apache::loncommon::help_open_topic("Prefs_Notification");
864: my $criticalMessageHelp = &Apache::loncommon::help_open_topic("Course_Critical_Message");
1.102 raeburn 865: my @allow_html = split(/,/,$userenv{'notifywithhtml'});
866: my %allnot = &get_notifications(\%userenv);
867: my $validatescript = &Apache::lonhtmlcommon::javascript_valid_email();
868: my $jscript = qq|
1.148 bisitz 869: <script type="text/javascript" language="JavaScript">
1.102 raeburn 870: function validate() {
871: for (var i=0; i<document.prefs.numnotify.value; i++) {
1.104 raeburn 872: var checkaddress = 0;
1.102 raeburn 873: var addr = document.prefs.elements['address_'+i].value;
1.104 raeburn 874: var rownum = i+1;
1.102 raeburn 875: if (i < document.prefs.numnotify.value-1) {
1.104 raeburn 876: if (document.prefs.elements['modify_notify_'+i].checked) {
1.102 raeburn 877: checkaddress = 1;
1.104 raeburn 878: }
1.102 raeburn 879: } else {
880: if (document.prefs.elements['add_notify_'+i].checked == true) {
881: checkaddress = 1;
882: }
883: }
1.104 raeburn 884: if (checkaddress == 1) {
1.102 raeburn 885: var addr = document.prefs.elements['address_'+i].value;
886: if (validmail(document.prefs.elements['address_'+i]) == false) {
1.104 raeburn 887: var multimsg = '';
888: if (addr.indexOf(",") >= 0) {
889: multimsg = "\\n($lt{'toen'}).";
890: }
1.110 bisitz 891: alert("$lt{'email'} "+rownum+" ('"+addr+"') $lt{'notv'}."+multimsg);
1.102 raeburn 892: return;
893: }
894: }
895: }
896: document.prefs.submit();
897: }
1.104 raeburn 898:
899: function address_changes (adnum) {
900: if (!document.prefs.elements['del_notify_'+adnum].checked) {
901: document.prefs.elements['modify_notify_'+adnum].checked = true;
902: }
903: }
904:
905: function new_address(adnum) {
906: document.prefs.elements['add_notify_'+adnum].checked = true;
907: }
908:
909: function delete_address(adnum) {
910: if (document.prefs.elements['del_notify_'+adnum].checked) {
911: document.prefs.elements['modify_notify_'+adnum].checked = false;
912: }
913: }
914:
915: function modify_address(adnum) {
916: if (document.prefs.elements['modify_notify_'+adnum].checked) {
917: document.prefs.elements['del_notify_'+adnum].checked = false;
918: }
919: }
920:
1.102 raeburn 921: $validatescript
922: </script>
923: |;
1.20 www 924: $r->print(<<ENDMSG);
1.102 raeburn 925: $jscript
926: $message
1.175 raeburn 927: <h3>$lt{'fwdm'} $forwardingHelp</h3>
1.88 albertel 928: <form name="prefs" action="/adm/preferences" method="post">
1.20 www 929: <input type="hidden" name="action" value="verify_and_change_msgforward" />
1.110 bisitz 930: $lt{'foad'} ($lt{'foad_exmpl'}):
1.175 raeburn 931: <input type="text" size="40" value="$msgforward" name="msgforward" />
932: <br /><br />
1.113 raeburn 933: <h3>$lt{'noti'} $notificationHelp</h3>
1.110 bisitz 934: $lt{'mnot'} ($lt{'mnot_exmpl'}):<br />
1.102 raeburn 935: ENDMSG
936: my @sortforwards = sort (keys(%allnot));
937: my $output = &Apache::loncommon::start_data_table().
938: &Apache::loncommon::start_data_table_header_row().
1.104 raeburn 939: '<th> </th>'.
1.102 raeburn 940: '<th>'.&mt('Action').'</th>'.
941: '<th>'.&mt('Notification address').'</th><th>'.
1.113 raeburn 942: &mt('Types of message for which notification is sent').
943: $criticalMessageHelp.'</th><th>'.
1.104 raeburn 944: &mt('Excerpt retains HTML tags in message').'</th>'.
1.102 raeburn 945: &Apache::loncommon::end_data_table_header_row();
946: my $num = 0;
1.104 raeburn 947: my $counter = 1;
1.102 raeburn 948: foreach my $item (@sortforwards) {
949: $output .= &Apache::loncommon::start_data_table_row().
1.104 raeburn 950: '<td><b>'.$counter.'</b></td>'.
951: '<td><span class="LC_nobreak"><label>'.
952: '<input type="checkbox" name="modify_notify_'.
953: $num.'" onclick="javscript:modify_address('."'$num'".')" />'.
954: &mt('Modify').'</label></span> '.
955: '<span class="LC_nobreak"><label>'.
956: '<input type="checkbox" name="del_notify_'.$num.
957: '" onclick="javscript:delete_address('."'$num'".')" />'.
958: &mt('Delete').'</label></span></td>'.
1.102 raeburn 959: '<td><input type="text" value="'.$item.'" name="address_'.
1.104 raeburn 960: $num.'" onFocus="javascript:address_changes('."'$num'".
961: ')" /></td><td>';
1.102 raeburn 962: my %chk;
963: if (defined($allnot{$item}{'crit'})) {
964: if (defined($allnot{$item}{'reg'})) {
965: $chk{'all'} = 'checked="checked" ';
966: } else {
967: $chk{'crit'} = 'checked="checked" ';
968: }
969: } else {
970: $chk{'reg'} = 'checked="checked" ';
971: }
972: foreach my $type ('all','crit','reg') {
973: $output .= '<span class="LC_nobreak"><label>'.
974: '<input type="radio" name="notify_type_'.$num.
1.104 raeburn 975: '" value="'.$type.'" '.$chk{$type}.
976: ' onchange="javascript:address_changes('."'$num'".')" />'.
1.175 raeburn 977: $lt{$type}.'</label></span>'.(' ' x4);
1.102 raeburn 978: }
979: my $htmlon = '';
980: my $htmloff = '';
981: if (grep/^\Q$item\E/,@allow_html) {
982: $htmlon = 'checked="checked" ';
983: } else {
984: $htmloff = 'checked="checked" ';
985: }
986: $output .= '</td><td><label><input type="radio" name="html_'.$num.
1.104 raeburn 987: '" value="1" '.$htmlon.
988: ' onchange="javascript:address_changes('."'$num'".')" />'.
1.175 raeburn 989: &mt('Yes').'</label>'.(' ' x3).
1.102 raeburn 990: '<label><input type="radio" name="html_'.$num.'" value="0" '.
1.104 raeburn 991: $htmloff. ' onchange="javascript:address_changes('."'$num'".
992: ')" />'.
993: &mt('No').'</label></td>'.
1.102 raeburn 994: &Apache::loncommon::end_data_table_row();
995: $num ++;
1.104 raeburn 996: $counter ++;
1.102 raeburn 997: }
998: my %defchk = (
999: all => 'checked="checked" ',
1000: crit => '',
1001: reg => '',
1002: );
1003: $output .= &Apache::loncommon::start_data_table_row().
1.104 raeburn 1004: '<td><b>'.$counter.'</b></td>'.
1005: '<td><span class="LC_nobreak"><label>'.
1006: '<input type="checkbox" name="add_notify_'.$num.
1007: '" value="1" />'.&mt('Add new address').'</label></span></td>'.
1.102 raeburn 1008: '<td><input type="text" value="" name="address_'.$num.
1.104 raeburn 1009: '" onFocus="javascript:new_address('."'$num'".')" /></td><td>';
1.102 raeburn 1010: foreach my $type ('all','crit','reg') {
1011: $output .= '<span class="LC_nobreak"><label>'.
1012: '<input type="radio" name="notify_type_'.$num.
1013: '" value="'.$type.'" '.$defchk{$type}.'/>'.
1.175 raeburn 1014: $lt{$type}.'</label></span>'.(' ' x4);
1.102 raeburn 1015: }
1016: $output .= '</td><td><label><input type="radio" name="html_'.$num.
1.175 raeburn 1017: '" value="1" />'.&mt('Yes').'</label>'.(' ' x3).
1.102 raeburn 1018: '<label><input type="radio" name="html_'.$num.'" value="0" '.
1019: ' checked="checked" />'.
1020: &mt('No').'</label></td>'.
1021: &Apache::loncommon::end_data_table_row().
1022: &Apache::loncommon::end_data_table();
1023: $num ++;
1024: $r->print($output);
1025: $r->print(qq|
1.113 raeburn 1026: <br /><hr />
1.102 raeburn 1027: <input type="hidden" name="numnotify" value="$num" />
1.136 schafran 1028: <input type="button" value="$lt{'prme'}" onclick="location.href='/adm/preferences'" />
1.102 raeburn 1029: <input type="button" value="$lt{'chg'}" onclick="javascript:validate()" />
1.20 www 1030: </form>
1.102 raeburn 1031: |);
1032:
1033: }
1034:
1035: sub get_notifications {
1036: my ($userenv) = @_;
1037: my %allnot;
1038: my @critnot = split(/,/,$userenv->{'critnotification'});
1039: my @regnot = split(/,/,$userenv->{'notification'});
1040: foreach my $item (@critnot) {
1041: $allnot{$item}{crit} = 1;
1042: }
1043: foreach my $item (@regnot) {
1044: $allnot{$item}{reg} = 1;
1045: }
1046: return %allnot;
1.20 www 1047: }
1048:
1049: sub verify_and_change_msgforward {
1050: my $r = shift;
1.59 albertel 1051: my $user = $env{'user.name'};
1052: my $domain = $env{'user.domain'};
1.20 www 1053: my $newscreen = '';
1054: my $message='';
1.182 raeburn 1055: foreach my $recip (split(/\,/,$env{'form.msgforward'})) {
1056: my ($msuser,$msdomain);
1057: if ($recip =~ /:/) {
1058: ($msuser,$msdomain)=split(':',$recip);
1059: } else {
1060: ($msuser,$msdomain)=split(/\@/,$recip);
1061: }
1.95 albertel 1062: $msuser = &LONCAPA::clean_username($msuser);
1063: $msdomain = &LONCAPA::clean_domain($msdomain);
1.20 www 1064: if (($msuser) && ($msdomain)) {
1065: if (&Apache::lonnet::homeserver($msuser,$msdomain) ne 'no_host') {
1.182 raeburn 1066: $newscreen.=$msuser.':'.$msdomain.',';
1067: } else {
1068: $message.= &mt('No such user: ').'<tt>'.$msuser.':'.$msdomain.'</tt><br />';
1069: }
1.20 www 1070: }
1071: }
1072: $newscreen=~s/\,$//;
1073: if ($newscreen) {
1074: &Apache::lonnet::put('environment',{'msgforward' => $newscreen});
1.116 raeburn 1075: &Apache::lonnet::appenv({'environment.msgforward' => $newscreen});
1.180 wenzelju 1076: $message .= &Apache::lonhtmlcommon::confirm_success(&mt('Set message forwarding to ').'<tt>"'.$newscreen.'"</tt>.<br />');
1.20 www 1077: } else {
1078: &Apache::lonnet::del('environment',['msgforward']);
1.139 raeburn 1079: &Apache::lonnet::delenv('environment.msgforward');
1.180 wenzelju 1080: $message.= &Apache::lonhtmlcommon::confirm_success(&mt("Set message forwarding to 'off'.").'<br />');
1.20 www 1081: }
1.102 raeburn 1082: my $critnotification;
1083: my $notification;
1084: my $notify_with_html;
1085: my $lastnotify = $env{'form.numnotify'}-1;
1.104 raeburn 1086: my $totaladdresses = 0;
1.102 raeburn 1087: for (my $i=0; $i<$env{'form.numnotify'}; $i++) {
1088: if ((!defined($env{'form.del_notify_'.$i})) &&
1.104 raeburn 1089: ((($i==$lastnotify) && ($env{'form.add_notify_'.$lastnotify} == 1)) ||
1.102 raeburn 1090: ($i<$lastnotify))) {
1091: if (defined($env{'form.address_'.$i})) {
1092: if ($env{'form.notify_type_'.$i} eq 'all') {
1093: $critnotification .= $env{'form.address_'.$i}.',';
1094: $notification .= $env{'form.address_'.$i}.',';
1095: } elsif ($env{'form.notify_type_'.$i} eq 'crit') {
1096: $critnotification .= $env{'form.address_'.$i}.',';
1097: } elsif ($env{'form.notify_type_'.$i} eq 'reg') {
1098: $notification .= $env{'form.address_'.$i}.',';
1099: }
1100: if ($env{'form.html_'.$i} eq '1') {
1101: $notify_with_html .= $env{'form.address_'.$i}.',';
1102: }
1.104 raeburn 1103: $totaladdresses ++;
1.102 raeburn 1104: }
1105: }
1106: }
1107: $critnotification =~ s/,$//;
1108: $critnotification=~s/\s//gs;
1109: $notification =~ s/,$//;
1.20 www 1110: $notification=~s/\s//gs;
1.102 raeburn 1111: $notify_with_html =~ s/,$//;
1112: $notify_with_html =~ s/\s//gs;
1.20 www 1113: if ($notification) {
1114: &Apache::lonnet::put('environment',{'notification' => $notification});
1.116 raeburn 1115: &Apache::lonnet::appenv({'environment.notification' => $notification});
1.180 wenzelju 1116: $message.=&Apache::lonhtmlcommon::confirm_success(&mt('Set non-critical message notification address(es) to ').'<tt>"'.$notification.'"</tt>.<br />');
1.20 www 1117: } else {
1118: &Apache::lonnet::del('environment',['notification']);
1.139 raeburn 1119: &Apache::lonnet::delenv('environment.notification');
1.180 wenzelju 1120: $message.=&Apache::lonhtmlcommon::confirm_success(&mt("Set non-critical message notification to 'off'.").'<br />');
1.20 www 1121: }
1122: if ($critnotification) {
1123: &Apache::lonnet::put('environment',{'critnotification' => $critnotification});
1.116 raeburn 1124: &Apache::lonnet::appenv({'environment.critnotification' => $critnotification});
1.180 wenzelju 1125: $message.=&Apache::lonhtmlcommon::confirm_success(&mt('Set critical message notification address(es) to ').'<tt>"'.$critnotification.'"</tt>.<br />');
1.20 www 1126: } else {
1127: &Apache::lonnet::del('environment',['critnotification']);
1.139 raeburn 1128: &Apache::lonnet::delenv('environment.critnotification');
1.180 wenzelju 1129: $message.=&Apache::lonhtmlcommon::confirm_success(&mt("Set critical message notification to 'off'.").'<br />');
1.102 raeburn 1130: }
1131: if ($critnotification || $notification) {
1132: if ($notify_with_html) {
1133: &Apache::lonnet::put('environment',{'notifywithhtml' => $notify_with_html});
1.116 raeburn 1134: &Apache::lonnet::appenv({'environment.notifywithhtml' => $notify_with_html});
1.180 wenzelju 1135: $message.=&Apache::lonhtmlcommon::confirm_success(&mt('Set address(es) to receive excerpts with html retained ').'<tt>"'.$notify_with_html.'"</tt>.');
1.102 raeburn 1136: } else {
1137: &Apache::lonnet::del('environment',['notifywithhtml']);
1.139 raeburn 1138: &Apache::lonnet::delenv('environment.notifywithhtml');
1.104 raeburn 1139: if ($totaladdresses == 1) {
1.180 wenzelju 1140: $message.=&Apache::lonhtmlcommon::confirm_success(&mt("Set notification address to receive excerpts with html stripped."));
1.104 raeburn 1141: } else {
1.180 wenzelju 1142: $message.=&Apache::lonhtmlcommon::confirm_success(&mt("Set all notification addresses to receive excerpts with html stripped."));
1.104 raeburn 1143: }
1.102 raeburn 1144: }
1145: } else {
1146: &Apache::lonnet::del('environment',['notifywithhtml']);
1.139 raeburn 1147: &Apache::lonnet::delenv('environment.notifywithhtml');
1.102 raeburn 1148: }
1.109 albertel 1149: &Apache::loncommon::flush_email_cache($user,$domain);
1.180 wenzelju 1150: $message=&Apache::loncommon::confirmwrapper($message);
1.102 raeburn 1151: &msgforwardchanger($r,$message);
1.6 www 1152: }
1153:
1.12 www 1154: ################################################################
1.19 www 1155: # Colors #
1.12 www 1156: ################################################################
1157:
1.19 www 1158: sub colorschanger {
1.12 www 1159: my $r = shift;
1.126 droeschl 1160: Apache::lonhtmlcommon::add_breadcrumb(
1161: { href => '/adm/preferences?action=changecolors',
1162: text => 'Change Colors'});
1.147 schafran 1163: $r->print(Apache::loncommon::start_page('Page Display Settings'));
1.126 droeschl 1164: $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Colors'));
1.19 www 1165: # figure out colors
1.80 albertel 1166: my $function=&Apache::loncommon::get_users_function();
1.19 www 1167: my $domain=&Apache::loncommon::determinedomain();
1.157 bisitz 1168: my %colortypes=&Apache::lonlocal::texthash(
1169: 'pgbg' => 'Page Background Color',
1170: 'tabbg' => 'Header Background Color',
1171: 'sidebg' => 'Header Border Color',
1172: 'font' => 'Font Color',
1173: 'fontmenu' => 'Font Menu Color',
1174: 'link' => 'Un-Visited Link Color',
1175: 'vlink' => 'Visited Link Color',
1176: 'alink' => 'Active Link Color',
1177: );
1.82 albertel 1178: my $start_data_table = &Apache::loncommon::start_data_table();
1.19 www 1179: my $chtable='';
1.22 matthew 1180: foreach my $item (sort(keys(%colortypes))) {
1.19 www 1181: my $curcol=&Apache::loncommon::designparm($function.'.'.$item,$domain);
1.82 albertel 1182: $chtable.=&Apache::loncommon::start_data_table_row().
1.83 albertel 1183: '<td>'.$colortypes{$item}.'</td><td style="background: '.$curcol.
1.19 www 1184: '"> </td><td><input name="'.$item.
1.21 www 1185: '" size="10" value="'.$curcol.
1186: '" /></td><td><a href="javascript:pjump('."'color_custom','".$colortypes{$item}.
1.19 www 1187: "','".$curcol."','"
1.157 bisitz 1188: .$item."','parmform.pres','psub'".');">'.&mt('Select').'</a></td>'.
1.83 albertel 1189: &Apache::loncommon::end_data_table_row()."\n";
1.19 www 1190: }
1.82 albertel 1191: my $end_data_table = &Apache::loncommon::end_data_table();
1.23 matthew 1192: my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
1.157 bisitz 1193: my $savebutton = &mt('Save');
1194: my $resetbutton = &mt('Reset All');
1195: my $resetbuttondesc = &mt('Reset All Colors to Default');
1.19 www 1196: $r->print(<<ENDCOL);
1.148 bisitz 1197: <script type="text/javascript" language="JavaScript">
1.19 www 1198:
1199: function pclose() {
1200: parmwin=window.open("/adm/rat/empty.html","LONCAPAparms",
1201: "height=350,width=350,scrollbars=no,menubar=no");
1202: parmwin.close();
1203: }
1204:
1.23 matthew 1205: $pjump_def
1.19 www 1206:
1207: function psub() {
1208: pclose();
1209: if (document.parmform.pres_marker.value!='') {
1.21 www 1210: if (document.parmform.pres_type.value!='') {
1.77 albertel 1211: eval('document.prefs.'+
1.21 www 1212: document.parmform.pres_marker.value+
1.19 www 1213: '.value=document.parmform.pres_value.value;');
1.21 www 1214: }
1.19 www 1215: } else {
1216: document.parmform.pres_value.value='';
1217: document.parmform.pres_marker.value='';
1218: }
1219: }
1220:
1221:
1222: </script>
1.21 www 1223: <form name="parmform">
1224: <input type="hidden" name="pres_marker" />
1225: <input type="hidden" name="pres_type" />
1226: <input type="hidden" name="pres_value" />
1227: </form>
1.88 albertel 1228: <form name="prefs" action="/adm/preferences" method="post">
1.19 www 1229: <input type="hidden" name="action" value="verify_and_change_colors" />
1.82 albertel 1230: $start_data_table
1.19 www 1231: $chtable
1.82 albertel 1232: $end_data_table
1.19 www 1233: </table>
1.157 bisitz 1234: <p>
1235: <input type="submit" value="$savebutton" />
1236: <input type="submit" name="resetall" value="$resetbutton" title="$resetbuttondesc" />
1237: </p>
1.12 www 1238: </form>
1.19 www 1239: ENDCOL
1.12 www 1240: }
1241:
1.19 www 1242: sub verify_and_change_colors {
1.12 www 1243: my $r = shift;
1.19 www 1244: # figure out colors
1.80 albertel 1245: my $function=&Apache::loncommon::get_users_function();
1.19 www 1246: my $domain=&Apache::loncommon::determinedomain();
1.157 bisitz 1247: my %colortypes=&Apache::lonlocal::texthash(
1248: 'pgbg' => 'Page Background Color',
1249: 'tabbg' => 'Header Background Color',
1250: 'sidebg' => 'Header Border Color',
1251: 'font' => 'Font Color',
1252: 'fontmenu' => 'Font Menu Color',
1253: 'link' => 'Un-Visited Link Color',
1254: 'vlink' => 'Visited Link Color',
1255: 'alink' => 'Active Link Color',
1256: );
1.19 www 1257:
1.12 www 1258: my $message='';
1.21 www 1259: foreach my $item (keys %colortypes) {
1.59 albertel 1260: my $color=$env{'form.'.$item};
1.21 www 1261: my $entry='color.'.$function.'.'.$item;
1.59 albertel 1262: if (($color=~/^\#[0-9A-Fa-f]{6}$/) && (!$env{'form.resetall'})) {
1.21 www 1263: &Apache::lonnet::put('environment',{$entry => $color});
1.116 raeburn 1264: &Apache::lonnet::appenv({'environment.'.$entry => $color});
1.157 bisitz 1265: $message.=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.$colortypes{$item}.'</i>','<tt>"'.$color.'"</tt>'))
1266: .'<br />';
1.21 www 1267: } else {
1268: &Apache::lonnet::del('environment',[$entry]);
1.138 schafran 1269: &Apache::lonnet::delenv('environment.'.$entry);
1.157 bisitz 1270: $message.=&Apache::lonhtmlcommon::confirm_success(&mt('Reset [_1]','<i>'.$colortypes{$item}.'</i>'))
1271: .'<br />';
1.21 www 1272: }
1273: }
1.158 bisitz 1274: $message=&Apache::loncommon::confirmwrapper($message);
1.157 bisitz 1275:
1.84 albertel 1276: my $now = time;
1277: &Apache::lonnet::put('environment',{'color.timestamp' => $now});
1.116 raeburn 1278: &Apache::lonnet::appenv({'environment.color.timestamp' => $now});
1.84 albertel 1279:
1.152 www 1280: &print_main_menu($r, $message);
1.12 www 1281: }
1282:
1.4 matthew 1283: ######################################################
1284: # password handler subroutines #
1285: ######################################################
1.3 matthew 1286: sub passwordchanger {
1.94 raeburn 1287: my ($r,$errormessage,$caller,$mailtoken) = @_;
1.4 matthew 1288: # This function is a bit of a mess....
1.3 matthew 1289: # Passwords are encrypted using londes.js (DES encryption)
1.4 matthew 1290: $errormessage = ($errormessage || '');
1.186.2.7! raeburn 1291: my ($user,$domain,$currentpass);
1.152 www 1292: &Apache::lonhtmlcommon::add_breadcrumb(
1.126 droeschl 1293: { href => '/adm/preferences?action=changepass',
1294: text => 'Change Password'});
1.144 raeburn 1295: unless ($caller eq 'reset_by_email') {
1.147 schafran 1296: $r->print(Apache::loncommon::start_page('Personal Data'));
1.144 raeburn 1297: $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Password'));
1298: }
1.94 raeburn 1299: if ((!defined($caller)) || ($caller eq 'preferences')) {
1300: $user = $env{'user.name'};
1301: $domain = $env{'user.domain'};
1302: if (!defined($caller)) {
1303: $caller = 'preferences';
1304: }
1305: } elsif ($caller eq 'reset_by_email') {
1306: my %data = &Apache::lonnet::tmpget($mailtoken);
1307: if (keys(%data) == 0) {
1.155 bisitz 1308: $r->print(&mt('Sorry, the URL you provided to complete the reset of your password was invalid. Either the token included in the URL has been deleted or the URL you provided was invalid. Please submit a [_1]new request[_2] for a password reset, and follow the link to the new URL included in the e-mail that will be sent to you, to allow you to enter a new password.'
1309: ,'<a href="/adm/resetpw">','</a>')
1310: );
1.94 raeburn 1311: return;
1312: }
1313: if (defined($data{time})) {
1314: if (time - $data{'time'} < 7200) {
1315: $user = $data{'username'};
1316: $domain = $data{'domain'};
1317: $currentpass = $data{'temppasswd'};
1318: } else {
1319: $r->print(&mt('Sorry, the token generated when you requested a password reset has expired.').'<br />');
1320: return;
1321: }
1322: } else {
1323: $r->print(&mt('Sorry, the URL generated when you requested reset of your password contained incomplete information.').'<br />');
1324: return;
1325: }
1.186.2.7! raeburn 1326: if (&Apache::lonnet::domain($domain) eq '') {
! 1327: $domain = $r->dir_config('lonDefDomain');
! 1328: }
1.94 raeburn 1329: } else {
1330: $r->print(&mt('Page requested in unexpected context').'<br />');
1331: return;
1332: }
1.3 matthew 1333: my $currentauth=&Apache::lonnet::queryauthenticate($user,$domain);
1334: # Check for authentication types that allow changing of the password.
1335: return if ($currentauth !~ /^(unix|internal):/);
1336: #
1337: # Generate keys
1338: my ($lkey_cpass ,$ukey_cpass ) = &des_keys();
1339: my ($lkey_npass1,$ukey_npass1) = &des_keys();
1340: my ($lkey_npass2,$ukey_npass2) = &des_keys();
1.4 matthew 1341: # Store the keys in the log files
1.3 matthew 1342: my $lonhost = $r->dir_config('lonHostID');
1343: my $logtoken=Apache::lonnet::reply('tmpput:'
1344: .$ukey_cpass . $lkey_cpass .'&'
1345: .$ukey_npass1 . $lkey_npass1.'&'
1346: .$ukey_npass2 . $lkey_npass2,
1347: $lonhost);
1.4 matthew 1348: # Hexify the keys for output as javascript variables
1.94 raeburn 1349: my %hexkey;
1350: $hexkey{'ukey_cpass'} = hex($ukey_cpass);
1351: $hexkey{'lkey_cpass'} = hex($lkey_cpass);
1352: $hexkey{'ukey_npass1'} = hex($ukey_npass1);
1353: $hexkey{'lkey_npass1'} = hex($lkey_npass1);
1354: $hexkey{'ukey_npass2'} = hex($ukey_npass2);
1355: $hexkey{'lkey_npass2'} = hex($lkey_npass2);
1.3 matthew 1356: # Output javascript to deal with passwords
1.4 matthew 1357: # Output DES javascript
1.3 matthew 1358: {
1359: my $include = $r->dir_config('lonIncludes');
1360: my $jsh=Apache::File->new($include."/londes.js");
1361: $r->print(<$jsh>);
1362: }
1.94 raeburn 1363: $r->print(&jscript_send($caller));
1.3 matthew 1364: $r->print(<<ENDFORM);
1.94 raeburn 1365: $errormessage
1366:
1367: <p>
1368: <!-- We separate the forms into 'server' and 'client' in order to
1369: ensure that unencrypted passwords will not be sent out by a
1370: crappy browser -->
1371: ENDFORM
1372: $r->print(&server_form($logtoken,$caller,$mailtoken));
1.186.2.7! raeburn 1373: $r->print(&client_form($caller,\%hexkey,$currentpass,$domain));
1.94 raeburn 1374:
1375: #
1376: return;
1377: }
1378:
1379: sub jscript_send {
1380: my ($caller) = @_;
1381: my $output = qq|
1.148 bisitz 1382: <script type="text/javascript" language="JavaScript">
1.3 matthew 1383:
1384: function send() {
1385: uextkey=this.document.client.elements.ukey_cpass.value;
1386: lextkey=this.document.client.elements.lkey_cpass.value;
1387: initkeys();
1388:
1.52 raeburn 1389: this.document.pserver.elements.currentpass.value
1.3 matthew 1390: =crypted(this.document.client.elements.currentpass.value);
1391:
1392: uextkey=this.document.client.elements.ukey_npass1.value;
1393: lextkey=this.document.client.elements.lkey_npass1.value;
1394: initkeys();
1.52 raeburn 1395: this.document.pserver.elements.newpass_1.value
1.3 matthew 1396: =crypted(this.document.client.elements.newpass_1.value);
1397:
1398: uextkey=this.document.client.elements.ukey_npass2.value;
1399: lextkey=this.document.client.elements.lkey_npass2.value;
1400: initkeys();
1.52 raeburn 1401: this.document.pserver.elements.newpass_2.value
1.3 matthew 1402: =crypted(this.document.client.elements.newpass_2.value);
1.94 raeburn 1403: |;
1404: if ($caller eq 'reset_by_email') {
1405: $output .= qq|
1406: this.document.pserver.elements.uname.value =
1407: this.document.client.elements.uname.value;
1408: this.document.pserver.elements.udom.value =
1409: this.document.client.elements.udom.options[this.document.client.elements.udom.selectedIndex].value;
1.173 raeburn 1410: this.document.pserver.elements.email.value =
1411: this.document.client.elements.email.value;
1.94 raeburn 1412: |;
1413: }
1414: $ output .= qq|
1.52 raeburn 1415: this.document.pserver.submit();
1.3 matthew 1416: }
1417: </script>
1.94 raeburn 1418: |;
1419: }
1.3 matthew 1420:
1.94 raeburn 1421: sub client_form {
1422: my ($caller,$hexkey,$currentpass,$defdom) = @_;
1.99 www 1423: my %lt=&Apache::lonlocal::texthash(
1.115 raeburn 1424: 'email' => 'E-mail Address',
1.99 www 1425: 'username' => 'Username',
1426: 'domain' => 'Domain',
1427: 'currentpass' => 'Current Password',
1428: 'newpass' => 'New Password',
1429: 'confirmpass' => 'Confirm Password',
1.169 raeburn 1430: 'changepass' => 'Save',
1431: );
1.99 www 1432:
1.164 bisitz 1433: my $output = '<form name="client">'
1434: .&Apache::lonhtmlcommon::start_pick_box();
1.94 raeburn 1435: if ($caller eq 'reset_by_email') {
1.164 bisitz 1436: $output .= &Apache::lonhtmlcommon::row_title(
1437: '<label for="email">'.$lt{'email'}.'</label>')
1438: .'<input type="text" name="email" size="30" />'
1439: .&Apache::lonhtmlcommon::row_closure()
1440: .&Apache::lonhtmlcommon::row_title(
1441: '<label for="uname">'.$lt{'username'}.'</label>')
1442: .'<input type="text" name="uname" size="15" />'
1443: .'<input type="hidden" name="currentpass" value="'.$currentpass.'" />'
1444: .&Apache::lonhtmlcommon::row_closure()
1445: .&Apache::lonhtmlcommon::row_title(
1446: '<label for="udom">'.$lt{'domain'}.'</label>')
1447: .&Apache::loncommon::select_dom_form($defdom,'udom')
1448: .&Apache::lonhtmlcommon::row_closure();
1.94 raeburn 1449: } else {
1.164 bisitz 1450: $output .= &Apache::lonhtmlcommon::row_title(
1451: '<label for="currentpass">'.$lt{'currentpass'}.'</label>')
1452: .'<input type="password" name="currentpass" size="10"/>'
1453: .&Apache::lonhtmlcommon::row_closure();
1454: }
1455: $output .= &Apache::lonhtmlcommon::row_title(
1456: '<label for="newpass_1">'.$lt{'newpass'}.'</label>')
1457: .'<input type="password" name="newpass_1" size="10" />'
1458: .&Apache::lonhtmlcommon::row_closure()
1459: .&Apache::lonhtmlcommon::row_title(
1460: '<label for="newpass_2">'.$lt{'confirmpass'}.'</label>')
1461: .'<input type="password" name="newpass_2" size="10" />'
1462: .&Apache::lonhtmlcommon::row_closure(1)
1463: .&Apache::lonhtmlcommon::end_pick_box();
1464: $output .= '<p><input type="button" value="'.$lt{'changepass'}.'" onClick="send();" /></p>'
1465: .qq|
1.94 raeburn 1466: <input type="hidden" name="ukey_cpass" value="$hexkey->{'ukey_cpass'}" />
1467: <input type="hidden" name="lkey_cpass" value="$hexkey->{'lkey_cpass'}" />
1468: <input type="hidden" name="ukey_npass1" value="$hexkey->{'ukey_npass1'}" />
1469: <input type="hidden" name="lkey_npass1" value="$hexkey->{'lkey_npass1'}" />
1470: <input type="hidden" name="ukey_npass2" value="$hexkey->{'ukey_npass2'}" />
1471: <input type="hidden" name="lkey_npass2" value="$hexkey->{'lkey_npass2'}" />
1.3 matthew 1472: </form>
1473: </p>
1.164 bisitz 1474: |;
1.94 raeburn 1475: return $output;
1476: }
1477:
1478: sub server_form {
1479: my ($logtoken,$caller,$mailtoken) = @_;
1480: my $action = '/adm/preferences';
1481: if ($caller eq 'reset_by_email') {
1482: $action = '/adm/resetpw';
1483: }
1484: my $output = qq|
1485: <form name="pserver" action="$action" method="post">
1486: <input type="hidden" name="logtoken" value="$logtoken" />
1487: <input type="hidden" name="currentpass" value="" />
1488: <input type="hidden" name="newpass_1" value="" />
1489: <input type="hidden" name="newpass_2" value="" />
1490: |;
1491: if ($caller eq 'reset_by_email') {
1492: $output .= qq|
1493: <input type="hidden" name="token" value="$mailtoken" />
1494: <input type="hidden" name="uname" value="" />
1495: <input type="hidden" name="udom" value="" />
1.173 raeburn 1496: <input type="hidden" name="email" value="" />
1.94 raeburn 1497:
1498: |;
1499: }
1500: $output .= qq|
1501: <input type="hidden" name="action" value="verify_and_change_pass" />
1502: </form>
1503: |;
1504: return $output;
1.3 matthew 1505: }
1506:
1507: sub verify_and_change_password {
1.94 raeburn 1508: my ($r,$caller,$mailtoken) = @_;
1509: my ($user,$domain,$homeserver);
1510: if ($caller eq 'reset_by_email') {
1511: $user = $env{'form.uname'};
1512: $domain = $env{'form.udom'};
1513: if ($user ne '' && $domain ne '') {
1514: $homeserver = &Apache::lonnet::homeserver($user,$domain);
1515: if ($homeserver eq 'no_host') {
1.99 www 1516: &passwordchanger($r,"<p>\n<span class='LC_error'>".
1517: &mt("Invalid username and/or domain")."</span>\n</p>",
1.94 raeburn 1518: $caller,$mailtoken);
1519: return 1;
1520: }
1521: } else {
1.99 www 1522: &passwordchanger($r,"<p>\n<span class='LC_error'>".
1523: &mt("Username and domain were blank")."</span>\n</p>",
1.94 raeburn 1524: $caller,$mailtoken);
1525: return 1;
1526: }
1527: } else {
1528: $user = $env{'user.name'};
1529: $domain = $env{'user.domain'};
1530: $homeserver = $env{'user.home'};
1531: }
1.3 matthew 1532: my $currentauth=&Apache::lonnet::queryauthenticate($user,$domain);
1.4 matthew 1533: # Check for authentication types that allow changing of the password.
1.94 raeburn 1534: if ($currentauth !~ /^(unix|internal):/) {
1535: if ($caller eq 'reset_by_email') {
1.99 www 1536: &passwordchanger($r,"<p>\n<span class='LC_error'>".
1537: &mt("Authentication type for this user can not be changed by this mechanism").
1538: "</span>\n</p>",
1.94 raeburn 1539: $caller,$mailtoken);
1540: return 1;
1541: } else {
1542: return;
1543: }
1544: }
1.3 matthew 1545: #
1.59 albertel 1546: my $currentpass = $env{'form.currentpass'};
1547: my $newpass1 = $env{'form.newpass_1'};
1548: my $newpass2 = $env{'form.newpass_2'};
1549: my $logtoken = $env{'form.logtoken'};
1.3 matthew 1550: # Check for empty data
1.4 matthew 1551: unless (defined($currentpass) &&
1552: defined($newpass1) &&
1553: defined($newpass2) ){
1.99 www 1554: &passwordchanger($r,"<p>\n<span class='LC_error'>".
1555: &mt("One or more password fields were blank").
1556: "</span>\n</p>",$caller,$mailtoken);
1.3 matthew 1557: return;
1558: }
1.16 albertel 1559: # Get the keys
1560: my $lonhost = $r->dir_config('lonHostID');
1.3 matthew 1561: my $tmpinfo = Apache::lonnet::reply('tmpget:'.$logtoken,$lonhost);
1562: if (($tmpinfo=~/^error/) || ($tmpinfo eq 'con_lost')) {
1.4 matthew 1563: # I do not a have a better idea about how to handle this
1.94 raeburn 1564: my $tryagain_text = &mt('Please log out and try again.');
1565: if ($caller eq 'reset_by_email') {
1566: $tryagain_text = &mt('Please try again later.');
1567: }
1.101 albertel 1568: my $unable=&mt("Unable to retrieve saved token for password decryption");
1.3 matthew 1569: $r->print(<<ENDERROR);
1570: <p>
1.99 www 1571: <span class="LC_error">$unable. $tryagain_text</span>
1.3 matthew 1572: </p>
1573: ENDERROR
1.4 matthew 1574: # Probably should log an error here
1.75 albertel 1575: return 1;
1.3 matthew 1576: }
1577: my ($ckey,$n1key,$n2key)=split(/&/,$tmpinfo);
1.4 matthew 1578: #
1.17 matthew 1579: $currentpass = &des_decrypt($ckey ,$currentpass);
1580: $newpass1 = &des_decrypt($n1key,$newpass1);
1581: $newpass2 = &des_decrypt($n2key,$newpass2);
1.94 raeburn 1582: #
1583: if ($caller eq 'reset_by_email') {
1584: my %data = &Apache::lonnet::tmpget($mailtoken);
1.117 raeburn 1585: if (keys(%data) == 0) {
1586: &passwordchanger($r,
1587: '<span class="LC_error">'.
1588: &mt('Could not verify current authentication.').' '.
1589: &mt('Please try again.').'</span>',$caller,$mailtoken);
1590: return 1;
1591: }
1.94 raeburn 1592: if ($currentpass ne $data{'temppasswd'}) {
1593: &passwordchanger($r,
1.99 www 1594: '<span class="LC_error">'.
1.110 bisitz 1595: &mt('Could not verify current authentication.').' '.
1596: &mt('Please try again.').'</span>',$caller,$mailtoken);
1.94 raeburn 1597: return 1;
1598: }
1599: }
1.3 matthew 1600: if ($newpass1 ne $newpass2) {
1.4 matthew 1601: &passwordchanger($r,
1.99 www 1602: '<span class="LC_error">'.
1.110 bisitz 1603: &mt('The new passwords you entered do not match.').' '.
1604: &mt('Please try again.').'</span>',$caller,$mailtoken);
1.75 albertel 1605: return 1;
1.4 matthew 1606: }
1607: if (length($newpass1) < 7) {
1608: &passwordchanger($r,
1.99 www 1609: '<span class="LC_error">'.
1.110 bisitz 1610: &mt('Passwords must be a minimum of 7 characters long.').' '.
1611: &mt('Please try again.').'</span>',$caller,$mailtoken);
1.75 albertel 1612: return 1;
1.3 matthew 1613: }
1.4 matthew 1614: #
1615: # Check for bad characters
1616: my $badpassword = 0;
1617: foreach (split(//,$newpass1)) {
1618: $badpassword = 1 if ((ord($_)<32)||(ord($_)>126));
1619: }
1620: if ($badpassword) {
1621: # I can't figure out how to enter bad characters on my browser.
1.99 www 1622: my $errormessage ='<span class="LC_error">'.
1.110 bisitz 1623: &mt('The password you entered contained illegal characters.').'<br />'.
1.99 www 1624: &mt('Valid characters are').(<<"ENDERROR");
1625: : space and <br />
1.4 matthew 1626: <pre>
1627: !"\#$%&\'()*+,-./0123456789:;<=>?\@
1628: ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_\`abcdefghijklmnopqrstuvwxyz{|}~
1.99 www 1629: </pre></span>
1.4 matthew 1630: ENDERROR
1.94 raeburn 1631: &passwordchanger($r,$errormessage,$caller,$mailtoken);
1632: return 1;
1.4 matthew 1633: }
1634: #
1635: # Change the password (finally)
1636: my $result = &Apache::lonnet::changepass
1.94 raeburn 1637: ($user,$domain,$currentpass,$newpass1,$homeserver,$caller);
1.4 matthew 1638: # Inform the user the password has (not?) been changed
1.126 droeschl 1639: my $message;
1.4 matthew 1640: if ($result =~ /^ok$/) {
1.170 bisitz 1641: $message = &Apache::lonhtmlcommon::confirm_success(&mt('The password for user [_1] was successfully changed.','<i>'.$user.'</i>'));
1.180 wenzelju 1642: $message = &Apache::loncommon::confirmwrapper($message);
1.144 raeburn 1643: if ($caller eq 'reset_by_email') {
1644: $r->print($message.'<br />');
1645: } else {
1646: &print_main_menu($r, $message);
1647: }
1.4 matthew 1648: } else {
1649: # error error: run in circles, scream and shout
1.173 raeburn 1650: if ($caller eq 'reset_by_email') {
1651: if (!$result) {
1652: return 1;
1653: } else {
1654: return $result;
1655: }
1656: } else {
1657: $message = &Apache::lonhtmlcommon::confirm_success(
1658: &mt("The password for user [_1] was not changed.",'<i>'.$user.'</i>').' '.&mt('Please make sure your old password was entered correctly.'),1);
1.158 bisitz 1659: $message=&Apache::loncommon::confirmwrapper($message);
1.144 raeburn 1660: &print_main_menu($r, $message);
1661: }
1.4 matthew 1662: }
1663: return;
1.3 matthew 1664: }
1665:
1.42 raeburn 1666: ################################################################
1667: # discussion display subroutines
1668: ################################################################
1669: sub discussionchanger {
1670: my $r = shift;
1.126 droeschl 1671: Apache::lonhtmlcommon::add_breadcrumb(
1672: { href => '/adm/preferences?action=changediscussions',
1673: text => 'Change Discussion Preferences'});
1.178 bisitz 1674: $r->print(Apache::loncommon::start_page('Change Discussion Preferences'));
1.126 droeschl 1675: $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Discussion Preferences'));
1.59 albertel 1676: my $user = $env{'user.name'};
1677: my $domain = $env{'user.domain'};
1.42 raeburn 1678: my %userenv = &Apache::lonnet::get
1.43 raeburn 1679: ('environment',['discdisplay','discmarkread']);
1680: my $discdisp = 'allposts';
1681: my $discmark = 'onmark';
1682:
1683: if (defined($userenv{'discdisplay'})) {
1684: unless ($userenv{'discdisplay'} eq '') {
1685: $discdisp = $userenv{'discdisplay'};
1686: }
1687: }
1688: if (defined($userenv{'discmarkread'})) {
1.171 raeburn 1689: unless ($userenv{'discmarkread'} eq '') {
1.43 raeburn 1690: $discmark = $userenv{'discmarkread'};
1691: }
1692: }
1693:
1694: my $newdisp = 'unread';
1695: my $newmark = 'ondisp';
1696:
1697: my $function = &Apache::loncommon::get_users_function();
1698: my $color = &Apache::loncommon::designparm($function.'.tabbg',
1.59 albertel 1699: $env{'user.domain'});
1.43 raeburn 1700: my %lt = &Apache::lonlocal::texthash(
1701: 'pref' => 'Display Preference',
1702: 'curr' => 'Current setting ',
1703: 'actn' => 'Action',
1.135 schafran 1704: 'sdpf' => 'Set display preferences for discussion posts for both discussion boards and individual resources in all your courses.',
1.43 raeburn 1705: 'prca' => 'Preferences can be set that determine',
1.135 schafran 1706: 'whpo' => 'Which posts are displayed when you display a discussion board or resource, and',
1.186.2.7! raeburn 1707: 'unwh' => 'Under what circumstances posts are identfied as "NEW"',
1.43 raeburn 1708: 'allposts' => 'All posts',
1709: 'unread' => 'New posts only',
1710: 'ondisp' => 'Once displayed',
1.186.2.7! raeburn 1711: 'onmark' => 'Once marked not NEW',
1.43 raeburn 1712: 'disa' => 'Posts displayed?',
1.186.2.7! raeburn 1713: 'npmr' => 'New posts cease to be identified as "NEW"?',
1.43 raeburn 1714: 'thde' => 'The preferences you set here can be overridden within each individual discussion.',
1715: 'chgt' => 'Change to '
1716: );
1717: my $dispchange = $lt{'unread'};
1718: my $markchange = $lt{'ondisp'};
1719: my $currdisp = $lt{'allposts'};
1720: my $currmark = $lt{'onmark'};
1721:
1722: if ($discdisp eq 'unread') {
1723: $dispchange = $lt{'allposts'};
1724: $currdisp = $lt{'unread'};
1725: $newdisp = 'allposts';
1726: }
1727:
1728: if ($discmark eq 'ondisp') {
1729: $markchange = $lt{'onmark'};
1730: $currmark = $lt{'ondisp'};
1731: $newmark = 'onmark';
1.42 raeburn 1732: }
1.171 raeburn 1733:
1.43 raeburn 1734: $r->print(<<"END");
1.88 albertel 1735: <form name="prefs" action="/adm/preferences" method="post">
1.42 raeburn 1736: <input type="hidden" name="action" value="verify_and_change_discussion" />
1737: <br />
1.87 albertel 1738: $lt{'sdpf'}<br /> $lt{'prca'} <ol><li>$lt{'whpo'}</li><li>$lt{'unwh'}</li></ol>
1.82 albertel 1739: END
1.158 bisitz 1740:
1741: $r->print('<p class="LC_info">'.$lt{'thde'}.'</p>');
1742:
1.82 albertel 1743: $r->print(&Apache::loncommon::start_data_table());
1744: $r->print(<<"END");
1745: <tr>
1746: <th>$lt{'pref'}</th>
1747: <th>$lt{'curr'}</th>
1748: <th>$lt{'actn'}?</th>
1.43 raeburn 1749: </tr>
1.82 albertel 1750: END
1751: $r->print(&Apache::loncommon::start_data_table_row());
1752: $r->print(<<"END");
1.43 raeburn 1753: <td>$lt{'disa'}</td>
1754: <td>$lt{$discdisp}</td>
1.82 albertel 1755: <td><label><input type="checkbox" name="discdisp" /><input type="hidden" name="newdisp" value="$newdisp" /> $lt{'chgt'} "$dispchange"</label></td>
1756: END
1757: $r->print(&Apache::loncommon::end_data_table_row().
1758: &Apache::loncommon::start_data_table_row());
1759: $r->print(<<"END");
1.43 raeburn 1760: <td>$lt{'npmr'}</td>
1761: <td>$lt{$discmark}</td>
1.82 albertel 1762: <td><label><input type="checkbox" name="discmark" /><input type="hidden" name="newmark" value="$newmark" /> $lt{'chgt'} "$markchange"</label></td>
1.43 raeburn 1763: </tr>
1.82 albertel 1764: END
1765: $r->print(&Apache::loncommon::end_data_table_row().
1766: &Apache::loncommon::end_data_table());
1.142 zhu 1767:
1.158 bisitz 1768: $r->print('<br />'
1769: .'<input type="submit" name="sub" value="'.&mt('Save').'" />'
1770: .'</form>'
1771: );
1.42 raeburn 1772: }
1773:
1774: sub verify_and_change_discussion {
1775: my $r = shift;
1.59 albertel 1776: my $user = $env{'user.name'};
1777: my $domain = $env{'user.domain'};
1.42 raeburn 1778: my $message='';
1.59 albertel 1779: if (defined($env{'form.discdisp'}) ) {
1780: my $newdisp = $env{'form.newdisp'};
1.43 raeburn 1781: if ($newdisp eq 'unread') {
1.171 raeburn 1782: $message .=&Apache::lonhtmlcommon::confirm_success(&mt('In discussions: only new posts will be displayed.')).'<br />';
1.43 raeburn 1783: &Apache::lonnet::put('environment',{'discdisplay' => $newdisp});
1.116 raeburn 1784: &Apache::lonnet::appenv({'environment.discdisplay' => $newdisp});
1.43 raeburn 1785: } else {
1.171 raeburn 1786: $message .= &Apache::lonhtmlcommon::confirm_success(&mt('In discussions: all posts will be displayed.')).'<br />';
1.43 raeburn 1787: &Apache::lonnet::del('environment',['discdisplay']);
1.139 raeburn 1788: &Apache::lonnet::delenv('environment.discdisplay');
1.43 raeburn 1789: }
1790: }
1.59 albertel 1791: if (defined($env{'form.discmark'}) ) {
1792: my $newmark = $env{'form.newmark'};
1.43 raeburn 1793: if ($newmark eq 'ondisp') {
1.152 www 1794: $message.=&Apache::lonhtmlcommon::confirm_success(&mt('In discussions: new posts will be cease to be identified as "NEW" after display.')).'<br />';
1.43 raeburn 1795: &Apache::lonnet::put('environment',{'discmarkread' => $newmark});
1.116 raeburn 1796: &Apache::lonnet::appenv({'environment.discmarkread' => $newmark});
1.43 raeburn 1797: } else {
1.186.2.7! raeburn 1798: $message.=&Apache::lonhtmlcommon::confirm_success(&mt('In discussions: posts will be identified as "NEW" until marked as not "NEW".')).'<br />';
1.43 raeburn 1799: &Apache::lonnet::del('environment',['discmarkread']);
1.139 raeburn 1800: &Apache::lonnet::delenv('environment.discmarkread');
1.43 raeburn 1801: }
1.42 raeburn 1802: }
1.158 bisitz 1803: $message=&Apache::loncommon::confirmwrapper($message);
1.152 www 1804: &print_main_menu($r, $message);
1.42 raeburn 1805: }
1806:
1.63 raeburn 1807: ################################################################
1808: # Subroutines for page display on course access (Course Coordinators)
1809: ################################################################
1810: sub coursedisplaychanger {
1811: my $r = shift;
1.152 www 1812: &Apache::lonhtmlcommon::add_breadcrumb(
1.126 droeschl 1813: { href => '/adm/preferences?action=changecourseinit',
1814: text => 'Change Course Init. Pref.'});
1815: $r->print(Apache::loncommon::start_page('Change Course Initialization Preference'));
1816: $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Course Init. Pref.'));
1.63 raeburn 1817: my $user = $env{'user.name'};
1818: my $domain = $env{'user.domain'};
1.66 albertel 1819: my %userenv = &Apache::lonnet::get('environment',['course_init_display']);
1.71 raeburn 1820: my $currvalue = 'whatsnew';
1.73 albertel 1821: my $firstselect = '';
1822: my $whatsnewselect = 'checked="checked"';
1.71 raeburn 1823: if (exists($userenv{'course_init_display'})) {
1824: if ($userenv{'course_init_display'} eq 'firstres') {
1825: $currvalue = 'firstres';
1.73 albertel 1826: $firstselect = 'checked="checked"';
1827: $whatsnewselect = '';
1.71 raeburn 1828: }
1.63 raeburn 1829: }
1.134 bisitz 1830: my %pagenames = &Apache::lonlocal::texthash(
1.71 raeburn 1831: firstres => 'First resource',
1.143 hauer 1832: whatsnew => "What's New Page",
1.71 raeburn 1833: );
1.134 bisitz 1834: my $whatsnew_off=&mt('Display the [_1]first resource[_2] in the course.','<b>','</b>');
1.143 hauer 1835: my $whatsnew_on=&mt("Display the [_1]What's New Page[_2] - a summary of items in the course which require attention.",'<b>','</b>');
1.63 raeburn 1836:
1.134 bisitz 1837: $r->print('<br /><b>'
1838: .&mt('Set the default page to be displayed when you select a course role')
1839: .'</b> '
1840: .&mt('(Currently: [_1])',$pagenames{$currvalue})
1841: .'<br />'
1.143 hauer 1842: .&mt("The global user preference you set for your courses can be overridden in an individual course by setting a course specific setting via the [_1]What's New Page[_2] in the course.",'<i>','</i>')
1.134 bisitz 1843: .'<br /><br />'
1844: );
1.63 raeburn 1845: $r->print(<<ENDLSCREEN);
1.88 albertel 1846: <form name="prefs" action="/adm/preferences" method="post">
1.63 raeburn 1847: <input type="hidden" name="action" value="verify_and_change_coursepage" />
1.72 albertel 1848: <br />
1.65 albertel 1849: <label><input type="radio" name="newdisp" value="firstres" $firstselect /> $whatsnew_off</label><br />
1.70 raeburn 1850: <label><input type="radio" name="newdisp" value="whatsnew" $whatsnewselect /> $whatsnew_on</label><input type="hidden" name="refpage" value="$env{'form.refpage'}" />
1.63 raeburn 1851: ENDLSCREEN
1.140 schafran 1852: $r->print('<br /><br /><input type="submit" value="'.&mt('Save').'" />
1.63 raeburn 1853: </form>');
1854: }
1855:
1856: sub verify_and_change_coursepage {
1857: my $r = shift;
1858: my $message='';
1859: my %lt = &Apache::lonlocal::texthash(
1.70 raeburn 1860: 'defs' => 'Default now set',
1.71 raeburn 1861: 'when' => 'when you select a course role from the roles screen',
1.63 raeburn 1862: 'ywbt' => 'you will be taken to the start of the course.',
1863: 'apwb' => 'a page will be displayed that lists items in the course that may require action from you.',
1864: 'gtts' => 'Go to the start of the course',
1.146 hauer 1865: 'dasp' => "Display the What's New Page",
1.63 raeburn 1866: );
1867: my $newdisp = $env{'form.newdisp'};
1.70 raeburn 1868: $message = '<b>'.$lt{'defs'}.'</b>: '.$lt{'when'}.', ';
1.63 raeburn 1869: if ($newdisp eq 'firstres') {
1.87 albertel 1870: $message .= $lt{'ywbt'}.'<br />';
1.63 raeburn 1871: &Apache::lonnet::put('environment',{'course_init_display' => $newdisp});
1.116 raeburn 1872: &Apache::lonnet::appenv({'environment.course_init_display' => $newdisp});
1.63 raeburn 1873: } else {
1.87 albertel 1874: $message .= $lt{'apwb'}.'<br />';
1.63 raeburn 1875: &Apache::lonnet::del('environment',['course_init_display']);
1.139 raeburn 1876: &Apache::lonnet::delenv('environment.course_init_display');
1.63 raeburn 1877: }
1.70 raeburn 1878: my $refpage = $env{'form.refpage'};
1.63 raeburn 1879: if (($env{'request.course.fn'}) && ($env{'request.course.id'})) {
1880: if ($newdisp eq 'firstres') {
1881: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1882: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1883: my ($furl,$ferr)=
1884: &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
1.180 wenzelju 1885: $message .= '<br /><a href="'.$furl.'">'.$lt{'gtts'}.' <i>'.&mt('now').'</i></a>';
1.63 raeburn 1886: } else {
1.180 wenzelju 1887: $message .= '<br /><a href="/adm/whatsnew?refpage='.
1888: $refpage.'">'.$lt{'dasp'}.'</a>';
1.63 raeburn 1889: }
1890: }
1.180 wenzelju 1891: $message = &Apache::lonhtmlcommon::confirm_success($message);
1892: $message = &Apache::loncommon::confirmwrapper($message);
1893: &print_main_menu($r,$message);
1.63 raeburn 1894: }
1895:
1.186 raeburn 1896: sub lockednameschanger {
1897: my $r = shift;
1898: &Apache::lonhtmlcommon::add_breadcrumb(
1899: { href => '/adm/preferences?action=changelockednames',
1900: text => 'Automatic name changes'});
1901: $r->print(Apache::loncommon::start_page('Automatic name changes'));
1902: $r->print(Apache::lonhtmlcommon::breadcrumbs('Allow/disallow name updates'));
1903: my %userenv = &Apache::lonnet::get('environment',['lockedname']);
1904: my $lockedname='';
1905: if (&can_toggle_namelocking()) {
1906: if ($userenv{'lockedname'}) {
1907: $lockedname = ' checked="checked"';
1908: }
1909: my %updateable;
1910: my %domconfig =
1911: &Apache::lonnet::get_dom('configuration',['autoupdate'],$env{'user.domain'});
1912: if (ref($domconfig{'autoupdate'}) eq 'HASH') {
1913: if ($domconfig{'autoupdate'}{'run'}) {
1914: my @inststatuses = split(':',$env{'environment.inststatus'});
1915: unless (@inststatuses) {
1916: @inststatuses = ('default');
1917: }
1918: %updateable = &updateable_userinfo($domconfig{'autoupdate'},\@inststatuses);
1919: }
1920: }
1921: if (keys(%updateable)) {
1922: my %longnames = &Apache::lonlocal::texthash (
1923: firstname => 'First Name',
1924: middlename => 'Middle Name',
1925: lastname => 'Last Name',
1926: );
1927: my $text=&mt('By default, based on your institutional affiliation, your LON-CAPA account can be automatically updated nightly based on directory information from your institution.').'<br />'.&mt('The following may be updated, unless you disallow updates:').
1928: '<ul>';
1929: foreach my $item ('firstname','middlename','lastname') {
1930: if ($updateable{$item}) {
1931: $text .= '<li>'.$longnames{$item}.'</li>';
1932: }
1933: }
1934: $text .= '</ul>';
1935: my $locking=&mt('Disallow automatic updates to name information for your LON-CAPA account');
1936: my $change=&mt('Save');
1937: $r->print(<<ENDSCREEN);
1938: <form name="prefs" action="/adm/preferences" method="post">
1939: <input type="hidden" name="action" value="verify_and_change_lockednames" />
1940: $text<br />
1941: <label><input type="checkbox" value="1" name="lockednames"$lockedname />$locking</label><br />
1942: <input type="submit" value="$change" />
1943: </form>
1944: ENDSCREEN
1945: } else {
1946: my $message = &mt('Based on your institutional affiliation no name information is automatically updated for your LON-CAPA account.');
1947: &print_main_menu($r,$message);
1948: }
1949: } else {
1950: my $message = &mt('You are not permitted to set a user preference for automatic name updates for your LON-CAPA account.');
1951: &print_main_menu($r,$message);
1952: }
1953: }
1954:
1955: sub verify_and_change_lockednames {
1956: my $r = shift;
1957: my $message;
1958: if (&can_toggle_namelocking()) {
1959: my $newlockedname = $env{'form.lockednames'};
1960: $newlockedname =~ s/\D//g;
1961: my $currlockedname = $env{'environment.lockedname'};
1962: if ($newlockedname ne $currlockedname) {
1963: if ($newlockedname) {
1964: if (&Apache::lonnet::put('environment',{lockedname => $newlockedname}) eq 'ok') {
1965: &Apache::lonnet::appenv({'environment.lockedname' => $newlockedname});
1966: }
1967: } elsif (&Apache::lonnet::del('environment',['lockedname']) eq 'ok') {
1968: &Apache::lonnet::delenv('environment.lockedname');
1969: }
1970: }
1971: my $status='';
1972: if ($newlockedname) {
1973: $status=&mt('disallowed');
1974: } else {
1975: $status=&mt('allowed');
1976: }
1977: $message=&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]','<i>'.&mt('Automatic update of first, middle and last names if institutional directory information indicates changes').'</i>','<tt>'.$status.'</tt>'));
1978: $message=&Apache::loncommon::confirmwrapper($message);
1979: }
1980: &print_main_menu($r,$message);
1981: }
1982:
1.126 droeschl 1983: sub print_main_menu {
1984: my ($r, $message) = @_;
1985: # Determine current authentication method
1986: my $user = $env{'user.name'};
1987: my $domain = $env{'user.domain'};
1988: my $currentauth=&Apache::lonnet::queryauthenticate($user,$domain);
1989:
1990: # build the data structure for menu generation
1991: my $aboutmeurl='/adm/'.$env{'user.domain'}.'/'.$env{'user.name'}.'/aboutme';
1992: my $role = ($env{'user.adv'} ? 'Roles' : 'Course');
1.131 raeburn 1993: my %permissions;
1994: if (&Apache::lonnet::usertools_access($user,$domain,'aboutme')) {
1995: $permissions{'aboutme'} = 'F';
1996: }
1.126 droeschl 1997: my @menu=
1998: ({ categorytitle=>'Personal Data',
1999: items =>[
1.141 weissno 2000: { linktext => 'Personal Information Page',
1.126 droeschl 2001: url => $aboutmeurl,
1.131 raeburn 2002: permission => $permissions{'aboutme'},
1.126 droeschl 2003: #help => 'Prefs_About_Me',
2004: icon => 'system-users.png',
2005: linktitle => 'Edit information about yourself that should be displayed on your public profile.'
2006: },
2007: { linktext => 'Screen Name',
2008: url => '/adm/preferences?action=changescreenname',
2009: permission => 'F',
2010: #help => 'Prefs_Screen_Name_Nickname',
2011: icon => 'preferences-desktop-font.png',
2012: linktitle => 'Change the name that is displayed in your posts.'
2013: },
2014: ]
2015: },
2016: { categorytitle=>'Content Display Settings',
2017: items =>[
2018: { linktext => 'Language',
2019: url => '/adm/preferences?action=changelanguages',
2020: permission => 'F',
2021: #help => 'Prefs_Language',
2022: icon => 'preferences-desktop-locale.png',
1.127 droeschl 2023: linktitle => 'Choose the default language for this user.'
1.126 droeschl 2024: },
1.128 droeschl 2025: { linktext => $role.' Page',
1.126 droeschl 2026: url => '/adm/preferences?action=changerolespref',
2027: permission => 'F',
2028: #help => '',
1.186.2.3 raeburn 2029: icon => 'role_hotlist.png',
1.126 droeschl 2030: linktitle => 'Configure the roles hotlist.'
2031: },
1.177 raeburn 2032: { linktext => 'Math display settings',
1.126 droeschl 2033: url => '/adm/preferences?action=changetexenginepref',
2034: permission => 'F',
2035: #help => '',
1.186.2.3 raeburn 2036: icon => 'dismath.png',
1.177 raeburn 2037: linktitle => 'Change how math is displayed.'
1.126 droeschl 2038: },
2039: ]
2040: },
1.185 droeschl 2041: { categorytitle=>'Page Display Settings',
2042: items =>[
2043: { linktext => 'Color Scheme',
2044: url => '/adm/preferences?action=changecolors',
2045: permission => 'F',
2046: #help => 'Change_Colors',
2047: icon => 'preferences-desktop-theme.png',
2048: linktitle => 'Change LON-CAPA default colors.'
2049: },
1.186.2.6 raeburn 2050: { linktext => 'Menu Display',
2051: url => '/adm/preferences?action=changeicons',
2052: permission => 'F',
2053: #help => '',
2054: icon => 'preferences-system-windows.png',
2055: linktitle => 'Change whether the menus are displayed with icons or icons and text.'
2056: }
1.185 droeschl 2057: ]
2058: },
1.178 bisitz 2059: { categorytitle=>'Messages & Notifications',
1.128 droeschl 2060: items =>[
1.153 www 2061: { linktext => 'Messages & Notifications',
1.128 droeschl 2062: url => '/adm/preferences?action=changemsgforward',
2063: permission => 'F',
2064: #help => 'Prefs_Messages',
2065: icon => 'mail-reply-all.png',
2066: linktitle => 'Change messageforwarding or notifications settings.'
2067: },
2068: { linktext => 'Discussion Display',
2069: url => '/adm/preferences?action=changediscussions',
2070: permission => 'F',
2071: #help => 'Change_Discussion_Display',
1.186.2.5 raeburn 2072: icon => 'chat.png',
1.135 schafran 2073: linktitle => 'Set display preferences for discussion posts for both discussion boards and individual resources in all your courses.'
1.128 droeschl 2074: },
2075: ]
2076: },
1.126 droeschl 2077: { categorytitle=>'Other',
2078: items =>[
1.153 www 2079: { linktext => 'Register Response Devices ("Clickers")',
1.126 droeschl 2080: url => '/adm/preferences?action=changeclicker',
2081: permission => 'F',
2082: #help => '',
2083: icon => 'network-workgroup.png',
2084: linktitle => 'Register your clicker.'
2085: },
2086: ]
2087: },
2088: );
2089:
2090: if ($currentauth =~ /^(unix|internal):/) {
2091: push(@{ $menu[0]->{items} }, {
2092: linktext => 'Password',
2093: url => '/adm/preferences?action=changepass',
2094: permission => 'F',
2095: #help => 'Change_Password',
2096: icon => 'emblem-readonly.png',
2097: linktitle => 'Change your password.',
2098: });
2099: }
1.186.2.1 raeburn 2100: if ($env{'environment.remote'} eq 'off') {
2101: push(@{ $menu[1]->{items} }, {
2102: linktext => 'Launch Remote Control',
2103: url => '/adm/remote?url=/adm/preferences&action=launch',
2104: permission => 'F',
2105: #help => '',
2106: icon => 'remotecontrol.png',
2107: linktitle => 'Launch the remote control for LON-CAPA.',
2108: });
2109: }else{
2110: push(@{ $menu[1]->{items} }, {
2111: linktext => 'Collapse Remote Control',
2112: url => '/adm/remote?url=/adm/preferences&action=collapse',
2113: permission => 'F',
2114: #help => '',
2115: icon => 'remotecontrol.png',
2116: linktitle => 'Collapse the remote control for LON-CAPA.',
2117: });
2118: }
2119:
1.186 raeburn 2120:
2121: if (&can_toggle_namelocking()) {
2122: push(@{ $menu[0]->{items} }, {
2123: linktext => 'Automatic name changes',
2124: url => '/adm/preferences?action=changelockednames',
2125: permission => 'F',
2126: #help => '',
2127: icon => 'system-lock-screen.png',
2128: linktitle => 'Allow/disallow propagation of name changes from institutional directory service',
2129: });
2130: }
2131:
1.126 droeschl 2132: my %author_roles = &Apache::lonnet::get_my_roles($user,$domain,'userroles','',['au']);
2133: if (keys(%author_roles) > 0) {
2134: push(@{ $menu[4]->{items} }, {
2135: linktext => 'Restrict Domain Coordinator Access',
2136: url => '/adm/preferences?action=changedomcoord',
2137: permission => 'F',
2138: #help => '',
2139: icon => 'system-lock-screen.png',
2140: linktitle => 'Restrict domain coordinator access.',
2141: });
2142: }
2143:
2144: if (&Apache::lonnet::allowed('whn',$env{'request.course.id'})
2145: || &Apache::lonnet::allowed('whn',$env{'request.course.id'}.'/'
2146: .$env{'request.course.sec'})) {
2147: push(@{ $menu[4]->{items} }, {
1.128 droeschl 2148: linktext => 'Course Initialization',
1.126 droeschl 2149: url => '/adm/preferences?action=changecourseinit',
2150: permission => 'F',
2151: #help => '',
1.186.2.3 raeburn 2152: icon => 'course_ini.png',
1.126 droeschl 2153: linktitle => 'Set the default page to be displayed when you select a course role.',
2154: });
2155:
2156: }
1.174 raeburn 2157: if (&can_toggle_debug()) {
1.126 droeschl 2158: push(@{ $menu[4]->{items} }, {
1.174 raeburn 2159: linktext => 'Toggle Debug Messages (Currently '.($env{'user.debug'} ? 'on)' : 'off)'),
1.126 droeschl 2160: url => '/adm/preferences?action=debugtoggle',
2161: permission => 'F',
2162: #help => '',
2163: icon => 'blog.png',
2164: linktitle => 'Toggle Debug Messages.',
2165: });
1.186 raeburn 2166: }
1.126 droeschl 2167:
1.147 schafran 2168: $r->print(&Apache::loncommon::start_page('My Space'));
1.126 droeschl 2169: $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Preferences'));
2170: $r->print($message);
2171: $r->print(Apache::lonhtmlcommon::generate_menu(@menu));
2172: $r->print(Apache::loncommon::end_page());
2173: }
1.63 raeburn 2174:
1.4 matthew 2175: ######################################################
2176: # other handler subroutines #
2177: ######################################################
2178:
1.3 matthew 2179: ################################################################
2180: # Main handler #
2181: ################################################################
1.126 droeschl 2182: sub handler {
2183: my $r = shift;
2184: Apache::loncommon::content_type($r,'text/html');
2185: # Some pages contain DES keys and should not be cached.
2186: Apache::loncommon::no_cache($r);
2187: $r->send_http_header;
2188: return OK if $r->header_only;
2189: #
2190: Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
2191: ['action','wysiwyg','returnurl','refpage']);
2192: #
2193: Apache::lonhtmlcommon::clear_breadcrumbs();
2194: Apache::lonhtmlcommon::add_breadcrumb
2195: ({href => '/adm/preferences',
1.150 droeschl 2196: text => 'Set User Preferences',
2197: help =>
2198: 'Prefs_About_Me,Prefs_Language,Prefs_Screen_Name_Nickname,Change_Colors,Change_Password,Prefs_Messages,Change_Discussion_Display'});
1.126 droeschl 2199: if(!exists $env{'form.action'}) {
1.150 droeschl 2200: &print_main_menu($r);
1.126 droeschl 2201: }elsif($env{'form.action'} eq 'changepass'){
2202: &passwordchanger($r);
2203: }elsif($env{'form.action'} eq 'verify_and_change_pass'){
2204: &verify_and_change_password($r);
2205: }elsif($env{'form.action'} eq 'changescreenname'){
2206: &screennamechanger($r);
2207: }elsif($env{'form.action'} eq 'verify_and_change_screenname'){
2208: &verify_and_change_screenname($r);
2209: }elsif($env{'form.action'} eq 'changemsgforward'){
2210: &msgforwardchanger($r);
2211: }elsif($env{'form.action'} eq 'verify_and_change_msgforward'){
2212: &verify_and_change_msgforward($r);
2213: }elsif($env{'form.action'} eq 'changecolors'){
2214: &colorschanger($r);
2215: }elsif($env{'form.action'} eq 'verify_and_change_colors'){
2216: &verify_and_change_colors($r);
2217: }elsif($env{'form.action'} eq 'changelanguages'){
2218: &languagechanger($r);
2219: }elsif($env{'form.action'} eq 'verify_and_change_languages'){
2220: &verify_and_change_languages($r);
2221: }elsif($env{'form.action'} eq 'changewysiwyg'){
2222: &wysiwygchanger($r);
2223: }elsif($env{'form.action'} eq 'set_wysiwyg'){
2224: &verify_and_change_wysiwyg($r);
2225: }elsif($env{'form.action'} eq 'changediscussions'){
2226: &discussionchanger($r);
2227: }elsif($env{'form.action'} eq 'verify_and_change_discussion'){
2228: &verify_and_change_discussion($r);
2229: }elsif($env{'form.action'} eq 'changerolespref'){
2230: &rolesprefchanger($r);
2231: }elsif($env{'form.action'} eq 'verify_and_change_rolespref'){
2232: &verify_and_change_rolespref($r);
2233: }elsif($env{'form.action'} eq 'changetexenginepref'){
2234: &texenginechanger($r);
2235: }elsif($env{'form.action'} eq 'verify_and_change_texengine'){
2236: &verify_and_change_texengine($r);
1.186.2.6 raeburn 2237: }elsif($env{'form.action'} eq 'changeicons'){
2238: &iconchanger($r);
2239: }elsif($env{'form.action'} eq 'verify_and_change_icons'){
2240: &verify_and_change_icons($r);
1.126 droeschl 2241: }elsif($env{'form.action'} eq 'changeclicker'){
2242: &clickerchanger($r);
2243: }elsif($env{'form.action'} eq 'verify_and_change_clicker'){
2244: &verify_and_change_clicker($r);
2245: }elsif($env{'form.action'} eq 'changedomcoord'){
2246: &domcoordchanger($r);
2247: }elsif($env{'form.action'} eq 'verify_and_change_domcoord'){
2248: &verify_and_change_domcoord($r);
2249: }elsif($env{'form.action'} eq 'lockwarning'){
2250: &lockwarning($r);
2251: }elsif($env{'form.action'} eq 'verify_and_change_locks'){
2252: &verify_and_change_lockwarning($r);
2253: }elsif($env{'form.action'} eq 'changecourseinit'){
2254: &coursedisplaychanger($r);
2255: }elsif($env{'form.action'} eq 'verify_and_change_coursepage'){
2256: &verify_and_change_coursepage($r);
2257: }elsif($env{'form.action'} eq 'debugtoggle'){
1.174 raeburn 2258: if (&can_toggle_debug()) {
2259: &toggle_debug();
2260: }
1.154 www 2261: &print_main_menu($r);
1.186 raeburn 2262: } elsif ($env{'form.action'} eq 'changelockednames') {
2263: &lockednameschanger($r);
2264: } elsif ($env{'form.action'} eq 'verify_and_change_lockednames') {
2265: &verify_and_change_lockednames($r);
1.126 droeschl 2266: }
2267:
1.165 bisitz 2268: # Properly end the HTML page of all preference pages
2269: # started in each sub routine
2270: # Exception: print_main_menu has its own end_page call
2271: unless (!exists $env{'form.action'} ||
2272: $env{'form.action'} eq 'debugtoggle') {
2273: $r->print(&Apache::loncommon::end_page());
2274: }
2275:
1.126 droeschl 2276: return OK;
1.35 matthew 2277: }
2278:
2279: sub toggle_debug {
1.59 albertel 2280: if ($env{'user.debug'}) {
1.139 raeburn 2281: &Apache::lonnet::delenv('user.debug');
1.35 matthew 2282: } else {
1.116 raeburn 2283: &Apache::lonnet::appenv({'user.debug' => 1});
1.35 matthew 2284: }
1.13 www 2285: }
1.1 www 2286:
1.174 raeburn 2287: sub can_toggle_debug {
2288: my $can_toggle = 0;
2289: my $page = 'toggledebug';
2290: if (&LONCAPA::lonauthcgi::can_view($page)) {
2291: $can_toggle = 1;
2292: } elsif (&LONCAPA::lonauthcgi::check_ipbased_access($page)) {
2293: $can_toggle = 1;
2294: }
2295: return $can_toggle;
2296: }
2297:
1.186 raeburn 2298: sub can_toggle_namelocking {
2299: my $lockablenames;
2300: my %domconfig =
2301: &Apache::lonnet::get_dom('configuration',['autoupdate'],$env{'user.domain'});
2302: if (ref($domconfig{'autoupdate'}) eq 'HASH') {
2303: if ($domconfig{'autoupdate'}{'run'}) {
2304: my @inststatuses = split(':',$env{'environment.inststatus'});
2305: unless (@inststatuses) {
2306: @inststatuses = ('default');
2307: }
2308: my %updateable = &updateable_userinfo($domconfig{'autoupdate'},\@inststatuses);
2309: if ($updateable{'lastname'} || $updateable{'firstname'} ||
2310: $updateable{'middlename'}) {
2311: if (ref($domconfig{'autoupdate'}{'lockablenames'}) eq 'ARRAY') {
2312: unless (@inststatuses) {
2313: @inststatuses = ('default');
2314: }
2315: foreach my $status (@inststatuses) {
2316: if (grep(/^\Q$status\E$/,@{$domconfig{'autoupdate'}{'lockablenames'}})) {
2317: $lockablenames = 1;
2318: last;
2319: }
2320: }
2321: }
2322: }
2323: }
2324: }
2325: return $lockablenames;
2326: }
2327:
2328: sub updateable_userinfo {
2329: my ($autoupdate,$inststatuses) = @_;
2330: my %updateable;
2331: return %updateable unless ((ref($autoupdate) eq 'HASH') &&
2332: (ref($inststatuses) eq 'ARRAY'));
2333: if (ref($autoupdate->{'fields'}) eq 'HASH') {
2334: foreach my $status (@{$inststatuses}) {
2335: if (ref($autoupdate->{'fields'}{$status}) eq 'ARRAY') {
2336: foreach my $field (@{$autoupdate->{'fields'}{$status}}) {
2337: $updateable{$field} = 1;
2338: }
2339: }
2340: }
2341: }
2342: return %updateable;
2343: }
2344:
1.1 www 2345: 1;
2346: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>