+
+ // Load template
+ displayMessage($content['message']);
+}
+
+// Does resend the user's confirmation link for given email address
+function doResendUserConfirmationLink ($email) {
+ // Email address not registered is default message
+ $message = '{--EMAIL_404--}';
+
+ // Confirmation link requested
+ if (fetchUserData($email, 'email')) {
+ // Email address found
+ $content = getUserDataArray();
+
+ // Is the account unconfirmed?
+ if ($content['status'] == 'UNCONFIRMED') {
+ // Load email template
+ $message = loadEmailTemplate('guest_request_confirm', array(), $content['userid']);
+
+ // Send email
+ sendEmail($content['userid'], '{--GUEST_REQUEST_CONFIRM_LINK_SUBJECT--}', $message);
+ } // END - if
+
+ // Create message based on the status
+ $message = getConfirmationMessageFromUserStatus($content['status']);
+ } // END - if
+
+ // Output message
+ displayMessage($message);
+}
+
+// Get a message (somewhat translation) from user status for confirmation link.
+// This is different to translateUserStatus() in text messages.
+function getConfirmationMessageFromUserStatus ($status) {
+ // Default is 'UNKNOWN'
+ $message = '{%message,GUEST_LOGIN_ID_UNKNOWN_STATUS=' . $status . '%}';
+
+ // Which status is it?
+ switch ($status) {
+ case 'UNCONFIRMED': // Account is unconfirmed
+ // And set message
+ $message = '{--GUEST_CONFIRM_LINK_SENT--}';
+ break;
+
+ case 'CONFIRMED': // Account already confirmed
+ $message = '{--GUEST_LOGIN_ID_CONFIRMED--}';
+ break;
+
+ case 'LOCKED': // Account is locked
+ $message = '{--GUEST_LOGIN_ID_LOCKED--}';
+ break;
+
+ default: // This should not happen
+ reportBug(__FUNCTION__, __LINE__, 'Unknown user status ' . $status . ' detected.');
+ break;
+ } // END - switch
+
+ // Return message
+ return $message;
+}
+
+// "Getter" for total tester accounts
+function getTotalTesterUsers () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Determine it
+ $GLOBALS[__FUNCTION__] = countSumTotalData('', 'user_data', 'userid', '', TRUE, runFilterChain('user_inclusion_sql'));
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
+// Checks whether the admin is allowed to create more tester accounts
+function isNewUserTesterAllowed () {
+ // By default only admins are allowed
+ if (!isAdmin()) {
+ // This should not happen and must be fixed
+ reportBug(__FUNCTION__, __LINE__, 'isAdmin()=false - Not allowed.');
+ } // END - if
+
+ // Are more tester accounts allowed?
+ $isAllowed = (getTotalTesterUsers() < bigintval(getTesterUserMaximum() + 1));
+
+ // Return result
+ return $isAllowed;
+}
+
+// "Getter" for next free tester account number
+function getNextFreeTesterUserNumber () {
+ // Get current total amount because we start with zero
+ $nextTester = getTotalTesterUsers();
+
+ // Prepend zeros
+ $nextTester = prependZeros($nextTester, 6);
+
+ // Return it
+ return $nextTester;
+}
+
+// Wrapper function to return a selection box for tester user default referral id
+function addTesterUserDefaultRefidSelectionBox ($fieldName = 'tester_user_default_refid') {
+ // Return it
+ return addMemberSelectionBox(getConfig('tester_user_default_refid'), FALSE, TRUE, TRUE, $fieldName, " WHERE `surname` LIKE '{?tester_user_surname_prefix?}%'");
+}
+
+// Checks whether given surname is a test user name
+function isTesterUserName ($surname) {
+ // Determine it
+ return (substr($surname, 0, strlen(getTesterUserSurnamePrefix())) == getTesterUserSurnamePrefix());
+}
+
+// Creates a tester account from given POST data
+function createTesterUserAccount () {
+ // Add generated surname
+ setPostRequestElement('surname', (getTesterUserSurnamePrefix() . getNextFreeTesterUserNumber()));
+
+ // Is the registration data complete?
+ if (!isRegistrationDataComplete()) {
+ // Then abort here
+ //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'isRegistrationDataComplete()=false, please check if you e.g. have selected the required minimum of categories.');
+ return FALSE;
+ } // END - if
+
+ // Do registration
+ $isCreated = doUserRegistration();
+
+ // Remove cache to force recalculation of total tester accounts
+ unset($GLOBALS['getTotalTesterUsers']);
+
+ // Return status
+ return $isCreated;
+}
+
+// Checks whether the given sub id is fused by current member
+function isMemberSubIdFree ($subId) {
+ // Only do this for logged-in members
+ assert(isMember());
+
+ // Check it
+ $isFree = (countSumTotalData(getMemberId(), 'user_subids', 'id', 'userid', TRUE, sprintf(" AND `subid`='%s'", $subId)) == 0);
+
+ // Return result
+ return $isFree;
+}
+
+// Checks whether the sub id is valid
+function isValidSubId ($subId) {
+ // First convert any spaces/dashes to underscores
+ $subId = str_replace(' ', '_', str_replace('-', '_', $subId));
+
+ // Then filter out any unwanted characters
+ $subIdTest = preg_replace('/([^a-zA-Z0-9_])/', '', $subId);
+
+ // Is it valid?
+ return ($subId == $subIdTest);
+} // END - if
+
+// Prepares found sub id for updating in database
+function prepareFoundSubId ($subId) {
+ // Then check if it is valid and available
+ if ((!isValidSubId($subId)) || (isMemberSubIdFree($subId))) {
+ // Is not free or invalid
+ $subId = FALSE;
+ } // END - if
+
+ // Return prepared sub id
+ return $subId;
+}
+
+// Validates sub id and returns FALSE if not valid
+function validateSubId ($subId) {
+ // Then check if it is valid and available
+ if (!isValidSubId($subId)) {
+ // Is not free or invalid
+ $subId = FALSE;
+ } // END - if
+
+ // Return prepared sub id
+ return $subId;
+}
+
+// Prepares given sub id for inserting into database
+function prepareSubId ($subId) {
+ // Then check if it is valid and available
+ if ((!isValidSubId($subId)) || (!isMemberSubIdFree($subId))) {
+ // Is not free or invalid
+ $subId = FALSE;
+ } // END - if
+
+ // Return prepared sub id
+ return $subId;
+}
+
+// Check whether given sub *id* is assigned to current member
+function isUserSubIdAssignedToMember ($subId, $userid = NULL) {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__][$subId][$userid])) {
+ // Determine it
+ $GLOBALS[__FUNCTION__][$subId][$userid] = (
+ (
+ // Is a userid set or current set?
+ (isValidUserId($userid)) || (isMember())
+ ) && (
+ // .. and it assigned with subid's id?
+ countSumTotalData(
+ (isValidUserId($userid) ? $userid : getMemberId()),
+ 'user_subids',
+ 'id',
+ 'userid',
+ true,
+ sprintf(" AND `id`=%s", bigintval($subId))
+ ) == 1
+ )
+ );
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__][$subId][$userid];
+}
+
+// Getter for subid from given id number
+function getSubId ($id) {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__][$id])) {
+ // Check database for record
+ $result = SQL_QUERY_ESC("SELECT `subid` FROM `{?_MYSQL_PREFIX?}_user_subids` WHERE `id`=%s LIMIT 1",
+ array(bigintval($id)), __FUNCTION__, __LINE__);
+
+ // Is there an entry?
+ if (SQL_NUMROWS($result) == 1) {
+ // Load it
+ list($GLOBALS[__FUNCTION__][$id]) = SQL_FETCHROW($result);
+ } // END - if
+
+ // Free result
+ SQL_FREERESULT($result);
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__][$id];
+}
+
+// "Getter for total count of current user's sub ids
+function getTotalMemberSubIds () {
+ // Only do this for logged-in members
+ assert(isMember());
+
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Determine it
+ $GLOBALS[__FUNCTION__] = countSumTotalData(getMemberId(), 'user_subids', 'id', 'userid', TRUE);
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
+//-----------------------------------------------------------------------------
+// EL code functions
+//-----------------------------------------------------------------------------
+
+// Expression call-back function for fetching user data
+function doExpressionUser ($data) {
+ // Use current userid by default
+ $functionName = 'getMemberId()';
+
+ // User-related data, so is there a userid?
+ if (!empty($data['matches'][4][$data['key']])) {
+ // Is there a userid or $userid?
+ if (substr($data['matches'][4][$data['key']], 0, 1) == '$') {
+ // Use dynamic call
+ $functionName = "getFetchedUserData('userid', " . $data['matches'][4][$data['key']] . ", '" . $data['callback'] . "')";
+ } elseif (!empty($data['matches'][4][$data['key']])) {
+ // Is there a number or a dollar sign in front of it?
+ if (preg_replace('/[^0123456789]/', '', $data['matches'][4][$data['key']]) != $data['matches'][4][$data['key']]) {
+ // Possible database column, so get it again
+ $data['matches'][4][$data['key']] = "getFetchedUserData('userid', getMemberId(), '" . $data['matches'][4][$data['key']] . "')";
+ } // END - if
+
+ // Fix all together
+ $functionName = "getFetchedUserData('userid', " . $data['matches'][4][$data['key']] . ", '" . $data['callback'] . "')";
+ }
+ } elseif ((!empty($data['callback'])) && (isUserDataValid())) {
+ // "Call-back" alias column for current logged in user's data
+ $functionName = "getUserData('" . $data['callback'] . "')";
+ }
+
+ // Is there another function to run (e.g. translations)
+ if (!empty($data['extra_func'])) {
+ // Surround the original function call with it
+ $functionName = $data['extra_func'] . '(' . $functionName . ')';
+ } // END - if
+ //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'functionName=' . $functionName);
+
+ // Generate replacer
+ $replacer = '{DQUOTE} . ' . $functionName . ' . {DQUOTE}';
+
+ // Now replace the code
+ $code = replaceExpressionCode($data, $replacer);
+
+ // Return replaced code
+ return $code;
+}
+
+//-----------------------------------------------------------------------------
+// Template helper functions
+//-----------------------------------------------------------------------------
+
+// Template call-back function for list_user admin function
+function doTemplateAdminListUserTitle ($template, $clear = FALSE) {
+ // Init title with "all accounts"
+ $code = '{--ADMIN_LIST_ALL_ACCOUNTS--}';
+
+ // Is there a 'status' or 'do' set?
+ if (isGetRequestElementSet('status')) {
+ // Set title according to the 'status'
+ $code = sprintf("{--ADMIN_LIST_STATUS_%s_ACCOUNTS--}", strtoupper(getRequestElement('status')));
+ } elseif (isGetRequestElementSet('do')) {
+ // Set title according to 'do'
+ $code = sprintf("{--ADMIN_LIST_DO_%s_ACCOUNTS--}", strtoupper(getRequestElement('do')));
+ }
+
+ // Return the code
+ return $code;
+}
+
+// Template call-back function for displaying "username"
+function doTemplateDisplayUsername ($template, $clear = FALSE, $userid = NULL) {
+ // Is a userid set?
+ if (!isValidUserId($userid)) {
+ // Please don't call this without a valid userid
+ reportBug(__FUNCTION__, __LINE__, 'template=' . $template . ',clear=' . intval($clear) . ',userid[' . gettype($userid) . ']=' . intval($userid) . ' - Invalid userid provided.');
+ } // END - if
+
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__][$userid])) {
+ // Generate code
+ $GLOBALS[__FUNCTION__][$userid] = $userid . ' ({%user,nickname,fixEmptyContentToDashes=' . $userid . '%})';
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__][$userid];
+}
+
+// ----------------------------------------------------------------------------
+// XML call-back functions
+// ----------------------------------------------------------------------------
+
+// For 'doing' add subid, the column-index is required
+function addXmlSpecialMemberAddDoUserSubid () {
+ // So set it all here
+ $GLOBALS['__COLUMN_INDEX']['doXmlCallbackFunction'] = 'column';
+ $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['column_index'] = 'column';
+}
+
+// ----------------------------------------------------------------------------
+// Wrapper functions for configuration entries
+// ----------------------------------------------------------------------------
+
+// Getter for user_alpha
+function getUserAlpha () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Determine it
+ $GLOBALS[__FUNCTION__] = getConfig('user_alpha');
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
+// Getter for user_limit
+function getUserLimit () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Determine it
+ $GLOBALS[__FUNCTION__] = getConfig('user_limit');
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
+// Getter for tester_user_surname_prefix
+function getTesterUserSurnamePrefix () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Determine it
+ $GLOBALS[__FUNCTION__] = getConfig('tester_user_surname_prefix');
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
+// Getter for tester_user_maximum
+function getTesterUserMaximum () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Determine it
+ $GLOBALS[__FUNCTION__] = getConfig('tester_user_maximum');
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
+// Getter for tester_user_check_cat
+function getTesterUserCheckCat () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Determine it
+ $GLOBALS[__FUNCTION__] = getConfig('tester_user_check_cat');
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
+// Getter for tester_user_gender
+function getTesterUserGender () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Determine it
+ $GLOBALS[__FUNCTION__] = getConfig('tester_user_gender');
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
+// Getter for tester_user_family
+function getTesterUserFamily () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Determine it
+ $GLOBALS[__FUNCTION__] = getConfig('tester_user_family');
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
+// Getter for tester_user_password
+function getTesterUserPassword () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Determine it
+ $GLOBALS[__FUNCTION__] = getConfig('tester_user_password');
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
+// Getter for tester_user_street_nr
+function getTesterUserStreetNr () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Determine it
+ $GLOBALS[__FUNCTION__] = getConfig('tester_user_street_nr');
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
+// Getter for tester_user_zip
+function getTesterUserZip () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Determine it
+ $GLOBALS[__FUNCTION__] = getConfig('tester_user_zip');
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
+// Getter for tester_user_city
+function getTesterUserCity () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Determine it
+ $GLOBALS[__FUNCTION__] = getConfig('tester_user_city');
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
+// Getter for tester_user_email
+function getTesterUserEmail () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Determine it
+ $GLOBALS[__FUNCTION__] = getConfig('tester_user_email');
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];