Completed
Push — master ( 3c661d...2a57f9 )
by Will
26s queued 12s
created

src/Checkout/OrderEmailNotifier.php (2 issues)

1
<?php
2
3
namespace SilverShop\Checkout;
4
5
use SilverShop\Extension\ShopConfigExtension;
6
use SilverShop\Model\Order;
7
use SilverShop\Model\OrderStatusLog;
8
use SilverShop\Page\CheckoutPage;
9
use SilverStripe\Control\Director;
10
use SilverStripe\Control\Email\Email;
11
use SilverStripe\Core\Config\Config;
12
use SilverStripe\Core\Config\Configurable;
13
use SilverStripe\Core\Injector\Injectable;
14
use SilverStripe\Core\Injector\Injector;
15
16
/**
17
 * Handles email notifications to customers and / or admins.
18
 *
19
 * @package shop
20
 */
21
class OrderEmailNotifier
22
{
23
    use Injectable;
24
    use Configurable;
25
26
    /**
27
     * @var Order $order
28
     */
29
    protected $order;
30
31
    /**
32
     * @var bool
33
     */
34
    protected $debugMode = false;
35
36
    /**
37
     * Assign the order to a local variable
38
     *
39
     * @param Order $order
40
     */
41
    public function __construct(Order $order)
42
    {
43
        $this->order = $order;
44
    }
45
46
    /**
47
     * @param bool $bool
48
     * @return $this
49
     */
50
    public function setDebugMode($bool)
51
    {
52
        $this->debugMode = $bool;
53
        return $this;
54
    }
55
56
    /**
57
     * @param string $template
58
     * @param string $subject
59
     *
60
     * @return Email
61
     */
62
    protected function buildEmail($template, $subject)
63
    {
64
        $from = ShopConfigExtension::config()->email_from ? ShopConfigExtension::config()->email_from : Email::config()->admin_email;
65
        $to = $this->order->getLatestEmail();
66
        $checkoutpage = CheckoutPage::get()->first();
67
        $completemessage = $checkoutpage ? $checkoutpage->PurchaseComplete : '';
68
69
        /**
70
         * @var Email $email
71
         */
72
        $email = Email::create()
73
            ->setHTMLTemplate($template)
74
            ->setFrom($from)
75
            ->setTo($to)
76
            ->setSubject($subject);
77
78
        $email->setData(
79
            [
80
                'PurchaseCompleteMessage' => $completemessage,
81
                'Order' => $this->order,
82
                'BaseURL' => Director::absoluteBaseURL(),
83
            ]
84
        );
85
86
        return $email;
87
    }
88
89
    /**
90
     * Send a mail of the order to the client (and another to the admin).
91
     *
92
     * @param string $template    - the class name of the email you wish to send
93
     * @param string $subject     - subject of the email
94
     * @param bool   $copyToAdmin - true by default, whether it should send a copy to the admin
95
     *
96
     * @return bool|string
97
     */
98
    public function sendEmail($template, $subject, $copyToAdmin = true)
99
    {
100
        $email = $this->buildEmail($template, $subject);
101
102
        if ($copyToAdmin) {
103
            $email->setBcc(Email::config()->admin_email);
104
        }
105
        if ($this->debugMode) {
106
            return $this->debug($email);
107
        } else {
108
            return $email->send();
109
        }
110
    }
111
112
    /**
113
     * Send customer a confirmation that the order has been received
114
     *
115
     * @return bool
116
     */
117
    public function sendConfirmation()
118
    {
119
        $subject = _t(
120
            'SilverShop\ShopEmail.ConfirmationSubject',
121
            'Order #{OrderNo} confirmation',
122
            '',
123
            array('OrderNo' => $this->order->Reference)
124
        );
125
        return $this->sendEmail(
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->sendEmail(..._confirmation_to_admin) also could return the type string which is incompatible with the documented return type boolean.
Loading history...
126
            'SilverShop/Model/Order_ConfirmationEmail',
127
            $subject,
128
            self::config()->bcc_confirmation_to_admin
129
        );
130
    }
131
132
    /**
133
     * Notify store owner about new order.
134
     *
135
     * @return bool|string
136
     */
137
    public function sendAdminNotification()
138
    {
139
        $subject = _t(
140
            'SilverShop\ShopEmail.AdminNotificationSubject',
141
            'Order #{OrderNo} notification',
142
            '',
143
            array('OrderNo' => $this->order->Reference)
144
        );
145
146
        $email = $this->buildEmail('SilverShop/Model/Order_AdminNotificationEmail', $subject)
147
            ->setTo(Email::config()->admin_email);
148
149
        if ($this->debugMode) {
150
            return $this->debug($email);
151
        } else {
152
            return $email->send();
153
        }
154
    }
155
156
    /**
157
     * Send customer an order receipt email.
158
     * Precondition: The order payment has been successful
159
     */
160
    public function sendReceipt()
161
    {
162
        $subject = _t(
163
            'SilverShop\ShopEmail.ReceiptSubject',
164
            'Order #{OrderNo} receipt',
165
            '',
166
            array('OrderNo' => $this->order->Reference)
167
        );
168
169
        return $this->sendEmail(
170
            'SilverShop/Model/Order_ReceiptEmail',
171
            $subject,
172
            self::config()->bcc_receipt_to_admin
173
        );
174
    }
175
176
    /**
177
     * Sends an email to the admin that an order has been cancelled
178
     */
179
    public function sendCancelNotification()
180
    {
181
        $email = Email::create()
182
            ->setSubject(_t(
183
                'SilverShop\ShopEmail.CancelSubject',
184
                'Order #{OrderNo} cancelled by member',
185
                '',
186
                ['OrderNo' => $this->order->Reference]
187
            ))
188
            ->setFrom(Email::config()->admin_email)
189
            ->setTo(Email::config()->admin_email)
190
            ->setBody($this->order->renderWith(Order::class));
191
192
        if ($this->debugMode) {
193
            return $this->debug($email);
194
        } else {
195
            return $email->send();
196
        }
197
    }
198
199
    /**
200
     * Send an email to the customer containing the latest note of {@link OrderStatusLog} and the current status.
201
     *
202
     * @param string $title Subject for email
203
     * @param string $note  Optional note-content (instead of using the OrderStatusLog)
204
     *
205
     * @return bool|string
206
     */
207
    public function sendStatusChange($title, $note = null)
208
    {
209
        if (!$note) {
210
            $latestLog = OrderStatusLog::get()
211
                ->filter("OrderID", $this->order->ID)
212
                ->filter("SentToCustomer", 1)
213
                ->first();
214
215
            if ($latestLog) {
0 ignored issues
show
$latestLog is of type SilverStripe\ORM\DataObject, thus it always evaluated to true.
Loading history...
216
                $note = $latestLog->Note;
217
                $title = $latestLog->Title;
218
            }
219
        }
220
221
        if (Config::inst()->get(OrderProcessor::class, 'receipt_email')) {
222
            $adminEmail = Config::inst()->get(OrderProcessor::class, 'receipt_email');
223
        } else {
224
            $adminEmail = Email::config()->admin_email;
225
        }
226
227
        /**
228
         * @var Email $e
229
         */
230
        $email = Email::create()
231
            ->setFrom($adminEmail)
232
            ->setSubject(_t('SilverShop\ShopEmail.StatusChangeSubject', 'SilverShop – {Title}', ['Title' => $title]))
233
            ->setTo($this->order->getLatestEmail())
234
            ->setHTMLTemplate('SilverShop/Model/Order_StatusEmail')
235
            ->setData(
236
                [
237
                    'Order' => $this->order,
238
                    'Note' => $note,
239
                    'FromEmail' => $adminEmail
240
                ]
241
            );
242
243
        if ($this->debugMode) {
244
            return $this->debug($email);
245
        } else {
246
            return $email->send();
247
        }
248
    }
249
250
    /**
251
     * The new Email::debug method in SilverStripe dumps the entire message with all message parts,
252
     * which makes it unusable to preview an Email.
253
     * This method simulates the old way of the message output and renders only the HTML body.
254
     *
255
     * @param Email $email
256
     * @return string
257
     */
258
    protected function debug(Email $email)
259
    {
260
        $email->render();
261
        $template = $email->getHTMLTemplate();
262
        $headers = $email->getSwiftMessage()->getHeaders()->toString();
263
264
        return "<h2>Email HTML template: $template</h2>\n" .
265
            "<pre>$headers</pre>" .
266
            $email->getBody();
267
    }
268
}
269