0
|
1 |
<?php
|
|
2 |
/*
|
|
3 |
Plugin Name: User control panel
|
|
4 |
Plugin URI: http://www.enanocms.org/
|
|
5 |
Description: Provides the page Special:Preferences.
|
|
6 |
Author: Dan Fuhry
|
|
7 |
Version: 1.0
|
|
8 |
Author URI: http://www.enanocms.org/
|
|
9 |
*/
|
|
10 |
|
|
11 |
/*
|
|
12 |
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
|
|
13 |
* Version 1.0 release candidate 2
|
|
14 |
* Copyright (C) 2006-2007 Dan Fuhry
|
|
15 |
*
|
|
16 |
* This program is Free Software; you can redistribute it and/or modify it under the terms of the GNU General Public License
|
|
17 |
* as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
|
|
18 |
*
|
|
19 |
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
20 |
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
|
|
21 |
*/
|
|
22 |
|
|
23 |
$userprefs_menu = Array();
|
|
24 |
$userprefs_menu_links = Array();
|
|
25 |
function userprefs_menu_add($section, $text, $link)
|
|
26 |
{
|
|
27 |
global $userprefs_menu;
|
|
28 |
if ( is_array($userprefs_menu[$section]) )
|
|
29 |
{
|
|
30 |
$userprefs_menu[$section][] = Array(
|
|
31 |
'text' => $text,
|
|
32 |
'link' => $link
|
|
33 |
);
|
|
34 |
}
|
|
35 |
else
|
|
36 |
{
|
|
37 |
$userprefs_menu[$section] = Array(Array(
|
|
38 |
'text' => $text,
|
|
39 |
'link' => $link
|
|
40 |
));
|
|
41 |
}
|
|
42 |
}
|
|
43 |
|
|
44 |
function userprefs_menu_html()
|
|
45 |
{
|
|
46 |
global $userprefs_menu;
|
|
47 |
global $userprefs_menu_links;
|
|
48 |
|
|
49 |
$html = '';
|
|
50 |
$quot = '"';
|
|
51 |
|
|
52 |
foreach ( $userprefs_menu as $section => $buttons )
|
|
53 |
{
|
|
54 |
$html .= ( isset($userprefs_menu_links[$section]) ) ? "<a href={$quot}{$userprefs_menu_links[$section]}{$quot}>{$section}</a>\n " : "<a>{$section}</a>\n ";
|
|
55 |
$html .= "<ul>\n ";
|
|
56 |
foreach ( $buttons as $button )
|
|
57 |
{
|
|
58 |
$html .= " <li><a href={$quot}{$button['link']}{$quot}>{$button['text']}</a></li>\n ";
|
|
59 |
}
|
|
60 |
$html .= "</ul>\n ";
|
|
61 |
}
|
|
62 |
|
|
63 |
return $html;
|
|
64 |
}
|
|
65 |
|
|
66 |
function userprefs_show_menu()
|
|
67 |
{
|
|
68 |
echo '<div class="menu_nojs">
|
|
69 |
' . userprefs_menu_html() . '
|
|
70 |
<span class="menuclear"></span>
|
|
71 |
</div>
|
|
72 |
<br />
|
|
73 |
';
|
|
74 |
}
|
|
75 |
|
|
76 |
function userprefs_menu_init()
|
|
77 |
{
|
|
78 |
global $db, $session, $paths, $template, $plugins; // Common objects
|
|
79 |
global $userprefs_menu_links;
|
|
80 |
|
|
81 |
userprefs_menu_add('Profile/membership', 'Edit e-mail address and password', makeUrlNS('Special', 'Preferences/EmailPassword'));
|
|
82 |
userprefs_menu_add('Profile/membership', 'Edit signature', makeUrlNS('Special', 'Preferences/Signature'));
|
|
83 |
userprefs_menu_add('Profile/membership', 'Edit public profile', makeUrlNS('Special', 'Preferences/Profile'));
|
|
84 |
userprefs_menu_add('Private messages', 'Inbox', makeUrlNS('Special', 'PrivateMessages/Folder/Inbox'));
|
|
85 |
userprefs_menu_add('Private messages', 'Outbox', makeUrlNS('Special', 'PrivateMessages/Folder/Outbox'));
|
|
86 |
userprefs_menu_add('Private messages', 'Sent items', makeUrlNS('Special', 'PrivateMessages/Folder/Sent'));
|
|
87 |
userprefs_menu_add('Private messages', 'Drafts', makeUrlNS('Special', 'PrivateMessages/Folder/Drafts'));
|
|
88 |
userprefs_menu_add('Private messages', 'Archive', makeUrlNS('Special', 'PrivateMessages/Folder/Archive'));
|
|
89 |
|
|
90 |
$userprefs_menu_links['Profile/membership'] = makeUrlNS('Special', 'Preferences');
|
|
91 |
$userprefs_menu_links['Private messages'] = makeUrlNS('Special', 'PrivateMessages');
|
|
92 |
|
|
93 |
$code = $plugins->setHook('userprefs_jbox');
|
|
94 |
foreach ( $code as $cmd )
|
|
95 |
{
|
|
96 |
eval($cmd);
|
|
97 |
}
|
|
98 |
}
|
|
99 |
|
|
100 |
$plugins->attachHook('session_started', 'userprefs_menu_init();');
|
|
101 |
|
|
102 |
function page_Special_Preferences()
|
|
103 |
{
|
|
104 |
global $db, $session, $paths, $template, $plugins; // Common objects
|
|
105 |
|
|
106 |
// We need a login to continue
|
|
107 |
if ( !$session->user_logged_in )
|
|
108 |
redirect(makeUrlNS('Special', 'Login/' . $paths->page), 'Login required', 'You need to be logged in to access this page. Please wait while you are redirected to the login page.');
|
|
109 |
|
|
110 |
// User ID - later this will be specified on the URL, but hardcoded for now
|
|
111 |
$uid = intval($session->user_id);
|
|
112 |
|
|
113 |
// Instanciate the AES encryptor
|
|
114 |
$aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
|
|
115 |
|
|
116 |
// Basic user info
|
|
117 |
$q = $db->sql_query('SELECT username, password, email, real_name, signature, theme, style FROM '.table_prefix.'users WHERE user_id='.$uid.';');
|
|
118 |
if ( !$q )
|
|
119 |
$db->_die();
|
|
120 |
|
|
121 |
$row = $db->fetchrow();
|
|
122 |
$db->free_result();
|
|
123 |
|
|
124 |
$section = $paths->getParam(0);
|
|
125 |
if ( !$section )
|
|
126 |
{
|
|
127 |
$section = 'Home';
|
|
128 |
}
|
|
129 |
|
|
130 |
$errors = '';
|
|
131 |
|
|
132 |
switch ( $section )
|
|
133 |
{
|
|
134 |
case 'EmailPassword':
|
|
135 |
// Require elevated privileges (well sortof)
|
|
136 |
if ( $session->auth_level < USER_LEVEL_CHPREF )
|
|
137 |
{
|
|
138 |
redirect(makeUrlNS('Special', 'Login/' . $paths->fullpage, 'level=' . USER_LEVEL_CHPREF, true), 'Authentication required', 'You need to re-authenticate to access this page.', 0);
|
|
139 |
}
|
|
140 |
|
|
141 |
if ( isset($_POST['submit']) )
|
|
142 |
{
|
|
143 |
$email_changed = false;
|
|
144 |
// First do the e-mail address
|
|
145 |
if ( strlen($_POST['newemail']) > 0 )
|
|
146 |
{
|
|
147 |
switch('foo') // Same reason as in the password code...
|
|
148 |
{
|
|
149 |
case 'foo':
|
|
150 |
if ( $_POST['newemail'] != $_POST['newemail_conf'] )
|
|
151 |
{
|
|
152 |
$errors .= '<div class="error-box">The e-mail addresses you entered did not match.</div>';
|
|
153 |
break;
|
|
154 |
}
|
|
155 |
}
|
|
156 |
$q = $db->sql_query('SELECT password FROM '.table_prefix.'users WHERE user_id='.$session->user_id.';');
|
|
157 |
if ( !$q )
|
|
158 |
$db->_die();
|
|
159 |
$row = $db->fetchrow();
|
|
160 |
$db->free_result();
|
|
161 |
$old_pass = $aes->decrypt($row['password'], $session->private_key, ENC_HEX);
|
|
162 |
|
|
163 |
$new_email = $_POST['newemail'];
|
|
164 |
|
|
165 |
$result = $session->update_user($session->user_id, false, $old_pass, false, $new_email);
|
|
166 |
if ( $result != 'success' )
|
|
167 |
{
|
|
168 |
die_friendly('Error updating e-mail address', '<p>Session API returned error: ' . $result . '</p>');
|
|
169 |
}
|
|
170 |
$email_changed = true;
|
|
171 |
}
|
|
172 |
// Obtain password
|
|
173 |
if ( $_POST['use_crypt'] == 'yes' && !empty($_POST['crypt_data']) )
|
|
174 |
{
|
|
175 |
$key = $session->fetch_public_key($_POST['crypt_key']);
|
|
176 |
if ( !$key )
|
|
177 |
die('Can\'t lookup key');
|
|
178 |
$key = hexdecode($key);
|
|
179 |
$newpass = $aes->decrypt($_POST['crypt_data'], $key, ENC_HEX);
|
|
180 |
// At this point we know if we _want_ to change the password...
|
|
181 |
|
|
182 |
// We can't check the password to see if it matches the confirmation
|
|
183 |
// because the confirmation was destroyed during the encryption. I figured
|
|
184 |
// this wasn't a big deal because if the encryption worked, then either
|
|
185 |
// the Javascript validated it or the user hacked the form. In the latter
|
|
186 |
// case, if he's smart enough to hack the encryption code, he's probably
|
|
187 |
// smart enough to remember his password.
|
|
188 |
|
|
189 |
if ( strlen($newpass) > 0 )
|
|
190 |
{
|
|
191 |
// Perform checks
|
|
192 |
if ( strlen($newpass) < 6 )
|
|
193 |
$errors .= '<div class="error-box">Password must be at least 6 characters. You hacked my script, darn you!</div>';
|
|
194 |
// Encrypt new password
|
|
195 |
$newpass_enc = $aes->encrypt($newpass, $session->private_key, ENC_HEX);
|
|
196 |
// Perform the swap
|
|
197 |
$q = $db->sql_query('UPDATE '.table_prefix.'users SET password=\'' . $newpass_enc . '\' WHERE user_id=' . $session->user_id . ';');
|
|
198 |
if ( !$q )
|
|
199 |
$db->_die();
|
|
200 |
// Log out and back in
|
|
201 |
$username = $session->username;
|
|
202 |
$session->logout();
|
|
203 |
if ( $email_changed )
|
|
204 |
{
|
|
205 |
if ( getConfig('account_activation') == 'user' )
|
|
206 |
{
|
|
207 |
redirect(makeUrl(getConfig('main_page')), 'Profile changed', 'Your password and e-mail address have been changed. Since e-mail activation is required on this site, you will need to re-activate your account to continue. An e-mail has been sent to the new e-mail address with an activation link. You must click that link in order to log in again.', 19);
|
|
208 |
}
|
|
209 |
else if ( getConfig('account_activation') == 'admin' )
|
|
210 |
{
|
|
211 |
redirect(makeUrl(getConfig('main_page')), 'Profile changed', 'Your password and e-mail address have been changed. Since administrative activation is requires on this site, a request has been sent to the administrators to activate your account for you. You will not be able to use your account until it is activated by an administrator.', 19);
|
|
212 |
}
|
|
213 |
}
|
|
214 |
$session->login_without_crypto($session->username, $newpass);
|
|
215 |
redirect(makeUrlNS('Special', 'Preferences'), 'Password changed', 'Your password has been changed, and you will now be redirected back to the user control panel.', 4);
|
|
216 |
}
|
|
217 |
}
|
|
218 |
else
|
|
219 |
{
|
|
220 |
switch('foo') // allow breaking out of our section...i can't wait until PHP6 (goto support!)
|
|
221 |
{
|
|
222 |
case 'foo':
|
|
223 |
$pass = $_POST['newpass'];
|
|
224 |
if ( $pass != $_POST['newpass_conf'] )
|
|
225 |
{
|
|
226 |
$errors .= '<div class="error-box">The passwords you entered did not match</div>';
|
|
227 |
break;
|
|
228 |
}
|
|
229 |
|
|
230 |
if ( $email_changed )
|
|
231 |
{
|
|
232 |
if ( getConfig('account_activation') == 'user' )
|
|
233 |
{
|
|
234 |
redirect(makeUrl(getConfig('main_page')), 'Profile changed', 'Your e-mail address has been changed. Since e-mail activation is required on this site, you will need to re-activate your account to continue. An e-mail has been sent to the new e-mail address with an activation link. You must click that link in order to log in again.', 19);
|
|
235 |
}
|
|
236 |
else if ( getConfig('account_activation') == 'admin' )
|
|
237 |
{
|
|
238 |
redirect(makeUrl(getConfig('main_page')), 'Profile changed', 'Your e-mail address has been changed. Since administrative activation is requires on this site, a request has been sent to the administrators to activate your account for you. You will not be able to use your account until it is activated by an administrator.', 19);
|
|
239 |
}
|
|
240 |
else
|
|
241 |
{
|
|
242 |
redirect(makeUrlNS('Special', 'Preferences'), 'Password changed', 'Your e-mail address has been changed, and you will now be redirected back to the user control panel.', 4);
|
|
243 |
}
|
|
244 |
}
|
|
245 |
|
|
246 |
return;
|
|
247 |
}
|
|
248 |
}
|
|
249 |
}
|
|
250 |
$template->tpl_strings['PAGE_NAME'] = 'Change E-mail Address or Password';
|
|
251 |
break;
|
|
252 |
case 'Signature':
|
|
253 |
$template->tpl_strings['PAGE_NAME'] = 'Editing signature';
|
|
254 |
break;
|
|
255 |
case 'Profile':
|
|
256 |
$template->tpl_strings['PAGE_NAME'] = 'Editing public profile';
|
|
257 |
break;
|
|
258 |
}
|
|
259 |
|
|
260 |
$template->header();
|
|
261 |
|
|
262 |
// Output the menu
|
|
263 |
// This is not templatized because it conforms to the jBox menu standard.
|
|
264 |
|
|
265 |
userprefs_show_menu();
|
|
266 |
|
|
267 |
switch ( $section )
|
|
268 |
{
|
|
269 |
case 'Home':
|
|
270 |
global $email;
|
|
271 |
$user_page = '<a href="' . makeUrlNS('User', str_replace(' ', '_', $session->username)) . '">user page</a> <sup>(<a href="' . makeUrlNS('User', str_replace(' ', '_', $session->username)) . '#do:comments">comments</a>)</sup>';
|
|
272 |
$site_admin = $email->encryptEmail(getConfig('contact_email'), '', '', 'administrator');
|
|
273 |
echo "<h3 style='margin-top: 0;'>$session->username, welcome to your control panel</h3>";
|
|
274 |
echo "<p>Here you can make changes to your profile, view statistics on yourself on this site, and set your preferences.</p>
|
|
275 |
<p>If you have not already done so, you are encouraged to make a $user_page and tell the other members of this site a little about yourself.</p>
|
|
276 |
<p>Use the menu at the top to navigate around. If you have any questions, you may contact the $site_admin.";
|
|
277 |
break;
|
|
278 |
case 'EmailPassword':
|
|
279 |
|
|
280 |
echo '<form action="' . makeUrlNS('Special', 'Preferences/EmailPassword') . '" method="post" onsubmit="return runEncryption();" name="empwform" >';
|
|
281 |
|
|
282 |
// Password change form
|
|
283 |
$pubkey = $session->rijndael_genkey();
|
|
284 |
|
|
285 |
echo '<fieldset>
|
|
286 |
<legend>Change password</legend>
|
|
287 |
Type a new password:<br />
|
|
288 |
<input type="password" name="newpass" size="30" tabindex="1" />
|
|
289 |
<br />
|
|
290 |
<br />
|
|
291 |
Type the password again to confirm:<br />
|
|
292 |
<input type="password" name="newpass_conf" size="30" tabindex="2" />
|
|
293 |
</fieldset><br />
|
|
294 |
<fieldset>
|
|
295 |
<legend>Change e-mail address</legend>
|
|
296 |
New e-mail address:<br />
|
|
297 |
<input type="text" name="newemail" size="30" tabindex="3" />
|
|
298 |
<br />
|
|
299 |
<br />
|
|
300 |
Confirm e-mail address:<br />
|
|
301 |
<input type="text" name="newemail_conf" size="30" tabindex="4" />
|
|
302 |
</fieldset>
|
|
303 |
<input type="hidden" name="use_crypt" value="no" />
|
|
304 |
<input type="hidden" name="crypt_key" value="' . $pubkey . '" />
|
|
305 |
<input type="hidden" name="crypt_data" value="" />
|
|
306 |
<br />
|
|
307 |
<div style="text-align: right;"><input type="submit" name="submit" value="Save Changes" tabindex="5" /></div>';
|
|
308 |
|
|
309 |
echo '</form>';
|
|
310 |
|
|
311 |
// ENCRYPTION CODE
|
|
312 |
?>
|
|
313 |
<script type="text/javascript">
|
|
314 |
disableJSONExts();
|
|
315 |
str = '';
|
|
316 |
for(i=0;i<keySizeInBits/4;i++) str+='0';
|
|
317 |
var key = hexToByteArray(str);
|
|
318 |
var pt = hexToByteArray(str);
|
|
319 |
var ct = rijndaelEncrypt(pt, key, "ECB");
|
|
320 |
var ct = byteArrayToHex(ct);
|
|
321 |
switch(keySizeInBits)
|
|
322 |
{
|
|
323 |
case 128:
|
|
324 |
v = '66e94bd4ef8a2c3b884cfa59ca342b2e';
|
|
325 |
break;
|
|
326 |
case 192:
|
|
327 |
v = 'aae06992acbf52a3e8f4a96ec9300bd7aae06992acbf52a3e8f4a96ec9300bd7';
|
|
328 |
break;
|
|
329 |
case 256:
|
|
330 |
v = 'dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087';
|
|
331 |
break;
|
|
332 |
}
|
|
333 |
var aes_testpassed = ( ct == v && md5_vm_test() );
|
|
334 |
function runEncryption()
|
|
335 |
{
|
|
336 |
var frm = document.forms.empwform;
|
|
337 |
if ( frm.newpass.value.length < 1 )
|
|
338 |
return true;
|
|
339 |
if(aes_testpassed)
|
|
340 |
{
|
|
341 |
frm.use_crypt.value = 'yes';
|
|
342 |
var cryptkey = frm.crypt_key.value;
|
|
343 |
frm.crypt_key.value = hex_md5(cryptkey);
|
|
344 |
cryptkey = hexToByteArray(cryptkey);
|
|
345 |
if(!cryptkey || ( ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ) && cryptkey.length != keySizeInBits / 8 )
|
|
346 |
{
|
|
347 |
frm.submit.disabled = true;
|
|
348 |
len = ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ? '\nLen: '+cryptkey.length : '';
|
|
349 |
alert('The key is messed up\nType: '+typeof(cryptkey)+len);
|
|
350 |
}
|
|
351 |
}
|
|
352 |
pass1 = frm.newpass.value;
|
|
353 |
pass2 = frm.newpass_conf.value;
|
|
354 |
if ( pass1 != pass2 )
|
|
355 |
{
|
|
356 |
alert('The passwords you entered do not match.');
|
|
357 |
return false;
|
|
358 |
}
|
|
359 |
if ( pass1.length < 6 && pass1.length > 0 )
|
|
360 |
{
|
|
361 |
alert('The new password must be 6 characters or greater in length.');
|
|
362 |
return false;
|
|
363 |
}
|
|
364 |
if(aes_testpassed)
|
|
365 |
{
|
|
366 |
pass = frm.newpass.value;
|
|
367 |
pass = stringToByteArray(pass);
|
|
368 |
cryptstring = rijndaelEncrypt(pass, cryptkey, 'ECB');
|
|
369 |
if(!cryptstring)
|
|
370 |
{
|
|
371 |
return false;
|
|
372 |
}
|
|
373 |
cryptstring = byteArrayToHex(cryptstring);
|
|
374 |
frm.crypt_data.value = cryptstring;
|
|
375 |
frm.newpass.value = "";
|
|
376 |
frm.newpass_conf.value = "";
|
|
377 |
}
|
|
378 |
return true;
|
|
379 |
}
|
|
380 |
</script>
|
|
381 |
<?php
|
|
382 |
|
|
383 |
break;
|
|
384 |
case 'Signature':
|
|
385 |
if ( isset($_POST['new_sig']) )
|
|
386 |
{
|
|
387 |
$sig = $_POST['new_sig'];
|
|
388 |
$sig = RenderMan::preprocess_text($sig, true, false);
|
|
389 |
$sql_sig = $db->escape($sig);
|
|
390 |
$q = $db->sql_query('UPDATE '.table_prefix.'users SET signature=\'' . $sql_sig . '\' WHERE user_id=' . $session->user_id . ';');
|
|
391 |
if ( !$q )
|
|
392 |
$db->_die();
|
|
393 |
$session->signature = $sig;
|
|
394 |
echo '<div class="info-box" style="margin: 0 0 10px 0;">Your signature has been saved.</div>';
|
|
395 |
}
|
|
396 |
echo '<form action="'.makeUrl($paths->fullpage).'" method="post">';
|
|
397 |
echo $template->tinymce_textarea('new_sig', $session->signature);
|
|
398 |
echo '<input type="submit" value="Save signature" />';
|
|
399 |
echo '</form>';
|
|
400 |
break;
|
|
401 |
case "Profile":
|
|
402 |
if ( isset($_POST['submit']) )
|
|
403 |
{
|
|
404 |
$real_name = htmlspecialchars($_POST['real_name']);
|
|
405 |
$real_name = $db->escape($real_name);
|
|
406 |
$q = $db->sql_query('UPDATE '.table_prefix."users SET real_name='$real_name' WHERE user_id=$session->user_id;");
|
|
407 |
if ( !$q )
|
|
408 |
$db->_die();
|
|
409 |
|
|
410 |
echo '<div class="info-box" style="margin: 0 0 10px 0;">Your profile has been updated.</div>';
|
|
411 |
}
|
|
412 |
echo '<form action="'.makeUrl($paths->fullpage).'" method="post">';
|
|
413 |
?>
|
|
414 |
<div class="tblholder">
|
|
415 |
<table border="0" cellspacing="1" cellpadding="4">
|
|
416 |
<tr>
|
|
417 |
<th colspan="2">Your public profile</th>
|
|
418 |
</tr>
|
|
419 |
<tr>
|
|
420 |
<td colspan="2" class="row3">Please note that all of the information you enter here will be <b>publicly viewable.</b> All of the fields on this page are optional and may be left blank if you so desire.</td>
|
|
421 |
</tr>
|
|
422 |
<tr>
|
|
423 |
<td class="row2" style="width: 50%;">Real name:</td>
|
|
424 |
<td class="row1" style="width: 50%;"><input type="text" name="real_name" value="<?php echo $session->real_name; ?>" size="30" /></td>
|
|
425 |
</tr>
|
|
426 |
<tr>
|
|
427 |
<td class="row2">Change theme:</td>
|
|
428 |
<td class="row1">If you don't like the look of the site, need a visual break, or are just curious, we might have some different themes for you to try out! <a href="<?php echo makeUrlNS('Special', 'ChangeStyle/' . $paths->page); ?>" onclick="ajaxChangeStyle(); return false;">Change my theme...</a></td>
|
|
429 |
</tr>
|
|
430 |
<tr>
|
|
431 |
<td colspan="2" class="row3"><small>More is coming soon - planned fields include AOL, WLM, Yahoo, and XMPP messenger fields, allow public display of e-mail address, allow private messages from users not on your buddy list, homepage, occupation, and location.</small></td>
|
|
432 |
</tr>
|
|
433 |
<tr>
|
|
434 |
<th class="subhead" colspan="2">
|
|
435 |
<input type="submit" name="submit" value="Save profile" />
|
|
436 |
</th>
|
|
437 |
</tr>
|
|
438 |
</table>
|
|
439 |
</div>
|
|
440 |
<?php
|
|
441 |
echo '</form>';
|
|
442 |
break;
|
|
443 |
default:
|
|
444 |
$good = false;
|
|
445 |
$code = $plugins->setHook('userprefs_body');
|
|
446 |
foreach ( $code as $cmd )
|
|
447 |
{
|
|
448 |
if ( eval($code) )
|
|
449 |
$good = true;
|
|
450 |
}
|
|
451 |
if ( !$good )
|
|
452 |
{
|
|
453 |
echo '<h3>Invalid module</h3>
|
|
454 |
<p>Userprefs module "'.$section.'" not found.</p>';
|
|
455 |
}
|
|
456 |
break;
|
|
457 |
}
|
|
458 |
|
|
459 |
$template->footer();
|
|
460 |
}
|
|
461 |
|
|
462 |
?>
|