function createNewUser()
{
    /*
    A new user has entered their information. We will create their account.
    */
    global $debug, $message, $success, $Dbc, $returnThis;
    $output = '';
    try {
        if (empty($_POST['firstName'])) {
            throw new Adrlist_CustomException('', '$_POST[\'lastName\'] is empty.');
        } elseif (empty($_POST['lastName'])) {
            throw new Adrlist_CustomException('', '$_POST[\'lastName\'] is empty.');
        } elseif (empty($_POST['email'])) {
            throw new Adrlist_CustomException('', 'email is empty.');
        } elseif (!emailValidate($_POST['email'])) {
            throw new Adrlist_CustomException('', 'Email address is not valid.');
        } elseif (!passwordValidate($_POST['password'])) {
            throw new Adrlist_CustomException('', '$_POST[\'password\'] is not valid.');
        } elseif (empty($_POST['password'])) {
            throw new Adrlist_CustomException('', '$_POST[\'password\'] is empty.');
        } elseif (empty($_POST['timeZone'])) {
            throw new Adrlist_CustomException('', '$_POST[\'timeZone\'] is empty.');
        }
        /*elseif(empty($_POST['recaptcha_challenge_field'])){
        			throw new Adrlist_CustomException('','$_POST[\'recaptcha_challenge_field\'] is empty.');
        		}elseif(empty($_POST['recaptcha_response_field'])){
        			throw new Adrlist_CustomException('','$_POST[\'recaptcha_response_field\'] is empty.');
        		}*/
        destroySession();
        $_POST['email'] = trim($_POST['email']);
        $passEncoded = sha1(trim($_POST['password']));
        $_POST['firstName'] = trim($_POST['firstName']);
        $_POST['lastName'] = trim($_POST['lastName']);
        $rememberMeCode = sha1($_POST['email']);
        $invitationCode = isset($_POST['invitationCode']) ? trim($_POST['invitationCode']) : '';
        /*
        $resp = recaptcha_check_answer(RECAPTCHAPRIVATEKEY, $_SERVER["REMOTE_ADDR"], $_POST['recaptcha_challenge_field'], $_POST['recaptcha_response_field']);
        if(!$resp->is_valid && !LOCAL){
        	throw new Adrlist_CustomException('The reCAPTCHA wasn\'t entered correctly. Please enter the new reCAPTCHA.','reCAPTCHA said: ' . $resp->error . '.');
        }
        $debug->add('The recaptcha response is valid.');
        */
        $Dbc->beginTransaction();
        //See if this email address is already in use.
        $getUserIdQuery = $Dbc->prepare("SELECT\n\tuserId AS 'userId'\nFROM\n\tusers\nWHERE\n\tprimaryEmail = ?");
        $getUserIdQuery->execute(array($_POST['email']));
        $row = $getUserIdQuery->fetch(PDO::FETCH_ASSOC);
        if (empty($row['userId'])) {
            //There are no users with the email address, so insert the user record.
            $insertUserQuery = $Dbc->prepare("INSERT INTO\n\tusers\nSET\n\tprimaryEmail = ?,\n\tuserPassword = ?,\n\tfirstName = ?,\n\tlastName = ?,\n\tdateAdded = ?");
            $insertUserQuery->execute(array($_POST['email'], $passEncoded, $_POST['firstName'], $_POST['lastName'], DATETIME));
            $userId = $Dbc->lastInsertId();
            if (!empty($invitationCode)) {
                $debug->add('$invitationCode: ' . "{$invitationCode}");
                //The user is responding to an invitation. Verify the invitation code matches the email.
                $verifyInviteQuery = $Dbc->prepare("SELECT\n\temail as 'email'\nFROM\n\tinvitations\nWHERE\n\tinvitationCode = ? AND\n\temail = ? AND\n\trespondDate IS NULL");
                $verifyInviteQuery->execute(array($invitationCode, $_POST['email']));
                $verifyInvite = $verifyInviteQuery->fetch(PDO::FETCH_ASSOC);
                if ($verifyInvite['email'] === '' || $verifyInvite['email'] === NULL) {
                    //The invitation code wasn't found or didn't match the email address. The user will still be created.
                    $message .= '<div class="red" style="padding:10px;">An invitation wasn\'t found. It may have been cancelled by the person who made the invitation.</div>';
                } else {
                    $invitedEmail = true;
                    //The invitation code and email have been verified. Look for more invitations.
                    $invitationsQuery = $Dbc->prepare("SELECT\n\tinvitationId AS 'invitationId',\n\tfolderId AS 'folderId',\n\tfolderRoleId AS 'folderRoleId',\n\tlistId AS 'listId',\n\tlistRoleId AS 'listRoleId',\n\tsenderId AS 'senderId'\nFROM\n\tinvitations\nWHERE\n\temail = ? AND\n\trespondDate IS NULL");
                    $invitationsQuery->execute(array($_POST['email']));
                    $folderArray = array();
                    //A nested associative array: requestingUserId => array(folderId,userFolderRoleId).
                    //Insert the new user's roles from the invitation(s).
                    while ($invitationsRow = $invitationsQuery->fetch(PDO::FETCH_ASSOC)) {
                        if (!empty($invitationsRow['folderId']) && !empty($invitationsRow['folderRoleId'])) {
                            //Add the folder to an array for creating list roles.
                            $folderArray[$invitationsRow['senderId']][$invitationsRow['folderId']] = $invitationsRow['folderRoleId'];
                            //Insert the folder role.
                            $insertFolderRole = $Dbc->prepare("INSERT INTO\n\tuserFolderSettings\nSET\n\tfolderId = ?,\n\tuserId = ?,\n\tfolderRoleId = ?,\n\tdateAdded = ?");
                            $insertFolderRole->execute(array($invitationsRow['folderId'], $userId, $invitationsRow['folderRoleId'], DATETIME));
                        }
                        if (!empty($invitationsRow['listId']) && !empty($invitationsRow['listRoleId'])) {
                            //Insert the list role.
                            $insertListRole = $Dbc->prepare("INSERT INTO\n\tuserListSettings\nSET\n\tlistId = ?,\n\tuserId = ?,\n\tlistRoleId = ?,\n\tdateAdded = ?");
                            $insertListRole->execute(array($invitationsRow['listId'], $userId, $invitationsRow['listRoleId'], DATETIME));
                        }
                        //Update the invitation respond date.
                        $respondDateQuery = $Dbc->prepare("UPDATE\n\tinvitations\nSET\n\trespondDate = ?\nWHERE\n\tinvitationId = ?");
                        $respondDateQuery->execute(array(DATETIME, $invitationsRow['invitationId']));
                    }
                    //Insert roles for each list in the sharedFolders array.
                    if (!empty($folderArray) && is_array($folderArray)) {
                        $debug->printArray($folderArray, '$folderArray');
                        foreach ($folderArray as $requestingUserId => $sharedFoldersArray) {
                            distributeRoles($requestingUserId, $userId, $sharedFoldersArray, true);
                        }
                    } elseif (!empty($folderArray)) {
                        error(__LINE__, '', '$sharedFoldersArray must be an associative array near line ' . __LINE__ . '.<br>');
                    }
                }
            }
            //Create the user's default userSettings.
            $insertUserSettingsQuery = $Dbc->prepare("INSERT\nINTO\n\tuserSiteSettings\nSET\n\tuserId = ?,\n\trememberMeCode = ?,\n\ttimeZone = ?,\n\tsiteRoleId = ?");
            $insertUserSettingsQuery->execute(array($userId, $rememberMeCode, $_POST['timeZone'], 1));
            //There is no default billing for a user. The user can select a plan, or there may be a promotion when starting an account.
            //We must insert a userBillingAction first.
            $userBillingActionStmt = $Dbc->prepare("INSERT\nINTO\n\tuserBillingActions\nSET\n\tuserId = ?,\n\tbillingOfferId = ?,\n\tbillingActionId = ?,\n\tvendorId = ?,\n\tbillingDatetime = ?");
            $userBillingActionStmt->execute(array($userId, 1, 10, 3, DATETIME));
            $userBillingActionId = $Dbc->lastInsertId();
            $billingQuery = $Dbc->prepare("INSERT\nINTO\n\tuserBilling\nSET\n\tuserId = ?,\n\tbillingOfferId = ?,\n\tuserBillingActionId = ?,\n\tdateAdded = ?");
            $billingQuery->execute(array($userId, 1, $userBillingActionId, DATETIME));
            //Send a welcome email.
            $subject = 'Welcome to ' . THENAMEOFTHESITE . '!';
            $body = '<table width="100%" cellpadding="0" cellspacing="0" border="0" align="center" bgcolor="#FFFFFF">
	<tr>
		<td align="left"><font face="' . FONT . '" size="' . SIZE5 . '"><b>Welcome to ' . THENAMEOFTHESITE . '!</b><br>
&nbsp;</font></td>
	</tr>
	<tr>
		<td align="left"><font face="' . FONT . '" size="' . SIZE3 . '"></font>Create your first ADR list by logging in: <a href="' . LINKLOGIN . '/?email=' . $_POST['email'] . '">' . LINKLOGIN . '</a>.<br>
			<div>&nbsp;</div>
			<div>&nbsp;</div>
			<div>&nbsp;</div>
		</td>
	</tr>
</table>';
            $textBody = "Welcome to " . THENAMEOFTHESITE . ".\nCreate your first list by logging in: https://" . DOMAIN . "/login?email=" . $_POST['email'] . "\nThis is an automated message. Please do not reply.";
            email(EMAILDONOTREPLY, $_POST['email'], $subject, $body, $textBody);
            setcookie(REMEMBERME, $rememberMeCode, time() + 60 * 60 * 24 * 365, COOKIEPATH, COOKIEDOMAIN, false);
            $Dbc->commit();
            $success = true;
            $returnThis['pass'] = $_POST['password'];
        } else {
            $message .= "The email address you entered is already in use. Please choose another or try logging in.<br>";
            $debug->add('The email address belongs to userId: ' . $row['userId'] . '.');
        }
    } catch (Adrlist_CustomException $e) {
    } catch (PDOException $e) {
        error(__LINE__, '', '<pre>' . $e . '</pre>');
        if (MODE == 'createNewUser') {
            returnData();
        }
    }
    returnData();
}
function updateFolderRole()
{
    //Update the user's folder role id. The role is also applied to all of the folder's lists.
    global $debug, $message, $success, $Dbc, $returnThis;
    $output = '';
    try {
        if (empty($_POST['userId'])) {
            throw new Adrlist_CustomException('', '$_POST[\'userId\'] is empty.');
        } elseif (empty($_POST['folderId'])) {
            throw new Adrlist_CustomException('', '$_POST[\'folderId\'] is empty.');
        } elseif (!isset($_POST['newRoleId'])) {
            //The newRoleId may be zero, so check that the value with isset() rather than empty().
            throw new Adrlist_CustomException('', '$_POST[\'newRoleId\'] is not set.');
        }
        if (distributeRoles($_SESSION['userId'], $_POST['userId'], array($_POST['folderId'] => $_POST['newRoleId']), false) === true) {
            $message .= 'Updated';
            $returnThis['buildFolderUsers'] = buildFolderUsers();
        }
        if ($_POST['newRoleId'] < 3) {
            //Delete pending shares started by this user for lists in this folder when their role is reduced below Manager (3).
            $deletePendingSharesStmt = $Dbc->prepare("DELETE FROM\n\t\tinvitations\n\tWHERE\n\t\tsenderId = ? AND\n\t\tlistId IN (SELECT listId FROM lists WHERE folderId = ?)");
            $deletePendingSharesStmt->execute(array($_POST['userId'], $_POST['folderId']));
        }
        $success = MODE == 'updateFolderRole' ? true : $success;
    } catch (Adrlist_CustomException $e) {
    } catch (PDOException $e) {
        error(__LINE__, '', '<pre>' . $e . '</pre>');
    }
    if (MODE == 'updateFolderRole') {
        returnData();
    }
}