dimanche 27 novembre 2016

PHP Observer pattern for sending email?

I have a contact form on my website where the client can send messages to me.

When my server receives the message, I want to send a notification to the client and another one to myself (server).

So I thought the observer pattern is suitable to this task where the client and the server are both observers.

Below is my attempt:

Interface:

interface Observer
{
    function onChanged(Observable $Observable, array $params);
}

interface Observable
{
    function addObserver(Observer $Observer);
    function removeObserver(Observer $Observer);
    function notifyObserver(array $params);
}

The concrete observable:

class MessageObservable implements Observable
{
    private $Observers = [];

    public function recieved($message)
    {
        return $this->notifyObserver($message);
    }

    public function addObserver(Observer $Observer)
    {
        $this->Observers[] = $Observer;
    }

    public function notifyObserver(array $params)
    {
        foreach($this->Observers as $Observer) {
            return $Observer->onChanged($this, $params);
        }
    }

    public function removeObserver(Observer $Observer)
    {
        foreach($this->Observers as $observerKey => $observerValue) {
            if ($observerValue === $Observer) {
                unset($this->Observers[ $observerKey ]);
            }
        }
    }
}

The concrete observers:

class ClientObserver implements Observer
{
    public function onChanged(Observable $Observable, array $params)
    {
        // Client e-mail.
        $emailTo = $params['email'];

        // Server e-mail.
        $emailFrom = 'server@example.com';

        // Headers.
        $emailHeaders = "From: " . $params['name'] . " <$emailFrom>";

        // Server subject.
        $emailSubject = 'Message Sent - ' . $params['subject'];

        // Server content.
        $emailContent = "Dear " . $params['name'] . ",

You have sent a message at example.com website using this e-mail.

Your Name : " . $params['name'] . "
Email : " . $params['email'] . "
Subject : " . $params['subject'] . "
Message : " . $params['content'] . "

With thanks,
example.com
";

        // Send email.
        // $sentMail = mail($emailTo, $emailSubject, $emailContent, $emailHeaders);

        // Assume sent OK.
        $sentMail = true;

        // If sent ok.
        if($sentMail) {
            return [
                "status" => "success",
                "message" => "Your message has been sent successfully. Thanks for contacting us."
            ];
        } else {
            return [
                "status" => "fail",
                "message" => "Your message is not sent. Please try again."
            ];
        }

    }
}

class ServerObserver implements Observer
{
    public function onChanged(Observable $Observable, array $params)
    {
        // Server e-mail
        $emailTo = 'server@example.com';

        // Client e-mail
        $emailFrom = $params['email'];

        // Client Headers
        $emailHeaders = "From: " . $params['name'] . " <$emailFrom>";

        // Client subject
        $emailSubject = $params['subject'];

        // Client Message.
        $emailContent = $params['content'];

        // Send email.
        // $sentMail = mail($emailTo, $emailSubject, $emailContent, $emailHeaders);

        // Assume sent OK.
        $sentMail = true;

        return false;
    }
}

On a controller:

$MessageObservable = new MessageObservable();
$ClientObserver = new ClientObserver();
$ServerObserver = new ServerObserver();
$MessageObservable->addObserver($ClientObserver);
$MessageObservable->addObserver($ServerObserver);

$message = [
    'name' => 'Client Name',
    'email' => 'Client Email',
    'subject' => 'Client Subject',
    'content' => 'Client content',
];

$res = $MessageObservable->recieved($message);
print_r($res);

Result:

Array
(
    [status] => success
    [message] => Your message has been sent successfully. Thanks for contacting us.
)

It works fine but I have repeated:

  1. $sentMail = mail($emailTo, $emailSubject, $emailContent, $emailHeaders);

  2. $emailTo, $emailFrom, etc.

Is there anyway to make to better? Or it is not the observer pattern that I should be using?

Aucun commentaire:

Enregistrer un commentaire