performMinimumRequirementsCheck()) { $this->runApplication(); } } /** * Performs a check for minimum requirements to run this application. * Does not run the further application when PHP version is lower than 5.3.7 * Does include the PHP password compatibility library when PHP version lower than 5.5.0 * (this library adds the PHP 5.5 password hashing functions to older versions of PHP) * @return bool Success status of minimum requirements check, default is false */ private function performMinimumRequirementsCheck() { if (version_compare(PHP_VERSION, '5.3.7', '<')) { echo "Sorry, Simple PHP Login does not run on a PHP version older than 5.3.7 !"; } elseif (version_compare(PHP_VERSION, '5.5.0', '<')) { require_once("_tools/_php_login/libraries/password_compatibility_library.php"); return true; } elseif (version_compare(PHP_VERSION, '5.5.0', '>=')) { return true; } // default return return false; } /** * This is basically the controller that handles the entire flow of the application. */ public function runApplication() { // check is user wants to see register page (etc.) $this->doRegistration(); $this->showPageRegistration(); } /** * Creates a PDO database connection (in this case to a SQLite flat-file database) * @return bool Database creation success status, false by default */ private function createDatabaseConnection() { try { $this->db_connection = new PDO($this->db_type . ':' . $this->db_sqlite_path); return true; } catch (PDOException $e) { $this->feedback = "PDO database connection problem: " . $e->getMessage(); } catch (Exception $e) { $this->feedback = "General problem: " . $e->getMessage(); } return false; } /** * The registration flow * @return bool */ private function doRegistration() { if ($this->checkRegistrationData()) { if ($this->createDatabaseConnection()) { $this->createNewUser(); } } // default return return false; } /** * Validates the user's registration input * @return bool Success status of user's registration data validation */ private function checkRegistrationData() { // if no registration form submitted: exit the method if (!isset($_POST["register"])) { return false; } // validating the input if (!empty($_POST['user_name']) && strlen($_POST['user_name']) <= 64 && strlen($_POST['user_name']) >= 2 && preg_match('/^[a-z\d]{2,64}$/i', $_POST['user_name']) && !empty($_POST['user_email']) && strlen($_POST['user_email']) <= 64 && filter_var($_POST['user_email'], FILTER_VALIDATE_EMAIL) && !empty($_POST['user_password_new']) && !empty($_POST['user_password_repeat']) && ($_POST['user_password_new'] === $_POST['user_password_repeat']) ) { // only this case return true, only this case is valid return true; } elseif (empty($_POST['user_name'])) { $this->feedback = "Empty Username"; } elseif (empty($_POST['user_password_new']) || empty($_POST['user_password_repeat'])) { $this->feedback = "Empty Password"; } elseif ($_POST['user_password_new'] !== $_POST['user_password_repeat']) { $this->feedback = "Password and password repeat are not the same"; } elseif (strlen($_POST['user_password_new']) < 6) { $this->feedback = "Password has a minimum length of 6 characters"; } elseif (strlen($_POST['user_name']) > 64 || strlen($_POST['user_name']) < 2) { $this->feedback = "Username cannot be shorter than 2 or longer than 64 characters"; } elseif (!preg_match('/^[a-z\d]{2,64}$/i', $_POST['user_name'])) { $this->feedback = "Username does not fit the name scheme: only a-Z and numbers are allowed, 2 to 64 characters"; } elseif (empty($_POST['user_email'])) { $this->feedback = "Email cannot be empty"; } elseif (strlen($_POST['user_email']) > 64) { $this->feedback = "Email cannot be longer than 64 characters"; } elseif (!filter_var($_POST['user_email'], FILTER_VALIDATE_EMAIL)) { $this->feedback = "Your email address is not in a valid email format"; } else { $this->feedback = "An unknown error occurred."; } // default return return false; } /** * Creates a new user. * @return bool Success status of user registration */ private function createNewUser() { // remove html code etc. from username and email $user_name = htmlentities($_POST['user_name'], ENT_QUOTES); $user_email = htmlentities($_POST['user_email'], ENT_QUOTES); $user_password = $_POST['user_password_new']; // crypt the user's password with the PHP 5.5's password_hash() function, results in a 60 char hash string. // the constant PASSWORD_DEFAULT comes from PHP 5.5 or the password_compatibility_library $user_password_hash = password_hash($user_password, PASSWORD_DEFAULT); $sql = 'SELECT * FROM users WHERE user_name = :user_name OR user_email = :user_email'; $query = $this->db_connection->prepare($sql); $query->bindValue(':user_name', $user_name); $query->bindValue(':user_email', $user_email); $query->execute(); // As there is no numRows() in SQLite/PDO (!!) we have to do it this way: // If you meet the inventor of PDO, punch him. Seriously. $result_row = $query->fetchObject(); if ($result_row) { $this->feedback = "Sorry, that username / email is already taken. Please choose another one."; } else { $sql = 'INSERT INTO users (user_name, user_password_hash, user_email) VALUES(:user_name, :user_password_hash, :user_email)'; $query = $this->db_connection->prepare($sql); $query->bindValue(':user_name', $user_name); $query->bindValue(':user_password_hash', $user_password_hash); $query->bindValue(':user_email', $user_email); // PDO's execute() gives back TRUE when successful, FALSE when not // @link http://stackoverflow.com/q/1661863/1114320 $registration_success_state = $query->execute(); if ($registration_success_state) { $this->feedback = "Your account has been created successfully. You can now log in."; return true; } else { $this->feedback = "Sorry, your registration failed. Please go back and try again."; } } // default return return false; } /** * Simple demo-"page" with the registration form. * In a real application you would probably include an html-template here, but for this extremely simple * demo the "echo" statements are totally okay. */ private function showPageRegistration() { if ($this->feedback) { echo $this->feedback . "

"; } echo '

Registration

'; echo '
'; echo ''; echo '
'; echo ''; echo '
'; echo ''; echo '
'; echo ''; echo '
'; echo ''; echo ''; echo ''; echo '
'; } } // run the application $application = new OneFileRegisterApplication($MYARGS);