Completed
Push — master ( a41cf8...39b49d )
by Nicolaas
04:41
created

OrderConfirmationPage_Controller::sendemail()   D

Complexity

Conditions 9
Paths 19

Size

Total Lines 43
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
dl 0
loc 43
rs 4.909
c 0
b 0
f 0
eloc 30
nc 19
nop 1
1
<?php
2
3
/**
4
 * @description:
5
 * The Order Confirmation page shows order history.
6
 * It also serves as the end point for the current order...
7
 * once submitted, the Order Confirmation page shows the
8
 * finalised detail of the order.
9
 *
10
 *
11
 * @authors: Nicolaas [at] Sunny Side Up .co.nz
12
 * @package: ecommerce
13
 * @sub-package: Pages
14
 * @inspiration: Silverstripe Ltd, Jeremy
15
 **/
16
class OrderConfirmationPage extends CartPage
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
17
{
18
    /**
19
     * Standard SS variable.
20
     *
21
     * @var string
22
     */
23
    private static $icon = 'ecommerce/images/icons/OrderConfirmationPage';
24
25
    /**
26
     * Standard SS variable.
27
     *
28
     * @var array
29
     */
30
    private static $db = array(
31
        'StartNewOrderLinkLabel' => 'Varchar(100)',
32
        'CopyOrderLinkLabel' => 'Varchar(100)',
33
        'OrderCancelledHeader' => 'Varchar(255)',
34
        'PaymentSuccessfulHeader' => 'Varchar(255)',
35
        'PaymentNotSuccessfulHeader' => 'Varchar(255)',
36
        'PaymentPendingHeader' => 'Varchar(255)',
37
        'OrderCancelledMessage' => 'HTMLText',
38
        'PaymentSuccessfulMessage' => 'HTMLText',
39
        'PaymentNotSuccessfulMessage' => 'HTMLText',
40
        'PaymentPendingMessage' => 'HTMLText',
41
        'EnableGoogleAnalytics' => 'Boolean',
42
    );
43
44
    /**
45
     * Standard SS variable.
46
     *
47
     * @var array
48
     */
49
    private static $defaults = array(
50
        'ShowInMenus' => false,
51
        'ShowInSearch' => false,
52
        'StartNewOrderLinkLabel' => 'start new order',
53
        'CopyOrderLinkLabel' => 'copy order items into a new order',
54
        'OrderCancelledHeader' => 'Order has been cancelled',
55
        'PaymentSuccessfulHeader' => 'Payment Successful',
56
        'PaymentNotSuccessfulHeader' => 'Payment not Completed',
57
        'PaymentPendingHeader' => 'Payment Pending',
58
        'OrderCancelledMessage' => '<p>This order is no longer valid.</p>',
59
        'PaymentSuccessfulMessage' => '<p>Your order will be processed.</p>',
60
        'PaymentNotSuccessfulMessage' => '<p>Your order will not be processed until your payment has been completed.</p>',
61
        'PaymentPendingMessage' => '<p>Please complete your payment before the order can be processed.</p>',
62
    );
63
64
    private static $casting = array(
65
        "PaymentMessage" => "HTMLText"
66
    );
67
68
    /**
69
     * standard SS variable.
70
     *
71
     * @Var String
72
     */
73
    private static $singular_name = 'Order Confirmation Page';
74
    public function i18n_singular_name()
75
    {
76
        return _t('OrderConfirmationpage.SINGULARNAME', 'Order Confirmation Page');
77
    }
78
79
    /**
80
     * standard SS variable.
81
     *
82
     * @Var String
83
     */
84
    private static $plural_name = 'Order Confirmation Pages';
85
    public function i18n_plural_name()
86
    {
87
        return _t('OrderConfirmationpage.PLURALNAME', 'Order Confirmation Pages');
88
    }
89
90
    /**
91
     * Standard SS variable.
92
     *
93
     * @var string
94
     */
95
    private static $description = 'A page where the customer can view her or his submitted order. Every e-commerce site needs an Order Confirmation Page.';
96
97
    /**
98
     * Standard SS function, we only allow for one OrderConfirmation Page to exist
99
     * but we do allow for extensions to exist at the same time.
100
     *
101
     * @param Member $member
102
     *
103
     * @return bool
104
     */
105
    public function canCreate($member = null)
106
    {
107
        return OrderConfirmationPage::get()->filter(array('ClassName' => 'OrderConfirmationPage'))->Count() ? false : $this->canEdit($member);
108
    }
109
110
    /**
111
     * Shop Admins can edit.
112
     *
113
     * @param Member $member
114
     *
115
     * @return bool
116
     */
117
    public function canEdit($member = null)
118
    {
119
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
120
            return true;
121
        }
122
123
        return parent::canEdit($member);
124
    }
125
126
    /**
127
     * Standard SS method.
128
     *
129
     * @param Member $member
130
     *
131
     * @return bool
132
     */
133
    public function canDelete($member = null)
134
    {
135
        return false;
136
    }
137
138
    /**
139
     * Standard SS method.
140
     *
141
     * @param Member $member
142
     *
143
     * @return bool
144
     */
145
    public function canPublish($member = null)
146
    {
147
        return $this->canEdit($member);
148
    }
149
150
    public function customFieldLabels()
151
    {
152
        $newLabels = array(
153
            'StartNewOrderLinkLabel' => _t('OrderConfirmationPage.STARTNEWORDERLINKLABEL', 'Label for starting new order - e.g. click here to start new order.'),
154
            'CopyOrderLinkLabel' => _t('OrderConfirmationPage.COPYORDERLINKLABEL', 'Label for copying order items into a new one  - e.g. click here start a new order with the current order items.'),
155
            'OrderCancelledHeader' => _t('OrderConfirmationPage.ORDERCANCELLEDHEADER', 'Header showing when order has been cancelled.'),
156
            'PaymentSuccessfulHeader' => _t('OrderConfirmationPage.PAYMENTSUCCESSFULHEADER', 'Header showing when order has been paid in full.'),
157
            'PaymentNotSuccessfulHeader' => _t('OrderConfirmationPage.PAYMENTNOTSUCCESSFULHEADER', 'Header showing when the order has not been paid in full.'),
158
            'PaymentPendingHeader' => _t('OrderConfirmationPage.PAYMENTPENDINGHEADER', 'Header showing when the order has not been paid in full - but the payment is pending.'),
159
            'OrderCancelledMessage' => _t('OrderConfirmationPage.ORDERCANCELLEDMESSAGE', 'Message showing when order has been paid cancelled.'),
160
            'PaymentSuccessfulMessage' => _t('OrderConfirmationPage.PAYMENTSUCCESSFULMESSAGE', 'Message showing when order has been paid in full.'),
161
            'PaymentNotSuccessfulMessage' => _t('OrderConfirmationPage.PAYMENTNOTSUCCESSFULMESSAGE', 'Message showing when the order has not been paid in full.'),
162
            'PaymentPendingMessage' => _t('OrderConfirmationPage.PAYMENTPENDINGMESSAGE', 'Message showing when the order has not been paid in full - but the payment is pending.'),
163
            'EnableGoogleAnalytics' => _t('OrderConfirmationPage.ENABLEGOOGLEANALYTICS', 'Enable E-commerce Google Analytics.  Make sure it is turned on in your Google Analytics account.'),
164
        );
165
166
        return $newLabels;
167
    }
168
169
    /**
170
     * standard SS method for decorators.
171
     *
172
     * @param bool - $includerelations: array of fields to start with
173
     *
174
     * @return array
175
     */
176
    public function fieldLabels($includerelations = true)
177
    {
178
        $defaultLabels = parent::fieldLabels();
179
        $newLabels = $this->customFieldLabels();
180
        $labels = array_merge($defaultLabels, $newLabels);
181
        $extendedArray = $this->extend('updateFieldLabels', $labels);
182
        if ($extendedArray !== null && is_array($extendedArray) && count($extendedArray)) {
183
            foreach ($extendedArray as $extendedResult) {
184
                $labels = array_merge($labels, $extendedResult);
185
            }
186
        }
187
188
        return $labels;
189
    }
190
191
    /**
192
     *@return FieldList
193
     **/
194
    public function getCMSFields()
195
    {
196
        $fields = parent::getCMSFields();
197
        $fields->removeFieldFromTab('Root.Messages.Messages.Actions', 'ProceedToCheckoutLabel');
198
        $fields->removeFieldFromTab('Root.Messages.Messages.Actions', 'ContinueShoppingLabel');
199
        $fields->removeFieldFromTab('Root.Messages.Messages.Actions', 'ContinuePageID');
200
        $fields->removeFieldFromTab('Root.Messages.Messages.Actions', 'SaveOrderLinkLabel');
201
        $fields->removeFieldFromTab('Root.Messages.Messages.Errors', 'NoItemsInOrderMessage');
202
        $fieldLabels = $this->fieldLabels();
203
        $fields->addFieldToTab('Root.Messages.Messages.Actions', new TextField('StartNewOrderLinkLabel', $fieldLabels['StartNewOrderLinkLabel']));
204
        $fields->addFieldToTab('Root.Messages.Messages.Actions', new TextField('CopyOrderLinkLabel', $fieldLabels['CopyOrderLinkLabel']));
205
        $fields->addFieldsToTab('Root.Messages.Messages.Payment', array(
206
            HeaderField::create('Successful'),
207
            TextField::create('PaymentSuccessfulHeader', $fieldLabels['PaymentSuccessfulHeader']),
208
            HTMLEditorField::create('PaymentSuccessfulMessage', $fieldLabels['PaymentSuccessfulMessage'])->setRows(3),
209
            HeaderField::create('Unsuccessful'),
210
            TextField::create('PaymentNotSuccessfulHeader', $fieldLabels['PaymentNotSuccessfulHeader']),
211
            HTMLEditorField::create('PaymentNotSuccessfulMessage', $fieldLabels['PaymentNotSuccessfulMessage'])->setRows(3),
212
            HeaderField::create('Pending'),
213
            TextField::create('PaymentPendingHeader', $fieldLabels['PaymentPendingHeader']),
214
            HTMLEditorField::create('PaymentPendingMessage', $fieldLabels['PaymentPendingMessage'])->setRows(3),
215
            HeaderField::create('Cancelled'),
216
            TextField::create('OrderCancelledHeader', $fieldLabels['OrderCancelledHeader']),
217
            HTMLEditorField::create('OrderCancelledMessage', $fieldLabels['OrderCancelledMessage'])->setRows(3),
218
        ));
219
        $fields->addFieldToTab('Root.Analytics', new CheckboxField('EnableGoogleAnalytics', $fieldLabels['EnableGoogleAnalytics']));
220
221
        return $fields;
222
    }
223
224
    /**
225
     * Returns the link or the Link to the OrderConfirmationPage page on this site.
226
     * @param string $action [optional]
227
     * @return string (URLSegment)
228
     */
229
    public static function find_link($action = null)
230
    {
231
        if ($page = OrderConfirmationPage::get()->filter(array('ClassName' => 'OrderConfirmationPage'))->First()) {
232
            return $page->Link($action);
233
        } elseif ($page = OrderConfirmationPage::get()->First()) {
234
            return $page->Link($action);
235
        }
236
237
        return CartPage::find_link();
238
    }
239
240
    /**
241
     * Return a link to view the order on this page.
242
     *
243
     * @param int|string $orderID ID of the order
244
     *
245
     * @return string (URLSegment)
246
     */
247
    public static function get_order_link($orderID)
248
    {
249
        return OrderConfirmationPage::find_link().'showorder/'.$orderID.'/';
250
    }
251
252
    /**
253
     * Return a link to view the order on this page.
254
     *
255
     * @param int|string $orderID                ID of the order
256
     * @param string     $type                   - the type of email you want to send.
257
     * @param bool       $actuallySendEmail      - do we actually send the email
258
     * @param int        $alternativeOrderStepID - OrderStep to use
259
     *
260
     * @return string (URLSegment)
261
     */
262
    public static function get_email_link($orderID, $emailClassName = 'Order_StatusEmail', $actuallySendEmail = false, $alternativeOrderStepID = 0)
263
    {
264
        $link = OrderConfirmationPage::find_link().'sendemail/'.$orderID.'/'.$emailClassName;
265
        $getParams = array();
266
        if ($actuallySendEmail) {
267
            $getParams['send'] = 1;
268
        }
269
        if ($alternativeOrderStepID) {
270
            $getParams['use'] = $alternativeOrderStepID;
271
        }
272
        $query = parse_url($url, PHP_URL_QUERY);
273
        $getParams = http_build_query($getParams);
274
        if ($query) {
275
            $url .= '&'.$getParams
276
        } else {
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected '}'
Loading history...
277
            $url .= '?'.$getParams;
278
        }
279
        return $link;
280
    }
281
282
    /**
283
     * Return a link to view the order on this page.
284
     *
285
     * @param int|string $orderID ID of the order
286
     *
287
     * @return string (URLSegment)
288
     */
289
    public function getOrderLink($orderID)
290
    {
291
        return OrderConfirmationPage::get_order_link($orderID);
292
    }
293
294
    /**
295
     * returns the Checkout_StepDescription assocatiated with the final step: the order confirmation.
296
     *
297
     * @param bool $isCurrentStep
298
     *
299
     * @return Checkout_StepDescription
300
     */
301
    public function CurrentCheckoutStep($isCurrentStep = false)
302
    {
303
        $do = new CheckoutPage_StepDescription();
304
        $do->Link = $this->Link;
305
        $do->Heading = $this->MenuTitle;
306
        $do->Code = $this->URLSegment;
307
        $do->LinkingMode = 'notCompleted';
308
        if ($isCurrentStep) {
309
            $do->LinkingMode .= ' current';
310
        }
311
        $do->Completed = 0;
312
        $do->ID = 99;
313
314
        return $do;
315
    }
316
317
    /**
318
     * standard SS method for use in templates
319
     * we are overriding the code from the Cart Page here.
320
     *
321
     * @return string
322
     */
323
    public function LinkingMode()
324
    {
325
        return parent::LinkingMode();
326
    }
327
328
    /**
329
     * standard SS method for use in templates
330
     * we are overriding the code from the Cart Page here.
331
     *
332
     * @return string
333
     */
334
    public function LinkOrSection()
335
    {
336
        return parent::LinkOrSection();
337
    }
338
339
    /**
340
     * standard SS method for use in templates
341
     * we are overriding the code from the Cart Page here.
342
     *
343
     * @return string
344
     */
345
    public function LinkOrCurrent()
346
    {
347
        return parent::LinkOrCurrent();
348
    }
349
350
    public function requireDefaultRecords()
351
    {
352
        parent::requireDefaultRecords();
353
        $checkoutPage = CheckoutPage::get()->first();
354
        if ($checkoutPage) {
355
            $orderConfirmationPage = OrderConfirmationPage::get()->first();
356
            if (!$orderConfirmationPage) {
357
                $orderConfirmationPage = OrderConfirmationPage::create();
358
                $orderConfirmationPage->Title = 'Order Confirmation';
359
                $orderConfirmationPage->MenuTitle = 'Order Confirmation';
360
                $orderConfirmationPage->URLSegment = 'order-confirmation';
361
                $orderConfirmationPage->writeToStage('Stage');
362
                $orderConfirmationPage->publish('Stage', 'Live');
363
            }
364
        }
365
    }
366
}
367
368
class OrderConfirmationPage_Controller extends CartPage_Controller
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
369
{
370
    /**
371
     * @static array
372
     * standard SS variable
373
     * it is important that we list all the options here
374
     */
375
    private static $allowed_actions = array(
376
        'saveorder',
377
        'sendreceipt',
378
        'CreateAccountForm',
379
        'retrieveorder',
380
        'loadorder',
381
        'startneworder',
382
        'showorder',
383
        'copyorder',
384
        'sendemail',
385
        'CancelForm',
386
        'PaymentForm',
387
    );
388
389
    /**
390
     * standard controller function.
391
     **/
392
    public function init()
393
    {
394
        //we retrieve the order in the parent page
395
        //the parent page also takes care of the security
396
        if ($sessionOrderID = Session::get('CheckoutPageCurrentOrderID')) {
397
            $this->currentOrder = Order::get()->byID($sessionOrderID);
398
            if ($this->currentOrder) {
399
                $this->overrideCanView = true;
400
                //more than an hour has passed...
401
                if (strtotime($this->currentOrder->LastEdited) < (strtotime('Now') - 60 * 60)) {
402
                    Session::clear('CheckoutPageCurrentOrderID');
403
                    Session::clear('CheckoutPageCurrentOrderID');
404
                    Session::set('CheckoutPageCurrentOrderID', 0);
405
                    Session::save();
406
                    $this->overrideCanView = false;
407
                    $this->currentOrder = null;
408
                }
409
            }
410
        }
411
        parent::init();
412
        Requirements::themedCSS('Order', 'ecommerce');
413
        Requirements::themedCSS('Order_Print', 'ecommerce', 'print');
414
        Requirements::themedCSS('CheckoutPage', 'ecommerce');
415
        Requirements::javascript('ecommerce/javascript/EcomPayment.js');
416
        Requirements::javascript('ecommerce/javascript/EcomPrintAndMail.js');
417
        $this->includeGoogleAnalyticsCode();
418
    }
419
420
    /**
421
     * This method exists just so that template
422
     * sets CurrentOrder variable.
423
     *
424
     * @param HTTPRequest
425
     *
426
     * @return array
427
     **/
428
    public function showorder(SS_HTTPRequest $request)
429
    {
430
        isset($project) ? $themeBaseFolder = $project : $themeBaseFolder = 'mysite';
431
        if (isset($_REQUEST['print'])) {
432
            Requirements::clear();
433
            Requirements::themedCSS('typography', $themeBaseFolder); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
434
            Requirements::themedCSS('OrderReport', 'ecommerce'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
435
            Requirements::themedCSS('Order_Invoice', 'ecommerce'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
436
            Requirements::themedCSS('Order_Invoice_Print_Only', 'ecommerce', 'print'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
437
            Config::nest();
438
            Config::inst()->update('SSViewer', 'theme_enabled', true);
439
            $html = $this->renderWith('Invoice');
440
            Config::unnest();
441
442
            return $html;
443
        } elseif (isset($_REQUEST['packingslip'])) {
444
            Requirements::clear();
445
            Requirements::themedCSS('typography', $themeBaseFolder); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
446
            Requirements::themedCSS('OrderReport', 'ecommerce'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
447
            Requirements::themedCSS('Order_PackingSlip', 'ecommerce'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
448
            Config::nest();
449
            Config::inst()->update('SSViewer', 'theme_enabled', true);
450
            $html = $this->renderWith('PackingSlip');
451
            Config::unnest();
452
453
            return $html;
454
        }
455
456
        return array();
457
    }
458
459
    /**
460
     * This is an additional way to look at an order.
461
     * The order is already retrieved from the init function.
462
     *
463
     * @return array
464
     **/
465
    public function retrieveorder(SS_HTTPRequest $request)
466
    {
467
        return array();
468
    }
469
470
    /**
471
     * copies either the current order into the shopping cart.
472
     *
473
     * TO DO: untested
474
     * TO DO: what to do with old order
475
     *
476
     * @param SS_HTTPRequest
477
     *
478
     * @return array
479
     */
480
    public function copyorder(SS_HTTPRequest $request)
481
    {
482
        self::set_message(_t('CartPage.ORDERLOADED', 'Order has been loaded.'));
483
        ShoppingCart::singleton()->copyOrder($this->currentOrder->ID);
484
485
        return $this->redirect(CheckoutPage::find_link());
486
    }
487
488
    /**
489
     * @param HTTPRequest
490
     *
491
     * @return array - just so the template is still displayed
492
     **/
493
    public function sendreceipt(SS_HTTPRequest $request)
494
    {
495
        if ($o = $this->currentOrder) {
496
            if ($m = $o->Member()) {
497
                if ($m->Email) {
498
                    $subject = _t('Account.COPYONLY', '--- COPY ONLY ---');
499
                    $message = _t('Account.COPYONLY', '--- COPY ONLY ---');
500
                    $o->sendReceipt($subject, $message, true);
501
                    $this->message = _t('OrderConfirmationPage.RECEIPTSENT', 'An order receipt has been sent to: ').$m->Email.'.';
502
                } else {
503
                    $this->message = _t('OrderConfirmationPage.RECEIPTNOTSENTNOTSENDING', 'Email could NOT be sent.');
504
                }
505
            } else {
506
                $this->message = _t('OrderConfirmationPage.RECEIPTNOTSENTNOEMAIL', 'No email could be found for sending this receipt.');
507
            }
508
        } else {
509
            $this->message = _t('OrderConfirmationPage.RECEIPTNOTSENTNOORDER', 'Order could not be found.');
510
        }
511
        $baseFolder = Director::baseFolder();
512
        if (!class_exists('\Pelago\Emogrifier')) {
513
            require_once Director::baseFolder().'/ecommerce/thirdparty/Emogrifier.php';
514
        }
515
        Requirements::clear();
516
        isset($project) ? $themeBaseFolder = $project : $themeBaseFolder = 'mysite';
517
        Requirements::themedCSS('typography', $themeBaseFolder); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
518
        Requirements::themedCSS('OrderReport', 'ecommerce'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
519
        Requirements::themedCSS('Order_Invoice', 'ecommerce', 'print'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
520
        Config::nest();
521
        Config::inst()->update('SSViewer', 'theme_enabled', true);
522
        $html = $this->renderWith('Order_ReceiptEmail');
523
        Config::unnest();
524
        // if it's an html email, filter it through emogrifier
525
        $cssFileLocation = $baseFolder.'/'.EcommerceConfig::get('Order_Email', 'css_file_location');
526
        $html .= "\r\n\r\n<!-- CSS can be found here: $cssFileLocation -->";
527
        $cssFileHandler = fopen($cssFileLocation, 'r');
528
        $css = fread($cssFileHandler,  filesize($cssFileLocation));
529
        fclose($cssFileHandler);
530
        $emog = new \Pelago\Emogrifier($html, $css);
531
        $html = $emog->emogrify();
532
533
        return $html;
534
    }
535
536
    /**
537
     * Returns a dataobject set of the checkout steps if
538
     * the OrderConfirmationPage is shown as part of the checkout process
539
     * We repeat these here so that you can show the user that (s)he has reached the last step.
540
     *
541
     * @param int $number - if set, it returns that one step.
542
     */
543
    public function CheckoutSteps($number = 0)
544
    {
545
        $where = '';
546
        if ($number) {
547
            $where = "\"CheckoutPage_StepDescription\".\"ID\" = $number";
548
        }
549
        if (EcommerceConfig::get('OrderConfirmationPage_Controller', 'include_as_checkout_step')) {
550
            if ($this->currentOrder->IsInSession()) {
551
                $dos = CheckoutPage_StepDescription::get()->where($where)->sort('ID', 'ASC');
552
                if ($number) {
553
                    if ($dos && $dos->count()) {
554
                        return $dos->First();
555
                    }
556
                }
557
                $arrayList = new ArrayList(array());
558
                foreach ($dos as $do) {
559
                    $do->LinkingMode = 'link completed';
560
                    $do->Completed = 1;
561
                    $do->Link = '';
562
                    $arrayList->push($do);
563
                }
564
                $do = $this->CurrentCheckoutStep(true);
565
                if ($do) {
566
                    $arrayList->push($do);
567
                }
568
569
                return $arrayList;
570
            }
571
        }
572
    }
573
574
    /**
575
     * returns the percentage of checkout steps done (0 - 100).
576
     *
577
     * @return int
578
     */
579
    public function PercentageDone()
580
    {
581
        return 100;
582
    }
583
584
    /**
585
     * @return string
586
     */
587
    public function PaymentHeader()
588
    {
589
        if ($order = $this->Order()) {
590
            if ($this->OrderIsCancelled()) {
591
                return $this->OrderCancelledHeader;
592
            } elseif ($this->PaymentIsPending()) {
593
                return $this->PaymentPendingHeader;
594
            } elseif ($this->IsPaid()) {
595
                return $this->PaymentSuccessfulHeader;
596
            } else {
597
                return $this->PaymentNotSuccessfulHeader;
598
            }
599
        }
600
    }
601
602
    /**
603
     * @return string | null
604
     */
605
    public function PaymentMessage()
606
    {
607
        if ($order = $this->Order()) {
608
            if ($this->OrderIsCancelled()) {
609
                return $this->OrderCancelledMessage;
610
            } elseif ($this->PaymentIsPending()) {
611
                return $this->PaymentPendingMessage;
612
            } elseif ($this->IsPaid()) {
613
                return $this->PaymentSuccessfulMessage;
614
            } else {
615
                return $this->PaymentNotSuccessfulMessage;
616
            }
617
        }
618
    }
619
620
    /**
621
     * @return string | null
622
     */
623
    public function PaymentMessageType()
624
    {
625
        if ($order = $this->Order()) {
626
            if ($this->OrderIsCancelled()) {
627
                return "bad";
628
            } elseif ($this->PaymentIsPending()) {
629
                return "warning";
630
            } elseif ($this->IsPaid()) {
631
                return "good";
632
            } else {
633
                return "bad";
634
            }
635
        }
636
    }
637
638
    /**
639
     * @return bool
640
     */
641
    public function OrderIsCancelled()
642
    {
643
        if ($order = $this->Order()) {
644
            return $order->getIsCancelled();
645
        }
646
    }
647
648
    /**
649
     * Is the Order paid?
650
     * This can be useful for choosing what header to show.
651
     *
652
     * @return bool
653
     */
654
    public function IsPaid()
655
    {
656
        if ($order = $this->Order()) {
657
            return $order->IsPaid();
658
        }
659
    }
660
661
    /**
662
     * Are there any order Payments Pending
663
     * This can be useful for choosing what header to show.
664
     *
665
     * @return bool
666
     */
667
    public function PaymentIsPending()
668
    {
669
        if ($order = $this->Order()) {
670
            return $order->PaymentIsPending();
671
        }
672
    }
673
674
    /**
675
     * Returns the form to cancel the current order,
676
     * checking to see if they can cancel their order
677
     * first of all.
678
     *
679
     * @return OrderForm_Cancel
680
     */
681
    public function CancelForm()
682
    {
683
        if ($this->Order()) {
684
            if ($this->currentOrder->canCancel()) {
685
                return OrderForm_Cancel::create($this, 'CancelForm', $this->currentOrder);
686
            }
687
        }
688
        //once cancelled, you will be redirected to main page - hence we need this...
689
        if ($this->orderID) {
690
            return array();
691
        }
692
    }
693
694
    /**
695
     * show the payment form.
696
     *
697
     * @return Form (OrderForm_Payment) or Null
698
     **/
699
    public function PaymentForm()
700
    {
701
        if ($this->currentOrder) {
702
            if ($this->currentOrder->canPay()) {
703
                Requirements::javascript('ecommerce/javascript/EcomPayment.js');
704
705
                return OrderForm_Payment::create($this, 'PaymentForm', $this->currentOrder);
706
            }
707
        }
708
709
        return array();
710
    }
711
712
    /**
713
     * Can this page only show Submitted Orders (e.g. OrderConfirmationPage) ?
714
     *
715
     * @return bool
716
     */
717
    protected function onlyShowSubmittedOrders()
718
    {
719
        return true;
720
    }
721
722
    /**
723
     * Can this page only show Unsubmitted Orders (e.g. CartPage) ?
724
     *
725
     * @return bool
726
     */
727
    protected function onlyShowUnsubmittedOrders()
728
    {
729
        return false;
730
    }
731
732
    /**
733
     * sends an order email, which can be specified in the URL
734
     * and displays a sample email
735
     * typically this link is opened in a new window.
736
     *
737
     * @param SS_HTTPRequest $request
738
     *
739
     * @return HTML
740
     **/
741
    public function sendemail(SS_HTTPRequest $request)
742
    {
743
        if ($this->currentOrder) {
744
            $emailClassName = 'Order_ReceiptEmail';
745
            if (class_exists($request->param('OtherID'))) {
746
                if (is_a(singleton($request->param('OtherID')), Object::getCustomClass('Order_Email'))) {
747
                    $emailClassName = $request->param('OtherID');
748
                }
749
            }
750
            if ($statusID = intval($request->getVar('use'))) {
751
                $subject = _t('Account.TEST_ONLY', '--- TEST ONLY ---');
752
                $step = OrderStep::get()->byID($statusID);
753
                if ($step) {
754
                    $emailClassName = $step->getEmailClassName();
755
                }
756
                if ($request->getVar('send')) {
757
                    $email = filter_var($request->getVar('send'), FILTER_SANITIZE_EMAIL);
758
                    if(! $email) { 
759
                        $email = true;
760
                    }
761
                    $this->currentOrder->sendEmail(
762
                        $subject,
763
                        $message,
764
                        $resend = true,
765
                        $adminOnlyOrToEmail = $email,
766
                        $emailClassName
767
                    );
768
                }
769
            }
770
            if ($request->getVar('send')) {
771
                if ($email = $this->currentOrder->getOrderEmail()) {
772
                    $subject = _t('Account.COPYONLY', '--- COPY ONLY ---');
773
                    $message = _t('Account.COPYONLY', '--- COPY ONLY ---');
774
                    if (
775
                        $this->currentOrder->sendEmail(
776
                            $subject,
777
                            $message,
778
                            $resend = true,
779
                            $adminOnlyOrToEmail = false,
780
                            $emailClassName
781
                        )
782
                    ) {
783
                        $this->message = _t('OrderConfirmationPage.RECEIPTSENT', 'An email has been sent to: ').$email.'.';
784
                    } else {
785
                        $this->message = _t('OrderConfirmationPage.RECEIPT_NOT_SENT', 'Email sent unsuccesfully to: ').$email.'. EMAIL NOT SENT.';
786
                    }
787
                } else {
788
                    $this->message = _t('OrderConfirmationPage.RECEIPTNOTSENTNOEMAIL', 'No customer details found.  EMAIL NOT SENT.');
789
                }
790
            } 
791
            //display same data...
792
            Requirements::clear();
793
794
            return $this->currentOrder->renderOrderInEmailFormat($this->message, $emailClassName);
795
        } else {
796
            return _t('OrderConfirmationPage.RECEIPTNOTSENTNOORDER', 'Order could not be found.');
797
        }
798
    }
799
800
    protected function includeGoogleAnalyticsCode()
801
    {
802
        if ($this->EnableGoogleAnalytics && $this->currentOrder && Director::isLive()) {
803
            $currencyUsedObject = $this->currentOrder->CurrencyUsed();
804
            if ($currencyUsedObject) {
805
                $currencyUsedString = $currencyUsedObject->Code;
806
            }
807
            if (empty($currencyUsedString)) {
808
                $currencyUsedString = EcommerceCurrency::default_currency_code();
809
            }
810
            $js = '
811
            jQuery(document).ready(
812
                function(){
813
                    _gaq(\'require\', \'ecommerce\');
814
                    _gaq(
815
                        \'ecommerce:addTransaction\',
816
                        {
817
                            \'id\': \''.$this->currentOrder->ID.'\',
818
                            \'revenue\': \''.$this->currentOrder->getSubTotal().'\',
819
                            \'currency\': \''.$currencyUsedString.'\'
820
                        }
821
                    );
822
                    _gaq(\'ecommerce:send\');
823
                }
824
            );
825
';
826
            Requirements::customScript($js, 'GoogleAnalyticsEcommerce');
827
        }
828
    }
829
}
830