- <?php
-
- /**
- * Email Validation Class
- *
- * Validates and verifies email addresses.
- *
- * @author Adam Delves <adam@sccode.com>
- */
- class EmailValidator
- {
- /**
- * Set to true if this email has not yet been saved to the database
- * @var boolean $newEntry
- */
- private $newEntry = false;
-
- /**
- * ID for this email address. Generated when saved to the database.
- * @var integer $id
- */
- private $id = null;
-
- /**
- * The Email address
- * @var string $email
- */
- private $email = null;
-
- /**
- * Verification code generated for this email address.
- * @var string $v_code
- */
- private $v_code = null;
-
- /**
- * True is the email has been verified.
- * @var boolean $verified
- */
- private $verified = false;
-
- /**
- * True is the email is valid.
- * @var boolean $valid
- */
- private $valid = false;
-
- /**
- * The location of the email database.
- * @var string $EMAIL_FILE
- */
- public static $EMAIL_FILE='emails.dat';
-
- /**
- * Holds a reference to the Sqllite database
- * @var SQLiteDatabase $db
- */
- private static $db = false;
-
- /**
- * Loads the database containing email addresses.
- * @return void
- */
- private static function loadEmailDB()
- {
- $exists = file_exists(self::$EMAIL_FILE);
-
- $error = false;
- self::$db = new SQLiteDatabase(self::$EMAIL_FILE, 0660, $error);
-
- if ($error) {
- throw new Exception('Failed to open email database: ' . $error);
- }
-
-
- @self::$db->queryExec('CREATE TABLE emails (
- id INTEGER PRIMARY KEY,
- email TEXT NOT NULL,
- v_code TEXT NOT NULL,
- verified BOOLEAN DEFAULT 0,
- valid BOOLEAN DEFAULT 0)');
- }
-
-
- /**
- * Class constructor
- *
- * Creates and instance of the EmailValidator using an ID or an email address. If an invalid ID is passed
- * an {link EmailValidatorException} is thrown.
- *
- * @param string $emailOrId The email address to validate or an ID of a previously saved email address.
- */
- public function __construct($emailOrId)
- {
- if (! self::$db) {
- self::loadEmailDB();
- }
-
- if (is_integer($emailOrId)) { // an ID has been passed for a previously saved email
- // search for email in database
- $result = self::$db->query("SELECT id,email,v_code,verified,valid FROM emails
- WHERE id=$emailOrId LIMIT 1", SQLITE_ASSOC);
-
- if ($result->numRows() == 0) {
- throw new EmailValidatorException('Email ID Not Found: ' . $emailOrId);
- } else {
- $emailInfo = $result->current();
-
- foreach($emailInfo as $name => $value) {
- $this->$name = $value;
- }
- }
- } else {
- $this->newEntry = true;
- $this->email = $emailOrId;
- }
- }
-
- /**
- * Class destructor.
- * If this is not a new entry, changes may have been made, to auto save to the database.
- *
- * @return void
- */
- public function __destruct()
- {
- if (! $this->newEntry) {
- $this->save();
- }
- }
-
- /**
- * Saves email and verification code to DB
- * @return integer ID
- */
- public function save()
- {
- $email = addslashes($this->email);
- $v_code = (string) $this->v_code;
- $verified = (int) $this->verified;
- $valid = (int) $this->valid;
-
- // if this is a new entry use an insert query
- if ($this->newEntry) {
- $query = "INSERT INTO emails (email,v_code,verified,valid) VALUES
- ('$email', '$v_code', $verified, $valid)";
- self::$db->queryExec($query);
- $this->newEntry = false;
-
- return ($this->id = self::$db->lastInsertRowid());
- } else {
- $query = "UPDATE emails SET email='$email',v_code='$v_code',
- verified=$verified,valid=$valid WHERE id={$this->id}";
- self::$db->queryExec($query);
- return $this->id;
- }
- }
-
- /**
- * Removes the email from the database.
- * @return void
- */
- public function remove()
- {
- if(! $this->id) {
- return;
- }
-
- $query = "DELETE FROM email WHERE email_id={$this->id}";
- self::$db->queryExec($query);
-
- $this->id = null;
- }
-
-
- /**
- * Pattern matches the email and checks the host name.
- * @return boolean
- */
- public function validate()
- {
- /* syntax check should not be too strict */
- $validatePattern = "/^[a-z0-9\-_~\.]+@(([a-z0-9\-]+\.)+[a-z]+)$/ix";
-
- if (preg_match($validatePattern, $this->email, $matches)) {
- // check the domain part is a valid host name
- if (gethostbynamel($matches[1] . '.') === false) {
- return false;
- } else {
- $this->generateVerificationCode();
- return ($this->valid=true);
- }
- } else {
- return false;
- }
-
- }
-
- /**
- * Checks a verification code.
- * Verification code check is case insensitive. Throws an {@link EmailValidatorException} if the email
- * address has not been validated.
- *
- * @param string $verifyCode 5 character verification code to check
- * @return boolean
- */
- public function verify($verifyCode)
- {
- if (! $this->valid) {
- throw new <a href="../emailvalidate/EmailValidatorException.html">EmailValidatorException</a>('Email must be vlaidated with validate() first.');
- }
-
- return ($this->verified = ($this->v_code == strtoupper($verifyCode)));
- }
-
- /**
- * Sends a verification email containing a verification code.
- * Throws an {@link EmailValidatorException} if the email address has not been validated or has not been
- * saved to the database.
- *
- * @return boolean True if the email was successfully sent, false if not
- */
- public function sendVerificationEmail()
- {
- if (! $this->valid) {
- throw new <a href="../emailvalidate/EmailValidatorException.html">EmailValidatorException</a>('Email must be vlaidated with validate() first.');
- } else if (! $this->id) {
- throw new <a href="../emailvalidate/EmailValidatorException.html">EmailValidatorException</a>('Email must first be saved with save().');
- }
-
- $subject = 'Validation Required';
- $headers = "Content-Type: text/html\r\nSubject: $subject";
- $body =
- <<<BODY
- <html>
- <head>
- </head>
- <body>
- <p>Thank you for registering. Before continuing, we must verify that you have entered the correct email address. Enter the
- verification code below to complete verify your email address.</p>
-
- <p><b>Verification code:</b> {$this->v_code}</p>
- </body>
- </html>
- BODY;
- return @mail($this->email, $subject, $body, $headers);
- }
-
- /**
- * Generates a random verification code.
- * @return string 5 character verification code containing A-Z and 0-9
- */
- private function generateVerificationCode()
- {
- // creates a 5 character random string containing capital letters or numbers
- $string = '';
-
- for ($x = 0; $x < 5; $x++) {
- $opt = rand(0,1);
- if ($opt) {
- // create a random number
- $chr = rand(48,57);
- } else {
- // create a random capital letter
- $chr = rand(65,90);
- }
-
- $string .= chr($chr);
- }
-
- $this->v_code = $string;
- }
-
- /**
- * Sets the value of the email property.
- * Once set, the email must be revalidated.
- *
- * @param $email
- * @return void
- */
- public function setEmail($email)
- {
- $this->valid = false;
- $this->verified = false;
- $this->email = $email;
- }
-
- /**
- * Gets the vlaue of the email {@link EmailValidator::ID ID} property
- * @return integer
- */
- public function getId()
- {
- return $this->id;
- }
-
- /**
- * Gets the value of the {@link EmailValidator::valid valid} property
- * @return boolean
- */
- public function getValid()
- {
- return $this->valid;
- }
-
- /**
- * Gets the value of the {@link EmailValidator::verified verified} property
- * @return boolean
- */
- public function getVerified()
- {
- return $this->verified;
- }
- }
-
- /**
- * Email Exception Class
- *
- * @author Adam Delves <adam@sccode.com>
- */
- class EmailValidatorException extends Exception
- {
- /**
- * @ignore
- */
- public function __construct($message, $code=0)
- {
- parent::__construct($message, (int)$code);
- }
- }