Commented out noisy debug lines (maybe another branch is needed for debug-only).
[mailer.git] / inc / modules / admin / admin-inc.php
1 <?php
2 /************************************************************************
3  * Mailer v0.2.1-FINAL                                Start: 08/31/2003 *
4  * ===================                          Last change: 11/23/2004 *
5  *                                                                      *
6  * -------------------------------------------------------------------- *
7  * File              : admin-inc.php                                    *
8  * -------------------------------------------------------------------- *
9  * Short description : Administrative related functions                 *
10  * -------------------------------------------------------------------- *
11  * Kurzbeschreibung  : Fuer die Administration benoetigte Funktionen    *
12  * -------------------------------------------------------------------- *
13  * $Revision::                                                        $ *
14  * $Date::                                                            $ *
15  * $Tag:: 0.2.1-FINAL                                                 $ *
16  * $Author::                                                          $ *
17  * -------------------------------------------------------------------- *
18  * Copyright (c) 2003 - 2009 by Roland Haeder                           *
19  * Copyright (c) 2009 - 2013 by Mailer Developer Team                   *
20  * For more information visit: http://mxchange.org                      *
21  *                                                                      *
22  * This program is free software; you can redistribute it and/or modify *
23  * it under the terms of the GNU General Public License as published by *
24  * the Free Software Foundation; either version 2 of the License, or    *
25  * (at your option) any later version.                                  *
26  *                                                                      *
27  * This program is distributed in the hope that it will be useful,      *
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
30  * GNU General Public License for more details.                         *
31  *                                                                      *
32  * You should have received a copy of the GNU General Public License    *
33  * along with this program; if not, write to the Free Software          *
34  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,               *
35  * MA  02110-1301  USA                                                  *
36  ************************************************************************/
37
38 // Some security stuff...
39 if (!defined('__SECURITY')) {
40         die();
41 } // END - if
42
43 // Register an administrator account
44 function addAdminAccount ($adminLogin, $passHash, $adminEmail, $accessLevel = 'deny') {
45         // Only let valid data pass
46         assert(in_array($accessLevel, array('allow', 'deny')));
47
48         // Login does already exist
49         $ret = 'already';
50
51         // Lookup the admin
52         $result = sqlQueryEscaped("SELECT `id` FROM `{?_MYSQL_PREFIX?}_admins` WHERE `login`='%s' LIMIT 1",
53                 array($adminLogin), __FUNCTION__, __LINE__);
54
55         // Is the entry there?
56         if (ifSqlHasZeroNums($result)) {
57                 // Is ext-admins installed and version at least 0.3.0?
58                 if (isExtensionInstalledAndNewer('admins', '0.3.0')) {
59                         // Ok, let's create the admin login
60                         sqlQueryEscaped("INSERT INTO `{?_MYSQL_PREFIX?}_admins` (`login`, `password`, `email`, `default_acl`) VALUES ('%s', '%s', '%s', '%s')",
61                                 array(
62                                         $adminLogin,
63                                         $passHash,
64                                         $adminEmail,
65                                         $accessLevel
66                                 ), __FUNCTION__, __LINE__);
67                 } else {
68                         // Ok, let's create the admin login
69                         sqlQueryEscaped("INSERT INTO `{?_MYSQL_PREFIX?}_admins` (`login`, `password`, `email`) VALUES ('%s', '%s', '%s')",
70                                 array(
71                                         $adminLogin,
72                                         $passHash,
73                                         $adminEmail
74                                 ), __FUNCTION__, __LINE__);
75                 }
76
77                 // All done
78                 $ret = 'done';
79         } // END - if
80
81         // Free memory
82         sqlFreeResult($result);
83
84         // Return result
85         return $ret;
86 }
87
88 // This function will be executed when the admin is not logged in and has submitted his login data
89 function ifAdminLoginDataIsValid ($adminLogin, $adminPassword) {
90         // First of all, no admin login is found, so the admin hash is null
91         $ret = '404';
92         $adminHash = NULL;
93
94         // Get admin id from login
95         $adminId = getAdminId($adminLogin);
96
97         // Continue only with found admin ids
98         if (isValidId($adminId)) {
99                 // Then we need to lookup the login name by getting the admin hash
100                 $adminHash = getAdminHash($adminId);
101
102                 // If this is fine, we can continue
103                 if ($adminHash != '-1') {
104                         // Get admin id and set it as current
105                         setCurrentAdminId($adminId);
106
107                         // Now, we need to encode the password in the same way the one is encoded in database
108                         $testHash = generateHash($adminPassword, $adminHash);
109
110                         // If they both match, the login data is valid
111                         if ($testHash == $adminHash) {
112                                 // All fine
113                                 $ret = 'done';
114                         } else {
115                                 // Did not match!
116                                 $ret = 'password';
117                         }
118                 } // END - if
119         } // END - if
120
121         // Prepare data array
122         $data = array(
123                 'id'         => $adminId,
124                 'login'      => $adminLogin,
125                 'plain_pass' => $adminPassword,
126                 'pass_hash'  => $adminHash
127         );
128
129         // Run a special filter
130         runFilterChain('do_admin_login_' . $ret, $data);
131
132         // Return status
133         return $ret;
134 }
135
136 // Only be executed on cookie checking
137 function ifAdminCookiesAreValid ($adminLogin, $passHash) {
138         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'adminLogin=' . $adminLogin . ',passHash=' . $passHash . ' - CALLED!');
139
140         // First of all, no admin login is found
141         $ret = '404';
142
143         // Then we need to lookup the login name by getting the admin hash
144         $adminHash = getAdminHash($adminLogin);
145
146         // If this is fine, we can continue
147         if ($adminHash != '-1') {
148                 // Now, we need to encode the password in the same way the one is encoded in database
149                 $testHash = encodeHashForCookie($adminHash);
150                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'adminLogin=' . $adminLogin . ',passHash='.$passHash.',adminHash='.$adminHash.',testHash='.$testHash);
151
152                 // If they both match, the login data is valid
153                 if ($testHash != $passHash) {
154                         // Passwords don't match
155                         $ret = 'password';
156                 } elseif (!isAdmin()) {
157                         // Is not valid session
158                         $ret = 'session';
159                 } else {
160                         // All fine
161                         $ret = 'done';
162                 }
163         } // END - if
164
165         // Return status
166         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'ret=' . $ret . ' - EXIT!');
167         return $ret;
168 }
169
170 // Do an admin action
171 function doAdminAction () {
172         // Determine correct 'what' value
173         $what = determineWhat();
174
175         // Get action value
176         $action = getActionFromModuleWhat(getModule(), $what);
177
178         // Load welcome template
179         if (isExtensionActive('admins')) {
180                 // @TODO This and the next getCurrentAdminId() call might be moved into the templates?
181                 $content['welcome'] = loadTemplate('admin_welcome_admins', TRUE, getCurrentAdminId());
182         } else {
183                 $content['welcome'] = loadTemplate('admin_welcome', TRUE, getCurrentAdminId());
184         }
185
186         // Load header, footer, render menu
187         $content['header'] = loadTemplate('admin_header' , TRUE, $content);
188         $content['footer'] = loadTemplate('admin_footer' , TRUE, $content);
189         $content['menu']   = addAdminMenu($action, $what);
190
191         // Load main template
192         loadTemplate('admin_main', FALSE, $content);
193
194         // Check if action/what pair is valid
195         $result_action = sqlQueryEscaped("SELECT
196         `id`
197 FROM
198         `{?_MYSQL_PREFIX?}_admin_menu`
199 WHERE
200         `action`='%s' AND
201         (
202                 (
203                         `what`='%s' AND `what` != 'welcome'
204                 ) OR (
205                         (
206                                 `what`='' OR `what` IS NULL
207                         ) AND (
208                                 '%s'='welcome'
209                         )
210                 )
211         )
212 LIMIT 1",
213                 array(
214                         $action,
215                         $what,
216                         $what
217                 ), __FUNCTION__, __LINE__);
218
219         // Is there an entry?
220         if (sqlNumRows($result_action) == 1) {
221                 // Is valid but does the inlcude file exists?
222                 $inc = sprintf('inc/modules/admin/action-%s.php', $action);
223                 if ((isIncludeReadable($inc)) && (isMenuActionValid('admin', $action, $what)) && ($GLOBALS['acl_allow'] === TRUE)) {
224                         // Ok, we finally load the admin action module
225                         loadInclude($inc);
226                 } elseif ($GLOBALS['acl_allow'] === FALSE) {
227                         // Access denied
228                         loadTemplate('admin_menu_failed', FALSE, '{%message,ADMIN_ACCESS_DENIED=' . $what . '%}');
229                 } else {
230                         // Include file not found :-(
231                         loadTemplate('admin_menu_failed', FALSE, '{%message,ADMIN_ACTION_404=' . $action . '%}');
232                 }
233         } else {
234                 // Invalid action/what pair found
235                 loadTemplate('admin_menu_failed', FALSE, '{%message,ADMIN_ACTION_INVALID=' . $action . '/' . $what . '%}');
236         }
237
238         // Free memory
239         sqlFreeResult($result_action);
240
241         // Tableset footer
242         loadTemplate('admin_main_footer', FALSE, $content);
243 }
244
245 /**
246  * Checks whether current admin is allowed to access given action/what
247  * combination (only one is allowed to be null!).
248  */
249 function isAdminAllowedAccessMenu ($action, $what = NULL) {
250         // Is there cache?
251         if (!isset($GLOBALS[__FUNCTION__][$action][$what])) {
252                 // ACL is always 'allow' when no ext-admins is installed
253                 // @TODO This can be rewritten into a filter
254                 $GLOBALS[__FUNCTION__][$action][$what] = ((!isExtensionInstalledAndNewer('admins', '0.2.0')) || ((isExtensionActive('admins')) && (isAdminsAllowedByAcl($action, $what))));
255         } // END - if
256
257         // Return the cached value
258         return $GLOBALS[__FUNCTION__][$action][$what];
259 }
260
261 // Adds an admin menu
262 function addAdminMenu ($action, $what) {
263         // Init variables
264         $SUB = FALSE;
265         $OUT = '';
266
267         // Menu descriptions
268         $GLOBALS['menu']['description'] = array();
269         $GLOBALS['menu']['title']       = array();
270
271         // Build main menu
272         $result_main = sqlQuery("SELECT
273         `action` AS `main_action`,
274         `title` AS `main_title`,
275         `descr` AS `main_descr`
276 FROM
277         `{?_MYSQL_PREFIX?}_admin_menu`
278 WHERE
279         (`what`='' OR `what` IS NULL)
280 ORDER BY
281         `sort` ASC,
282         `id` DESC", __FUNCTION__, __LINE__);
283
284         // Are there entries?
285         if (!ifSqlHasZeroNums($result_main)) {
286                 $OUT .= '<ul class="admin_menu_main">';
287
288                 // Load all 'action' menus
289                 while ($mainContent = sqlFetchArray($result_main)) {
290                         // Filename
291                         $inc = sprintf('inc/modules/admin/action-%s.php', $mainContent['main_action']);
292
293                         // Is the current admin allowed to access this 'action' menu?
294                         if (isAdminAllowedAccessMenu($mainContent['main_action'])) {
295                                 if ($SUB === FALSE) {
296                                         // Insert compiled menu title and description
297                                         $GLOBALS['menu']['title'][$mainContent['main_action']]       = $mainContent['main_title'];
298                                         $GLOBALS['menu']['description'][$mainContent['main_action']] = $mainContent['main_descr'];
299                                 } // END - if
300                                 $OUT .= '<li class="admin_menu"' . addJavaScriptMenuContent('admin', $mainContent['main_action'], $action, $what) . '>
301 <div class="nobr"><strong>&middot;</strong>&nbsp;';
302
303                                 // Is the file readable?
304                                 if (isIncludeReadable($inc)) {
305                                         if (($mainContent['main_action'] == $action) && (empty($what))) {
306                                                 $OUT .= '<strong>';
307                                         } else {
308                                                 $OUT .= '[<a href="{%url=modules.php?module=admin&amp;action=' . $mainContent['main_action'] . '%}">';
309                                         }
310                                 } else {
311                                         $OUT .= '<span class="bad" style="cursor:help" title="{%message,ADMIN_MENU_ACTION_404_TITLE=' . $mainContent['main_action'] . '%}">';
312                                 }
313
314                                 $OUT .= $mainContent['main_title'];
315
316                                 // Is the file readable?
317                                 if (isIncludeReadable($inc)) {
318                                         if (($mainContent['main_action'] == $action) && (empty($what))) {
319                                                 $OUT .= '</strong>';
320                                         } else {
321                                                 $OUT .= '</a>]';
322                                         }
323                                 } else {
324                                         $OUT .= '</span>';
325                                 }
326
327                                 $OUT .= '</div>
328 </li>';
329
330                                 // Add sub menu
331                                 $OUT .= addAdminSubMenu($mainContent, $action, $what);
332                         } // END - if
333                 } // END - while
334
335                 // Close ul-tag
336                 $OUT .= '</ul>';
337
338                 // Free memory
339                 sqlFreeResult($result_main);
340         } // END - if
341
342         // Return content
343         return $OUT;
344 }
345
346 // Add admin sub menu
347 function addAdminSubMenu ($mainContent, $action, $what) {
348         // Init content
349         $OUT = '';
350
351         // Check for menu entries
352         $result_what = sqlQueryEscaped("SELECT
353         `what` AS `sub_what`,
354         `title` AS `sub_title`,
355         `descr` AS `sub_descr`
356 FROM
357         `{?_MYSQL_PREFIX?}_admin_menu`
358 WHERE
359         `action`='%s' AND
360         `what` != '' AND
361         `what` IS NOT NULL
362 ORDER BY
363         `sort` ASC,
364         `id` DESC",
365                 array($mainContent['main_action']), __FUNCTION__, __LINE__);
366
367         // Remember the count for later checks
368         setAdminMenuHasEntries($mainContent['main_action'], ((!ifSqlHasZeroNums($result_what)) && (($action == $mainContent['main_action']) || (isAdminMenuJavascriptEnabled()))));
369
370         // Start li-tag for sub menu content
371         $OUT .= '<li class="admin_menu_sub" id="action_menu_' . $mainContent['main_action'] . '"' . addStyleMenuContent('admin', $mainContent['main_action'], $action) . '>';
372
373         // Are there entries?
374         if (ifAdminMenuHasEntries($mainContent['main_action'])) {
375                 // Sub menu has been called
376                 $SUB = TRUE;
377
378                 // Are there entries?
379                 if (!ifSqlHasZeroNums($result_what)) {
380                         // Start HTML code
381                         $OUT .= '<ul class="admin_menu_sub">';
382
383                         // Load all entries
384                         while ($subContent = sqlFetchArray($result_what)) {
385                                 // Filename
386                                 $inc = sprintf('inc/modules/admin/what-%s.php', $subContent['sub_what']);
387
388                                 // Is the current admin allowed to access this 'what' menu?
389                                 if (isAdminAllowedAccessMenu(NULL, $subContent['sub_what'])) {
390                                         // Insert compiled title and description
391                                         $GLOBALS['menu']['title'][$subContent['sub_what']]       = $subContent['sub_title'];
392                                         $GLOBALS['menu']['description'][$subContent['sub_what']] = $subContent['sub_descr'];
393                                         $OUT .= '<li class="admin_menu">
394 <div class="nobr"><strong>--&gt;</strong>&nbsp;';
395
396                                         // Is the file readable?
397                                         if (isIncludeReadable($inc)) {
398                                                 if ($what == $subContent['sub_what']) {
399                                                         $OUT .= '<strong>';
400                                                 } else {
401                                                         $OUT .= '[<a href="{%url=modules.php?module=admin&amp;what=' . $subContent['sub_what'] . '%}">';
402                                                 }
403                                         } else {
404                                                 $OUT .= '<span class="bad" style="cursor:help" title="{%message,ADMIN_MENU_WHAT_404_TITLE=' . $subContent['sub_what'] . '%}">';
405                                         }
406
407                                         $OUT .= $subContent['sub_title'];
408
409                                         // Is the file readable?
410                                         if (isIncludeReadable($inc)) {
411                                                 if ($what == $subContent['sub_what']) {
412                                                         $OUT .= '</strong>';
413                                                 } else {
414                                                         $OUT .= '</a>]';
415                                                 }
416                                         } else {
417                                                 $OUT .= '</span>';
418                                         }
419                                         $OUT .= '</div>
420 </li>';
421                                 } // END - if
422                         } // END - while
423
424                         // Finish HTML output
425                         $OUT .= '</ul>';
426                 } // END - if
427
428                 // Free memory
429                 sqlFreeResult($result_what);
430         } // END - if
431
432         // Close li-tag
433         $OUT .= '</li>';
434
435         // Return content
436         return $OUT;
437 }
438
439 // Create an admin selection box form
440 function addAdminSelectionBox ($adminId = NULL, $special = '') {
441         // Default is email as "special column"
442         $ADD = ',`email` AS `special`';
443
444         // Is a special column given?
445         if (!empty($special)) {
446                 // Additional column for SQL query
447                 $ADD = ',`' . $special . '` AS `special`';
448         } // END - if
449
450         // Query all entries
451         $result = sqlQuery('SELECT
452         `id`,
453         `login`
454         ' . $ADD . '
455 FROM
456         `{?_MYSQL_PREFIX?}_admins`
457 ORDER BY
458         `login` ASC', __FUNCTION__, __LINE__);
459
460         // Init output
461         $OUT = '';
462
463         // Load all entries
464         while ($content = sqlFetchArray($result)) {
465                 // Default is none
466                 $content['default'] = '';
467
468                 // Is the id the same?
469                 if ($content['id'] == $adminId) {
470                         // Set this as default
471                         $content['default'] = ' selected="selected"';
472                 } // END - if
473
474                 // Add the entry
475                 $OUT .= loadTemplate('select_admins_option', TRUE, $content);
476         } // END - if
477
478         // Free memory
479         sqlFreeResult($result);
480
481         // Add form to content
482         $content['form_selection'] = $OUT;
483
484         // Output form
485         loadTemplate('select_admins_box', FALSE, $content);
486 }
487
488 // Create a member selection box
489 function addMemberSelectionBox ($userid = NULL, $add_all = FALSE, $return = FALSE, $none = FALSE, $field = 'userid', $whereStatement = " WHERE `surname` NOT LIKE '{?tester_user_surname_prefix?}%'") {
490         // Output selection form with all confirmed user accounts listed
491         $result = sqlQuery('SELECT
492         `userid`,
493         `surname`,
494         `family`
495 FROM
496         `{?_MYSQL_PREFIX?}_user_data`
497 ' . $whereStatement . '
498 ORDER BY
499         `userid` ASC', __FUNCTION__, __LINE__);
500
501         // Default output
502         $OUT = '';
503
504         // USe this only for adding points (e.g. adding refs really makes no sence ;-) )
505         if ($add_all === TRUE) {
506                 $OUT = '      <option value="all">{--ALL_MEMBERS--}</option>';
507         } elseif ($none === TRUE) {
508                 $OUT = '      <option value="0">{--SELECT_NONE--}</option>';
509         }
510
511         // Load all entries
512         while ($content = sqlFetchArray($result)) {
513                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'userid=' . intval($userid) . '/' . $content['userid']);
514                 $OUT .= '<option value="' . bigintval($content['userid']) . '"';
515                 if ($userid === $content['userid']) {
516                         $OUT .= ' selected="selected"';
517                 } // END - if
518                 $OUT .= '>' . $content['surname'] . ' ' . $content['family'] . ' (' . $content['userid'] . ')</option>';
519         } // END - while
520
521         // Free memory
522         sqlFreeResult($result);
523
524         if ($return === FALSE) {
525                 // Remeber options in constant
526                 $content['form_selection'] = $OUT;
527                 $content['what']           = '{%pipe,getWhat%}';
528
529                 // Load template
530                 loadTemplate('admin_form_selection_box', FALSE, $content);
531         } else {
532                 // Return content in selection frame
533                 return '<select class="form_select" name="' . handleFieldWithBraces($field) . '" size="1">' . $OUT . '</select>';
534         }
535 }
536
537 // Create a menu selection box for given menu system
538 // @TODO Try to rewrite this to adminAddMenuSelectionBox()
539 // @DEPRECATED
540 function adminMenuSelectionBox_DEPRECATED ($mode, $default = '', $defid = '') {
541         $what = "`what` != '' AND `what` IS NOT NULL";
542         if ($mode == 'action') $what = "(`what`='' OR `what` IS NULL) AND `action` != 'login'";
543
544         $result = sqlQueryEscaped("SELECT `%s` AS `menu`, `title` FROM `{?_MYSQL_PREFIX?}_admin_menu` WHERE ".$what." ORDER BY `sort` ASC",
545                 array($mode), __FUNCTION__, __LINE__);
546         if (!ifSqlHasZeroNums($result)) {
547                 // Load menu as selection
548                 $OUT = '<select name="' . $mode . '_menu';
549                 if (!isValidId($defid)) $OUT .= '[' . intval($defid) . ']';
550                 $OUT .= '" size="1" class="form_select">
551         <option value="">{--SELECT_NONE--}</option>';
552                 // Load all entries
553                 while ($content = sqlFetchArray($result)) {
554                         $OUT .= '<option value="' . $content['menu'] . '"';
555                         if ((!empty($default)) && ($default == $content['menu'])) {
556                                 $OUT .= ' selected="selected"';
557                         } // END - if
558                         $OUT .= '>' . $content['title'] . '</option>';
559                 } // END - while
560
561                 // Free memory
562                 sqlFreeResult($result);
563
564                 // Add closing select-tag
565                 $OUT .= '</select>';
566         } else {
567                 // No menus???
568                 $OUT = '{--ADMIN_PROBLEM_NO_MENU--}';
569         }
570
571         // Return output
572         return $OUT;
573 }
574
575 // Wrapper for $_POST and adminSaveSettings
576 function adminSaveSettingsFromPostData ($tableName = '_config', $whereStatement = '`config`=0', $translateComma = array(), $alwaysAdd = FALSE, $displayMessage = TRUE) {
577         // Get the array
578         $postData = postRequestArray();
579
580         // Call the lower function
581         adminSaveSettings($postData, $tableName, $whereStatement, $translateComma, $alwaysAdd, $displayMessage);
582 }
583
584 // Save settings to the database
585 function adminSaveSettings (&$postData, $tableName = '_config', $whereStatement = '`config`=0', $translateComma = array(), $alwaysAdd = FALSE, $displayMessage = TRUE) {
586         // Prepare all arrays, variables
587         $tableData = array();
588         $skip = FALSE;
589
590         // Now, walk through all entries and prepare them for saving
591         //* BUG: */ reportBug(__FUNCTION__, __LINE__, '<pre>'.print_r(postRequestArray(), TRUE).'</pre>');
592         foreach ($postData as $id => $val) {
593                 // Process only formular field but not submit buttons ;)
594                 if ($id == 'save_config') {
595                         // Skip this button
596                         continue;
597                 } // END - if
598
599                 // Do not save the ok value
600                 convertSelectionsToEpocheTime($postData, $tableData, $id, $skip);
601
602                 // Shall we process this id? It muss not be empty, of course
603                 if (($skip === FALSE) && (!empty($id)) && ((!isset($GLOBALS['skip_config'][$id]))) || ($tableName != '_config')) {
604                         // Translate the value? (comma to dot!)
605                         if ((is_array($translateComma)) && (in_array($id, $translateComma))) {
606                                 // Then do it here... :)
607                                 $val = convertCommaToDot($val);
608                         } // END - if
609
610                         // Test value on float
611                         $test = (float) $val;
612
613                         // Debug message
614                         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'test=' . $test . ',val=' . $val . ',id=' . $id);
615
616                         // Shall we add numbers or strings?
617                         if ('' . $val . '' == '' . $test . '') {
618                                 // Add numbers
619                                 array_push($tableData, sprintf('`%s`=%s', $id, $test));
620                         } elseif (is_null($val)) {
621                                 // Add NULL
622                                 array_push($tableData, sprintf('`%s`=NULL', $id));
623                         } else {
624                                 // Add strings
625                                 array_push($tableData, sprintf("`%s`='%s'", $id, trim($val)));
626                         }
627
628                         // Do not add a config entry twice
629                         $GLOBALS['skip_config'][$id] = TRUE;
630
631                         // Update current configuration
632                         setConfigEntry($id, $val);
633                 } // END - if
634         } // END - foreach
635
636         // Check if entry does exist
637         $result = FALSE;
638         if ($alwaysAdd === FALSE) {
639                 if (!empty($whereStatement)) {
640                         $result = sqlQuery('SELECT * FROM `{?_MYSQL_PREFIX?}' . $tableName . '` WHERE ' . $whereStatement . ' LIMIT 1', __FUNCTION__, __LINE__);
641                 } else {
642                         $result = sqlQuery('SELECT * FROM `{?_MYSQL_PREFIX?}' . $tableName . '` LIMIT 1', __FUNCTION__, __LINE__);
643                 }
644         } // END - if
645
646         if (sqlNumRows($result) == 1) {
647                 // "Implode" all data to single string
648                 $updatedData = implode(', ', $tableData);
649
650                 // Generate SQL string
651                 $sql = sprintf('UPDATE `{?_MYSQL_PREFIX?}%s` SET %s WHERE %s LIMIT 1',
652                         $tableName,
653                         $updatedData,
654                         $whereStatement
655                 );
656         } else {
657                 // Add Line (does only work with AUTO_INCREMENT!
658                 $keys = array(); $values = array();
659                 foreach ($tableData as $entry) {
660                         // Split up
661                         $line = explode('=', $entry);
662                         array_push($keys  , $line[0]);
663                         array_push($values, $line[1]);
664                 } // END - foreach
665
666                 // Add both in one line
667                 $keys   = implode('`, `', $keys);
668                 $values = implode(', '  , $values);
669
670                 // Generate SQL string
671                 $sql = sprintf('INSERT INTO `{?_MYSQL_PREFIX?}%s` (%s) VALUES (%s)',
672                         $tableName,
673                         $keys,
674                         $values
675                 );
676         }
677
678         // Free memory
679         sqlFreeResult($result);
680
681         // Simply run generated SQL string
682         sqlQuery($sql, __FUNCTION__, __LINE__);
683
684         // Remember affected rows
685         $affected = sqlAffectedRows();
686
687         // Rebuild cache
688         rebuildCache('config', 'config');
689
690         // Settings saved, so display message?
691         if ($displayMessage === TRUE) {
692                 // Display a message
693                 displayMessage('{--SETTINGS_SAVED--}');
694         } // END - if
695
696         // Return affected rows
697         return $affected;
698 }
699
700 // Generate a selection box
701 function adminAddMenuSelectionBox ($menu, $type, $name, $default = '') {
702         // Open the requested menu directory
703         $menuArray = getArrayFromDirectory(sprintf('inc/modules/%s/', $menu), $type . '-', FALSE, FALSE);
704
705         // Init the selection box
706         $OUT = '<select name="' . $name . '" class="form_select" size="1"><option value="">{--ADMIN_IS_TOP_MENU--}</option>';
707
708         // Walk through all files
709         foreach ($menuArray as $file) {
710                 // Is this a PHP script?
711                 if ((!isDirectory($file)) && (isInString('' . $type . '-', $file)) && (isInString('.php', $file))) {
712                         // Then test if the file is readable
713                         $test = sprintf('inc/modules/%s/%s', $menu, $file);
714
715                         // Is the file there?
716                         if (isIncludeReadable($test)) {
717                                 // Extract the value for what=xxx
718                                 $part = substr($file, (strlen($type) + 1));
719                                 $part = substr($part, 0, -4);
720
721                                 // Is that part different from the overview?
722                                 if ($part != 'welcome') {
723                                         $OUT .= '<option value="' . $part . '"';
724                                         if ($part == $default) {
725                                                 $OUT .= ' selected="selected"';
726                                         } // END - if
727                                         $OUT .= '>' . $part . '</option>';
728                                 } // END - if
729                         } // END - if
730                 } // END - if
731         } // END - foreach
732
733         // Close selection box
734         $OUT .= '</select>';
735
736         // Return contents
737         return $OUT;
738 }
739
740 // Creates a user-profile link for the admin. This function can also be used for many other purposes
741 function generateUserProfileLink ($userid, $title = '', $what = '') {
742         // Is there cache?
743         if (!isset($GLOBALS[__FUNCTION__][$userid][$title . '_' . $what])) {
744                 // Is title empty and valid userid?
745                 if (($title == '') && (isValidId($userid))) {
746                         // Set userid as title
747                         $title = $userid;
748                 } elseif (!isValidId($userid)) {
749                         // User id zero is invalid
750                         return '<strong>' . convertNullToZero($userid) . '</strong>';
751                 }
752
753                 // Is what set?
754                 if (empty($what)) {
755                         // Then get it to 'list_user'
756                         $what = 'list_user';
757                 } // END - if
758
759                 if (($title == '0') && ($what == 'list_refs')) {
760                         // Return title again
761                         return $title;
762                 } elseif (!empty($title)) {
763                         // Not empty, so skip next one
764                 } elseif (isExtensionActive('nickname')) {
765                         // Get nickname
766                         $nick = getNickname($userid);
767
768                         // Is it not empty, use it as title else the userid
769                         if (!empty($nick)) {
770                                 $title = $nick . '(' . $userid . ')';
771                         } else {
772                                 $title = $userid;
773                         }
774                 }
775
776                 // Set it in cache
777                 $GLOBALS[__FUNCTION__][$userid][$title . '_' . $what] = '[<a href="{%url=modules.php?module=admin&amp;what=' . $what . '&amp;userid=' . $userid . '%}" title="{--ADMIN_USER_PROFILE_TITLE--}">' . $title . '</a>]';
778         } // END - if
779
780         // Return cache
781         return $GLOBALS[__FUNCTION__][$userid][$title . '_' . $what];
782 }
783
784 // Check "logical-area-mode"
785 function adminGetMenuMode () {
786         // Set the default menu mode as the mode for all admins
787         $mode = 'global';
788
789         // If ext-sql_patches is up-to-date enough, use the configuration
790         if (isExtensionInstalledAndNewer('sql_patches', '0.3.2')) {
791                 $mode = getAdminMenu();
792         } // END - if
793
794         // Backup it
795         $adminMode = $mode;
796
797         // Get admin id
798         $adminId = getCurrentAdminId();
799
800         // Check individual settings of current admin
801         if (isset($GLOBALS['cache_array']['admin']['la_mode'][$adminId])) {
802                 // Load from cache
803                 $adminMode = $GLOBALS['cache_array']['admin']['la_mode'][$adminId];
804                 incrementStatsEntry('cache_hits');
805         } elseif (isExtensionInstalledAndNewer('admins', '0.6.7')) {
806                 // Load from database when version of 'admins' is enough
807                 $result = sqlQueryEscaped('SELECT `la_mode` FROM `{?_MYSQL_PREFIX?}_admins` WHERE `id`=%s LIMIT 1',
808                         array($adminId), __FUNCTION__, __LINE__);
809
810                 // Is there an entry?
811                 if (sqlNumRows($result) == 1) {
812                         // Load data
813                         list($adminMode) = sqlFetchRow($result);
814                 } // END - if
815
816                 // Free memory
817                 sqlFreeResult($result);
818         }
819
820         // Check what the admin wants and set it when it's not the default mode
821         if ($adminMode != 'global') {
822                 $mode = $adminMode;
823         } // END - if
824
825         // Return admin-menu's mode
826         return $mode;
827 }
828
829 // Change activation status
830 function adminChangeActivationStatus ($IDs, $table, $row, $idRow = 'id') {
831         $count = '0';
832         if ((is_array($IDs)) && (count($IDs) > 0)) {
833                 // "Walk" all through and count them
834                 foreach ($IDs as $id => $selected) {
835                         // Secure the id number
836                         $id = bigintval($id);
837
838                         // Should always be set... ;-)
839                         if (!empty($selected)) {
840                                 // Determine new status
841                                 $result = sqlQueryEscaped('SELECT %s FROM `{?_MYSQL_PREFIX?}_%s` WHERE `%s`=%s LIMIT 1',
842                                         array(
843                                                 $row,
844                                                 $table,
845                                                 $idRow,
846                                                 $id
847                                         ), __FUNCTION__, __LINE__);
848
849                                 // Row found?
850                                 if (sqlNumRows($result) == 1) {
851                                         // Load the status
852                                         list($currStatus) = sqlFetchRow($result);
853
854                                         // And switch it N<->Y
855                                         $newStatus = convertBooleanToYesNo(!($currStatus == 'Y'));
856
857                                         // Change this status
858                                         sqlQueryEscaped("UPDATE `{?_MYSQL_PREFIX?}_%s` SET `%s`='%s' WHERE `%s`=%s LIMIT 1",
859                                                 array(
860                                                         $table,
861                                                         $row,
862                                                         $newStatus,
863                                                         $idRow,
864                                                         $id
865                                                 ), __FUNCTION__, __LINE__);
866
867                                         // Count up affected rows
868                                         $count += sqlAffectedRows();
869                                 } // END - if
870
871                                 // Free the result
872                                 sqlFreeResult($result);
873                         } // END - if
874                 } // END - foreach
875
876                 // Output status
877                 displayMessage(sprintf(getMessage('ADMIN_STATUS_CHANGED'), $count, count($IDs)));
878         } else {
879                 // Nothing selected!
880                 displayMessage('{--ADMIN_NOTHING_SELECTED_CHANGE--}');
881         }
882 }
883
884 // Build a special template list
885 // @TODO cacheFiles is not yet supported
886 function adminListBuilder ($listType, $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn, $rawUserId = array('userid'), $content = array()) {
887         // Call inner (general) function
888         doGenericListBuilder('admin', $listType, $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn, $rawUserId, $content);
889 }
890
891 // Change status of "build" list
892 function adminBuilderStatusHandler ($mode, $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn, $statusArray, $rawUserId = array('userid'), $cacheFiles = array()) {
893         // $tableName must be an array
894         if ((!is_array($tableName)) || (count($tableName) != 1)) {
895                 // No tableName specified
896                 reportBug(__FUNCTION__, __LINE__, 'tableName is not given. Please fix your XML,tableName[]=' . gettype($tableName) . '!=array: userIdColumn=' . $userIdColumn);
897         } elseif (!is_array($idColumn)) {
898                 // $idColumn is no array
899                 reportBug(__FUNCTION__, __LINE__, 'idColumn[]=' . gettype($idColumn) . '!=array: userIdColumn=' . $userIdColumn);
900         } elseif ((!is_array($userIdColumn)) || (count($userIdColumn) != 1)) {
901                 // $tableName is no array
902                 reportBug(__FUNCTION__, __LINE__, 'userIdColumn[]=' . gettype($userIdColumn) . '!=array: userIdColumn=' . $userIdColumn);
903         } // END - if
904
905         // "Walk" through all entries
906         foreach (postRequestElement($idColumn[0]) as $id => $sel) {
907                 // Construct SQL query
908                 $sql = sprintf('UPDATE `{?_MYSQL_PREFIX?}_%s` SET', sqlEscapeString($tableName[0]));
909
910                 // Load data of entry
911                 $result = sqlQueryEscaped('SELECT * FROM `{?_MYSQL_PREFIX?}_%s` WHERE `%s`=%s LIMIT 1',
912                         array(
913                                 $tableName[0],
914                                 $idColumn[0],
915                                 $id
916                         ), __FUNCTION__, __LINE__);
917
918                 // Fetch the data
919                 $content = sqlFetchArray($result);
920
921                 // Free the result
922                 sqlFreeResult($result);
923
924                 // Add all status entries (e.g. status column last_updated or so)
925                 $newStatus = 'UNKNOWN';
926                 $oldStatus = 'UNKNOWN';
927                 $statusColumn = 'unknown';
928                 foreach ($statusArray as $column => $statusInfo) {
929                         // Does the entry exist?
930                         if ((isset($content[$column])) && (isset($statusInfo[$content[$column]]))) {
931                                 // Add these entries for update
932                                 $sql .= sprintf(" `%s`='%s',", sqlEscapeString($column), sqlEscapeString($statusInfo[$content[$column]]));
933
934                                 // Remember status
935                                 if ($statusColumn == 'unknown') {
936                                         // Always (!!!) change status column first!
937                                         $oldStatus = $content[$column];
938                                         $newStatus = $statusInfo[$oldStatus];
939                                         $statusColumn = $column;
940                                 } // END - if
941                         } elseif (isset($content[$column])) {
942                                 // Unfinished!
943                                 reportBug(__FUNCTION__, __LINE__, ':UNFINISHED: id=' . $id . ',column=' . $column . '[' . gettype($statusInfo) . '] = ' . $content[$column]);
944                         }
945                 } // END - foreach
946
947                 // Add other columns as well
948                 foreach (postRequestArray() as $key => $entries) {
949                         // Debug message
950                         /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Found entry: ' . $key);
951
952                         // Skip id, raw userid and 'do_$mode'
953                         if (!in_array($key, array($idColumn[0], $rawUserId[0], ('do_' . $mode)))) {
954                                 // Are there brackets () at the end?
955                                 if (substr($entries[$id], -2, 2) == '()') {
956                                         // Direct SQL command found
957                                         $sql .= sprintf(' `%s`=%s,', sqlEscapeString($key), sqlEscapeString($entries[$id]));
958                                 } else {
959                                         // Add regular entry
960                                         $sql .= sprintf(" `%s`='%s',", sqlEscapeString($key), sqlEscapeString($entries[$id]));
961
962                                         // Add entry
963                                         $content[$key] = $entries[$id];
964                                 }
965                         } elseif (isDebugModeEnabled()) {
966                                 // Skipped entry
967                                 logDebugMessage(__FUNCTION__, __LINE__, 'Skipped: ' . $key);
968                         }
969                 } // END - foreach
970
971                 // Finish SQL statement
972                 $sql = substr($sql, 0, -1) . sprintf(" WHERE `%s`=%s AND `%s`='%s' LIMIT 1",
973                         $idColumn[0],
974                         bigintval($id),
975                         $statusColumn,
976                         $oldStatus
977                 );
978
979                 // Run the SQL
980                 sqlQuery($sql, __FUNCTION__, __LINE__);
981
982                 // Send "build mails" out
983                 sendGenericBuildMails($mode, $tableName, $content, $id, $statusInfo[$content[$column]], $userIdColumn);
984         } // END - foreach
985 }
986
987 // Delete rows by given id numbers
988 function adminDeleteEntriesConfirm ($tableName, $columns = array(), $filterFunctions = array(), $extraValues = array(), $deleteNow = array(FALSE), $idColumn = array('id'), $userIdColumn = array('userid'), $rawUserId = array('userid'), $cacheFiles = array(), $content = array()) {
989         // $tableName must be an array
990         if ((!is_array($tableName)) || (count($tableName) != 1)) {
991                 // No tableName specified
992                 reportBug(__FUNCTION__, __LINE__, 'tableName is not given. Please fix your XML,tableName[]=' . gettype($tableName) . '!=array: userIdColumn=' . $userIdColumn);
993         } elseif (!is_array($idColumn)) {
994                 // $idColumn is no array
995                 reportBug(__FUNCTION__, __LINE__, 'idColumn[]=' . gettype($idColumn) . '!=array: userIdColumn=' . $userIdColumn);
996         } elseif (!is_array($userIdColumn)) {
997                 // $userIdColumn is no array
998                 reportBug(__FUNCTION__, __LINE__, 'userIdColumn[]=' . gettype($userIdColumn) . '!=array: userIdColumn=' . $userIdColumn);
999         } elseif (!is_array($deleteNow)) {
1000                 // $deleteNow is no array
1001                 reportBug(__FUNCTION__, __LINE__, 'deleteNow[]=' . gettype($deleteNow) . '!=array: userIdColumn=' . $userIdColumn);
1002         } // END - if
1003
1004         // Shall we delete here or list for deletion?
1005         if ($deleteNow[0] === TRUE) {
1006                 // Call generic function
1007                 $affected = doGenericDeleteEntriesConfirm($tableName, $columns, $filterFunctions, $extraValues, $deleteNow, $idColumn, $userIdColumn, $rawUserId, $cacheFiles);
1008
1009                 // Was this fine?
1010                 if ($affected == countPostSelection($idColumn[0])) {
1011                         // All deleted
1012                         displayMessage('{--ADMIN_ALL_ENTRIES_REMOVED--}');
1013                 } else {
1014                         // Some are still there :(
1015                         displayMessage(sprintf(getMessage('ADMIN_SOME_ENTRIES_NOT_DELETED'), sqlAffectedRows(), countPostSelection($idColumn[0])));
1016                 }
1017         } else {
1018                 // List for deletion confirmation
1019                 adminListBuilder('delete', $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn, $rawUserId, $content);
1020         }
1021 }
1022
1023 // Edit rows by given id numbers
1024 function adminEditEntriesConfirm ($tableName, $columns = array(), $filterFunctions = array(), $extraValues = array(), $timeColumns = array(), $editNow = array(FALSE), $idColumn = array('id'), $userIdColumn = array('userid'), $rawUserId = array('userid'), $cacheFiles = array(), $content = array()) {
1025         // $tableName must be an array
1026         if ((!is_array($tableName)) || (count($tableName) != 1)) {
1027                 // No tableName specified
1028                 reportBug(__FUNCTION__, __LINE__, 'tableName is not given. Please fix your XML,tableName[]=' . gettype($tableName) . '!=array: userIdColumn=' . $userIdColumn);
1029         } elseif (!is_array($idColumn)) {
1030                 // $idColumn is no array
1031                 reportBug(__FUNCTION__, __LINE__, 'idColumn[]=' . gettype($idColumn) . '!=array: userIdColumn=' . $userIdColumn);
1032         } elseif (!is_array($userIdColumn)) {
1033                 // $userIdColumn is no array
1034                 reportBug(__FUNCTION__, __LINE__, 'userIdColumn[]=' . gettype($userIdColumn) . '!=array: userIdColumn=' . $userIdColumn);
1035         } elseif (!is_array($editNow)) {
1036                 // $editNow is no array
1037                 reportBug(__FUNCTION__, __LINE__, 'editNow[]=' . gettype($editNow) . '!=array: userIdColumn=' . $userIdColumn);
1038         } // END - if
1039
1040         // Shall we change here or list for editing?
1041         if ($editNow[0] === TRUE) {
1042                 // Call generic change method
1043                 $affected = doGenericEditEntriesConfirm($tableName, $columns, $filterFunctions, $extraValues, $timeColumns, $editNow, $idColumn, $userIdColumn, $rawUserId, $cacheFiles);
1044
1045                 // Was this fine?
1046                 if ($affected == countPostSelection($idColumn[0])) {
1047                         // All deleted
1048                         displayMessage('{--ADMIN_ALL_ENTRIES_EDITED--}');
1049                 } else {
1050                         // Some are still there :(
1051                         displayMessage(sprintf(getMessage('ADMIN_SOME_ENTRIES_NOT_EDITED'), $affected, countPostSelection($idColumn[0])));
1052                 }
1053         } else {
1054                 // List for editing
1055                 adminListBuilder('edit', $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn, $rawUserId, $content);
1056         }
1057 }
1058
1059 // Un-/lock rows by given id numbers
1060 // @TODO rawUserId/content is not yet supported
1061 function adminLockEntriesConfirm ($tableName, $columns = array(), $filterFunctions = array(), $extraValues = array(), $statusArray = array(), $lockNow = array(FALSE), $idColumn = array('id'), $userIdColumn = array('userid')) {
1062         // $tableName must be an array
1063         if ((!is_array($tableName)) || (count($tableName) != 1)) {
1064                 // No tableName specified
1065                 reportBug(__FUNCTION__, __LINE__, 'tableName is not given. Please fix your XML,tableName[]=' . gettype($tableName) . '!=array: userIdColumn=' . $userIdColumn);
1066         } elseif (!is_array($idColumn)) {
1067                 // $idColumn is no array
1068                 reportBug(__FUNCTION__, __LINE__, 'idColumn[]=' . gettype($idColumn) . '!=array: userIdColumn=' . $userIdColumn);
1069         } elseif (!is_array($lockNow)) {
1070                 // $lockNow is no array
1071                 reportBug(__FUNCTION__, __LINE__, 'lockNow[]=' . gettype($lockNow) . '!=array: userIdColumn=' . $userIdColumn);
1072         } // END - if
1073
1074         // Shall we un-/lock here or list for locking?
1075         if ($lockNow[0] === TRUE) {
1076                 // Un-/lock entries
1077                 adminBuilderStatusHandler('lock', $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn, $statusArray);
1078         } else {
1079                 // List for editing
1080                 adminListBuilder('lock', $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn);
1081         }
1082 }
1083
1084 // Undelete rows by given id numbers
1085 // @TODO rawUserId/cacheFiles/content is not yet supported
1086 function adminUndeleteEntriesConfirm ($tableName, $columns = array(), $filterFunctions = array(), $extraValues = array(), $statusArray = array(), $undeleteNow = array(FALSE), $idColumn = array('id'), $userIdColumn = array('userid')) {
1087         // $tableName must be an array
1088         if ((!is_array($tableName)) || (count($tableName) != 1)) {
1089                 // No tableName specified
1090                 reportBug(__FUNCTION__, __LINE__, 'tableName is not given. Please fix your XML,tableName[]=' . gettype($tableName) . '!=array: userIdColumn=' . $userIdColumn);
1091         } elseif (!is_array($idColumn)) {
1092                 // $idColumn is no array
1093                 reportBug(__FUNCTION__, __LINE__, 'idColumn[]=' . gettype($idColumn) . '!=array: userIdColumn=' . $userIdColumn);
1094         } elseif (!is_array($undeleteNow)) {
1095                 // $undeleteNow is no array
1096                 reportBug(__FUNCTION__, __LINE__, 'undeleteNow[]=' . gettype($undeleteNow) . '!=array: userIdColumn=' . $userIdColumn);
1097         } // END - if
1098
1099         // Shall we un-/lock here or list for locking?
1100         if ($undeleteNow[0] === TRUE) {
1101                 // Undelete entries
1102                 adminBuilderStatusHandler('undelete', $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn, $statusArray);
1103         } else {
1104                 // List for editing
1105                 adminListBuilder('undelete', $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn);
1106         }
1107 }
1108
1109 // Adds a given entry to the database
1110 function adminAddEntries ($tableName, $columns = array(), $filterFunctions = array(), $extraValues = array(), $timeColumns = array(), $columnIndex = NULL) {
1111         // Is the userid set?
1112         if (!isPostRequestElementSet('userid')) {
1113                 // Then set NULL here
1114                 setPostRequestElement('userid', NULL);
1115         } // END - if
1116
1117         // Call inner function
1118         doGenericAddEntries($tableName, $columns, $filterFunctions, $extraValues, $timeColumns, $columnIndex);
1119
1120         // Entry has been added?
1121         if ((!ifSqlHasZeroAffectedRows()) && ($GLOBALS['__XML_PARSE_RESULT'] === TRUE)) {
1122                 // Display success message
1123                 displayMessage('{--ADMIN_ENTRY_ADDED--}');
1124         } else {
1125                 // Display failed message
1126                 displayMessage('{--ADMIN_ENTRY_NOT_ADDED--}');
1127         }
1128 }
1129
1130 // Checks proxy settins by fetching check-updates3.php from mxchange.org
1131 function adminTestProxySettings ($settingsArray) {
1132         // Set temporary the new settings
1133         mergeConfig($settingsArray);
1134
1135         // Now get the test URL
1136         $content = sendHttpGetRequest('check-updates3.php');
1137
1138         // Is the first line with "200 OK"?
1139         $valid = isInString('200 OK', $content[0]);
1140
1141         // Return result
1142         return $valid;
1143 }
1144
1145 // Sends out a link to the given email adress so the admin can reset his/her password
1146 function sendAdminPasswordResetLink ($email) {
1147         // Init output
1148         $OUT = '';
1149
1150         // Look up administator login
1151         $result = sqlQueryEscaped("SELECT `id`, `login`, `password` FROM `{?_MYSQL_PREFIX?}_admins` WHERE '%s' REGEXP `email` LIMIT 1",
1152                 array($email), __FUNCTION__, __LINE__);
1153
1154         // Is there an account?
1155         if (ifSqlHasZeroNums($result)) {
1156                 // No account found
1157                 return '{--ADMIN_NO_LOGIN_WITH_EMAIL--}';
1158         } // END - if
1159
1160         // Load all data
1161         $content = sqlFetchArray($result);
1162
1163         // Free result
1164         sqlFreeResult($result);
1165
1166         // Generate hash for reset link
1167         $content['hash'] = generateHash(getUrl() . getEncryptSeparator() . $content['id'] . getEncryptSeparator() . $content['login'] . getEncryptSeparator() . $content['password'], substr($content['password'], getSaltLength()));
1168
1169         // Remove some data
1170         unset($content['id']);
1171         unset($content['password']);
1172
1173         // Prepare email
1174         $mailText = loadEmailTemplate('admin_reset_password', $content);
1175
1176         // Send it out
1177         sendEmail($email, '{--ADMIN_RESET_PASSWORD_LINK_SUBJECT--}', $mailText);
1178
1179         // Prepare output
1180         return '{--ADMIN_RESET_PASSWORD_LINK_SENT--}';
1181 }
1182
1183 // Validate hash and login for password reset
1184 function adminResetValidateHashLogin ($hash, $login) {
1185         // By default nothing validates... ;)
1186         $valid = FALSE;
1187
1188         // Then try to find that user
1189         $result = sqlQueryEscaped("SELECT `id`, `password`, `email` FROM `{?_MYSQL_PREFIX?}_admins` WHERE `login`='%s' LIMIT 1",
1190                 array($login), __FUNCTION__, __LINE__);
1191
1192         // Is an account here?
1193         if (sqlNumRows($result) == 1) {
1194                 // Load all data
1195                 $content = sqlFetchArray($result);
1196
1197                 // Generate hash again
1198                 $hashFromData = generateHash(getUrl() . getEncryptSeparator() . $content['id'] . getEncryptSeparator() . $login . getEncryptSeparator() . $content['password'], substr($content['password'], getSaltLength()));
1199
1200                 // Does both match?
1201                 $valid = ($hash == $hashFromData);
1202         } // END - if
1203
1204         // Free result
1205         sqlFreeResult($result);
1206
1207         // Return result
1208         return $valid;
1209 }
1210
1211 // Reset the password for the login. Do NOT call this function without calling above function first!
1212 function doResetAdminPassword ($login, $password) {
1213         // Generate hash (we already check for ext-sql_patches in generateHash())
1214         $passHash = generateHash($password);
1215
1216         // Prepare fake POST data
1217         $postData = array(
1218                 'login'    => array(getAdminId($login) => $login),
1219                 'password' => array(getAdminId($login) => $passHash),
1220         );
1221
1222         // Update database
1223         $message = adminsChangeAdminAccount($postData, '', FALSE);
1224
1225         // Run filters
1226         runFilterChain('post_form_reset_pass', array('login' => $login, 'hash' => $passHash, 'message' => $message));
1227
1228         // Return output
1229         return '{--ADMIN_PASSWORD_RESET_DONE--}';
1230 }
1231
1232 // Solves a task by given id number
1233 function adminSolveTask ($id) {
1234         // Update the task data
1235         adminUpdateTaskData($id, 'status', 'SOLVED');
1236 }
1237
1238 // Marks a given task as deleted
1239 function adminDeleteTask ($id) {
1240         // Update the task data
1241         adminUpdateTaskData($id, 'status', 'DELETED');
1242 }
1243
1244 // Function to update task data
1245 function adminUpdateTaskData ($id, $row, $data) {
1246         // Should be admin and valid id
1247         if (!isAdmin()) {
1248                 // Not an admin so redirect better
1249                 reportBug(__FUNCTION__, __LINE__, 'id=' . $id . ',row=' . $row . ',data=' . $data . ' - isAdmin()=false');
1250         } elseif ($id <= 0) {
1251                 // Initiate backtrace
1252                 reportBug(__FUNCTION__, __LINE__, sprintf('id is invalid: %s. row=%s, data=%s',
1253                         $id,
1254                         $row,
1255                         $data
1256                 ));
1257         } // END - if
1258
1259         // Update the task
1260         sqlQueryEscaped("UPDATE `{?_MYSQL_PREFIX?}_task_system` SET `%s`='%s' WHERE `id`=%s LIMIT 1",
1261                 array(
1262                         $row,
1263                         $data,
1264                         bigintval($id)
1265                 ), __FUNCTION__, __LINE__);
1266 }
1267
1268 // Checks whether if the admin menu has entries
1269 function ifAdminMenuHasEntries ($action) {
1270         return (
1271                 ((
1272                         // Is the entry set?
1273                         isset($GLOBALS['admin_menu_has_entries'][$action])
1274                 ) && (
1275                         // And do we have a menu for this action?
1276                         $GLOBALS['admin_menu_has_entries'][$action] === TRUE
1277                 )) || (
1278                         // Login has always a menu
1279                         $action == 'login'
1280                 )
1281         );
1282 }
1283
1284 // Setter for 'admin_menu_has_entries'
1285 function setAdminMenuHasEntries ($action, $hasEntries) {
1286         $GLOBALS['admin_menu_has_entries'][$action] = (bool) $hasEntries;
1287 }
1288
1289 // Creates a link to the user's admin-profile
1290 function adminCreateUserLink ($userid) {
1291         // Is the userid set correctly?
1292         if (isValidId($userid)) {
1293                 // Create a link to that profile
1294                 return '{%url=modules.php?module=admin&amp;what=list_user&amp;userid=' . bigintval($userid) . '%}';
1295         } // END - if
1296
1297         // Return a link to the user list
1298         return '{%url=modules.php?module=admin&amp;what=list_user%}';
1299 }
1300
1301 // Generate a "link" for the given admin id (admin_id)
1302 function generateAdminLink ($adminId) {
1303         // No assigned admin is default
1304         $adminLink = '{--ADMIN_NO_ADMIN_ASSIGNED--}';
1305
1306         // Zero? = Not assigned
1307         if (isValidId($adminId)) {
1308                 // Load admin's login
1309                 $login = getAdminLogin($adminId);
1310
1311                 // Is the login valid?
1312                 if ($login != '***') {
1313                         // Is the extension there?
1314                         if (isExtensionActive('admins')) {
1315                                 // Admin found
1316                                 $adminLink = '<a href="' . generateEmailLink(getAdminEmail($adminId), 'admins') . '" title="{--ADMIN_CONTACT_LINK_TITLE--}">' . $login . '</a>';
1317                         } else {
1318                                 // Extension not found
1319                                 $adminLink = '{%message,ADMIN_TASK_ROW_EXTENSION_NOT_INSTALLED=admins%}';
1320                         }
1321                 } else {
1322                         // Maybe deleted?
1323                         $adminLink = '<div class="bad">{%message,ADMIN_ID_404=' . $adminId . '%}</div>';
1324                 }
1325         } // END - if
1326
1327         // Return result
1328         return $adminLink;
1329 }
1330
1331 // Verifies if the current admin has confirmed to alter expert settings
1332 //
1333 // Return values:
1334 // 'failed'    = Something goes wrong (default)
1335 // 'agreed'    = Has verified and and confirmed it to see them
1336 // 'forbidden' = Has not the proper right to alter them
1337 // 'update'    = Need to update extension 'admins'
1338 // 'ask'       = A form was send to the admin
1339 function doVerifyExpertSettings () {
1340         // Default return status is failed
1341         $return = 'failed';
1342
1343         // Is the extension installed and recent?
1344         if (isExtensionInstalledAndNewer('admins', '0.7.3')) {
1345                 // Okay, load the status
1346                 $expertSettings = getAminsExpertSettings();
1347
1348                 // Is he allowed?
1349                 if ($expertSettings == 'Y') {
1350                         // Okay, does he want to see them?
1351                         if (isAdminsExpertWarningEnabled()) {
1352                                 // Ask for them
1353                                 if (isFormSent('save_expert')) {
1354                                         // Is the element set, then we need to change the admin
1355                                         if (isPostRequestElementSet('expert_settings')) {
1356                                                 // Get it and prepare final post data array
1357                                                 $postData['login'][getCurrentAdminId()] = getCurrentAdminLogin();
1358                                                 $postData['expert_warning'][getCurrentAdminId()] = 'N';
1359
1360                                                 // Change it in the admin
1361                                                 adminsChangeAdminAccount($postData, 'expert_warning');
1362                                         } // END - if
1363
1364                                         // All fine!
1365                                         $return = 'agreed';
1366                                 } else {
1367                                         // Send form
1368                                         loadTemplate('admin_expert_settings_form');
1369
1370                                         // Asked for it
1371                                         $return = 'ask';
1372                                 }
1373                         } else {
1374                                 // Do not display
1375                                 $return = 'agreed';
1376                         }
1377
1378                         // Is a form sent?
1379                         if ((isFormSent()) && (isPostRequestElementSet('expert_settings'))) {
1380                                 // Clear form
1381                                 unsetPostRequestElement('ok');
1382                                 unsetPostRequestElement('expert_settings');
1383                         } // END - if
1384                 } else {
1385                         // Forbidden
1386                         $return = 'forbidden';
1387                 }
1388         } else {
1389                 // Out-dated extension or not installed
1390                 $return = 'update';
1391         }
1392
1393         // Output message for other status than ask/agreed
1394         if (($return != 'ask') && ($return != 'agreed')) {
1395                 // Output message
1396                 displayMessage('{--ADMIN_EXPERT_SETTINGS_STATUS_' . strtoupper($return) . '--}');
1397         } // END - if
1398
1399         // Return status
1400         return $return;
1401 }
1402
1403 // Generate link to unconfirmed mails for admin
1404 function generateUnconfirmedAdminLink ($id, $unconfirmed, $type) {
1405         // Init output
1406         $OUT = $unconfirmed;
1407
1408         // Is there unconfirmed mails?
1409         if ($unconfirmed > 0) {
1410                 // Add link to list_unconfirmed what-file
1411                 $OUT = '<a href="{%url=modules.php?module=admin&amp;what=list_unconfirmed&amp;type=' . $type . '&amp;id=' . $id . '%}">{%pipe,translateComma=' . $unconfirmed . '%}</a>';
1412         } // END - if
1413
1414         // Return it
1415         return $OUT;
1416 }
1417
1418 // Generates a navigation row for listing emails
1419 function addEmailNavigation ($numPages, $offset, $show_form, $colspan, $return=false) {
1420         // Don't do anything if $numPages is 1
1421         if ($numPages == 1) {
1422                 // Abort here with empty content
1423                 return '';
1424         } // END - if
1425
1426         $TOP = '';
1427         if ($show_form === FALSE) {
1428                 $TOP = ' top';
1429         } // END - if
1430
1431         $NAV = '';
1432         for ($page = 1; $page <= $numPages; $page++) {
1433                 // Is the page currently selected or shall we generate a link to it?
1434                 if (($page == getRequestElement('page')) || ((!isGetRequestElementSet('page')) && ($page == 1))) {
1435                         // Is currently selected, so only highlight it
1436                         $NAV .= '<strong>-';
1437                 } else {
1438                         // Open anchor tag and add base URL
1439                         $NAV .= '<a href="{%url=modules.php?module=admin&amp;what=' . getWhat() . '&amp;page=' . $page . '&amp;offset=' . $offset;
1440
1441                         // Add userid when we shall show all mails from a single member
1442                         if ((isGetRequestElementSet('userid')) && (isValidId(getRequestElement('userid')))) $NAV .= '&amp;userid=' . bigintval(getRequestElement('userid'));
1443
1444                         // Close open anchor tag
1445                         $NAV .= '%}">';
1446                 }
1447                 $NAV .= $page;
1448                 if (($page == getRequestElement('page')) || ((!isGetRequestElementSet('page')) && ($page == 1))) {
1449                         // Is currently selected, so only highlight it
1450                         $NAV .= '-</strong>';
1451                 } else {
1452                         // Close anchor tag
1453                         $NAV .= '</a>';
1454                 }
1455
1456                 // Add separator if total pages has not been reached
1457                 if ($page < $numPages) {
1458                         // Add it
1459                         $NAV .= '|';
1460                 } // END - if
1461         } // END - for
1462
1463         // Define constants only once
1464         $content['nav']  = $NAV;
1465         $content['span'] = $colspan;
1466         $content['top']  = $TOP;
1467
1468         // Load navigation template
1469         $OUT = loadTemplate('admin_email_nav_row', TRUE, $content);
1470
1471         if ($return === TRUE) {
1472                 // Return generated HTML-Code
1473                 return $OUT;
1474         } else {
1475                 // Output HTML-Code
1476                 outputHtml($OUT);
1477         }
1478 }
1479
1480 // Process menu editing form
1481 function adminProcessMenuEditForm ($type, $subMenu) {
1482         // An action is done...
1483         foreach (postRequestElement('sel') as $sel => $menu) {
1484                 $AND = "(`what` = '' OR `what` IS NULL)";
1485
1486                 $sel = bigintval($sel);
1487
1488                 if (!empty($subMenu)) {
1489                         $AND = "`action`='" . $subMenu . "'";
1490                 } // END - if
1491
1492                 switch (postRequestElement('ok')) {
1493                         case 'edit': // Edit menu
1494                                 // Shall we update a menu or sub menu?
1495                                 if (!isGetRequestElementSet('sub')) {
1496                                         // Update with 'what'=null
1497                                         sqlQueryEscaped("UPDATE `{?_MYSQL_PREFIX?}_%s_menu` SET `title`='%s',`action`='%s',`what`=NULL WHERE ".$AND." AND `id`=%s LIMIT 1",
1498                                                 array(
1499                                                         $type,
1500                                                         $menu,
1501                                                         postRequestElement('sel_action', $sel),
1502                                                         $sel
1503                                                 ), __FUNCTION__, __LINE__);
1504                                 } else {
1505                                         // Update with selected 'what'
1506                                         sqlQueryEscaped("UPDATE `{?_MYSQL_PREFIX?}_%s_menu` SET `title`='%s',`action`='%s',`what`='%s' WHERE ".$AND." AND `id`=%s LIMIT 1",
1507                                                 array(
1508                                                         $type,
1509                                                         $menu,
1510                                                         postRequestElement('sel_action', $sel),
1511                                                         postRequestElement('sel_what', $sel),
1512                                                         $sel
1513                                                 ), __FUNCTION__, __LINE__);
1514                                 }
1515                                 break;
1516
1517                         case 'delete': // Delete menu
1518                                 sqlQueryEscaped("DELETE LOW_PRIORITY FROM `{?_MYSQL_PREFIX?}_%s_menu` WHERE ".$AND." AND `id`=%s LIMIT 1",
1519                                         array(
1520                                                 $type,
1521                                                 $sel
1522                                         ), __FUNCTION__, __LINE__);
1523                                 break;
1524
1525                         case 'status': // Change status of menus
1526                                 sqlQueryEscaped("UPDATE `{?_MYSQL_PREFIX?}_%s_menu` SET `visible`='%s',`locked`='%s' WHERE ".$AND." AND `id`=%s LIMIT 1",
1527                                         array(
1528                                                 $type,
1529                                                 postRequestElement('visible', $sel),
1530                                                 postRequestElement('locked', $sel),
1531                                                 $sel
1532                                         ), __FUNCTION__, __LINE__);
1533                                 break;
1534
1535                         default: // Unexpected action
1536                                 logDebugMessage(__FUNCTION__, __LINE__, sprintf('Unsupported action %s detected.', postRequestElement('ok')));
1537                                 displayMessage('{%message,ADMIN_UNKNOWN_OKAY=' . postRequestElement('ok') . '%}');
1538                                 break;
1539                 } // END - switch
1540         } // END - foreach
1541
1542         // Load template
1543         displayMessage('{--SETTINGS_SAVED--}');
1544 }
1545
1546 // Handle weightning
1547 function doAdminProcessMenuWeightning ($type, $AND) {
1548         // Are there all required (generalized) GET parameter?
1549         if ((isGetRequestElementSet('act')) && (isGetRequestElementSet('tid')) && (isGetRequestElementSet('fid'))) {
1550                 // Init variables
1551                 $tid = ''; $fid = '';
1552
1553                 // Get ids
1554                 if (isGetRequestElementSet('w')) {
1555                         // Sub menus selected
1556                         $result = sqlQueryEscaped("SELECT `id` FROM `{?_MYSQL_PREFIX?}_%s_menu` WHERE `action`='%s' AND `sort`=%s LIMIT 1",
1557                                 array(
1558                                         $type,
1559                                         getRequestElement('act'),
1560                                         bigintval(getRequestElement('tid'))
1561                                 ), __FUNCTION__, __LINE__);
1562                         list($tid) = sqlFetchRow($result);
1563                         sqlFreeResult($result);
1564                         $result = sqlQueryEscaped("SELECT `id` FROM `{?_MYSQL_PREFIX?}_%s_menu` WHERE `action`='%s' AND `sort`=%s LIMIT 1",
1565                                 array(
1566                                         $type,
1567                                         getRequestElement('act'),
1568                                         bigintval(getRequestElement('fid'))
1569                                 ), __FUNCTION__, __LINE__);
1570                         list($fid) = sqlFetchRow($result);
1571                         sqlFreeResult($result);
1572                 } else {
1573                         // Main menu selected
1574                         $result = sqlQueryEscaped("SELECT `id` FROM `{?_MYSQL_PREFIX?}_%s_menu` WHERE (`what`='' OR `what` IS NULL) AND `sort`=%s LIMIT 1",
1575                                 array(
1576                                         $type,
1577                                         bigintval(getRequestElement('tid'))
1578                                 ), __FUNCTION__, __LINE__);
1579                         list($tid) = sqlFetchRow($result);
1580                         sqlFreeResult($result);
1581                         $result = sqlQueryEscaped("SELECT `id` FROM `{?_MYSQL_PREFIX?}_%s_menu` WHERE (`what`='' OR `what` IS NULL) AND `sort`=%s LIMIT 1",
1582                                 array(
1583                                         $type,
1584                                         bigintval(getRequestElement('fid'))
1585                                 ), __FUNCTION__, __LINE__);
1586                         list($fid) = sqlFetchRow($result);
1587                         sqlFreeResult($result);
1588                 }
1589
1590                 if ((!empty($tid)) && (!empty($fid))) {
1591                         // Sort menu
1592                         sqlQueryEscaped("UPDATE `{?_MYSQL_PREFIX?}_%s_menu` SET `sort`=%s WHERE ".$AND." AND `id`=%s LIMIT 1",
1593                                 array(
1594                                         $type,
1595                                         bigintval(getRequestElement('tid')),
1596                                         bigintval($fid)
1597                                 ), __FUNCTION__, __LINE__);
1598                         sqlQueryEscaped("UPDATE `{?_MYSQL_PREFIX?}_%s_menu` SET `sort`=%s WHERE ".$AND." AND `id`=%s LIMIT 1",
1599                                 array(
1600                                         $type,
1601                                         bigintval(getRequestElement('fid')),
1602                                         bigintval($tid)
1603                                 ), __FUNCTION__, __LINE__);
1604                 } // END - if
1605         } // END - if
1606 }
1607
1608 // Function to register first admin
1609 function registerFirstAdmin () {
1610         // Make sure that no admin is registered
1611         assert(!isAdminRegistered());
1612
1613         // Admin is not registered so we have to inform the user
1614         if ((isFormSent('add_first_admin')) && ((!isPostRequestElementSet('admin_login')) || (!isPostRequestElementSet('admin_password1')) || (strlen(postRequestElement('admin_password1')) < getConfig('minium_admin_pass_length')) || (!isPostRequestElementSet('admin_password2')) || (strlen(postRequestElement('admin_password2')) < getConfig('minium_admin_pass_length')) || (postRequestElement('admin_password1') != postRequestElement('admin_password2')))) {
1615                 setPostRequestElement('add_first_admin', '***');
1616         } // END - if
1617
1618         // Clear error message
1619         $errorMessage = '';
1620         $ret = 'init';
1621
1622         // Is form for first admin sent?
1623         if ((isFormSent('add_first_admin')) && (postRequestElement('add_first_admin') != '***')) {
1624                 // Hash the password with the old function because we are here in install mode
1625                 $hashedPass = md5(postRequestElement('admin_password1'));
1626
1627                 // Kill maybe existing session variables
1628                 destroyAdminSession();
1629
1630                 // Do registration
1631                 $ret = addAdminAccount(postRequestElement('admin_login'), $hashedPass, getWebmaster(), 'allow');
1632
1633                 // Check if registration wents fine
1634                 switch ($ret) {
1635                         case 'done':
1636                                 // Change ADMIN_REGISTERED entry
1637                                 $done = changeDataInLocalConfigurationFile('ADMIN-SETUP', "setConfigEntry('ADMIN_REGISTERED', '", "');", 'Y', 0);
1638
1639                                 // Was it successfull?
1640                                 if ($done === TRUE) {
1641                                         // Registering is done
1642                                         redirectToUrl('modules.php?module=admin&amp;register=done');
1643                                 } else {
1644                                         // Registration incomplete
1645                                         $errorMessage = '{--ADMIN_CANNOT_COMPLETE--}';
1646
1647                                         // Set this to have our error message displayed
1648                                         setPostRequestElement('add_first_admin', '***');
1649                                 }
1650                                 break;
1651
1652                         case 'failed': // Registration has failed
1653                                 $errorMessage = '{--ADMIN_REGISTER_FAILED--}';
1654
1655                                 // Set this to have our error message displayed
1656                                 setPostRequestElement('add_first_admin', '***');
1657                                 break;
1658
1659                         case 'already': // Admin does already exists!
1660                                 $errorMessage = '{--ADMIN_LOGIN_ALREADY_REG--}';
1661
1662                                 // Set this to have our error message displayed
1663                                 setPostRequestElement('add_first_admin', '***');
1664                                 break;
1665
1666                         default:
1667                                 // Any other kind will be logged
1668                                 $errorMessage = sprintf('Unknown return code %s from ifAdminLoginDataIsValid().', $ret);
1669                                 logDebugMessage(__FUNCTION__, __LINE__, $errorMessage);
1670
1671                                 // Set this to have our error message displayed
1672                                 setPostRequestElement('add_first_admin', '***');
1673                                 break;
1674                 } // END - switch
1675         } // END - if
1676
1677         // Whas that action okay?
1678         if ($ret != 'done') {
1679                 // Init login name
1680                 $content['admin_login'] = '';
1681                 if (isPostRequestElementSet('admin_login')) {
1682                         $content['admin_login'] = postRequestElement('admin_login');
1683                 } // END - if
1684
1685                 // Init array elements
1686                 $content['login_message'] = '';
1687                 $content['password1_message'] = '';
1688                 $content['password2_message'] = '';
1689                 $content['error_message'] = '';
1690
1691                 // Yet-another notice-fix
1692                 if ((isFormSent('add_first_admin')) && (postRequestElement('add_first_admin') == '***')) {
1693                         // Init variables
1694                         $loginMessage = '';
1695                         $password1Message = '';
1696                         $password2Message = '';
1697
1698                         // No login entered?
1699                         if (empty($content['admin_login'])) {
1700                                 $loginMessage = '{--ADMIN_NO_LOGIN--}';
1701                         } // END - if
1702
1703                         // An error comes back from registration?
1704                         if ((!empty($ret)) && ($ret != 'init')) {
1705                                 $loginMessage = $errorMessage;
1706                         } // END - if
1707
1708                         // No password 1 entered or to short?
1709                         if (!isPostRequestElementSet('admin_password1')) {
1710                                 $password1Message = '{--ADMIN_NO_PASSWORD1--}';
1711                         } elseif (!isStrongPassword(postRequestElement('admin_password1'))) {
1712                                 $password1Message = '{--ADMIN_WEAK_PASSWORD1--}';
1713                         }
1714
1715                         // No password 2 entered or to short?
1716                         if (!isPostRequestElementSet('admin_password2')) {
1717                                 $password2Message = '{--ADMIN_NO_PASSWORD2--}';
1718                         } elseif (!isStrongPassword(postRequestElement('admin_password2'))) {
1719                                 $password2Message = '{--ADMIN_WEAK_PASSWORD2--}';
1720                         }
1721
1722                         // Both didn't match?
1723                         if (postRequestElement('admin_password1') != postRequestElement('admin_password2')) {
1724                                 // No match
1725                                 if (empty($password1Message)) $password1Message = '{--ADMIN_PASSWORD1_MISMATCH--}';
1726                                 if (empty($password2Message)) $password2Message = '{--ADMIN_PASSWORD2_MISMATCH--}';
1727                         } // END - if
1728
1729                         // Output error messages
1730                         $content['login_message']     = loadTemplate('admin_login_msg', TRUE, $loginMessage);
1731                         $content['password1_message'] = loadTemplate('admin_login_msg', TRUE, $password1Message);
1732                         $content['password2_message'] = loadTemplate('admin_login_msg', TRUE, $password2Message);
1733                         $content['error_message']     = loadTemplate('admin_login_msg', TRUE, $errorMessage);
1734                 } // END - if
1735
1736                 // Output message in seperate template
1737                 displayMessage('{--ADMIN_ACCOUNT_NOT_REGISTERED_YET--}');
1738
1739                 // Load register template
1740                 loadTemplate('admin_reg_form', FALSE, $content);
1741         } // END - if
1742 }
1743
1744 // [EOF]
1745 ?>