0

I am creating a registration and login system using PHP and MYSQL. When the user first signs up with their username, email and password, they should get an email with an activation link. However, although the account details enter the database successfully, the account activation email is not send.

This is my config.php

<?php
// database hostname
define('db_host', 'localhost');
// database username
define('db_user', 'username');
// database password
define('db_pass', 'password');
// database name
define('db_name', 'dbname');
// database charset
define('db_charset', 'utf8');
// Email activation variables
// account activation required?
define('account_activation', true);
define('mail_from', 'StanCafe <noreply@stancafe.com>');
// Link to activation file, update this
define('activation_link', 'https://stancafe.com/StanCafe/activate.php');
?>

this is my main.php

<?php
// The main file contains the database connection, session initializing, and functions, other PHP files will depend on this file.
// Include thee configuration file
include_once 'config.php';
// We need to use sessions, so you should always start sessions using the below code.
session_start();
// No need to edit below
try {
    $pdo = new PDO('mysql:host=' . db_host . ';dbname=' . db_name . ';charset=' . db_charset, db_user, db_pass);
} catch (PDOException $exception) {
    // If there is an error with the connection, stop the script and display the error.
    exit('Failed to connect to database!');
}
// The below function will check if the user is logged-in and also check the remember me cookie
function check_loggedin($pdo, $redirect_file = 'index.php') {
    // Check for remember me cookie variable and loggedin session variable
    if (isset($_COOKIE['rememberme']) && !empty($_COOKIE['rememberme']) && !isset($_SESSION['loggedin'])) {
        // If the remember me cookie matches one in the database then we can update the session variables.
        $stmt = $pdo->prepare('SELECT * FROM accounts WHERE rememberme = ?');
        $stmt->execute([ $_COOKIE['rememberme'] ]);
        $account = $stmt->fetch(PDO::FETCH_ASSOC);
        if ($account) {
            // Found a match, update the session variables and keep the user logged-in
            session_regenerate_id();
            $_SESSION['loggedin'] = TRUE;
            $_SESSION['name'] = $account['username'];
            $_SESSION['id'] = $account['id'];
            $_SESSION['role'] = $account['role'];
        } else {
            // If the user is not remembered redirect to the login page.
            header('Location: ' . $redirect_file);
            exit;
        }
    } else if (!isset($_SESSION['loggedin'])) {
        // If the user is not logged in redirect to the login page.
        header('Location: ' . $redirect_file);
        exit;
    }
}
// Send activation email function
function send_activation_email($email, $code) {
    $subject = 'Account Activation Required';
    $headers = 'From: ' . mail_from . "\r\n" . 'Reply-To: ' . mail_from . "\r\n" . 'Return-Path: ' . mail_from . "\r\n" . 'X-Mailer: PHP/' . phpversion() . "\r\n" . 'MIME-Version: 1.0' . "\r\n" . 'Content-Type: text/html; charset=UTF-8' . "\r\n";
    $activate_link = activation_link . '?email=' . $email . '&code=' . $code;
    $email_template = str_replace('%link%', $activate_link, file_get_contents('https://stancafe.com/StanCafe/activation-email-template.html'));
    mail($email, $subject, $email_template, $headers, '-f ' . mail_from);
}
?>

This is my activation-email-template.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

  <head>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Account Activation Required</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <link href="https://fonts.googleapis.com/css2?family=Montserrat&display=swap" rel="stylesheet">

    <style>

      .heading {
        font-family: 'Montserrat', sans-serif;
        text-align: center;
        font-weight: bold;
        color: white;
        font-size: 2rem;
}

      .footer {
        font-family: "Montserrat", sans-serif;
        font-weight: lighter;
        color: white;
        font-size: 0.8rem;
}

      a {
        text-decoration: none;
}

    </style>


  </head>

  <body style="margin: 0; padding: 0;">

   <table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tr>
     <td  style="padding: 20px 0 30px 0;">

       <table align="center" border="0" cellpadding="0" cellspacing="0" width="600" style="border-collapse: collapse; border: 1px solid #CCCCCC;">
        <tr>
         <td bgcolor="#1DA0F2" style="padding: 40px 0 30px 0;" class="heading">
          Welcome to StanCafe!
         </td>
        </tr>
        <tr>
         <td bgcolor="#FFFFFF" style="padding: 40px 30px 40px 30px;">
           <table border="0" cellpadding="0" cellspacing="0" width="100%">
             <tr>
              <td style="padding: 20px 0 30px 0; text-align: center;">
               <img src="https://img.icons8.com/doodle/100/000000/party-whistle.png" alt="fireworks">
              </td>
             </tr>
             <tr>
              <td style="padding: 20px 0 30px 0; text-align: center; font-family: Montserrat, sans-serif;">
               Thank you for joining StanCafe! We're sure that you'll find some great communities. Before we get started, we'll need you to verify your email.
              </td>
             </tr>
             <tr>
              <td style="padding: 20px 0 30px 0; text-align: center; font-family: Montserrat, sans-serif;">
                <a href="%link%">Click here to activate your account.</a>
              </td>
             </tr>
            </table>
           </td>
          </tr>
          <tr>
           <td bgcolor="#1DA0F2" style="padding: 40px 0 30px 0; text-align: center;" class="footer">
            Sent by StanCafe.<br>Images courtesy of <a href="https://icons8.com/icon/81256/party-whistle">Party Whistle icon by Icons8</a>
           </td>
          </tr>
          <tr>
         </table>

     </td>
    </tr>
   </table>

  </body>


</html>

This is my register.php

<?php
include 'main.php';
// Now we check if the data was submitted, isset() function will check if the data exists.
if (!isset($_POST['username'], $_POST['password'], $_POST['cpassword'], $_POST['email'])) {
    // Could not get the data that should have been sent.
    exit('Please complete the registration form!');
}
// Make sure the submitted registration values are not empty.
if (empty($_POST['username']) || empty($_POST['password']) || empty($_POST['email'])) {
    // One or more values are empty.
    exit('Please complete the registration form');
}
// Check to see if the email is valid.
if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
    exit('Email is not valid!');
}
// Username must contain only characters and numbers.
if (!preg_match('/^[a-zA-Z0-9]+$/', $_POST['username'])) {
    exit('Username is not valid!');
}
// Password must be between 5 and 20 characters long.
if (strlen($_POST['password']) > 20 || strlen($_POST['password']) < 5) {
    exit('Password must be between 5 and 20 characters long!');
}
// Check if both the password and confirm password fields match
if ($_POST['cpassword'] != $_POST['password']) {
    exit('Passwords do not match!');
}
// Check if the account with that username already exists
$stmt = $pdo->prepare('SELECT id, password FROM accounts WHERE username = ? OR email = ?');
$stmt->execute([ $_POST['username'], $_POST['email'] ]);
$account = $stmt->fetch(PDO::FETCH_ASSOC);
// Store the result so we can check if the account exists in the database.
if ($account) {
    // Username already exists
    echo 'Username and/or email exists!';
} else {
    // Username doesnt exists, insert new account
    $stmt = $pdo->prepare('INSERT INTO accounts (username, password, email, activation_code) VALUES (?, ?, ?, ?)');
    // We do not want to expose passwords in our database, so hash the password and use password_verify when a user logs in.
    $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
    $uniqid = account_activation ? uniqid() : '';
    $stmt->execute([ $_POST['username'], $password, $_POST['email'], $uniqid ]);
    if (account_activation) {
        // Account activation required, send the user the activation email with the "send_activation_email" function from the "main.php" file
        send_activation_email($_POST['email'], $uniqid);
        echo 'Please check your email to activate your account!';
    } else {
        echo 'You have successfully registered, you can now login!';
    }
}
?>

When I press Sign Up on the registration page it says 'Please check your email to activate your account!' but no email is sent.

I have tried editing the email's html and using absolute links but nothing has worked..

I would greatly appreciate any help!

Thank you.

Widgit
  • 11
  • 2
  • You sure that a mailing-server is on your system installed? PHP alone can't do that. – Melvin Aug 30 '20 at 22:37
  • Note, don't rely on the output of a SELECT query to avoid inserting duplicates. In a multi-user system, another process could insert into the database between the time when your SELECT runs and your subsequent INSERT runs. Instead, create a UNIQUE constraint on the field in question and then verify that your INSERT succeeded. – Alex Howansky Aug 31 '20 at 00:10
  • @Melvin I have a web host that uses stackcp and that has a mailing sever installed – Widgit Aug 31 '20 at 01:47

0 Answers0