Completed
Push — 2.0 ( 7f87f2...afdd14 )
by Roman
16:48
created

OrderEmailNotifier::sendCancelNotification()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 16
ccs 0
cts 15
cp 0
rs 9.4285
cc 1
eloc 12
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 * Handles email notifications to customers and / or admins.
5
 *
6
 * @package shop
7
 */
8
class OrderEmailNotifier
9
{
10
    /**
11
     * @var Order $order
12
     */
13
    protected $order;
14
15
    /**
16
     * @param Order $order
17
     *
18
     * @return OrderEmailNotifier
19
     */
20 12
    public static function create(Order $order)
21
    {
22 12
        return Injector::inst()->create('OrderEmailNotifier', $order);
23
    }
24
25
    /**
26
     * Assign the order to a local variable
27
     *
28
     * @param Order $order
29
     */
30 12
    public function __construct(Order $order)
31
    {
32 12
        $this->order = $order;
33 12
    }
34
35
    /**
36
     * @param string $template
37
     * @param string $subject
38
     *
39
     * @return Email
40
     */
41 3
    private function buildEmail($template, $subject)
42
    {
43 3
        $from = ShopConfig::config()->email_from ? ShopConfig::config()->email_from : Email::config()->admin_email;
44 3
        $to = $this->order->getLatestEmail();
45 3
        $checkoutpage = CheckoutPage::get()->first();
46 3
        $completemessage = $checkoutpage ? $checkoutpage->PurchaseComplete : '';
47
48
        /** @var Email $email */
49 3
        $email = Injector::inst()->create('ShopEmail');
50 3
        $email->setTemplate($template);
51 3
        $email->setFrom($from);
52 3
        $email->setTo($to);
53 3
        $email->setSubject($subject);
54 3
        $email->populateTemplate(
55
            array(
56 3
                'PurchaseCompleteMessage' => $completemessage,
57 3
                'Order'                   => $this->order,
58 3
                'BaseURL'                 => Director::absoluteBaseURL(),
59
            )
60 3
        );
61
62 3
        return $email;
63
    }
64
65
    /**
66
     * Send a mail of the order to the client (and another to the admin).
67
     *
68
     * @param $template    - the class name of the email you wish to send
69
     * @param $subject     - subject of the email
70
     * @param $copyToAdmin - true by default, whether it should send a copy to the admin
71
     *
72
     * @return bool
73
     */
74 2
    public function sendEmail($template, $subject, $copyToAdmin = true)
75
    {
76 2
        $email = $this->buildEmail($template, $subject);
77
78 2
        if ($copyToAdmin) {
79
            $email->setBcc(Email::config()->admin_email);
80
        }
81
82 2
        return $email->send();
83
    }
84
85
    /**
86
     * Send customer a confirmation that the order has been received
87
     */
88 1
    public function sendConfirmation()
89
    {
90 1
        $subject = _t(
91 1
            'ShopEmail.ConfirmationSubject',
92 1
            'Order #{OrderNo} confirmation',
93 1
            '',
94 1
            array('OrderNo' => $this->order->Reference)
0 ignored issues
show
Documentation introduced by
array('OrderNo' => $this->order->Reference) is of type array<string,string,{"OrderNo":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
95 1
        );
96 1
        $this->sendEmail(
97 1
            'Order_ConfirmationEmail',
98 1
            $subject,
99 1
            self::config()->bcc_confirmation_to_admin
100 1
        );
101 1
    }
102
103
    /**
104
     * Notify store owner about new order.
105
     */
106 1
    public function sendAdminNotification()
107
    {
108 1
        $subject = _t(
109 1
            'ShopEmail.AdminNotificationSubject',
110 1
            'Order #{OrderNo} notification',
111 1
            '',
112 1
            array('OrderNo' => $this->order->Reference)
0 ignored issues
show
Documentation introduced by
array('OrderNo' => $this->order->Reference) is of type array<string,string,{"OrderNo":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
113 1
        );
114
115 1
        $this->buildEmail('Order_AdminNotificationEmail', $subject)
116 1
            ->setTo(Email::config()->admin_email)
117 1
            ->send();
118 1
    }
119
120
    /**
121
     * Send customer an order receipt email.
122
     * Precondition: The order payment has been successful
123
     */
124 1
    public function sendReceipt()
125
    {
126 1
        $subject = _t(
127 1
            'ShopEmail.ReceiptSubject',
128 1
            'Order #{OrderNo} receipt',
129 1
            '',
130 1
            array('OrderNo' => $this->order->Reference)
0 ignored issues
show
Documentation introduced by
array('OrderNo' => $this->order->Reference) is of type array<string,string,{"OrderNo":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
131 1
        );
132
133 1
        $this->sendEmail(
134 1
            'Order_ReceiptEmail',
135 1
            $subject,
136 1
            self::config()->bcc_receipt_to_admin
137 1
        );
138 1
        $this->order->ReceiptSent = SS_Datetime::now()->Rfc2822();
139 1
        $this->order->write();
140 1
    }
141
142
    /**
143
     * Sends an email to the admin that an order has been cancelled
144
     */
145
    public function sendCancelNotification()
146
    {
147
        $email = Injector::inst()->create(
148
            'ShopEmail',
149
            Email::config()->admin_email,
150
            Email::config()->admin_email,
151
            _t(
152
                'ShopEmail.CancelSubject',
153
                'Order #{OrderNo} cancelled by member',
154
                '',
155
                array('OrderNo' => $this->order->Reference)
0 ignored issues
show
Documentation introduced by
array('OrderNo' => $this->order->Reference) is of type array<string,string,{"OrderNo":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
156
            ),
157
            $this->order->renderWith('Order')
158
        );
159
        $email->send();
160
    }
161
162
    /**
163
     * Send a message to the client containing the latest
164
     * note of {@link OrderStatusLog} and the current status.
165
     *
166
     * Used in {@link OrderReport}.
167
     *
168
     * @param string $note Optional note-content (instead of using the OrderStatusLog)
169
     */
170 1
    public function sendStatusChange($title, $note = null)
171
    {
172 1
        if (!$note) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $note of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
173 1
            $latestLog = OrderStatusLog::get()
174 1
                ->filter("OrderID", $this->order->ID)
175 1
                ->filter("SentToCustomer", 1)
176 1
                ->first();
177
178 1
            if ($latestLog) {
179
                $note = $latestLog->Note;
180
                $title = $latestLog->Title;
181
            }
182 1
        }
183 1
        $member = $this->order->Member();
0 ignored issues
show
Documentation Bug introduced by
The method Member does not exist on object<Order>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
184 1
        if (Config::inst()->get('OrderProcessor', 'receipt_email')) {
185
            $adminEmail = Config::inst()->get('OrderProcessor', 'receipt_email');
186
        } else {
187 1
            $adminEmail = Email::config()->admin_email;
188
        }
189 1
        $e = Injector::inst()->create('ShopEmail');
190 1
        $e->setTemplate('Order_StatusEmail');
191 1
        $e->populateTemplate(
192
            array(
193 1
                "Order"  => $this->order,
194 1
                "Member" => $member,
195 1
                "Note"   => $note,
196
            )
197 1
        );
198 1
        $e->setFrom($adminEmail);
199 1
        $e->setSubject($title);
200 1
        $e->setTo($member->Email);
201 1
        $e->send();
202 1
    }
203
204 2
    public static function config()
205
    {
206 2
        return new Config_ForClass("OrderEmailNotifier");
207
    }
208
}
209