]> git.mxchange.org Git - mailer.git/blob - inc/mysql-manager.php
First batch of removal of the headers needed for revision-functions.php
[mailer.git] / inc / mysql-manager.php
1 <?php
2 /************************************************************************
3  * Mailer v0.2.1-FINAL                                Start: 08/26/2003 *
4  * ===================                          Last change: 11/29/2004 *
5  *                                                                      *
6  * -------------------------------------------------------------------- *
7  * File              : mysql-manager.php                                *
8  * -------------------------------------------------------------------- *
9  * Short description : All database-related functions                   *
10  * -------------------------------------------------------------------- *
11  * Kurzbeschreibung  : Alle datenbank-relevanten Funktionen             *
12  * -------------------------------------------------------------------- *
13  * Copyright (c) 2003 - 2009 by Roland Haeder                           *
14  * Copyright (c) 2009 - 2013 by Mailer Developer Team                   *
15  * For more information visit: http://mxchange.org                      *
16  *                                                                      *
17  * This program is free software; you can redistribute it and/or modify *
18  * it under the terms of the GNU General Public License as published by *
19  * the Free Software Foundation; either version 2 of the License, or    *
20  * (at your option) any later version.                                  *
21  *                                                                      *
22  * This program is distributed in the hope that it will be useful,      *
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
25  * GNU General Public License for more details.                         *
26  *                                                                      *
27  * You should have received a copy of the GNU General Public License    *
28  * along with this program; if not, write to the Free Software          *
29  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,               *
30  * MA  02110-1301  USA                                                  *
31  ************************************************************************/
32
33 // Some security stuff...
34 if (!defined('__SECURITY')) {
35         die();
36 } // END - if
37
38 // "Getter" for module description
39 // @TODO Can we cache this?
40 function getTitleFromMenu ($mode, $what, $column = 'what', $ADD = '') {
41         // Debug message
42         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'mode=' . $mode . ',what=' . $what . ',column=' . $column . ',add=' . $ADD);
43
44         // Fix empty 'what'
45         if (empty($what)) {
46                 $what = getIndexHome();
47         } elseif ((isGetRequestElementSet('action')) && ($column == 'what')) {
48                 // Get it from action
49                 return getTitleFromMenu($mode, getAction(), 'action', $ADD);
50         } elseif ($what == 'welcome') {
51                 // Overview page
52                 return '{--WHAT_IS_WELCOME--}';
53         }
54
55         // Default is not found
56         $data['title'] = '??? (' . $what . ')';
57
58         // Look for title
59         $result = sqlQueryEscaped("SELECT `title` FROM `{?_MYSQL_PREFIX?}_%s_menu` WHERE `%s`='%s'" . $ADD . " LIMIT 1",
60                 array(
61                         $mode,
62                         $column,
63                         $what
64                 ), __FUNCTION__, __LINE__);
65
66         // Is there an entry?
67         if (sqlNumRows($result) == 1) {
68                 // Fetch the title
69                 $data = sqlFetchArray($result);
70         } // END - if
71
72         // Free result
73         sqlFreeResult($result);
74
75         // Return it
76         return $data['title'];
77 }
78
79 // Add link into output stream (or return it) for 'You Are Here' navigation
80 function addYouAreHereLink ($accessLevel, $FQFN, $return = FALSE) {
81         // Use only filename of the FQFN...
82         $file = basename($FQFN);
83
84         // Init variables
85         $linkAdd = '';
86         $OUT = '';
87         $ADD = '';
88         $prefix = '';
89
90         // First we have to do some analysis...
91         if (substr($file, 0, 7) == 'action-') {
92                 // This is an action file!
93                 $type = 'action';
94                 $search = substr($file, 7);
95
96                 // Get access level from it
97                 $modCheck = getModuleFromFileName($file, $accessLevel);
98
99                 // Add what
100                 $ADD = " AND (`what`='' OR `what` IS NULL)";
101         } elseif (substr($file, 0, 5) == 'what-') {
102                 // This is a 'what file'!
103                 $type = 'what';
104                 $search = substr($file, 5);
105
106                 // Get access level from it
107                 $modCheck = getModuleFromFileName($file, $accessLevel);
108
109                 // Is there admin? Then display all
110                 $ADD = " AND `visible`='Y' AND `locked`='N'";
111                 if (isAdmin()) {
112                         // Display all!
113                         $ADD = '';
114                 } // END - if
115
116                 $dummy = substr($search, 0, -4);
117                 $ADD .= sprintf(" AND `action`='%s'", getActionFromModuleWhat($accessLevel, $dummy));
118         } elseif ($accessLevel == 'sponsor') {
119                 // Sponsor menu
120                 $type     = 'what';
121                 $search   = $file;
122                 $modCheck = getModule();
123         } else {
124                 // Other
125                 $type     = 'menu';
126                 $search   = $file;
127                 $modCheck = getModule();
128         }
129
130         // Begin the navigation line
131         if (!isset($GLOBALS['nav_depth'])) {
132                 // Init nav_depth
133                 $GLOBALS['nav_depth'] = '0';
134
135                 // Run the pre-filter chain
136                 $ret = runFilterChain('pre_youhere_line', array('access_level' => $accessLevel, 'type' => $type, 'search' => $search, 'prefix' => $prefix, 'link_add' => $linkAdd, 'content' => '', 'add' => $ADD));
137
138                 // Add pre-content
139                 $prefix = $ret['content'];
140
141                 // Add default content
142                 $prefix .= '<div class="you_are_here">{--YOU_ARE_HERE--}&nbsp;<strong><a class="you_are_here" href="{%url=modules.php?module=' . getModule() . $linkAdd . '%}">Home</a></strong>';
143         } elseif ($return === FALSE) {
144                 // Count depth
145                 $GLOBALS['nav_depth']++;
146         }
147
148         // Add arrow
149         $prefix .= '&nbsp;-&gt;&nbsp;';
150
151         // We need to remove .php and the end
152         if (substr($search, -4, 4) == '.php') {
153                 // Remove the .php
154                 $search = substr($search, 0, -4);
155         } // END - if
156
157         // Is ext-sql_patches installed?
158         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'isExtensionInstalledAndNewer()=' . intval(isExtensionInstalledAndNewer('sql_patches', '0.2.3')) . ',youre_here=' . getYoureHere() . ',isAdmin()=' . intval(isAdmin()) . ',modCheck=' . $modCheck);
159         if (((isExtensionInstalledAndNewer('sql_patches', '0.2.3')) && (isYoureHereEnabled())) || ((isAdmin()) && ($modCheck == 'admin'))) {
160                 // Output HTML code
161                 $OUT = $prefix . '<strong><a class="you_are_here" href="{%url=modules.php?module=' . $modCheck . '&amp;' . $type . '=' . $search . $linkAdd . '%}">' . getTitleFromMenu($accessLevel, $search, $type, $ADD) . '</a></strong>';
162
163                 // Can we close the you-are-here navigation?
164                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'type=' . $type . ',getWhat()=' . getWhat() . ',accessLevel=' . $accessLevel . ',isWhatSet()=' . intval(isWhatSet()));
165                 if (($type == 'what') || (($type == 'action') && ((!isWhatSet()) || (($accessLevel == 'admin') && (getWhat() == 'welcome'))))) {
166                         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'type=' . $type);
167                         // Add closing div and br-tag
168                         $GLOBALS['nav_depth'] = '0';
169
170                         // Run the post-filter chain
171                         $ret = runFilterChain('post_youhere_line', array('access_level' => $accessLevel, 'type' => $type, 'search' => $search, 'prefix' => $prefix, 'link_add' => $linkAdd, 'content' => $OUT, 'add' => $ADD));
172
173                         // Get content from filter back
174                         $OUT = $ret['content'];
175
176                         // Close div-tag, so not the filters have to do it
177                         $OUT .= '</div>';
178                 } // END - if
179         } // END - if
180
181         // Return or output HTML code?
182         if ($return === TRUE) {
183                 // Return HTML code
184                 return $OUT;
185         } else {
186                 // Output HTML code here
187                 outputHtml($OUT);
188         }
189 }
190
191 // Adds a menu (mode = guest/member/admin/sponsor) to output
192 function addMenu ($mode, $action, $what) {
193         // Init some variables
194         $main_cnt = '0';
195
196         // is the menu action valid?
197         if (!isMenuActionValid($mode, $action, $what, TRUE)) {
198                 return getCode('MENU_NOT_VALID');
199         } // END - if
200
201         // Non-admin shall not see all menus
202         $ADD = " AND `visible`='Y' AND `locked`='N'";
203         if (isAdmin()) {
204                 // Is admin, so make all visible
205                 $ADD = '';
206         } // END - if
207
208         // Load SQL data and add the menu to the output stream...
209         $result_main = sqlQueryEscaped("SELECT
210         `title`,
211         `what`,
212         `action`,
213         `visible`,
214         `locked`
215 FROM
216         `{?_MYSQL_PREFIX?}_%s_menu`
217 WHERE
218         (`what`='' OR `what` IS NULL)
219         ".$ADD."
220 ORDER BY
221         `sort` ASC",
222                 array($mode), __FUNCTION__, __LINE__);
223
224         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'main_cnt=' . $main_cnt . ',getWhat()=' . getWhat());
225         if (!ifSqlHasZeroNums($result_main)) {
226                 // There are menus available, so we simply display them... :)
227                 $GLOBALS['rows'] = '';
228                 while ($content = sqlFetchArray($result_main)) {
229                         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'main_cnt=' . $main_cnt . ',action=' . $content['action'] . ',getWhat()=' . getWhat());
230                         // Disable the block-mode
231                         enableBlockMode(FALSE);
232
233                         // Load menu header template
234                         $GLOBALS['rows'] .= loadTemplate($mode . '_menu_title', TRUE, $content);
235
236                         // Sub menu
237                         $result_sub = sqlQueryEscaped("SELECT
238         `title` AS `sub_title`,
239         `what` AS `sub_what`,
240         `visible` AS `sub_visible`,
241         `locked` AS `sub_locked`
242 FROM
243         `{?_MYSQL_PREFIX?}_%s_menu`
244 WHERE
245         `action`='%s' AND
246         `what` != '' AND
247         `what` IS NOT NULL
248         " . $ADD . "
249 ORDER BY
250         `sort` ASC",
251                                 array(
252                                         $mode,
253                                         $content['action']
254                                 ), __FUNCTION__, __LINE__);
255
256                         // Are there some entries?
257                         if (!ifSqlHasZeroNums($result_sub)) {
258                                 // Init counter
259                                 $count = '0';
260
261                                 // Load all sub menus
262                                 while ($content2 = sqlFetchArray($result_sub)) {
263                                         // Merge both arrays in one
264                                         $content = merge_array($content, $content2);
265
266                                         // Init content
267                                         $OUT = '';
268
269                                         // Full file name for checking menu
270                                         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'sub_what=' . $content['sub_what']);
271                                         $inc = sprintf('inc/modules/%s/what-%s.php', $mode, $content['sub_what']);
272                                         if (isIncludeReadable($inc)) {
273                                                 // Mark currently selected menu - open
274                                                 if ((!empty($what)) && (($what == $content['sub_what']))) {
275                                                         $OUT = '<strong>';
276                                                 } // END - if
277
278                                                 // Is ext-sql_patches up-to-date, and display_home_in_index is Y?
279                                                 if ((getModule() == 'index') && (isExtensionInstalledAndNewer('sql_patches', '0.8.3')) && (isDisplayHomeInIndexEnabled()) && ($content['sub_what'] == getIndexHome())) {
280                                                         // Use index.php as link
281                                                         $OUT .= '<a name="menu" class="menu_blur" href="{%url=index.php%}" target="_self">';
282                                                 } else {
283                                                         // Regular navigation link
284                                                         $OUT .= '<a name="menu" class="menu_blur" href="{%url=modules.php?module=' . getModule() . '&amp;what=' . $content['sub_what'] . '%}" target="_self">';
285                                                 }
286                                         } else {
287                                                 // Not found - open
288                                                 $OUT .= '<span class="bad" style="cursor:help" title="{%message,ADMIN_MENU_WHAT_404_TITLE=' . $content['sub_what'] . '%}">';
289                                         }
290
291                                         // Menu title
292                                         $OUT .= '{?menu_blur_spacer?}' . $content['sub_title'];
293
294                                         if (isIncludeReadable($inc)) {
295                                                 $OUT .= '</a>';
296
297                                                 // Mark currently selected menu - close
298                                                 if ((!empty($what)) && (($what == $content['sub_what']))) {
299                                                         $OUT .= '</strong>';
300                                                 } // END - if
301                                         } else {
302                                                 // Not found - close
303                                                 $OUT .= '</span>';
304                                         }
305
306                                         // Cunt it up
307                                         $count++;
308
309                                         // Rewrite array
310                                         $content = array(
311                                                 'menu'    => $OUT,
312                                                 'what'    => $content['sub_what'],
313                                                 'visible' => $content['sub_visible'],
314                                                 'locked'  => $content['locked'],
315                                         );
316
317                                         // Add regular menu row or bottom row?
318                                         if ($count < sqlNumRows($result_sub)) {
319                                                 $GLOBALS['rows'] .= loadTemplate($mode . '_menu_row', TRUE, $content);
320                                         } else {
321                                                 $GLOBALS['rows'] .= loadTemplate($mode . '_menu_bottom', TRUE, $content);
322                                         }
323                                 } // END - while
324                         } else {
325                                 // This is a menu block... ;-)
326                                 enableBlockMode();
327
328                                 // Load menu block
329                                 $INC = sprintf('inc/modules/%s/action-%s.php', $mode, $content['action']);
330                                 if (isFileReadable($INC)) {
331                                         // Load include file
332                                         if ((!isExtensionActive($content['action'])) || ($content['action'] == 'online')) $GLOBALS['rows'] .= loadTemplate('menu_what_begin', TRUE, $mode);
333                                         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'main_cnt=' . $main_cnt . ',action=' . $content['action'] . ',getWhat()=' . getWhat());
334                                         loadInclude($INC);
335                                         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'main_cnt=' . $main_cnt . ',action=' . $content['action'] . ',getWhat()=' . getWhat());
336                                         if ((!isExtensionActive($content['action'])) || ($content['action'] == 'online')) $GLOBALS['rows'] .= loadTemplate('menu_what_end', TRUE, $mode);
337                                 }
338                                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'main_cnt=' . $main_cnt . ',action=' . $content['action'] . ',getWhat()=' . getWhat());
339                         }
340
341                         // Free result
342                         sqlFreeResult($result_sub);
343
344                         // Count one up
345                         $main_cnt++;
346
347                         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'main_cnt=' . $main_cnt . ',getWhat()=' . getWhat());
348                         if (sqlNumRows($result_main) > $main_cnt) {
349                                 // Add separator
350                                 $GLOBALS['rows'] .= loadTemplate('menu_separator', TRUE, $mode);
351
352                                 // Prepare filter data array
353                                 $filterData = array(
354                                         'output'    => '',
355                                         'exclusive' => FALSE,
356                                         'action'    => $action,
357                                         'mode'      => $mode,
358                                 );
359
360                                 // Run filter chain
361                                 $filterData = runFilterChain($mode . '_menu_advert', $filterData);
362
363                                 // Add content output
364                                 $GLOBALS['rows'] .= $filterData['output'];
365                         } // END - if
366                 } // END - while
367
368                 // Free memory
369                 sqlFreeResult($result_main);
370
371                 // Prepare filter data array
372                 $filterData = array(
373                         'output'    => '',
374                         'exclusive' => FALSE,
375                         'action'    => $action,
376                         'mode'      => $mode,
377                 );
378
379                 // Run filter chain
380                 $filterData = runFilterChain($mode . '_menu_advert_end', $filterData);
381
382                 // Add content output
383                 $GLOBALS['rows'] .= $filterData['output'];
384
385                 // Prepare data
386                 $content = array(
387                         'rows'      => $GLOBALS['rows'],
388                         'menu_mode' => $mode
389                 );
390
391                 // Load main template
392                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'main_cnt=' . $main_cnt . ',getWhat()=' . getWhat());
393                 loadTemplate('menu_table', FALSE, $content);
394         } // END - if
395 }
396
397 // Checks whether the current user is a member
398 function isMember () {
399         // By default no member
400         $ret = FALSE;
401
402         // Fix missing 'last_online' array, damn stupid code :(((
403         // @TODO Try to rewrite this to one or more functions
404         if ((!isset($GLOBALS['last_online'])) || (!is_array($GLOBALS['last_online']))) {
405                 $GLOBALS['last_online'] = array();
406         } // END - if
407
408         // Is the cache entry there?
409         if (isset($GLOBALS[__FUNCTION__])) {
410                 // Then return it
411                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'CACHED! (' . intval($GLOBALS[__FUNCTION__]) . ')');
412                 return $GLOBALS[__FUNCTION__];
413         } elseif ((!isSessionVariableSet('userid')) || (!isSessionVariableSet('u_hash'))) {
414                 // Destroy any existing user session data
415                 destroyMemberSession();
416                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'No member set in cookie/session.');
417
418                 // Abort further processing
419                 return FALSE;
420         }
421
422         // Get userid secured from session
423         setMemberId(getSession('userid'));
424
425         // ... and set it as currently handled user id
426         setCurrentUserId(getMemberId());
427
428         // Init user data array
429         initUserData();
430
431         // Fix "deleted" cookies
432         fixDeletedCookies(array('userid', 'u_hash'));
433
434         // Are cookies set and can the member data be loaded?
435         if ((isMemberIdSet()) && (isSessionVariableSet('u_hash')) && (fetchUserData(getMemberId()) === TRUE)) {
436                 // Validate password by created the difference of it and the secret key
437                 $valPass = encodeHashForCookie(getUserData('password'));
438
439                 // So did we now have valid data and an unlocked user?
440                 if ((getUserData('status') == 'CONFIRMED') && ($valPass == getSession('u_hash'))) {
441                         // Transfer last module and online time
442                         $GLOBALS['last_online']['module'] = getUserData(getUserLastWhatName());
443                         $GLOBALS['last_online']['online'] = getUserData('last_online');
444
445                         // Account is confirmed and all cookie data is valid so he is definely logged in! :-)
446                         $ret = TRUE;
447                 } // END - if
448         } // END - if
449
450         // Is $ret still false?
451         if ($ret === FALSE) {
452                 // Yes, so destroy the session
453                 destroyMemberSession();
454         } // END - if
455
456         // Cache status
457         $GLOBALS[__FUNCTION__] = $ret;
458
459         // Return status
460         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'ret=' . intval($ret));
461         return $ret;
462 }
463
464 // Fetch user data for given user id
465 function fetchUserData ($value, $column = 'userid') {
466         // Extension ext-user must be there at any case
467         if (!isExtensionActive('user')) {
468                 // Absent ext-user is really not good
469                 return FALSE;
470         } elseif (is_null($value)) {
471                 // This shall never happen, so please report it
472                 reportBug(__FUNCTION__, __LINE__, 'value=NULL,column=' . $column . ' - value can never be NULL');
473         }
474
475         // If we should look for userid secure&set it here
476         if (substr($column, -2, 2) == 'id') {
477                 // Secure userid
478                 $value = bigintval($value);
479
480                 // Don't look for invalid userids...
481                 if (!isValidId($value)) {
482                         // Invalid, so abort here
483                         reportBug(__FUNCTION__, __LINE__, 'User id ' . $value . ' is invalid.');
484                 } // END - if
485
486                 // Unset cached values if found and different
487                 if ((isCurrentUserIdSet()) && (getCurrentUserId() != $value)) {
488                         // Unset it
489                         unsetCurrentUserId();
490                 } elseif (isValidUserData()) {
491                         // Use cache, so it is fine
492                         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'value=' . $value . ' is valid, using cache #1');
493                         return TRUE;
494                 } // END - if
495         } elseif (isValidUserData()) {
496                 // Using cache is fine
497                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'value=' . $value . ' is valid, using cache #2');
498                 return TRUE;
499         }
500
501         // By default none was found
502         $found = FALSE;
503
504         // Extra SQL statements
505         $ADD = runFilterChain('convert_user_data_columns', ' ');
506
507         // Query for the user
508         $result = sqlQueryEscaped("SELECT *" . $ADD . " FROM `{?_MYSQL_PREFIX?}_user_data` WHERE `%s`='%s' LIMIT 1",
509                 array(
510                         $column,
511                         $value
512                 ), __FUNCTION__, __LINE__);
513
514         // Is there a record?
515         if (sqlNumRows($result) == 1) {
516                 // Load data from cookies
517                 $data = sqlFetchArray($result);
518
519                 // Set the userid for later use
520                 setCurrentUserId($data['userid']);
521
522                 // And cache the data for this userid
523                 $GLOBALS['user_data'][getCurrentUserId()] = $data;
524
525                 // Rewrite 'last_failure' if found and ext-user has version >= 0.3.7
526                 if ((isExtensionInstalledAndNewer('user', '0.3.7')) && (isset($GLOBALS['user_data'][getCurrentUserId()]['last_failure']))) {
527                         // Backup the raw one and zero it
528                         $GLOBALS['user_data'][getCurrentUserId()]['last_failure_raw'] = $GLOBALS['user_data'][getCurrentUserId()]['last_failure'];
529                         $GLOBALS['user_data'][getCurrentUserId()]['last_failure'] = NULL;
530
531                         // Is it not zero?
532                         if (!is_null($GLOBALS['user_data'][getCurrentUserId()]['last_failure_raw'])) {
533                                 // Seperate data/time
534                                 $array = explode(' ', $GLOBALS['user_data'][getCurrentUserId()]['last_failure_raw']);
535
536                                 // Seperate data and time again
537                                 $array['date'] = explode('-', $array[0]);
538                                 $array['time'] = explode(':', $array[1]);
539
540                                 // Now pass it to mktime()
541                                 $GLOBALS['user_data'][getCurrentUserId()]['last_failure'] = mktime(
542                                         $array['time'][0],
543                                         $array['time'][1],
544                                         $array['time'][2],
545                                         $array['date'][1],
546                                         $array['date'][2],
547                                         $array['date'][0]
548                                 );
549                         } // END - if
550                 } // END - if
551
552                 // Found, but valid?
553                 $found = isValidUserData();
554         } // END - if
555
556         // Free memory
557         sqlFreeResult($result);
558
559         // Return result
560         return $found;
561 }
562
563 /*
564  * Checks whether the current session bears a valid admin id and password hash.
565  *
566  * This patched function will reduce many SELECT queries for the current admin
567  * login.
568  */
569 function isAdmin () {
570         // Is there cache?
571         if (isset($GLOBALS[__FUNCTION__])) {
572                 // Return it
573                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'isAdmin()=' . intval($GLOBALS[__FUNCTION__]));
574                 return $GLOBALS[__FUNCTION__];
575         } // END - if
576
577         // No admin in installation phase!
578         if ((isInstaller()) || (!isAdminRegistered())) {
579                 $GLOBALS[__FUNCTION__] = FALSE;
580                 return FALSE;
581         } // END - if
582
583         // Init variables
584         $ret = FALSE;
585         $adminId = '0';
586         $passwordFromCookie = '';
587         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, $adminId);
588
589         // If admin login is not given take current from cookies...
590         if ((isSessionVariableSet('admin_id')) && (isSessionVariableSet('admin_md5'))) {
591                 // Get admin login and password from session/cookies
592                 $adminId            = getCurrentAdminId();
593                 $passwordFromCookie = getAdminMd5();
594         } // END - if
595         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'adminId=' . $adminId . ',passwordFromCookie=' . $passwordFromCookie);
596
597         // Abort if admin id is zero
598         if (($adminId == '0') || (empty($passwordFromCookie))) {
599                 // A very noisy debug message ...
600                 //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Current adminId is zero. isSessionVariableSet(admin_id)=' . intval(isSessionVariableSet('admin_id')) . ',isSessionVariableSet(admin_md5)=' . intval(isSessionVariableSet('admin_md5')));
601
602                 // Abort here now
603                 $GLOBALS[__FUNCTION__] = FALSE;
604                 return FALSE;
605         } // END - if
606
607         // Init it with failed
608         $GLOBALS[__FUNCTION__] = FALSE;
609
610         // Search in array for entry
611         if (isset($GLOBALS['admin_hash'])) {
612                 // Use cached string
613                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Using admin_hash=' . $GLOBALS['admin_hash'] . ' from cache');
614         } elseif ((!empty($adminId)) && (!empty($passwordFromCookie)) && (isAdminHashSet($adminId) === TRUE)) {
615                 // Get admin hash and hash it
616                 $GLOBALS['admin_hash'] = encodeHashForCookie(getAdminHash($adminId));
617                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'valPass=' . $GLOBALS['admin_hash']);
618
619                 // Count cache hits
620                 incrementStatsEntry('cache_hits');
621         } elseif ((!empty($adminId)) && ((!isExtensionActive('cache')) || (isAdminHashSet($adminId) === FALSE))) {
622                 // Get admin hash and hash it
623                 $GLOBALS['admin_hash'] = encodeHashForCookie(getAdminHash($adminId));
624                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'valPass=' . $GLOBALS['admin_hash']);
625         }
626
627         // Check if password is valid
628         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, '(' . $GLOBALS['admin_hash'] . '==' . $passwordFromCookie . ')='.intval($GLOBALS['admin_hash'] == $passwordFromCookie));
629         $GLOBALS[__FUNCTION__] = ((!empty($GLOBALS['admin_hash'])) && ($GLOBALS['admin_hash'] == $passwordFromCookie));
630
631         // Return result of comparision
632         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'isAdmin()=' . intval($GLOBALS[__FUNCTION__]));
633         return $GLOBALS[__FUNCTION__];
634 }
635
636 // Generates a list of "max receiveable emails per day"
637 function addMaxReceiveList ($mode, $default = '') {
638         $OUT = '';
639         $result = FALSE;
640
641         switch ($mode) {
642                 case 'guest':
643                         // Guests (in the registration form) are not allowed to select 0 mails per day.
644                         $result = sqlQuery('SELECT `value`, `comment` FROM `{?_MYSQL_PREFIX?}_max_receive` WHERE `value` > 0 ORDER BY `value` ASC',
645                         __FUNCTION__, __LINE__);
646                         break;
647
648                 case 'admin':
649                 case 'member':
650                         // Members are allowed to set to zero mails per day (we will change this soon!)
651                         $result = sqlQuery('SELECT `value`, `comment` FROM `{?_MYSQL_PREFIX?}_max_receive` ORDER BY `value` ASC',
652                         __FUNCTION__, __LINE__);
653                         break;
654
655                 default: // Invalid!
656                         logDebugMessage(__FUNCTION__, __LINE__, sprintf('Invalid mode %s detected.', $mode));
657                         break;
658         }
659
660         // Some entries are found?
661         if (!ifSqlHasZeroNums($result)) {
662                 $OUT = '';
663                 while ($content = sqlFetchArray($result)) {
664                         $OUT .= '      <option value="' . $content['value'] . '"';
665
666                         if (postRequestElement('max_mails') == $content['value']) {
667                                 $OUT .= ' selected="selected"';
668                         } // END - if
669
670                         $OUT .= '>' . $content['value'] . ' {--PER_DAY--}';
671                         if (!empty($content['comment'])) $OUT .= '(' . $content['comment'] . ')';
672                         $OUT .= '</option>';
673                 }
674
675                 // Load template
676                 $OUT = loadTemplate(($mode . '_receive_table'), TRUE, $OUT);
677         } else {
678                 // Maybe the admin has to setup some maximum values?
679                 reportBug(__FUNCTION__, __LINE__, 'Nothing is being done here?');
680         }
681
682         // Free result
683         sqlFreeResult($result);
684
685         // Return generated HTML code
686         return $OUT;
687 }
688
689 // Checks whether the given email address is used.
690 function isEmailTaken ($email) {
691         // Default is no userid
692         $useridSql = ' IS NOT NULL';
693
694         // Is a member logged in?
695         if (isMember()) {
696                 // Get userid
697                 $useridSql = '!= ' . bigintval(getMemberId());
698         } // END - if
699
700         // Replace dot with {DOT}
701         $email = str_replace('.', '{DOT}', $email);
702
703         // Query the database
704         $result = sqlQueryEscaped("SELECT
705         COUNT(`userid`) AS `cnt`
706 FROM
707         `{?_MYSQL_PREFIX?}_user_data`
708 WHERE
709         '%s' REGEXP `email` AND
710         `userid` %s
711 LIMIT 1",
712                 array(
713                         $email,
714                         $useridSql
715                 ), __FUNCTION__, __LINE__);
716
717         // Is the email there?
718         list($count) = sqlFetchRow($result);
719
720         // Free the result
721         sqlFreeResult($result);
722
723         // Return result
724         return ($count == 1);
725 }
726
727 // Validate the given menu action
728 function isMenuActionValid ($mode, $action, $what, $updateEntry = FALSE) {
729         // Is the cache entry there and we shall not update?
730         if ((isset($GLOBALS['action_valid'][$mode][$action][$what])) && ($updateEntry === FALSE)) {
731                 // Count cache hit
732                 incrementStatsEntry('cache_hits');
733
734                 // Then use this cache
735                 return $GLOBALS['action_valid'][$mode][$action][$what];
736         } // END - if
737
738         // By default nothing is valid
739         $ret = FALSE;
740
741         // Look in all menus or only unlocked
742         $add = '';
743         if ((!isAdmin()) && ($mode != 'admin')) $add = " AND `locked`='N'";
744
745         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'mode=' . $mode . ',action=' . $action . ',what=' . $what);
746         if (($mode != 'admin') && ($updateEntry === TRUE)) {
747                 // Update guest or member menu
748                 $sql = sqlQueryEscaped("UPDATE `{?_MYSQL_PREFIX?}_%s_menu` SET `counter`=`counter`+1 WHERE `action`='%s' AND `what`='%s'".$add." LIMIT 1",
749                         array(
750                                 $mode,
751                                 $action,
752                                 $what
753                         ), __FUNCTION__, __LINE__, FALSE);
754         } elseif (($what != 'welcome') && (!empty($what))) {
755                 // Other actions
756                 $sql = sqlQueryEscaped("SELECT `id`, `what` FROM `{?_MYSQL_PREFIX?}_%s_menu` WHERE `action`='%s' AND `what`='%s'".$add." ORDER BY `action` DESC LIMIT 1",
757                         array(
758                                 $mode,
759                                 $action,
760                                 $what
761                         ), __FUNCTION__, __LINE__, FALSE);
762         } else {
763                 // Admin login overview
764                 $sql = sqlQueryEscaped("SELECT `id`, `what` FROM `{?_MYSQL_PREFIX?}_%s_menu` WHERE `action`='%s' AND (`what`='' OR `what` IS NULL)".$add." ORDER BY `action` DESC LIMIT 1",
765                         array(
766                                 $mode,
767                                 $action
768                         ), __FUNCTION__, __LINE__, FALSE);
769         }
770
771         // Run SQL command
772         $result = sqlQuery($sql, __FUNCTION__, __LINE__);
773
774         // Should we look for affected rows (only update) or found rows?
775         if ($updateEntry === TRUE) {
776                 // Check updated/affected rows
777                 $ret = (!ifSqlHasZeroAffectedRows());
778         } else {
779                 // Check found rows
780                 $ret = (!ifSqlHasZeroNums($result));
781         }
782
783         // Free memory
784         sqlFreeResult($result);
785
786         // Set cache entry
787         $GLOBALS['action_valid'][$mode][$action][$what] = $ret;
788
789         // Return result
790         return $ret;
791 }
792
793 // Get action value from mode (admin/guest/member) and what-value
794 function getActionFromModuleWhat ($module, $what) {
795         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'module=' . $module . ',what=' . $what);
796         // Init status
797         $data['action'] = '';
798
799         if (!isExtensionInstalledAndNewer('sql_patches', '0.0.5')) {
800                 // ext-sql_patches is missing so choose depending on mode
801                 $what = determineWhat($module);
802         } elseif ((empty($what)) && ($module != 'admin')) {
803                 // Use configured 'home'
804                 $what = getIndexHome();
805         } // END - if
806
807         if ($module == 'admin') {
808                 // Action value for admin area
809                 if (isGetRequestElementSet('action')) {
810                         // Use from request!
811                         return getRequestElement('action');
812                 } elseif (isActionSet()) {
813                         // Get it directly from URL
814                         return getAction();
815                 } elseif (($what == 'welcome') || (!isWhatSet())) {
816                         // Default value for admin area
817                         $data['action'] = 'login';
818                 }
819         } elseif (isActionSet()) {
820                 // Get it directly from URL
821                 return getAction();
822         }
823         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, ' ret=' . $data['action']);
824
825         // Does the module have a menu?
826         if (ifModuleHasMenu($module)) {
827                 // Rewriting modules to menu
828                 $module = mapModuleToTable($module);
829
830                 // Guest and member menu is 'main' as the default
831                 if (empty($data['action'])) {
832                         $data['action'] = 'main';
833                 } // END - if
834
835                 // Load from database
836                 $result = sqlQueryEscaped("SELECT `action` FROM `{?_MYSQL_PREFIX?}_%s_menu` WHERE `what`='%s' LIMIT 1",
837                         array(
838                                 $module,
839                                 $what
840                         ), __FUNCTION__, __LINE__);
841
842                 // Entry found?
843                 if (sqlNumRows($result) == 1) {
844                         // Load action value and pray that this one is the right you want... ;-)
845                         $data = sqlFetchArray($result);
846                 } // END - if
847
848                 // Free memory
849                 sqlFreeResult($result);
850         } elseif ((!isExtensionInstalled('sql_patches')) && ($module != 'admin') && ($module != 'unknown')) {
851                 // No ext-sql_patches installed, but maybe we need to register an admin?
852                 if (isAdminRegistered()) {
853                         // Redirect to admin area
854                         redirectToUrl('admin.php');
855                 } // END - if
856         }
857
858         // Return action value
859         return $data['action'];
860 }
861
862 // Get category name back
863 function getCategory ($cid) {
864         // Default is not found
865         $data['cat'] = '{--_CATEGORY_404--}';
866
867         // Is the category id set?
868         if (!isValidId($cid)) {
869                 // No category
870                 $data['cat'] = '{--_CATEGORY_NONE--}';
871         } elseif (isValidId($cid)) {
872                 // Lookup the category in database
873                 $result = sqlQueryEscaped('SELECT `cat` FROM `{?_MYSQL_PREFIX?}_cats` WHERE `id`=%s LIMIT 1',
874                         array(bigintval($cid)), __FUNCTION__, __LINE__);
875                 if (sqlNumRows($result) == 1) {
876                         // Category found... :-)
877                         $data = sqlFetchArray($result);
878                 } // END - if
879
880                 // Free result
881                 sqlFreeResult($result);
882         } // END - if
883
884         // Return result
885         return $data['cat'];
886 }
887
888 // Get a string of "mail title" and price back
889 function getPaymentTitlePrice ($paymentsId, $full = FALSE) {
890         // Only title or also including price?
891         if ($full === FALSE) {
892                 $ret = getPaymentData($paymentsId, 'main_title');
893         } else {
894                 $ret = getPaymentData($paymentsId, 'main_title') . ' / {%pipe,getPaymentData,translateComma=' . $paymentsId . '%} {?POINTS?}';
895         }
896
897         // Return result
898         return $ret;
899 }
900
901 // Get payment price
902 function getPaymentPrice ($paymentsId) {
903         // Return result
904         return getPaymentData($paymentsId, 'price');
905 }
906
907 // Get payment time
908 function getPaymentTime ($paymentsId) {
909         // Return result
910         return getPaymentData($paymentsId, 'time');
911 }
912
913 // Get payment 'payment'
914 function getPaymentPayment ($paymentsId) {
915         // Return result
916         return getPaymentData($paymentsId, 'payment');
917 }
918
919 // "Getter" for payment data (cached)
920 function getPaymentData ($paymentsId, $lookFor) {
921         // Default value...
922         $data[$lookFor] = NULL;
923
924         // Is there cache?
925         if (isset($GLOBALS['cache_array']['payments'][$lookFor][$paymentsId])) {
926                 // Use it if found to save SQL queries
927                 $data[$lookFor] = $GLOBALS['cache_array']['payments'][$lookFor][$paymentsId];
928
929                 // Update cache hits
930                 incrementStatsEntry('cache_hits');
931         } elseif (!isExtensionActive('cache')) {
932                 // Search for it in database
933                 $result = sqlQueryEscaped('SELECT `%s` FROM `{?_MYSQL_PREFIX?}_payments` WHERE `id`=%s LIMIT 1',
934                         array(
935                                 $lookFor,
936                                 bigintval($paymentsId)
937                         ), __FUNCTION__, __LINE__);
938
939                 // Is the entry there?
940                 if (sqlNumRows($result) == 1) {
941                         // Payment type found... :-)
942                         $data = sqlFetchArray($result);
943                 } // END - if
944
945                 // Free result
946                 sqlFreeResult($result);
947         }
948
949         // Return value
950         return $data[$lookFor];
951 }
952
953 // Remove a receiver's id from $receivers and add a link for him to confirm
954 function removeReceiver (&$receivers, $key, $userid, $poolId, $statsId = 0, $isBonusMail = FALSE) {
955         // Default is not removed
956         $ret = 'failed';
957
958         // Is the userid valid?
959         if (isValidId($userid)) {
960                 // Remove entry from array
961                 unset($receivers[$key]);
962
963                 // Is there already a line for this user available?
964                 if (isValidId($statsId)) {
965                         // Default is 'normal' mail
966                         $type = 'NORMAL';
967                         $rowName = 'stats_id';
968
969                         // Only when we got a real stats id continue searching for the entry
970                         if ($isBonusMail === TRUE) {
971                                 $type = 'BONUS';
972                                 $rowName = 'bonus_id';
973                         } // END - if
974
975                         // Try to look the entry up
976                         $result = sqlQueryEscaped("SELECT `id` FROM `{?_MYSQL_PREFIX?}_user_links` WHERE `%s`=%s AND `userid`=%s AND `link_type`='%s' LIMIT 1",
977                                 array(
978                                         $rowName,
979                                         bigintval($statsId),
980                                         bigintval($userid),
981                                         $type
982                                 ), __FUNCTION__, __LINE__);
983
984                         // Was it *not* found?
985                         if (ifSqlHasZeroNums($result)) {
986                                 // So we add one!
987                                 sqlQueryEscaped("INSERT INTO `{?_MYSQL_PREFIX?}_user_links` (`%s`, `userid`, `link_type`) VALUES (%s,%s,'%s')",
988                                         array(
989                                                 $rowName,
990                                                 bigintval($statsId),
991                                                 bigintval($userid),
992                                                 $type
993                                         ), __FUNCTION__, __LINE__);
994
995                                 // Update 'mails_sent' if ext-sql_patches is updated
996                                 if (isExtensionInstalledAndNewer('sql_patches', '0.7.4')) {
997                                         // Update the pool
998                                         updatePoolDataById($poolId, 'mails_sent', 1, '+');
999                                 } // END - if
1000                                 $ret = 'done';
1001                         } else {
1002                                 // Already found
1003                                 $ret = 'already';
1004                         }
1005
1006                         // Free memory
1007                         sqlFreeResult($result);
1008                 } // END - if
1009         } // END - if
1010
1011         // Return status for sending routine
1012         return $ret;
1013 }
1014
1015 // Calculate sum (default) or count records of given criteria
1016 function countSumTotalData ($search, $tableName, $lookFor = 'id', $whereStatement = 'userid', $countRows = FALSE, $add = '', $mode = '=') {
1017         // Debug message
1018         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'search=' . $search . ',tableName=' . $tableName . ',lookFor=' . $lookFor . ',whereStatement=' . $whereStatement . ',add=' . $add);
1019         if ((empty($search)) && (!is_null($search))) {
1020                 // Count or sum whole table?
1021                 if ($countRows === TRUE) {
1022                         // Count whole table
1023                         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'COUNT!');
1024                         $result = sqlQueryEscaped('SELECT COUNT(`%s`) AS `res` FROM `{?_MYSQL_PREFIX?}_%s`' . $add . ' LIMIT 1',
1025                                 array(
1026                                         $lookFor,
1027                                         $tableName
1028                                 ), __FUNCTION__, __LINE__);
1029                 } else {
1030                         // Sum whole table
1031                         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'SUM!');
1032                         $result = sqlQueryEscaped('SELECT SUM(`%s`) AS `res` FROM `{?_MYSQL_PREFIX?}_%s`' . $add . ' LIMIT 1',
1033                                 array(
1034                                         $lookFor,
1035                                         $tableName
1036                                 ), __FUNCTION__, __LINE__);
1037                 }
1038         } elseif (($countRows === TRUE) || ($lookFor == 'userid')) {
1039                 // Count rows
1040                 if (is_null($search)) {
1041                         // Fix mode
1042                         if ($mode == '=') {
1043                                 $mode = 'IS';
1044                         } elseif ($mode == '!=') {
1045                                 $mode = 'IS NOT';
1046                         }
1047
1048                         // Look for NULL/0
1049                         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'COUNT-NULL!');
1050                         $result = sqlQueryEscaped("SELECT COUNT(`%s`) AS `res` FROM `{?_MYSQL_PREFIX?}_%s` WHERE (`%s` %s NULL OR `%s`=0)" . $add . ' LIMIT 1',
1051                                 array(
1052                                         $lookFor,
1053                                         $tableName,
1054                                         $whereStatement,
1055                                         $mode,
1056                                         $whereStatement
1057                                 ), __FUNCTION__, __LINE__);
1058                 } else {
1059                         // Regular entry
1060                         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'COUNT!');
1061                         $result = sqlQueryEscaped("SELECT COUNT(`%s`) AS `res` FROM `{?_MYSQL_PREFIX?}_%s` WHERE `%s`%s'%s'" . $add . ' LIMIT 1',
1062                                 array(
1063                                         $lookFor,
1064                                         $tableName,
1065                                         $whereStatement,
1066                                         $mode,
1067                                         $search
1068                                 ), __FUNCTION__, __LINE__);
1069                 }
1070         } else {
1071                 // Sum all rows
1072                 if (is_null($search)) {
1073                         // Fix mode
1074                         if ($mode == '=') {
1075                                 $mode = 'IS';
1076                         } elseif ($mode == '!=') {
1077                                 $mode = 'IS NOT';
1078                         }
1079
1080                         // Look for NULL/0
1081                         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'SUM-NULL!');
1082                         $result = sqlQueryEscaped("SELECT SUM(`%s`) AS `res` FROM `{?_MYSQL_PREFIX?}_%s` WHERE (`%s` %s NULL OR `%s`=0)" . $add . ' LIMIT 1',
1083                                 array(
1084                                         $lookFor,
1085                                         $tableName,
1086                                         $whereStatement,
1087                                         $mode,
1088                                         $whereStatement
1089                                 ), __FUNCTION__, __LINE__);
1090                 } else {
1091                         // Regular entry
1092                         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'SUM!');
1093                         $result = sqlQueryEscaped("SELECT SUM(`%s`) AS `res` FROM `{?_MYSQL_PREFIX?}_%s` WHERE `%s`%s'%s'" . $add . ' LIMIT 1',
1094                                 array(
1095                                         $lookFor,
1096                                         $tableName,
1097                                         $whereStatement,
1098                                         $mode,
1099                                         $search
1100                                 ), __FUNCTION__, __LINE__);
1101                 }
1102         }
1103
1104         // Load row
1105         $data = sqlFetchArray($result);
1106
1107         // Free result
1108         sqlFreeResult($result);
1109
1110         // Fix empty values
1111         if ((empty($data['res'])) && ($lookFor != 'counter') && ($lookFor != 'id') && ($lookFor != 'userid') && ($lookFor != 'rallye_id')) {
1112                 // Float number
1113                 $data['res'] = '0.00000';
1114         } elseif ('' . $data['res'] . '' == '') {
1115                 // Fix empty result
1116                 $data['res'] = '0';
1117         }
1118
1119         // Return value
1120         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'res=' . $data['res']);
1121         return $data['res'];
1122 }
1123
1124 /**
1125  * Sends out mail to all administrators. This function is no longer obsolete
1126  * because we need it when there is no ext-admins installed
1127  */
1128 function sendAdminEmails ($subject, $message, $isBugReport = FALSE) {
1129         // Default is no special header
1130         $mailHeader = '';
1131
1132         // Is it a bug report?
1133         if ($isBugReport === TRUE) {
1134                 // Then add a reply-to line back to the author (me)
1135                 $mailHeader = 'Reply-To: webmaster@mxchange.org' . PHP_EOL;
1136         } // END - if
1137
1138         // Load all admin email addresses
1139         $result = sqlQuery('SELECT `email` FROM `{?_MYSQL_PREFIX?}_admins` ORDER BY `id` ASC', __FUNCTION__, __LINE__);
1140
1141         // And send the notification to all of them
1142         while ($content = sqlFetchArray($result)) {
1143                 // Send the email out
1144                 sendEmail($content['email'], $subject, $message, 'N', $mailHeader);
1145         } // END - if
1146
1147         // Free result
1148         sqlFreeResult($result);
1149
1150         // Really simple... ;-)
1151 }
1152
1153 // Get id number from administrator's login name
1154 function getAdminId ($adminLogin) {
1155         // By default no admin is found
1156         $data['id'] = -1;
1157
1158         // Check cache
1159         if (isset($GLOBALS['cache_array']['admin']['admin_id'][$adminLogin])) {
1160                 // Use it if found to save SQL queries
1161                 $data['id'] = $GLOBALS['cache_array']['admin']['admin_id'][$adminLogin];
1162
1163                 // Update cache hits
1164                 incrementStatsEntry('cache_hits');
1165         } elseif (!isExtensionActive('cache')) {
1166                 // Load from database
1167                 $result = sqlQueryEscaped("SELECT `id` FROM `{?_MYSQL_PREFIX?}_admins` WHERE `login`='%s' LIMIT 1",
1168                         array($adminLogin), __FUNCTION__, __LINE__);
1169
1170                 // Is there an entry?
1171                 if (sqlNumRows($result) == 1) {
1172                         // Get it
1173                         $data = sqlFetchArray($result);
1174                 } // END - if
1175
1176                 // Free result
1177                 sqlFreeResult($result);
1178         }
1179
1180         // Return the id
1181         return $data['id'];
1182 }
1183
1184 // "Getter" for current admin id
1185 function getCurrentAdminId () {
1186         // Log debug message
1187         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'called!');
1188
1189         // Is there cache?
1190         if (!isset($GLOBALS['current_admin_id'])) {
1191                 // Get the admin login from session
1192                 $adminId = getSession('admin_id');
1193
1194                 // Remember in cache securely
1195                 setCurrentAdminId(bigintval($adminId));
1196         } // END - if
1197
1198         // Return it
1199         return $GLOBALS['current_admin_id'];
1200 }
1201
1202 // Setter for current admin id
1203 function setCurrentAdminId ($currentAdminId) {
1204         // Set it secured
1205         $GLOBALS['current_admin_id'] = bigintval($currentAdminId);
1206 }
1207
1208 // Get password hash from administrator's login name
1209 function getAdminHash ($adminId) {
1210         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'adminId=' . $adminId . ' - ENTERED!');
1211         // By default an invalid hash is returned
1212         $data['password'] = -1;
1213
1214         // Is admin hash set?
1215         if (isAdminHashSet($adminId)) {
1216                 // Check cache
1217                 $data['password'] = $GLOBALS['cache_array']['admin']['password'][$adminId];
1218
1219                 // Update cache hits
1220                 incrementStatsEntry('cache_hits');
1221         } elseif (!isExtensionActive('cache')) {
1222                 // Load from database
1223                 $result = sqlQueryEscaped("SELECT `password` FROM `{?_MYSQL_PREFIX?}_admins` WHERE `id`=%s LIMIT 1",
1224                         array(bigintval($adminId)), __FUNCTION__, __LINE__);
1225
1226                 // Is there an entry?
1227                 if (sqlNumRows($result) == 1) {
1228                         // Fetch data
1229                         $data = sqlFetchArray($result);
1230
1231                         // Set cache
1232                         setAdminHash($adminId, $data['password']);
1233                 } // END - if
1234
1235                 // Free result
1236                 sqlFreeResult($result);
1237         }
1238
1239         // Return password hash
1240         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'adminId=' . $adminId . ',data[password]=' . $data['password'] . ' - EXIT!');
1241         return $data['password'];
1242 }
1243
1244 // "Getter" for admin login
1245 function getAdminLogin ($adminId) {
1246         // By default a non-existent login is returned (other functions react on this!)
1247         $data['login'] = '***';
1248
1249         if (isset($GLOBALS['cache_array']['admin']['login'][$adminId])) {
1250                 // Get cache
1251                 $data['login'] = $GLOBALS['cache_array']['admin']['login'][$adminId];
1252
1253                 // Update cache hits
1254                 incrementStatsEntry('cache_hits');
1255         } elseif (!isExtensionActive('cache')) {
1256                 // Load from database
1257                 $result = sqlQueryEscaped("SELECT `login` FROM `{?_MYSQL_PREFIX?}_admins` WHERE `id`=%s LIMIT 1",
1258                         array(bigintval($adminId)), __FUNCTION__, __LINE__);
1259
1260                 // Entry found?
1261                 if (sqlNumRows($result) == 1) {
1262                         // Fetch data
1263                         $data = sqlFetchArray($result);
1264
1265                         // Set cache
1266                         $GLOBALS['cache_array']['admin']['login'][$adminId] = $data['login'];
1267                 } // END - if
1268
1269                 // Free memory
1270                 sqlFreeResult($result);
1271         }
1272
1273         // Return the result
1274         return $data['login'];
1275 }
1276
1277 // Get email address of admin id
1278 function getAdminEmail ($adminId) {
1279         // By default an invalid emails is returned
1280         $data['email'] = '***';
1281
1282         if (isset($GLOBALS['cache_array']['admin']['email'][$adminId])) {
1283                 // Get cache
1284                 $data['email'] = $GLOBALS['cache_array']['admin']['email'][$adminId];
1285
1286                 // Update cache hits
1287                 incrementStatsEntry('cache_hits');
1288         } elseif (!isExtensionActive('cache')) {
1289                 // Load from database
1290                 $result_admin_id = sqlQueryEscaped("SELECT `email` FROM `{?_MYSQL_PREFIX?}_admins` WHERE `id`=%s LIMIT 1",
1291                         array(bigintval($adminId)), __FUNCTION__, __LINE__);
1292
1293                 // Entry found?
1294                 if (sqlNumRows($result_admin_id) == 1) {
1295                         // Get data
1296                         $data = sqlFetchArray($result_admin_id);
1297
1298                         // Set cache
1299                         $GLOBALS['cache_array']['admin']['email'][$adminId] = $data['email'];
1300                 } // END - if
1301
1302                 // Free result
1303                 sqlFreeResult($result_admin_id);
1304         }
1305
1306         // Return email
1307         return $data['email'];
1308 }
1309
1310 // Get default ACL of admin id
1311 function getAdminDefaultAcl ($adminId) {
1312         // By default an invalid ACL value is returned
1313         $data['default_acl'] = 'NO-ACL';
1314
1315         // Is ext-sql_patches there and was it found in cache?
1316         if (!isExtensionActive('sql_patches')) {
1317                 // Not found, which is bad, so we need to allow all
1318                 $data['default_acl'] = 'allow';
1319         } elseif (isset($GLOBALS['cache_array']['admin']['default_acl'][$adminId])) {
1320                 // Use cache
1321                 $data['default_acl'] = $GLOBALS['cache_array']['admin']['default_acl'][$adminId];
1322
1323                 // Update cache hits
1324                 incrementStatsEntry('cache_hits');
1325         } elseif (!isExtensionActive('cache')) {
1326                 // Load from database
1327                 $result_admin_id = sqlQueryEscaped("SELECT `default_acl` FROM `{?_MYSQL_PREFIX?}_admins` WHERE `id`=%s LIMIT 1",
1328                         array(bigintval($adminId)), __FUNCTION__, __LINE__);
1329
1330                 // Is there an entry?
1331                 if (sqlNumRows($result_admin_id) == 1) {
1332                         // Fetch data
1333                         $data = sqlFetchArray($result_admin_id);
1334
1335                         // Set cache
1336                         $GLOBALS['cache_array']['admin']['default_acl'][$adminId] = $data['default_acl'];
1337                 }
1338
1339                 // Free result
1340                 sqlFreeResult($result_admin_id);
1341         }
1342
1343         // Return default ACL
1344         return $data['default_acl'];
1345 }
1346
1347 // Get menu mode (la_mode) of admin id
1348 function getAdminMenuMode ($adminId) {
1349         // By default an invalid mode
1350         $data['la_mode'] = 'INVALID';
1351
1352         // Is ext-sql_patches there and was it found in cache?
1353         if (!isExtensionActive('sql_patches')) {
1354                 // Not found, which is bad, so we need to allow all
1355                 $data['la_mode'] = 'global';
1356         } elseif (isset($GLOBALS['cache_array']['admin']['la_mode'][$adminId])) {
1357                 // Use cache
1358                 $data['la_mode'] = $GLOBALS['cache_array']['admin']['la_mode'][$adminId];
1359
1360                 // Update cache hits
1361                 incrementStatsEntry('cache_hits');
1362         } elseif (!isExtensionActive('cache')) {
1363                 // Load from database
1364                 $result_admin_id = sqlQueryEscaped("SELECT `la_mode` FROM `{?_MYSQL_PREFIX?}_admins` WHERE `id`=%s LIMIT 1",
1365                         array(bigintval($adminId)), __FUNCTION__, __LINE__);
1366
1367                 // Is there an entry?
1368                 if (sqlNumRows($result_admin_id) == 1) {
1369                         // Fetch data
1370                         $data = sqlFetchArray($result_admin_id);
1371
1372                         // Set cache
1373                         $GLOBALS['cache_array']['admin']['la_mode'][$adminId] = $data['la_mode'];
1374                 }
1375
1376                 // Free result
1377                 sqlFreeResult($result_admin_id);
1378         }
1379
1380         // Return default ACL
1381         return $data['la_mode'];
1382 }
1383
1384 // Generates an option list from various parameters
1385 function generateOptions ($table, $key, $value, $default = '', $extra = '', $whereStatement = '', $disabled = array(), $callback = '', $allowNone = FALSE) {
1386         $ret = '';
1387
1388         // Allow none?
1389         if ($allowNone === TRUE) {
1390                 // Add option for none
1391                 $ret .= '<option value="0">{--SELECT_NONE--}</option>';
1392         } // END - if
1393
1394         if ($table == '/ARRAY/') {
1395                 // Selection from array
1396                 if ((is_array($key)) && (is_array($value)) && ((count($key)) == (count($value)) || (!empty($callback)))) {
1397                         // Both are arrays
1398                         foreach ($key as $idx => $optionValue) {
1399                                 $ret .= '<option value="' . $optionValue . '"';
1400                                 if ($default == $optionValue) {
1401                                         // Selected by default
1402                                         $ret .= ' selected="selected"';
1403                                 } elseif (isset($disabled[$optionValue])) {
1404                                         // Disabled!
1405                                         $ret .= ' disabled="disabled"';
1406                                 }
1407
1408                                 // Is the call-back function set?
1409                                 if (!empty($callback)) {
1410                                         // Call it
1411                                         $value[$idx] = call_user_func_array($callback, array($key[$idx]));
1412                                 } // END - if
1413
1414                                 // Finish option tag
1415                                 $ret .= '>' . $value[$idx] . '</option>';
1416                         } // END - foreach
1417                 } else {
1418                         // Problem in request
1419                         reportBug(__FUNCTION__, __LINE__, 'Not all are arrays: key[' . count($key) . ']=' . gettype($key) . ',value[' . count($value) . ']=' . gettype($value) . ',callback=' . $callback);
1420                 }
1421         } else {
1422             ///////////////////////
1423                 // Data from database /
1424                 ///////////////////////
1425
1426                 // Init extra column (if requested)
1427                 $extraColumn = '';
1428                 if (!empty($extra)) {
1429                         $extraColumn = ',`' . $extra . '` AS `extra`';
1430                 } // END - if
1431
1432                 // Run SQL query
1433                 $result = sqlQueryEscaped("SELECT `%s` AS `key`, `%s` AS `value`" . $extraColumn . " FROM `{?_MYSQL_PREFIX?}_%s` " . $whereStatement . " ORDER BY `%s` ASC",
1434                         array(
1435                                 $key,
1436                                 $value,
1437                                 $table,
1438                                 $value
1439                         ), __FUNCTION__, __LINE__);
1440
1441                 // Is there rows?
1442                 if (!ifSqlHasZeroNums($result)) {
1443                         // Found data so add them as OPTION lines
1444                         while ($content = sqlFetchArray($result)) {
1445                                 // Is extra set?
1446                                 if (!isset($content['extra'])) {
1447                                         // Set it to empty
1448                                         $content['extra'] = '';
1449                                 } // END - if
1450
1451                                 $ret .= '<option value="' . $content['key'] . '"';
1452
1453                                 if ($default == $content['key']) {
1454                                         // Selected by default
1455                                         $ret .= ' selected="selected"';
1456                                 } elseif (isset($disabled[$content['key']])) {
1457                                         // Disabled!
1458                                         $ret .= ' disabled="disabled"';
1459                                 }
1460
1461                                 // Add it, if set
1462                                 if (!empty($content['extra'])) {
1463                                         $content['extra'] = ' (' . $content['extra'] . ')';
1464                                 } // END - if
1465
1466                                 // Is the call-back function set?
1467                                 if (!empty($callback)) {
1468                                         // Call it
1469                                         $content['value'] = call_user_func_array($callback, array($content['value']));
1470                                 } // END - if
1471
1472                                 // Finish option list
1473                                 $ret .= '>' . $content['value'] . $content['extra'] . '</option>';
1474                         } // END - while
1475                 } else {
1476                         // No data found
1477                         $ret = '<option value="x">{--SELECT_NONE--}</option>';
1478                 }
1479
1480                 // Free memory
1481                 sqlFreeResult($result);
1482         }
1483
1484         // Return - hopefully - the requested data
1485         return $ret;
1486 }
1487
1488 // Deletes a user account with given reason
1489 function deleteUserAccount ($userid, $reason) {
1490         // Init points
1491         $data['points'] = '0';
1492
1493         // Search for the points and user data
1494         $result = sqlQueryEscaped("SELECT
1495         (SUM(`p`.`points`) - `d`.`used_points`) AS `points`
1496 FROM
1497         `{?_MYSQL_PREFIX?}_user_points` AS `p`
1498 LEFT JOIN
1499         `{?_MYSQL_PREFIX?}_user_data` AS `d`
1500 ON
1501         `p`.`userid`=`d`.`userid`
1502 WHERE
1503         `p`.`userid`=%s
1504 LIMIT 1",
1505                 array(bigintval($userid)), __FUNCTION__, __LINE__);
1506
1507         // Is there an entry?
1508         if (sqlNumRows($result) == 1) {
1509                 // Save his points to add them to the jackpot
1510                 $data = sqlFetchArray($result);
1511
1512                 // Delete points entries as well
1513                 // @TODO Rewrite these lines to a filter
1514                 sqlQueryEscaped("DELETE LOW_PRIORITY FROM `{?_MYSQL_PREFIX?}_user_points` WHERE `userid`=%s",
1515                         array(bigintval($userid)), __FUNCTION__, __LINE__);
1516
1517                 // Update mediadata as well
1518                 if (isExtensionInstalledAndNewer('mediadata', '0.0.4')) {
1519                         // Update database
1520                         updateMediadataEntry(array('total_points'), 'sub', $data['points']);
1521                 } // END - if
1522
1523                 // Now, when we have all his points adds them do the jackpot!
1524                 if (isExtensionActive('jackpot')) {
1525                         addPointsToJackpot($data['points']);
1526                 } // END - if
1527         } // END - if
1528
1529         // Free the result
1530         sqlFreeResult($result);
1531
1532         // Delete category selections as well...
1533         sqlQueryEscaped("DELETE LOW_PRIORITY FROM `{?_MYSQL_PREFIX?}_user_cats` WHERE `userid`=%s",
1534                 array(bigintval($userid)), __FUNCTION__, __LINE__);
1535
1536         // Remove from rallye if found
1537         // @TODO Rewrite this to a filter
1538         if (isExtensionActive('rallye')) {
1539                 sqlQueryEscaped("DELETE LOW_PRIORITY FROM `{?_MYSQL_PREFIX?}_rallye_users` WHERE `userid`=%s",
1540                         array(bigintval($userid)), __FUNCTION__, __LINE__);
1541         } // END - if
1542
1543         // Add reason and translate points
1544         $data['text'] = $reason;
1545
1546         // Now a mail to the user and that's all...
1547         $message = loadEmailTemplate('member_user_deleted', $data, $userid);
1548         sendEmail($userid, '{--ADMIN_DELETE_ACCOUNT--}', $message);
1549
1550         // Ok, delete the account!
1551         sqlQueryEscaped("DELETE LOW_PRIORITY FROM `{?_MYSQL_PREFIX?}_user_data` WHERE `userid`=%s LIMIT 1", array(bigintval($userid)), __FUNCTION__, __LINE__);
1552 }
1553
1554 // Gets the matching what name from module
1555 function getWhatFromModule ($modCheck) {
1556         // Is the request element set?
1557         if (isGetRequestElementSet('what')) {
1558                 // Then return this!
1559                 return getRequestElement('what');
1560         } // END - if
1561
1562         // Default is empty
1563         $what = '';
1564
1565         // Check on given module
1566         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'modCheck=' . $modCheck);
1567         switch ($modCheck) {
1568                 case 'index': // Guest area
1569                         // Is ext-sql_patches installed and newer than 0.0.5?
1570                         if (isExtensionInstalledAndNewer('sql_patches', '0.0.5')) {
1571                                 // Use it from config
1572                                 $what = getIndexHome();
1573                         } else {
1574                                 // Use default 'welcome'
1575                                 $what = 'welcome';
1576                         }
1577                         break;
1578
1579                 default: // Default for all other menus (getIndexHome() is for index module only)
1580                         $what = 'welcome';
1581                         break;
1582         } // END - switch
1583
1584         // Return what value
1585         return $what;
1586 }
1587
1588 // Returns HTML code with an option list of all categories
1589 function generateCategoryOptionsList ($mode, $userid = NULL) {
1590         // Prepare WHERE statement
1591         $whereStatement = " WHERE `visible`='Y'";
1592         if (isAdmin()) $whereStatement = '';
1593
1594         // Initialize array...
1595         $categories = array(
1596                 'id'      => array(),
1597                 'name'    => array(),
1598                 'userids' => array()
1599         );
1600
1601         // Get categories
1602         $result = sqlQuery('SELECT
1603         `id`,
1604         `cat`
1605 FROM
1606         `{?_MYSQL_PREFIX?}_cats`
1607 ' . $whereStatement . '
1608 ORDER BY
1609         `sort` ASC',
1610                 __FUNCTION__, __LINE__);
1611
1612         // Are there entries?
1613         if (!ifSqlHasZeroNums($result)) {
1614                 // ... and begin loading stuff
1615                 while ($content = sqlFetchArray($result)) {
1616                         // Transfer some data
1617                         $categories['id'][]   = $content['id'];
1618                         array_push($categories['name'], $content['cat']);
1619
1620                         // Check which users are in this category
1621                         $result_userids = sqlQueryEscaped("SELECT `userid` FROM `{?_MYSQL_PREFIX?}_user_cats` WHERE `cat_id`=%s AND `userid` != %s ORDER BY `userid` ASC",
1622                                 array(
1623                                         bigintval($content['id']),
1624                                         convertNullToZero($userid)
1625                                 ), __FUNCTION__, __LINE__);
1626
1627                         // Init count
1628                         $userid_cnt = '0';
1629
1630                         // Start adding all
1631                         while ($data = sqlFetchArray($result_userids)) {
1632                                 // Add user count
1633                                 $userid_cnt += countSumTotalData($data['userid'], 'user_data', 'userid', 'userid', TRUE, runFilterChain('user_exclusion_sql', " AND `status`='CONFIRMED' AND `receive_mails` > 0"));
1634                         } // END - while
1635
1636                         // Free memory
1637                         sqlFreeResult($result_userids);
1638
1639                         // Add counter
1640                         array_push($categories['userids'], $userid_cnt);
1641                 } // END - while
1642
1643                 // Free memory
1644                 sqlFreeResult($result);
1645
1646                 // Generate options
1647                 $OUT = '';
1648                 foreach ($categories['id'] as $key => $value) {
1649                         $OUT .= '      <option value="' . $value . '">' . $categories['name'][$key] . ' (' . $categories['userids'][$key] . ' {--USERS_IN_CATEGORY--})</option>';
1650                 } // END - foreach
1651         } else {
1652                 // No cateogries are defined yet
1653                 $OUT = '<option class="bad">{--MEMBER_NO_CATEGORIES--}</option>';
1654         }
1655
1656         // Return HTML code
1657         return $OUT;
1658 }
1659
1660 // Add bonus mail to queue
1661 function addBonusMailToQueue ($subject, $text, $receiverList, $points, $seconds, $url, $categoryId, $mode='normal', $receiver=0) {
1662         // Is admin or bonus extension there?
1663         if (!isAdmin()) {
1664                 // Abort here
1665                 return FALSE;
1666         } elseif (!isExtensionActive('bonus')) {
1667                 // Abort here
1668                 return FALSE;
1669         }
1670
1671         // Calculcate target sent
1672         $target = countSelection(explode(';', $receiverList));
1673
1674         // Receiver is zero?
1675         if ($receiver == '0') {
1676                 // Then auto-fix it
1677                 $receiver = $target;
1678         } // END - if
1679
1680         // HTML extension active?
1681         if (isExtensionActive('html_mail')) {
1682                 // Add HTML mail
1683                 sqlQueryEscaped("INSERT INTO `{?_MYSQL_PREFIX?}_bonus` (
1684         `subject`,
1685         `text`,
1686         `receivers`,
1687         `points`,
1688         `time`,
1689         `data_type`,
1690         `timestamp`,
1691         `url`,
1692         `cat_id`,
1693         `target_send`,
1694         `mails_sent`,
1695         `html_msg`
1696 ) VALUES (
1697         '%s',
1698         '%s',
1699         '%s',
1700         %s,
1701         %s,
1702         'NEW',
1703         UNIX_TIMESTAMP(),
1704         '%s',
1705         %s,
1706         %s,
1707         %s,
1708         '%s'
1709 )",
1710                 array(
1711                         $subject,
1712                         $text,
1713                         $receiverList,
1714                         $points,
1715                         bigintval($seconds),
1716                         $url,
1717                         bigintval($categoryId),
1718                         $target,
1719                         bigintval($receiver),
1720                         convertBooleanToYesNo($mode == 'html')
1721                 ), __FUNCTION__, __LINE__);
1722         } else {
1723                 // Add regular mail
1724                 sqlQueryEscaped("INSERT INTO `{?_MYSQL_PREFIX?}_bonus` (
1725         `subject`,
1726         `text`,
1727         `receivers`,
1728         `points`,
1729         `time`,
1730         `data_type`,
1731         `timestamp`,
1732         `url`,
1733         `cat_id`,
1734         `target_send`,
1735         `mails_sent`
1736 ) VALUES (
1737         '%s',
1738         '%s',
1739         '%s',
1740         %s,
1741         %s,
1742         'NEW',
1743         UNIX_TIMESTAMP(),
1744         '%s',
1745         %s,
1746         %s,
1747         %s
1748 )",
1749                 array(
1750                         $subject,
1751                         $text,
1752                         $receiverList,
1753                         $points,
1754                         bigintval($seconds),
1755                         $url,
1756                         bigintval($categoryId),
1757                         $target,
1758                         bigintval($receiver),
1759                 ), __FUNCTION__, __LINE__);
1760         }
1761 }
1762
1763 // Generate a receiver list for given category and maximum receivers
1764 function generateReceiverList ($categoryId, $receiver, $mode = '') {
1765         // Init variables
1766         $extraColumns = '';
1767         $receiverList = '';
1768         $result       = FALSE;
1769
1770         // Secure data
1771         $categoryId = bigintval($categoryId);
1772         $receiver   = bigintval($receiver);
1773
1774         // Is the receiver zero and mode set?
1775         if (($receiver == '0') && (!empty($mode))) {
1776                 // Auto-fix receiver maximum
1777                 $receiver = getTotalReceivers($mode);
1778         } // END - if
1779
1780         // Exclude (maybe exclude) testers
1781         $addWhere = runFilterChain('user_exclusion_sql', ' ');
1782
1783         // Category given?
1784         if (isValidId($categoryId)) {
1785                 // Select category
1786                 $extraColumns  = "LEFT JOIN `{?_MYSQL_PREFIX?}_user_cats` AS `c` ON `d`.`userid`=`c`.`userid`";
1787                 $addWhere = sprintf(' AND `c`.`cat_id`=%s', $categoryId);
1788         } // END - if
1789
1790         // Exclude users in holiday?
1791         if (isExtensionInstalledAndNewer('holiday', '0.1.3')) {
1792                 // Add something for the holiday extension
1793                 $addWhere .= " AND `d`.`holiday_active`='N'";
1794         } // END - if
1795
1796         // Run query
1797         $result = sqlQueryEscaped("SELECT
1798         `d`.`userid`
1799 FROM
1800         `{?_MYSQL_PREFIX?}_user_data` AS `d`
1801         " . $extraColumns . "
1802 WHERE
1803         `d`.`status`='CONFIRMED'
1804         " . $addWhere . "
1805 ORDER BY
1806         `d`.`{?order_select?}` {?order_mode?}
1807 LIMIT %s",
1808                 array(
1809                         $receiver
1810                 ), __FUNCTION__, __LINE__);
1811
1812         // Entries found?
1813         if ((sqlNumRows($result) >= $receiver) && ($receiver > 0)) {
1814                 // Load all entries
1815                 while ($content = sqlFetchArray($result)) {
1816                         // Add receiver when not empty
1817                         if (!empty($content['userid'])) {
1818                                 $receiverList .= $content['userid'] . ';';
1819                         } // END - if
1820                 } // END - while
1821
1822                 // Free memory
1823                 sqlFreeResult($result);
1824
1825                 // Remove trailing semicolon
1826                 $receiverList = substr($receiverList, 0, -1);
1827         } // END - if
1828
1829         // Return list
1830         return $receiverList;
1831 }
1832
1833 // Recuce the amount of received emails for the receipients for given email
1834 function reduceRecipientReceivedMails ($column, $id, $count) {
1835         // Search for mail in database
1836         $result = sqlQueryEscaped("SELECT * FROM `{?_MYSQL_PREFIX?}_user_links` WHERE `%s`=%s ORDER BY `userid` ASC LIMIT %s",
1837                 array(
1838                         $column,
1839                         bigintval($id),
1840                         $count
1841                 ), __FUNCTION__, __LINE__
1842         );
1843
1844         // Are there entries?
1845         if (!ifSqlHasZeroNums($result)) {
1846                 // Now load all userids for one big query!
1847                 $userids = array();
1848                 while ($data = sqlFetchArray($result)) {
1849                         // By default reduce and found no emails
1850                         $num = 0;
1851
1852                         // We must now look if he has already confirmed this mail, so might sound double, but it may resolve problems
1853                         // @TODO Rewrite this to a filter
1854                         if ((isset($data['stats_id'])) && (isValidId($data['stats_id']))) {
1855                                 // User email
1856                                 $num = countSumTotalData($data['userid'], 'user_stats_data', 'id', 'userid', TRUE, sprintf(" AND `stats_type`='mailid' AND `stats_data`=%s", bigintval($data['stats_id'])));
1857                         } elseif ((isset($data['bonus_id'])) && (isValidId($data['bonus_id']))) {
1858                                 // Bonus mail
1859                                 $num = countSumTotalData($data['userid'], 'user_stats_data', 'id', 'userid', TRUE, sprintf(" AND `stats_type`='bonusid' AND `stats_data`=%s", bigintval($data['bonus_id'])));
1860                         }
1861
1862                         // Reduce this users total received emails?
1863                         if ($num === 0) {
1864                                 $userids[$data['userid']] = $data['userid'];
1865                         } // END - if
1866                 } // END - while
1867
1868                 if (isFilledArray($userids)) {
1869                         // Now update all user accounts
1870                         sqlQueryEscaped("UPDATE `{?_MYSQL_PREFIX?}_user_data` SET `emails_received`=`emails_received`-1 WHERE `userid` IN (%s) LIMIT %s",
1871                                 array(
1872                                         implode(',', $userids),
1873                                         count($userids)
1874                                 ), __FUNCTION__, __LINE__);
1875                 } else {
1876                         // Nothing deleted
1877                         displayMessage('{%message,ADMIN_MAIL_NOTHING_DELETED=' . $id . '%}');
1878                 }
1879         } // END - if
1880
1881         // Free result
1882         sqlFreeResult($result);
1883 }
1884
1885 // Creates a new task
1886 function createNewTask ($subject, $notes, $taskType, $userid = NULL, $adminId = NULL, $strip = TRUE) {
1887         // Insert the task data into the database
1888         sqlQueryEscaped("INSERT INTO `{?_MYSQL_PREFIX?}_task_system` (`assigned_admin`, `userid`, `status`, `task_type`, `subject`, `text`, `task_created`) VALUES (%s, %s, 'NEW', '%s', '%s', '%s', UNIX_TIMESTAMP())",
1889                 array(
1890                         convertZeroToNull($adminId),
1891                         convertZeroToNull($userid),
1892                         $taskType,
1893                         $subject,
1894                         $notes
1895                 ), __FUNCTION__, __LINE__, TRUE, $strip);
1896
1897         // Return insert id which is the task id
1898         return getSqlInsertId();
1899 }
1900
1901 // Updates last module / online time
1902 function updateLastActivity ($userid) {
1903         // Is 'what' set?
1904         if (isWhatSet()) {
1905                 // Run the update query
1906                 sqlQueryEscaped("UPDATE
1907         `{?_MYSQL_PREFIX?}_user_data`
1908 SET
1909         `{%%pipe,getUserLastWhatName%%}`='{%%pipe,getWhat%%}',
1910         `last_online`=UNIX_TIMESTAMP(),
1911         `REMOTE_ADDR`='{%%pipe,detectRemoteAddr%%}'
1912 WHERE
1913         `userid`=%s
1914 LIMIT 1",
1915                 array(
1916                         bigintval($userid)
1917                 ), __FUNCTION__, __LINE__);
1918         } else {
1919                 // No what set, needs to be ignored (last_module is last_what)
1920                 sqlQueryEscaped("UPDATE
1921         `{?_MYSQL_PREFIX?}_user_data`
1922 SET
1923         `{%%pipe,getUserLastWhatName%%}`=NULL,
1924         `last_online`=UNIX_TIMESTAMP(),
1925         `REMOTE_ADDR`='{%%pipe,detectRemoteAddr%%}'
1926 WHERE
1927         `userid`=%s
1928 LIMIT 1",
1929                 array(
1930                         bigintval($userid)
1931                 ), __FUNCTION__, __LINE__);
1932         }
1933 }
1934
1935 // List all given joined rows (callback function from XML)
1936 function doGenericJoinedListEntries ($tableTemplate, $rowTemplate, $noEntryMessageId, $tableName, $tableJoinType, $tableJoinName, $joinOnLeftTable, $joinOnCondition, $joinOnRightTable, $columns, $whereColumns, $orderByColumns, $callbackColumns, $extraParameters = array(), $conditions = array(), $content = array()) {
1937         // Verify that tableName and columns are not empty
1938         if ((!is_array($tableName)) || (count($tableName) != 1)) {
1939                 // No tableName specified
1940                 reportBug(__FUNCTION__, __LINE__, 'tableName is not given. Please fix your XML,tableName[]=' . gettype($tableName) . '!=array,tableTemplate=' . $tableTemplate . ',rowTemplate=' . $rowTemplate);
1941         } elseif (!isFilledArray($columns)) {
1942                 // No columns specified
1943                 reportBug(__FUNCTION__, __LINE__, 'columns is not given. Please fix your XML,tableTemplate=' . $tableTemplate . ',rowTemplate=' . $rowTemplate . ',tableName[0]=' . $tableName[0]);
1944         }
1945
1946         // This is the minimum query, so at least columns and tableName must have entries
1947         $sql = 'SELECT ';
1948
1949         // Get the sql part back from given array
1950         $sql .= getSqlPartFromXmlArray($columns);
1951
1952         // Add "FROM"
1953         $sql .= getSqlXmlFromTable($tableName);
1954
1955         // Add "JOIN"
1956         $sql .= getSqlXmlJoinedTable($tableJoinType, $tableJoinName, $joinOnLeftTable, $joinOnCondition, $joinOnRightTable);
1957
1958         // Add "WHERE"
1959         $sql .= getSqlXmlWhereConditions($whereColumns, $conditions);
1960
1961         // Add "ORDER BY"
1962         $sql .= getSqlXmlOrderBy($orderByColumns);
1963
1964         // Now handle all over to the inner function which will execute the listing
1965         doListEntries($sql, $tableTemplate, $noEntryMessageId, $rowTemplate, $callbackColumns, $extraParameters, $content);
1966 }
1967
1968 // List all given rows (callback function from XML)
1969 function doGenericListEntries ($tableTemplate, $rowTemplate, $noEntryMessageId, $tableName, $columns, $whereColumns, $orderByColumns, $callbackColumns, $extraParameters = array(), $conditions = array(), $content = array()) {
1970         // Verify that tableName and columns are not empty
1971         if ((!is_array($tableName)) || (count($tableName) != 1)) {
1972                 // No tableName specified
1973                 reportBug(__FUNCTION__, __LINE__, 'tableName is not given. Please fix your XML,tableName[]=' . gettype($tableName) . '!=array,tableTemplate=' . $tableTemplate . ',rowTemplate=' . $rowTemplate);
1974         } elseif (!isFilledArray($columns)) {
1975                 // No columns specified
1976                 reportBug(__FUNCTION__, __LINE__, 'columns is not given. Please fix your XML,tableTemplate=' . $tableTemplate . ',rowTemplate=' . $rowTemplate . ',tableName[0]=' . $tableName[0]);
1977         }
1978
1979         // This is the minimum query, so at least columns and tableName must have entries
1980         $sql = 'SELECT ';
1981
1982         // Get the sql part back from given array
1983         $sql .= getSqlPartFromXmlArray($columns);
1984
1985         // Add "FROM"
1986         $sql .= getSqlXmlFromTable($tableName);
1987
1988         // Add "WHERE"
1989         $sql .= getSqlXmlWhereConditions($whereColumns, $conditions);
1990
1991         // Add "ORDER BY"
1992         $sql .= getSqlXmlOrderBy($orderByColumns);
1993
1994         // Now handle all over to the inner function which will execute the listing
1995         doListEntries($sql, $tableTemplate, $noEntryMessageId, $rowTemplate, $callbackColumns, $extraParameters, $content);
1996 }
1997
1998 // Do the listing of entries
1999 function doListEntries ($sql, $tableTemplate, $noEntryMessageId, $rowTemplate, $callbackColumns, $extraParameters = array(), $content = array()) {
2000         // Run the SQL query
2001         $result = sqlQuery($sql, __FUNCTION__, __LINE__);
2002
2003         // Are there some URLs left?
2004         if (!ifSqlHasZeroNums($result)) {
2005                 // List all URLs
2006                 $OUT = '';
2007                 while ($row = sqlFetchArray($result)) {
2008                         // "Translate" content
2009                         foreach ($callbackColumns as $columnName => $callbackName) {
2010                                 // Fill the callback arguments
2011                                 $args = array($row[$columnName]);
2012
2013                                 // Is there more to add?
2014                                 if (isset($extraParameters[$columnName])) {
2015                                         // Add them as well
2016                                         $args = merge_array($args, $extraParameters[$columnName]);
2017                                 } // END - if
2018
2019                                 // Call the callback-function
2020                                 //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'callbackFunction=' . $callbackName . ',args=<pre>'.print_r($args, TRUE).'</pre>');
2021                                 // @TODO If the EL sub-system can support more than one parameter, this call_user_func_array() can be avoided
2022                                 $row[$columnName] = call_user_func_array($callbackName, $args);
2023                         } // END - foreach
2024
2025                         // Load row template
2026                         $OUT .= loadTemplate(trim($rowTemplate[0]), TRUE, $row);
2027                 } // END - while
2028
2029                 // Is at least one entry set in content?
2030                 if (isFilledArray($content)) {
2031                         // Then add generic 'rows' element
2032                         $content['rows'] = $OUT;
2033                 } else {
2034                         // Direct output is content
2035                         $content = $OUT;
2036                 }
2037
2038                 // Load main template
2039                 loadTemplate(trim($tableTemplate[0]), FALSE, $content);
2040         } else {
2041                 // No URLs in surfbar
2042                 displayMessage('{--' .$noEntryMessageId[0] . '--}');
2043         }
2044
2045         // Free result
2046         sqlFreeResult($result);
2047 }
2048
2049 // Adds a given entry to the database
2050 function doGenericAddEntries ($tableName, $columns = array(), $filterFunctions = array(), $extraValues = array(), $timeColumns = array(), $columnIndex = NULL) {
2051         //* DEBUG: */ die(__FUNCTION__.':columns=<pre>'.print_r($columns,TRUE).'</pre>,filterFunctions=<pre>'.print_r($filterFunctions,TRUE).'</pre>,extraValues=<pre>'.print_r($extraValues,TRUE).'</pre>,timeColumns=<pre>'.print_r($timeColumns,TRUE).'</pre>,columnIndex=<pre>'.print_r($columnIndex,TRUE).'</pre>,POST=<pre>'.print_r($_POST,TRUE).'</pre>');
2052         // Verify that tableName and columns are not empty
2053         if ((!is_array($tableName)) || (count($tableName) != 1)) {
2054                 // No tableName specified
2055                 reportBug(__FUNCTION__, __LINE__, 'tableName is not given. Please fix your XML,tableName[]=' . gettype($tableName) . '!=array: userIdColumn=' . $userIdColumn);
2056         } elseif (!isFilledArray($columns)) {
2057                 // No columns specified
2058                 reportBug(__FUNCTION__, __LINE__, 'columns is not given. Please fix your XML.');
2059         }
2060
2061         // Init columns and value elements
2062         $sqlColumns = array();
2063         $sqlValues  = array();
2064
2065         // Default is that all went fine
2066         $GLOBALS['__XML_PARSE_RESULT'] = TRUE;
2067
2068         // Is there "time columns"?
2069         if (isFilledArray($timeColumns)) {
2070                 // Then "walk" through all entries
2071                 foreach ($timeColumns as $column) {
2072                         // Convert all (possible) selections
2073                         convertSelectionsToEpocheTimeInPostData($column . '_ye');
2074                 } // END - foreach
2075         } // END - if
2076
2077         // Add columns and values
2078         foreach ($columns as $key => $columnName) {
2079                 //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',columnName=' . $columnName);
2080                 // Is columnIndex set?
2081                 if (!is_null($columnIndex)) {
2082                         // Check conditions
2083                         //* DEBUG: */ die('columnName=<pre>'.print_r($columnName,TRUE).'</pre>columnIndex=<pre>'.print_r($columnIndex,TRUE).'</pre>'.debug_get_printable_backtrace());
2084                         assert((is_array($columnName)) && (is_string($columnIndex)) && (isset($columnName[$columnIndex])));
2085
2086                         // Then use that index "blindly"
2087                         $columnName = $columnName[$columnIndex];
2088                 } // END - if
2089
2090                 // Debug message
2091                 //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',columnName[' . gettype($columnName) . ']=' . $columnName . ',filterFunctions=' . $filterFunctions[$key] . ',extraValues=' . intval(isset($extraValues[$key])) . ',extraValuesName=' . intval(isset($extraValues[$columnName . '_list'])));
2092
2093                 // Get value back (no array supported)
2094                 $value = postRequestElement($columnName);
2095
2096                 // Is this an array and element 0 is set?
2097                 if ((is_array($value)) && (isset($value[0]))) {
2098                         // Then only take this
2099                         $value = $value[0];
2100                 } // END - if
2101
2102                 // Copy entry securely to the final arrays
2103                 $sqlColumns[$key] = sqlEscapeString($columnName);
2104                 $sqlValues[$key]  = sqlEscapeString($value);
2105
2106                 // Search for it
2107                 $search = key(search_array($columns, 'column', $columnName));
2108
2109                 // Try to handle call-back functions and/or extra values on the list
2110                 //* DEBUG: */ outputHtml($key . '/' . $columnName . '=<pre>'.print_r($columns,true).'</pre>search_array()=<pre>'.print_r(search_array($columns, 'column', $columnName), TRUE).'</pre>');
2111                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'sqlValues[' . $key . '(' . gettype($key) . ')][' . gettype($sqlValues[$key]) . ']=' . $sqlValues[$key] . ' - BEFORE!');
2112                 if (is_string($key)) {
2113                         // Key is a string
2114                         $sqlValues[$key] = doHandleExtraValues($filterFunctions, $extraValues, $key . '_list', $sqlValues[$key], array(''), $search);
2115                 } else {
2116                         // Is a number
2117                         $sqlValues[$key] = doHandleExtraValues($filterFunctions, $extraValues, $key, $sqlValues[$key], array(''), $search);
2118                 }
2119
2120                 // Is the value not a number?
2121                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'sqlValues[' . $key . '(' . gettype($key) . ')][' . gettype($sqlValues[$key]) . ']=' . $sqlValues[$key] . ' - AFTER!');
2122                 if (($sqlValues[$key] != 'NULL') && (is_string($sqlValues[$key]))) {
2123                         // Add quotes around it
2124                         $sqlValues[$key] = chr(39) . $sqlValues[$key] . chr(39);
2125                 } // END - if
2126
2127                 // Is the value false?
2128                 if ($sqlValues[$key] === FALSE) {
2129                         // One "parser" didn't like it
2130                         $GLOBALS['__XML_PARSE_RESULT'] = FALSE;
2131                         break;
2132                 } // END - if
2133         } // END - foreach
2134
2135         // If all values are okay, continue
2136         if ($sqlValues[$key] !== FALSE) {
2137                 // Build the SQL query
2138                 $sql = 'INSERT INTO `{?_MYSQL_PREFIX?}_' . $tableName[0] . '` (`' . implode('`, `', $sqlColumns) . "`) VALUES (" . implode(',', $sqlValues) . ')';
2139
2140                 // Run the SQL query
2141                 sqlQuery($sql, __FUNCTION__, __LINE__);
2142
2143                 // Add id number
2144                 setPostRequestElement('id', getSqlInsertId());
2145
2146                 // Prepare filter data array
2147                 $filterData = array(
2148                         'mode'          => 'add',
2149                         'table_name'    => $tableName,
2150                         'content'       => postRequestArray(),
2151                         'id'            => getSqlInsertId(),
2152                         'subject'       => '',
2153                         // @TODO Used generic 'userid' here
2154                         'userid_column' => array('userid'),
2155                         'raw_userid'    => array('userid'),
2156                         'affected'      => sqlAffectedRows(),
2157                         'sql'           => $sql,
2158                 );
2159
2160                 // Send "build mail" out
2161                 runFilterChain('send_build_mail', $filterData);
2162         } // END - if
2163 }
2164
2165 // Edit rows by given id numbers
2166 function doGenericEditEntriesConfirm ($tableName, $columns = array(), $filterFunctions = array(), $extraValues = array(), $timeColumns = array(), $editNow = array(FALSE), $idColumn = array('id'), $userIdColumn = array('userid'), $rawUserId = array('userid'), $cacheFiles = array(), $subject = '') {
2167         // Is there "time columns"?
2168         if (isFilledArray($timeColumns)) {
2169                 // Then "walk" through all entries
2170                 foreach ($timeColumns as $column) {
2171                         // Convert all (possible) selections
2172                         convertSelectionsToEpocheTimeInPostData($column . '_ye');
2173                 } // END - foreach
2174         } // END - if
2175
2176         // Change them all
2177         $affected = '0';
2178         foreach (postRequestElement($idColumn[0]) as $id => $sel) {
2179                 // Secure id number
2180                 $id = bigintval($id);
2181
2182                 // Prepare content array (new values)
2183                 $content = array();
2184
2185                 // Prepare SQL for this row
2186                 $sql = sprintf('UPDATE `{?_MYSQL_PREFIX?}_%s` SET',
2187                         sqlEscapeString($tableName[0])
2188                 );
2189
2190                 // "Walk" through all entries
2191                 foreach (postRequestArray() as $key => $entries) {
2192                         // Skip raw userid which is always invalid
2193                         if (($key == $rawUserId[0]) || ($key == ($rawUserId[0] . '_raw')) || ($key == 'do_edit')) {
2194                                 // Continue with next field
2195                                 //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',idColumn[0]=' . $idColumn[0] . ',rawUserId=' . $rawUserId[0]);
2196                                 continue;
2197                         } // END - if
2198
2199                         // Debug message
2200                         //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',id=' . $id . ',idColumn[0]=' . $idColumn[0] . ',entries=<pre>'.print_r($entries,TRUE).'</pre>');
2201
2202                         // Is entries an array?
2203                         if (($key != $idColumn[0]) && (is_array($entries)) && (isset($entries[$id]))) {
2204                                 // Search for the right array index
2205                                 $search = key(search_array($columns, 'column', $key));
2206
2207                                 // Add this entry to content
2208                                 $content[$key] = $entries[$id];
2209
2210                                 // Debug message
2211                                 //* BUG: */ die($key.'/'.$id.'/'.$search.'=<pre>'.print_r($columns,TRUE).'</pre><pre>'.print_r($filterFunctions,TRUE).'</pre>');
2212
2213                                 // Handle possible call-back functions and/or extra values
2214                                 $entries[$id] = doHandleExtraValues($filterFunctions, $extraValues, $key, $entries[$id], $userIdColumn, $search);
2215
2216                                 // Add key/value pair to SQL string
2217                                 $sql .= addKeyValueSql($key, $entries[$id]);
2218                         } elseif (($key != $idColumn[0]) && (!is_array($entries))) {
2219                                 // Search for it
2220                                 $search = key(search_array($columns, 'column', $key));
2221                                 //* BUG: */ die($key.'/<pre>'.print_r($search, TRUE).'</pre>=<pre>'.print_r($columns, TRUE).'</pre>');
2222
2223                                 // Debug message
2224                                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',entries[' . gettype($entries) . ']=' . $entries . ',search=' . $search . ' - BEFORE!');
2225
2226                                 // Add normal entries as well
2227                                 $content[$key] = $entries;
2228
2229                                 // Handle possible call-back functions and/or extra values
2230                                 $entries = doHandleExtraValues($filterFunctions, $extraValues, $key, $entries, $userIdColumn, $search);
2231
2232                                 // Debug message
2233                                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',entries[' . gettype($entries) . ']=' . $entries . ',search=' . $search . ' - AFTER!');
2234
2235                                 // Add key/value pair to SQL string
2236                                 $sql .= addKeyValueSql($key, $entries);
2237                         }
2238                 } // END - foreach
2239
2240                 // Finish SQL command
2241                 $sql = substr($sql, 0, -1) . " WHERE `" . sqlEscapeString($idColumn[0]) . "`=" . $id;
2242                 if ((isset($rawUserId[0])) && (isset($userIdColumn[0])) && (isPostRequestElementSet($rawUserId[0])) && (!is_array(postRequestElement($rawUserId[0])))) {
2243                         // Add user id as well
2244                         $sql .= ' AND `' . $userIdColumn[0] . '`=' . bigintval(postRequestElement($rawUserId[0]));
2245                 } // END - if
2246                 $sql .= " LIMIT 1";
2247
2248                 // Run this query
2249                 //* BUG: */ die($sql.'<pre>'.print_r(postRequestArray(), TRUE).'</pre>');
2250                 sqlQuery($sql, __FUNCTION__, __LINE__);
2251
2252                 // Add affected rows
2253                 $edited = sqlAffectedRows();
2254                 $affected += $edited;
2255
2256                 // Load all data from that id
2257                 $result = sqlQueryEscaped("SELECT * FROM `{?_MYSQL_PREFIX?}_%s` WHERE `%s`=%s LIMIT 1",
2258                         array(
2259                                 $tableName[0],
2260                                 $idColumn[0],
2261                                 $id
2262                         ), __FUNCTION__, __LINE__);
2263
2264                 // Fetch the data and merge it into $content
2265                 $content = merge_array($content, sqlFetchArray($result));
2266
2267                 // Prepare filter data array
2268                 $filterData = array(
2269                         'mode'          => 'edit',
2270                         'table_name'    => $tableName,
2271                         'content'       => $content,
2272                         'id'            => $id,
2273                         'subject'       => $subject,
2274                         'userid_column' => $userIdColumn,
2275                         'raw_userid'    => $rawUserId,
2276                         'affected'      => $edited,
2277                         'sql'           => $sql,
2278                 );
2279
2280                 // Send "build mail" out
2281                 runFilterChain('send_build_mail', $filterData);
2282
2283                 // Free the result
2284                 sqlFreeResult($result);
2285         } // END - foreach
2286
2287         // Delete cache?
2288         if ((isFilledArray($cacheFiles)) && (!empty($cacheFiles[0]))) {
2289                 // Delete cache file(s)
2290                 foreach ($cacheFiles as $cache) {
2291                         // Skip any empty entries
2292                         if (empty($cache)) {
2293                                 // This may cause trouble in loadCacheFile()
2294                                 continue;
2295                         } // END - if
2296
2297                         // Use rebuildCache() to delete it
2298                         rebuildCache($cache);
2299                 } // END - foreach
2300         } // END - if
2301
2302         // Return affected rows
2303         return $affected;
2304 }
2305
2306 // Delete rows by given id numbers
2307 function doGenericDeleteEntriesConfirm ($tableName, $columns = array(), $filterFunctions = array(), $extraValues = array(), $deleteNow = array(FALSE), $idColumn = array('id'), $userIdColumn = array('userid'), $rawUserId = array('userid'), $cacheFiles = array()) {
2308         // The base SQL command:
2309         $sql = "DELETE LOW_PRIORITY FROM `{?_MYSQL_PREFIX?}_%s` WHERE `%s` IN (%s)";
2310
2311         // Is a user id provided?
2312         //* BUG: */ die('<pre>'.print_r($rawUserId,TRUE).'</pre><pre>'.print_r($userIdColumn,TRUE).'</pre>');
2313         if ((isset($rawUserId[0])) && (isset($userIdColumn[0])) && (isPostRequestElementSet($rawUserId[0])) && (!is_array(postRequestElement($rawUserId[0])))) {
2314                 // Add user id as well
2315                 $sql .= ' AND `' . $userIdColumn[0] . '`=' . bigintval(postRequestElement($rawUserId[0]));
2316         } // END - if
2317
2318         // $idColumn[0] in POST must be an array again
2319         if (!is_array(postRequestElement($idColumn[0]))) {
2320                 // This indicates that you have conflicting form field naming with XML names
2321                 reportBug(__FUNCTION__, __LINE__, 'You have a wrong form field element, idColumn[0]=' . $idColumn[0]);
2322         } // END - if
2323
2324         // Delete them all
2325         //* BUG: */ die($sql.'<pre>'.print_r($tableName,TRUE).'</pre><pre>'.print_r($columns,TRUE).'</pre><pre>'.print_r($filterFunctions,TRUE).'</pre><pre>'.print_r($extraValues,TRUE).'</pre><pre>'.print_r($deleteNow,TRUE).'</pre><pre>'.print_r($idColumn,TRUE).'</pre>');
2326         $idList = '';
2327         foreach (postRequestElement($idColumn[0]) as $id => $sel) {
2328                 // Is id zero?
2329                 if (!isValidId($id)) {
2330                         // Then skip this
2331                         continue;
2332                 } // END - if
2333
2334                 // Is there a userid?
2335                 if (isPostRequestElementSet($userIdColumn[0])) {
2336                         // Load all data from that id
2337                         $result = sqlQueryEscaped("SELECT * FROM `{?_MYSQL_PREFIX?}_%s` WHERE `%s`=%s LIMIT 1",
2338                                 array(
2339                                         $tableName[0],
2340                                         $idColumn[0],
2341                                         $id
2342                                 ), __FUNCTION__, __LINE__);
2343
2344                         // Fetch the data
2345                         $content = sqlFetchArray($result);
2346
2347                         // Free the result
2348                         sqlFreeResult($result);
2349
2350                         // Send "build mails" out
2351                         sendGenericBuildMails('delete', $tableName, $content, $id, '', $userIdColumn);
2352                 } // END - if
2353
2354                 // Add id number
2355                 $idList .= $id . ',';
2356         } // END - foreach
2357
2358         // Run the query
2359         sqlQueryEscaped($sql,
2360                 array(
2361                         $tableName[0],
2362                         $idColumn[0],
2363                         convertNullToZero(substr($idList, 0, -1))
2364                 ), __FUNCTION__, __LINE__);
2365
2366         // Return affected rows
2367         return sqlAffectedRows();
2368 }
2369
2370 // Build a special template list
2371 // @TODO cacheFiles is not yet supported
2372 function doGenericListBuilder ($prefix, $listType, $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn, $rawUserId = array('userid'), $content = array()) {
2373         // $tableName and $idColumn must bove be arrays!
2374         if ((!is_array($tableName)) || (count($tableName) != 1)) {
2375                 // $tableName is no array
2376                 reportBug(__FUNCTION__, __LINE__, 'tableName[]=' . gettype($tableName) . '!=array: userIdColumn=' . $userIdColumn);
2377         } elseif (!is_array($idColumn)) {
2378                 // $idColumn is no array
2379                 reportBug(__FUNCTION__, __LINE__, 'idColumn[]=' . gettype($idColumn) . '!=array: userIdColumn=' . $userIdColumn);
2380         } elseif ((!is_array($userIdColumn)) || (count($userIdColumn) != 1)) {
2381                 // $tableName is no array
2382                 reportBug(__FUNCTION__, __LINE__, 'userIdColumn[]=' . gettype($userIdColumn) . '!=array: userIdColumn=' . $userIdColumn);
2383         }
2384
2385         // Init row output
2386         $OUT = '';
2387
2388         // "Walk" through all entries
2389         //* DEBUG: */ reportBug(__FUNCTION__, __LINE__, 'listType=<pre>'.print_r($listType,TRUE).'</pre>,tableName<pre>'.print_r($tableName,TRUE).'</pre>,columns=<pre>'.print_r($columns,TRUE).'</pre>,filterFunctions=<pre>'.print_r($filterFunctions,TRUE).'</pre>,extraValues=<pre>'.print_r($extraValues,TRUE).'</pre>,idColumn=<pre>'.print_r($idColumn,TRUE).'</pre>,userIdColumn=<pre>'.print_r($userIdColumn,TRUE).'</pre>,rawUserId=<pre>'.print_r($rawUserId,TRUE).'</pre>');
2390         foreach (postRequestElement($idColumn[0]) as $id => $selected) {
2391                 // Secure id number
2392                 $id = bigintval($id);
2393
2394                 // Get result from a given column array and table name
2395                 $result = getSqlResultFromArray($tableName[0], $columns, $idColumn[0], $id, __FUNCTION__, __LINE__);
2396
2397                 // Is there one entry?
2398                 if (sqlNumRows($result) == 1) {
2399                         // Load all data
2400                         $row = sqlFetchArray($result);
2401
2402                         // Filter all data
2403                         foreach ($row as $key => $value) {
2404                                 // Search index
2405                                 $idx  = searchXmlArray($key, $columns, 'column');
2406
2407                                 // Default name is NULL
2408                                 $name = NULL;
2409
2410                                 // Is the name there?
2411                                 if (isset($columns[$idx]['name'])) {
2412                                         // Then use it
2413                                         $name = $columns[$idx]['name'];
2414                                 } // END - if
2415
2416                                 // Skip any missing entries
2417                                 if ($idx === FALSE) {
2418                                         // Skip this one
2419                                         //* DEBUG: */ reportBug(__FUNCTION__, __LINE__, 'key=' . $key . ' - SKIPPED!');
2420                                         continue;
2421                                 } // END - if
2422
2423                                 // Is there a userid?
2424                                 //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',userIdColumn=' . $userIdColumn[0]);
2425                                 if ($key == $userIdColumn[0]) {
2426                                         // Add it again as raw id
2427                                         //* DEBUG: */ reportBug(__FUNCTION__, __LINE__, 'key=' . $key . ',userIdColumn=' . $userIdColumn[0]);
2428                                         $row[$userIdColumn[0]] = convertZeroToNull($value);
2429                                         $row[$userIdColumn[0] . '_raw'] = $row[$userIdColumn[0]];
2430                                 } // END - if
2431
2432                                 // If the key matches the idColumn variable, we need to temporary remember it
2433                                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',idColumn=' . $idColumn[0] . ',value=' . $value);
2434                                 if ($key == $idColumn[0]) {
2435                                         /*
2436                                          * Found, so remember it securely (to make sure only id
2437                                          * numbers can pass, don't use alpha-numerical values!)
2438                                          */
2439                                         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'value=' . $value . ' - set as ' . $prefix . '_list_builder_id_value!');
2440                                         $GLOBALS[$prefix . '_list_builder_id_value'] = bigintval($value);
2441                                 } // END - if
2442
2443                                 // Try to handle call-back functions and/or extra values
2444                                 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'idx=' . $idx . ',row[' . $key . ']=' . $row[$key]);
2445                                 //if ($key == 'forced_campaign_created') die($idx.'=<pre>'.print_r($columns,true).'</pre><pre>'.print_r($extraValues,true).'</pre>');
2446                                 $row[$key] = doHandleExtraValues($filterFunctions, $extraValues, $idx, $row[$key], $userIdColumn, ((!is_null($name)) ? $name : $key), $id);
2447                         } // END - foreach
2448
2449                         // Then list it
2450                         $OUT .= loadTemplate(sprintf('%s_%s_%s_row',
2451                                 $prefix,
2452                                 $listType,
2453                                 $tableName[0]
2454                                 ), TRUE, $row
2455                         );
2456                 } // END - if
2457
2458                 // Free the result
2459                 sqlFreeResult($result);
2460         } // END - foreach
2461
2462         // Is there an entry in $content?
2463         if (isFilledArray($content)) {
2464                 // Use generic 'rows'
2465                 $content['rows'] = $OUT;
2466         } else {
2467                 // Use direct output
2468                 $content = $OUT;
2469         }
2470
2471         // Load master template
2472         loadTemplate(
2473                 sprintf('%s_%s_%s',
2474                         $prefix,
2475                         $listType,
2476                         $tableName[0]
2477                 ), FALSE, $content
2478         );
2479 }
2480
2481 // Adds key/value pair to a working SQL string together
2482 function addKeyValueSql ($key, $value) {
2483         // Init SQL
2484         $sql = '';
2485
2486         // Is it NULL?
2487         if (($value == 'NULL') || (is_null($value))) {
2488                 // Add key with NULL
2489                 $sql .= sprintf(' `%s`=NULL,',
2490                         sqlEscapeString($key)
2491                 );
2492         } elseif ((is_double($value)) || (is_float($value)) || (is_int($value))) {
2493                 // Is a number, so addd it directly
2494                 $sql .= sprintf(' `%s`=%s,',
2495                         sqlEscapeString($key),
2496                         $value
2497                 );
2498         } else {
2499                 // Else add the value escape'd
2500                 $sql .= sprintf(" `%s`='%s',",
2501                         sqlEscapeString($key),
2502                         sqlEscapeString($value)
2503                 );
2504         }
2505
2506         // Return SQL string
2507         return $sql;
2508 }
2509
2510 // "Getter" for an array from given table and columns
2511 function getArrayFromTable ($tableName, $columns, $orderBy, $ordered = 'ASC', $whereSql = '') {
2512         // The table must exist
2513         assert(ifSqlTableExists($tableName));
2514
2515         // Search for it
2516         $result = sqlQueryEscaped('SELECT
2517         `' . implode('`, `', $columns) . '`
2518 FROM
2519         `{?_MYSQL_PREFIX?}_%s`
2520 ' . $whereSql . '
2521 ORDER BY
2522         `%s` %S',
2523                 array(
2524                         $tableName,
2525                         $orderBy,
2526                         $ordered
2527                 ), __FUNCTION__, __LINE__
2528         );
2529
2530         // Init array
2531         $rows = array();
2532
2533         // Are there entries?
2534         if (!ifSqlHasZeroNums($result)) {
2535                 // Load all entries
2536                 while ($row = sqlFetchArray($result)) {
2537                         array_push($rows, $row);
2538                 } // END - while
2539         } // END - if
2540
2541         // Free result
2542         sqlFreeResult($result);
2543
2544         // Return all found rows
2545         return $rows;
2546 }
2547
2548 // [EOF]
2549 ?>