english

learn php

learn css

learn html

learn javascript

learn php

9. web

solution 9.2
4 minutes / 611 words

nine / solution 9.2

<?php

function addError(string $e)
{
    global $errors;
    !isset($errors) && ($errors = []);
    $e == "noData" && ($e = "no data was submitted.");
    $e == "nameMissing" && ($e = "you must have a name.");
    $e == "emailMissing" && ($e = "you must have an email.");
    $e == "passwordMissing" && ($e = "you must have a password.");
    $e == "passwordVerifyMissing" && ($e = "you must verify your password.");
    $e == "agreeMissing" && ($e = "you must agree to the terms and conditions.");
    $e == "nameFailed" && ($e = "your name must be at least your first and last names.");
    $e == "emailFailed" && ($e = "your email must be a valid email.");
    $e == "passwordFailed" && ($e = "your password must match and contain at least one letter, one number and one symbol and be a minimum of eight characters long.");
    !in_array($e, $errors) && ($errors[] = $e);
}

function showErrors()
{
    global $errors;
    if (!isset($errors) || !count($errors)) {
        return;
    }
    print_r("<ul>");
    foreach ($errors as $e) {
        print_r("<li>" . $e . "</li>");
    }
    print_r("</ul>");
}

function doSignup()
{
    global $errors;
    if (!isset($_POST) || !count($_POST)) {
        addError("noData");
        return false;
    }
    $f = [];
    foreach (["name", "email", "password", "passwordVerify"] as $k) {
        !(($f[$k] = getPost($k)) && strlen($f[$k])) && addError($k . "Missing");
    }
    !($f["name"] = verifyName($f["name"])) && addError("nameFailed");
    !($f["email"] = verifyEmail($f["email"])) && addError("emailFailed");
    !($f["hash"] = verifyPassword($f["password"], $f["passwordVerify"])) && addError("passwordFailed");

    // always good to remove passwords from arrays you'll be passing around
    unset($f["password"], $f["passwordVerify"]);

    !getPost("agree") == "yes" && addError("agreeMissing");

    return isset($errors) && count($errors) ? false : verifyUser($f);
}

function verifyName(string $i)
{
    $i = preg_replace('/[^\p{L}\s\'\-]/u', "", $i);
    $i = trim(preg_replace("/\s+/", " ", $i));
    $i = mb_convert_case($i, MB_CASE_TITLE);
    return strlen($i) < 3 || count(explode(" ", $i)) < 2 ? false : $i;
}

function verifyEmail(string $e)
{
    // check for basic pattern ([email protected])
    if (!preg_match("/.+@.+\..+/", $e)) {
        return false;
    }

    // convert to lowercase
    $e = mb_convert_case($e, MB_CASE_LOWER);

    // eliminate whitespace
    $e = preg_replace("/\s+/", "", $e);

    // simplify consecutive periods
    $e = preg_replace("/\.+/", ".", $e);

    // split email into name and domain because their constraints are different
    $name = explode("@", $e)[0];
    $domain = explode("@", $e)[1];

    // check for both elements
    if (!strlen($name) || !strlen($domain)) {
        return false;
    }

    // remove leading/trailing periods
    $name = trim($name, ".");
    $domain = trim($domain, ".");

    // remove invalid characters from both sections
    $name = preg_replace("/[^a-z0-9!#%\$&\'\*\+\-\/\=\?\^_`\{|\}~\.]/", "", $name);
    $domain = preg_replace("/[^a-z0-9\-\.]/", "", $domain);

    // crop name to 64 characters
    $name = substr($name, 0, 64);

    // crop each domain segment to 63 characters
    $domain = explode(".", $domain);
    foreach ($domain as &$i) {
        $i = substr($i, 0, 63);
    }
    $domain = implode(".", $domain);

    // check for both elements again (in case all characters were invalid)
    if (!strlen($name) || !strlen($domain)) {
        return false;
    }

    // rebuild email
    $e = $name . "@" . $domain;

    return $e;
}

function verifyPassword(string $p, string $q)
{
    return $p !== $q || !preg_match("/^(?=.*[A-Za-z])(?=.*\d)(?=.*[\W_]).{8,}$/", $p) ? false : password_hash($p, PASSWORD_DEFAULT);
}

function verifyUser(array $f)
{
    if (!count($f) || !isset($f["name"]) || !isset($f["email"]) || !isset($f["hash"])) {
        return false;
    }
    // you can hardcode the server url if you know it
    $protocol = (!empty($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] !== "off") || $_SERVER["SERVER_PORT"] == 443 ? "https://" : "http://";
    $url = $protocol . $_SERVER["HTTP_HOST"];
    $f["id"] = uniqid("", true);
    $f["verification"] = randomString(64);
    $f["verificationLink"] = $url . "/verifyUser.php?" . $f["verification"];
    print_r("<p>welcome, " . explode(" ", $f["name"])[0] . "! please check your email for a verification link.</p>");
    return $f;
}

function randomString(int $length = 32, string $c = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", $s = "")
{
    for ($i = 0; $i < $length; $i++) {
        $s .= $c[random_int(0, strlen($c) - 1)];
    }
    return $s;
}

function getPost(string $k)
{
    return !isset($_POST) || !isset($_POST[$k]) || !strlen($_POST[$k]) ? "" : $_POST[$k];
}

!($user = doSignup()) && showErrors();

learn php

learn css

learn html

learn javascript

powered by akelei. an avi sato project.