/**
 * Show Register Form
 *
 * Controller for the Authenticate module.
 *
 * @author      Goran Halusa <*****@*****.**>
 * @since       0.1.0
 */
function show_register_form()
{
    $app = \Slim\Slim::getInstance();
    $final_global_template_vars = $app->config('final_global_template_vars');
    require_once $final_global_template_vars["default_module_list"]["user_account"]["absolute_path_to_this_module"] . "/models/user_account.class.php";
    require_once $final_global_template_vars["default_module_list"]["register_account"]["absolute_path_to_this_module"] . "/models/register_account.class.php";
    require_once $final_global_template_vars["default_module_list"]["group"]["absolute_path_to_this_module"] . "/models/group.class.php";
    $env = $app->environment();
    $db_conn = new \PHPSkeleton\models\db($final_global_template_vars["db_connection"]);
    $db_resource = $db_conn->get_resource();
    $user_account = new \PHPSkeleton\UserAccount($db_resource, $final_global_template_vars["session_key"]);
    $register_account = new \PHPSkeleton\RegisterAccount($db_resource, $final_global_template_vars["session_key"]);
    $group = new \PHPSkeleton\Group($db_resource, $final_global_template_vars["session_key"]);
    $needs_group = true;
    // Check to see if they are already registered (group selected).
    // If they are already registered, don't let them register again.
    $is_registered = $register_account->is_registered($_SESSION[$final_global_template_vars["session_key"]]["user_account_id"]);
    // Check to see if this user is already assigned to a group - they may have been added by another administrator.
    $current_groups = $user_account->get_user_account_groups($_SESSION[$final_global_template_vars["session_key"]]["user_account_id"]);
    if ($current_groups) {
        $needs_group = false;
    }
    $group_hierarchy = $group->get_group_hierarchy("--");
    $flat_group_hierarchy = $group->flatten_group_hierarchy($group_hierarchy);
    $app->render('register_form.php', array("page_title" => false, "hide_side_nav" => true, "is_registered" => $is_registered, "groups" => $flat_group_hierarchy, "needs_group" => $needs_group, "submitted_data" => $app->request()->post(), "errors" => !empty($env["default_validation_errors"]) ? $env["default_validation_errors"] : false));
}
/**
 * Check Local Account
 *
 * Controller for the Authenticate module.
 *
 * @author      Goran Halusa <*****@*****.**>
 * @since       0.1.0
 */
function check_local_account()
{
    $app = \Slim\Slim::getInstance();
    $final_global_template_vars = $app->config('final_global_template_vars');
    require_once $final_global_template_vars["default_module_list"]["user_account"]["absolute_path_to_this_module"] . "/models/register_account.class.php";
    $env = $app->environment();
    $db_conn = new \PHPSkeleton\models\db($final_global_template_vars["db_connection"]);
    $db_resource = $db_conn->get_resource();
    $register_account = new \PHPSkeleton\RegisterAccount($db_resource, $final_global_template_vars["session_key"]);
    if (!empty($_SESSION[$final_global_template_vars["session_key"]]) && empty($env["default_validation_errors"])) {
        // Check to see if the author has a role in the system and is registered (AUP).
        $local_user_account = $register_account->is_registered($_SESSION[$final_global_template_vars["session_key"]]['user_account_id']);
        if (!$local_user_account) {
            $app->redirect($final_global_template_vars["path_to_this_module"] . "/register");
        }
    }
}
/**
 * Reset Password
 *
 * Controller for the User Account module.
 *
 * @author      Goran Halusa <*****@*****.**>
 * @since       0.1.0
 */
function reset_password()
{
    $app = \Slim\Slim::getInstance();
    $final_global_template_vars = $app->config('final_global_template_vars');
    require_once $final_global_template_vars["absolute_path_to_this_module"] . "/models/register_account.class.php";
    require_once $_SERVER["PATH_TO_VENDOR"] . "phpmailer/phpmailer/PHPMailerAutoload.php";
    $db_conn = new \PHPSkeleton\models\db($final_global_template_vars["db_connection"]);
    $db_resource = $db_conn->get_resource();
    $register_account = new \PHPSkeleton\RegisterAccount($db_resource, $final_global_template_vars["session_key"]);
    $mail = new PHPMailer();
    $posted_data = $app->request()->post() ? $app->request()->post() : false;
    $account_email_exists = false;
    // Is the email address in the database?
    if ($posted_data) {
        $account_email_exists = $register_account->account_email_exists($posted_data["user_account_email"]);
        if (!$account_email_exists) {
            $app->flash('message', 'The entered email address was not found in our database.');
            $app->redirect($final_global_template_vars["path_to_this_module"] . "/password/");
        }
    }
    // If there are no errors, process posted data and email to user
    if ($account_email_exists && $posted_data) {
        $emailed_hash = md5(rand(0, 1000));
        // Attempt to update the emailed_hash and set account to inactive (returns boolean)
        $updated = $register_account->update_emailed_hash($account_email_exists['user_account_id'], $emailed_hash);
        if ($updated) {
            // Prepare the email...
            // The email subject.
            $subject = 'Reset Password';
            // The message, including the link.
            $message = '<h2>Reset Your Password</h2>
            <hr>
            <p>Please click this link to reset your password:<br />
            <a href="http://' . $_SERVER["SERVER_NAME"] . '/user_account/reset/?user_account_email=' . $account_email_exists['user_account_email'] . '&emailed_hash=' . $emailed_hash . '">http://' . $_SERVER["SERVER_NAME"] . '/user_account/reset/?user_account_email=' . $account_email_exists['user_account_email'] . '&emailed_hash=' . $emailed_hash . '</a></p>';
            // For the ability to send emails from an AWS EC2 instance...
            // If you need this functionality, you can configure the settings accordingly in /default_global_settings.php
            if ($final_global_template_vars["hosting_vendor"] && $final_global_template_vars["hosting_vendor"] == "aws_ec2") {
                $email = array();
                require_once $final_global_template_vars["path_to_smtp_settings"];
                // SMTP Settings
                $mail->IsSMTP();
                $mail->SMTPAuth = $email['settings']['smtpauth'];
                $mail->SMTPSecure = $email['settings']['smtpsecure'];
                $mail->Host = $email['settings']['host'];
                $mail->Username = $email['settings']['username'];
                $mail->Password = $email['settings']['password'];
            }
            // From (verified email address).
            $mail->SetFrom($final_global_template_vars["send_emails_from"], $final_global_template_vars["site_name"] . ' Accounts');
            // Subject
            $mail->Subject = $subject;
            // Message
            $mail->MsgHTML($message);
            // Recipient
            $mail->AddAddress($posted_data['user_account_email']);
            // Send the email.
            $mail->Send();
            $app->flash('message', 'Thank you. Further instructions are being sent to your email address.');
        } else {
            $app->flash('message', 'Processing failed.');
        }
        $app->redirect($final_global_template_vars["path_to_this_module"] . "/password/");
    }
}
/**
 * Update Password
 *
 * Controller for the User Account module.
 *
 * @author      Goran Halusa <*****@*****.**>
 * @since       0.1.0
 */
function update_password()
{
    $app = \Slim\Slim::getInstance();
    $final_global_template_vars = $app->config('final_global_template_vars');
    require_once $_SERVER["PATH_TO_VENDOR"] . "wixel/gump/gump.class.php";
    require_once $final_global_template_vars["absolute_path_to_this_module"] . "/models/register_account.class.php";
    require_once $final_global_template_vars["default_module_list"]["authenticate"]["absolute_path_to_this_module"] . "/models/authenticate.class.php";
    require_once $_SERVER["PATH_TO_VENDOR"] . "phpmailer/phpmailer/PHPMailerAutoload.php";
    $db_conn = new \PHPSkeleton\models\db($final_global_template_vars["db_connection"]);
    $db_resource = $db_conn->get_resource();
    $register_account = new \PHPSkeleton\RegisterAccount($db_resource, $final_global_template_vars["session_key"]);
    $authenticate = new \PHPSkeleton\Authenticate($db_resource, $final_global_template_vars["session_key"]);
    $gump = new GUMP();
    $mail = new PHPMailer();
    $post = $app->request()->post() ? $app->request()->post() : false;
    $account_email_exists = false;
    // Is the email address in the database?
    if ($post) {
        $account_email_exists = $register_account->account_email_exists($post["user_account_email"]);
        if (!$account_email_exists) {
            $app->flash('message', 'The entered email address was not found in our database.');
            $app->redirect($final_global_template_vars["path_to_this_module"] . "/password/");
        }
    }
    $rules = array();
    if ($account_email_exists) {
        $rules = array("user_account_password" => "required|max_len,100|min_len,6", "password_check" => "required|max_len,100|min_len,6");
    }
    $validated = $gump->validate($post, $rules);
    if ($post["user_account_password"] != $post["password_check"]) {
        $validated_password_check = array("field" => "user_account_password_check", "value" => null, "rule" => "validate_required");
        if (is_array($validated)) {
            array_push($validated, $validated_password_check);
        } else {
            $validated = array($validated_password_check);
        }
    }
    $errors = array();
    if ($validated !== true) {
        $errors = \phpskeleton\models\utility::gump_parse_errors($validated);
    }
    if (isset($errors["user_account_password_check"])) {
        $errors["user_account_password_check"] = "Passwords did not match.";
    }
    // If there are no errors, process posted data and email to user
    if (empty($errors) && $post) {
        // Attempt to update the user_account_password and set the account to active (returns boolean)
        $updated = $register_account->update_password($authenticate->generate_hashed_password($post["user_account_password"]), $account_email_exists['user_account_id'], $post["emailed_hash"]);
        if ($updated) {
            // Prepare the email...
            // The email subject.
            $subject = 'Your Password Has Been Reset';
            // The message.
            $message = '<h2>Your Password Has Been Reset</h2>
            <hr>
            <p>If you did not execute this change, please contact the site administrator as soon as possible.</p>';
            // For the ability to send emails from an AWS EC2 instance
            // If you need this functionality, you can configure the settings accordingly in /default_global_settings.php
            if ($final_global_template_vars["hosting_vendor"] && $final_global_template_vars["hosting_vendor"] == "aws_ec2") {
                $email = array();
                require_once $final_global_template_vars["path_to_smtp_settings"];
                // SMTP Settings
                $mail = new PHPMailer();
                $mail->IsSMTP();
                $mail->SMTPAuth = $email['settings']['smtpauth'];
                $mail->SMTPSecure = $email['settings']['smtpsecure'];
                $mail->Host = $email['settings']['host'];
                $mail->Username = $email['settings']['username'];
                $mail->Password = $email['settings']['password'];
            }
            // From (verified email address).
            $mail->SetFrom($final_global_template_vars["send_emails_from"], $final_global_template_vars["site_name"] . ' Accounts');
            // Subject
            $mail->Subject = $subject;
            $mail->MsgHTML($message);
            // Recipient
            $mail->AddAddress($post['user_account_email']);
            // Send the email.
            $mail->Send();
            $app->flash('message', 'Your password has been reset.');
            $app->redirect($final_global_template_vars["path_to_this_module"] . "/password/");
        } else {
            $app->flash('message', 'Processing failed.');
            $app->redirect($final_global_template_vars["path_to_this_module"] . "/password/");
        }
    } else {
        $app->flash('message', $errors["user_account_password"]);
        $app->redirect($final_global_template_vars["path_to_this_module"] . "/reset/?user_account_email=" . $account_email_exists['user_account_email'] . "&emailed_hash=" . $post["emailed_hash"]);
    }
}
/**
 * Insert User Account
 *
 * Controller for the User Account module.
 *
 * @author      Goran Halusa <*****@*****.**>
 * @since       0.1.0
 */
function insert_user_account()
{
    $app = \Slim\Slim::getInstance();
    $env = $app->environment();
    $final_global_template_vars = $app->config('final_global_template_vars');
    require_once $_SERVER["PATH_TO_VENDOR"] . "wixel/gump/gump.class.php";
    require_once $final_global_template_vars["absolute_path_to_this_module"] . "/models/user_account.class.php";
    require_once $final_global_template_vars["absolute_path_to_this_module"] . "/models/register_account.class.php";
    require_once $final_global_template_vars["default_module_list"]["authenticate"]["absolute_path_to_this_module"] . "/models/authenticate.class.php";
    require_once $_SERVER["PATH_TO_VENDOR"] . "phpmailer/phpmailer/PHPMailerAutoload.php";
    $db_conn = new \PHPSkeleton\models\db($final_global_template_vars["db_connection"]);
    $db_resource = $db_conn->get_resource();
    $useraccount = new \PHPSkeleton\UserAccount($db_resource, $final_global_template_vars["session_key"]);
    $register_account = new \PHPSkeleton\RegisterAccount($db_resource, $final_global_template_vars["session_key"]);
    $authenticate = new \PHPSkeleton\Authenticate($db_resource, $final_global_template_vars["session_key"]);
    $gump = new GUMP();
    $mail = new PHPMailer();
    $errors = false;
    $posted_data = $app->request()->post() ? $app->request()->post() : false;
    $account_email_exists = $register_account->account_email_exists($posted_data["user_account_email"]);
    if ($account_email_exists) {
        $app->flash('message', 'It looks like you already have an account. Email address is already in use.');
        $app->redirect($final_global_template_vars["path_to_this_module"] . "/register/");
    }
    // GUMP validation rules
    $rules = array("user_account_email" => "required|valid_email", "user_account_password" => "required|max_len,100|min_len,6", "first_name" => "required|alpha_numeric", "last_name" => "required|alpha_numeric");
    // Validation using GUMP
    if ($posted_data) {
        $validated = array();
        $errors = array();
        $validated = $gump->validate($posted_data, $rules);
        if ($validated !== true) {
            $errors = \phpskeleton\models\utility::gump_parse_errors($validated);
        }
        if ($errors) {
            $env = $app->environment();
            $env["default_validation_errors"] = $errors;
        }
    }
    $default_validation_errors = isset($env["default_validation_errors"]) ? $env["default_validation_errors"] : false;
    // If there are no errors, process posted data and email to user
    if (!$default_validation_errors && $posted_data) {
        $emailed_hash = md5(rand(0, 1000));
        // INSERT this user into the user_account table
        $statement = $db_resource->prepare("INSERT INTO user_account\n          (user_account_email, user_account_password, first_name, last_name, acceptable_use_policy, created_date, active, emailed_hash)\n          VALUES ( :user_account_email, :user_account_password, :first_name, :last_name, 1, NOW(), 0, :emailed_hash )");
        $statement->bindValue(":user_account_email", $posted_data['user_account_email'], PDO::PARAM_STR);
        $statement->bindValue(":user_account_password", $authenticate->generate_hashed_password($posted_data['user_account_password']), PDO::PARAM_STR);
        $statement->bindValue(":first_name", $posted_data['first_name'], PDO::PARAM_STR);
        $statement->bindValue(":last_name", $posted_data['last_name'], PDO::PARAM_STR);
        $statement->bindValue(":emailed_hash", $emailed_hash, PDO::PARAM_STR);
        $statement->execute();
        $error = $db_resource->errorInfo();
        if ($error[0] != "00000") {
            die('The INSERT INTO user_account failed.');
        }
        $last_inserted_user_account_id = $db_resource->lastInsertId();
        // INSERT this user into the user_account_groups table with "Author" privileges
        $statement = $db_resource->prepare("INSERT INTO user_account_groups\n          (role_id, user_account_id, group_id)\n          VALUES ( 2, :user_account_id, 1 )");
        $statement->bindValue(":user_account_id", $last_inserted_user_account_id, PDO::PARAM_INT);
        $statement->execute();
        $error = $db_resource->errorInfo();
        if ($error[0] != "00000") {
            die('The INSERT INTO user_account_groups failed.');
        }
        // Send emails
        // Email setup for user
        $to = $posted_data['user_account_email'];
        // Send email to our user
        $subject = 'Signup | Verification';
        // Give the email a subject
        $message = '<h2>Hello ' . $posted_data['first_name'] . '!</h2>
        <p>Your account has been created, you can login with the following credentials after you have 
        activated your account by accessing the url below.</p>
        <hr>
        <p>Username: '******'user_account_email'] . '</p>
        <p>Password: (The password you submitted during the registration process.)</p>
        <hr>
        <p>Please click this link to activate your account:<br />
        <a href="http://' . $_SERVER["SERVER_NAME"] . '/user_account/verify/?user_account_email=' . $posted_data['user_account_email'] . '&emailed_hash=' . $emailed_hash . '">http://' . $_SERVER["SERVER_NAME"] . '/user_account/verify/?user_account_email=' . $posted_data['user_account_email'] . '&emailed_hash=' . $emailed_hash . '</a></p>';
        // Our message above including the link
        // Email setup for Universal Administrators
        // First, get all of the "Universal Administrator" email addresses
        $admin_emails = array();
        $universal_administrator_emails = $useraccount->get_universal_administrator_emails();
        // Create a comma-delimited list of email addresses
        if (is_array($universal_administrator_emails) && !empty($universal_administrator_emails)) {
            foreach ($universal_administrator_emails as $email) {
                array_push($admin_emails, $email["user_account_email"]);
            }
        }
        $subject_admins = 'New User Registration';
        // Give the email a subject
        $message_admins = '<h2>New User</h2>
        <p>A new user has registered.</p>
        <h3>Details</h3>
        <p>Name: ' . $posted_data['first_name'] . ' ' . $posted_data['last_name'] . '</p>
        <p>Email: ' . $posted_data['user_account_email'] . '</p>
        <hr>
        <p><a href="http://' . $_SERVER["SERVER_NAME"] . '/authenticate/">Login to administer</a></p>';
        // Our message above including the link
        // For the ability to send emails from an AWS EC2 instance
        // If you need this functionality, you can configure the settings accordingly in /default_global_settings.php
        if ($final_global_template_vars["hosting_vendor"] && $final_global_template_vars["hosting_vendor"] == "aws_ec2") {
            $email = array();
            require_once $final_global_template_vars["path_to_smtp_settings"];
            // SMTP Settings
            $mail->IsSMTP();
            $mail->SMTPAuth = $email['settings']['smtpauth'];
            $mail->SMTPSecure = $email['settings']['smtpsecure'];
            $mail->Host = $email['settings']['host'];
            $mail->Username = $email['settings']['username'];
            $mail->Password = $email['settings']['password'];
        }
        // Send email to user
        $mail->SetFrom($final_global_template_vars["send_emails_from"], $final_global_template_vars["site_name"] . ' Accounts');
        // From (verified email address)
        $mail->Subject = $subject;
        // Subject
        $mail->MsgHTML($message);
        $mail->AddAddress($to);
        // Recipient
        $mail->Send();
        $mail->ClearAllRecipients();
        // Send email to Universal Administrators
        // Subject
        $mail->Subject = $subject_admins;
        $mail->MsgHTML($message_admins);
        // Universal Admin recipients
        if (is_array($universal_administrator_emails) && !empty($universal_administrator_emails)) {
            foreach ($universal_administrator_emails as $email) {
                $mail->AddAddress($email["user_account_email"]);
            }
            $mail->Send();
            $mail->ClearAllRecipients();
        }
    }
    if (!$errors) {
        $app->flash('message', 'Account creation was successful. You will receive an email shortly with further instructions.');
        $app->redirect($final_global_template_vars["path_to_this_module"] . "/register/");
    } else {
        $env = $app->environment();
        $env["default_validation_errors"] = $errors;
    }
}