mowgli
mowgli

Reputation: 2869

Emulating successful send via phpmailer ($mail->Send())

When I'm building and testing my website on local server, I would like to emulate successful sending via phpmailer, so I avoid actually sending emails.

I normally use if ($mail->Send()) { the mail was sent, now do this }.

For local testing I think the best would be to skip the whole phpmailer inclusion, instead of adding a lot of if statements etc.

But skipping phpmailer would then cause php to complain about $mail->Send(), $mail->addAddress('emailaddress') etc.

How could I fake the function (or object/class) so that calls to $mail->Send() are always true, and the rest $mail->something() etc. are just ignored/true, so that no email is sent?

Upvotes: 2

Views: 940

Answers (2)

steros
steros

Reputation: 1924

Extend the PHPMailer class and override the public function send().

class UnitTestMailer extends PHPMailer {

    public function send() {
        return $this;
    }

}

class User {
   public function __construct(PHPMailer $mailer) {
      $this->mailer = $mailer;
   }

   public function sendActiviation() {
      return $this->mailer->send();
   }
}

// ... somewhere in your test
public function test_if_from_is_properly_set() {
    // ...
    $user = new User(new UnitTestMailer);
    // ...
    $mailer = $user->sendActivation();
    $this->assertEquals($expectedFrom, $mailer->From);
}

Upvotes: 2

SierraOscar
SierraOscar

Reputation: 17647

Why emulate?

I use INI files to provide configuration variables for PHPMailer depending on the environment. Live obviously has the server's mail settings. Local uses my Gmail account credentials to send mail.

You can have the best of both worlds :)


Keep a config.ini file for example somewhere in your working directory (I tend to use root but that's preference) and make sure it's in your .gitignore or similar. Your local version would look something like:

[PHPMailer Settings]
EMAIL_HOST = "smtp.gmail.com"
EMAIL_PORT = 587
EMAIL_SMTPSECURE = "tls"
EMAIL_SMTPAUTH = "true"
EMAIL_USERNAME = "[email protected]"
EMAIL_PASSWORD = "my_password"

then in your PHP:

$ini = parse_ini_file($_SERVER['DOCUMENT_ROOT'] . "/config.ini", true, INI_SCANNER_TYPED);

// use settings from INI file:

$foo = $ini['PHPMailer Settings']['EMAIL_HOST'];
$bar = $ini['PHPMailer Settings']['EMAIL_PORT'];

Security Bonus

Change the syntax of your INI file to look like the below and rename it to config.ini.php:

; <?php
; die();
; /*
[PHPMailer Settings]
EMAIL_HOST = "smtp.gmail.com"
EMAIL_PORT = 587
EMAIL_SMTPSECURE = "tls"
EMAIL_SMTPAUTH = "true"
EMAIL_USERNAME = "[email protected]"
EMAIL_PASSWORD = "my_password"
; */ ?>

(remember to use the new filename in your PHP code)

PHP can still parse the settings, but if anyone tried to access the INI file it would be parsed as PHP comments and just show ";"

Upvotes: 0

Related Questions