Auth.php 5.66 KB
<?php

namespace Tz\WordPress\Tools\Auth;

use Tz\WordPress\Tools;
use Tz\Common;
use Exception, LogicException, InvalidArgumentException, BadMethodCallException;

const REG_METH_AUTO_REG    = 1;
const REG_METH_VALID_EMAIL = 2;

const FORGOT_METH_VALID_EMAIL = 1;
const FORGOT_METH_RAND_PASS   = 2;

// The things with these is they're dynamic but static functions aren't...
const ACTION_ACTIVATE = 'auth_activate';

const OPTION_NAME = 'tz_auth'; // Database lookup key (`wp_options`.`option_name`)

    call_user_func(function() {
        Vars::$options = new Tools\WP_Option(OPTION_NAME);

        if (is_admin()) {
            require_once(__DIR__ . DIRECTORY_SEPARATOR . 'Settings.php');
        }

        if (is_array(Vars::$options['third_party'])) {
            foreach (Vars::$options['third_party'] as $tp => $on) {
                if ($on) {
                    require_once(__DIR__ . DIRECTORY_SEPARATOR . $tp . DIRECTORY_SEPARATOR . $tp . '.php');
                }
            }
        }
    });

/**
 * Attempts to login the user
 * @param {String} $username
 * @param {String} $password
 * @param {Boolean} $remember
 * @returns WP_User instance
 * @throws LogicException If headers have already been passed
 * @throws InvalidArgumentException If the authentication is invalid
 */
function login($username, $password, $remember = true) {
    if (headers_sent()) {
        throw new LogicException('Unable to login because headers have been sent');
    }

    $auth = _signon(Array(
        'user_login'    => esc_sql($username)
      , 'user_password' => esc_sql($password)
      , 'remember'      => $remember
    ));

    if (get_class($auth) == 'WP_User') {
        _set_current_user($auth->ID); // Not sure why I had to do this, oh well

        return $auth;
    }

    throw new InvalidArgumentException('Invalid username/password');
        //$auth->get_error_message()); this would be nice except it links to a wp-page
}

/**
 * Attempts to log the user out
 * @returns Boolean
 * @throws LogicException If HTTP headers have already been sent
 */
function logout() {
    if (headers_sent()) {
        throw new LogicException('Unable to logout because headers have been sent');
    }

    _logout();

    return true;
}

/**
 * @param {Array} $user_data User data array, requires minimum (username, password, email)
 * @param {Integer} $registration_method Method of registeration, see constants beginning with REG_METH
 * @throws {InvalidArgumentException} If an invalid $registration_method is passed
 * @throw {BadMethodCallException} If any of the $user_data parameters are invalid
 * @returns {Integer} New user $id if successful
 * @uses wp-includes/registration.php
 */
function register($user_data = Array(), $registration_method = 1) {
    if (!in_array($registration_method, Array(REG_METH_AUTO_REG, REG_METH_VALID_EMAIL))) {
        throw new InvalidArgumentException("Invalid registration method selected");
    }

    require_once(ABSPATH . WPINC . DIRECTORY_SEPARATOR . 'registration.php');

    $valid = new Validation($user_data);
    if (count($valid->errors) > 0) {
        throw new BadMethodCallException(implode("\n", $valid->errors));
    }

    array_filter($user_data, 'esc_sql');
    // $key = substr( md5( time() . rand() . $user_email ), 0, 16 );

    // possibly call wpmu_signup_user() if REG_METH_VALID_EMAIL; _insert_user if REG_METH_AUTO_REG
    // Can't do that without making a database call; the unique registration key is created and destroyed in the function
    // I'll have to make a database call to retreive it, at the very lest
    // I can't do that at all; the function sends an email to the user with a auto-generated password
    // I'll have to do database manipulation manually
    $id = (int)_insert_user($user_data);

    // should I call ACTION_ACTIVATE if REG_METHOD_AUTO_REG?

    // this is so wrong
    global $wpdb;
    $wpdb->query("UPDATE `{$wpdb->users}` SET `user_status` = 1 WHERE `ID` = {$id}");

    return $id;
}

// Don't think I need $username
function activate($username, $activation_key) {
// wpmu_activate_signup
// I can't do that either; that function sends a WordPress email

    do_action(ACTION_ACTIVATE, $user_id);
}

// Not sure I need this function
// Application can just set rand password
// Or perhapds I do need it, move it to registered again or something???
function forgot_password($username, $forgot_method) {
    
}

class Validation extends Common\Validation {
    /**
     * @rule Not blank
     * @rule Valid WordPress username
     * @returns Boolean
     */
    protected function username($val) {
        if (empty($val)) {
            throw new Exception('Username is blank');
        }

        require_once(ABSPATH . WPINC . DIRECTORY_SEPARATOR . 'registration.php');
        if (!validate_username($val)) {
            throw new Exception('Username must be at least 4 characters, letters and numbers only');
        }

        if (username_exists($_POST['reg_username'])) {
            throw new Exception('Username already exists');
        }
    }

    /**
     * @rule Not blank
     * @returns Boolean 
     */
    protected function password($val) {
        if (empty($val)) {
            throw new Exception('Password can not be blank');
        }
    }

    /**
     * @rule Valid email address (*@*.*)
     * @returns Boolean
     */
    protected function email($val) {
        if (!(boolean)filter_var($val, FILTER_VALIDATE_EMAIL)) {
            throw new Exception('Invalid email address');
        }

        if (false !== email_exists($val)) {
            throw new Exception('Email address already registered');
        }
    }
}

class Vars {
    /**
     * WordPress option for this module
     * @type WP_Option
     */
    public static $options;
}
?>