Completed
Push — master ( ef78ba...2eee10 )
by
unknown
09:09
created

code/OrderConfirmationPage.php (4 issues)

Check that @param annotations have the correct type.

Documentation Informational

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
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
        'IsFeedbackEnabled' => 'Boolean',
43
        'FeedbackFormLinkText' => 'Varchar(255)',
44
        'FeedbackHeader' => 'Varchar(255)',
45
        'FeedbackValuesFieldLabel' => 'Varchar(255)',
46
        'FeedbackValuesOptions' => 'Varchar(255)',
47
        'FeedbackNotesFieldLabel' => 'Varchar(255)',
48
        'FeedbackFormSubmitLabel' => 'Varchar(255)',
49
        'FeedbackFormThankYou' => 'Varchar(255)'
50
    );
51
52
    /**
53
     * Standard SS variable.
54
     *
55
     * @var array
56
     */
57
    private static $defaults = array(
58
        'ShowInMenus' => false,
59
        'ShowInSearch' => false,
60
        'StartNewOrderLinkLabel' => 'start new order',
61
        'CopyOrderLinkLabel' => 'copy order items into a new order',
62
        'OrderCancelledHeader' => 'Order has been cancelled',
63
        'PaymentSuccessfulHeader' => 'Payment Successful',
64
        'PaymentNotSuccessfulHeader' => 'Payment not Completed',
65
        'PaymentPendingHeader' => 'Payment Pending',
66
        'OrderCancelledMessage' => '<p>This order is no longer valid.</p>',
67
        'PaymentSuccessfulMessage' => '<p>Your order will be processed.</p>',
68
        'PaymentNotSuccessfulMessage' => '<p>Your order will not be processed until your payment has been completed.</p>',
69
        'PaymentPendingMessage' => '<p>Please complete your payment before the order can be processed.</p>',
70
        'FeedbackFormLinkText' => 'Do have any feedback about the order process? Let us know ... ',
71
        'FeedbackHeader' => 'Feedback',
72
        'FeedbackValuesFieldLabel' => 'How likely are you to recommend us to your friends?',
73
        'FeedbackValuesOptions' => 'Not At All, Not Likely, Not Sure, Likely, Very Likely',
74
        'FeedbackNotesFieldLabel' => 'What can we do to improve the ordering experience?',
75
        'FeedbackFormSubmitLabel' => 'Submit Your Feedback',
76
        'FeedbackFormThankYou' => 'Thank you for taking the time to submit your feedback, we appreciate it!'
77
    );
78
79
    private static $casting = array(
80
        "PaymentMessage" => "HTMLText"
81
    );
82
83
    /**
84
     * standard SS variable.
85
     *
86
     * @Var String
87
     */
88
    private static $singular_name = 'Order Confirmation Page';
89
    public function i18n_singular_name()
90
    {
91
        return _t('OrderConfirmationpage.SINGULARNAME', 'Order Confirmation Page');
92
    }
93
94
    /**
95
     * standard SS variable.
96
     *
97
     * @Var String
98
     */
99
    private static $plural_name = 'Order Confirmation Pages';
100
    public function i18n_plural_name()
101
    {
102
        return _t('OrderConfirmationpage.PLURALNAME', 'Order Confirmation Pages');
103
    }
104
105
    /**
106
     * Standard SS variable.
107
     *
108
     * @var string
109
     */
110
    private static $description = 'A page where the customer can view her or his submitted order. Every e-commerce site needs an Order Confirmation Page.';
111
112
    /**
113
     * Standard SS function, we only allow for one OrderConfirmation Page to exist
114
     * but we do allow for extensions to exist at the same time.
115
     *
116
     * @param Member $member
0 ignored issues
show
Should the type for parameter $member not be Member|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
117
     *
118
     * @return bool
119
     */
120
    public function canCreate($member = null)
121
    {
122
        return OrderConfirmationPage::get()->filter(array('ClassName' => 'OrderConfirmationPage'))->Count() ? false : $this->canEdit($member);
123
    }
124
125
    /**
126
     * Shop Admins can edit.
127
     *
128
     * @param Member $member
0 ignored issues
show
Should the type for parameter $member not be Member|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
129
     *
130
     * @return bool
131
     */
132
    public function canEdit($member = null)
133
    {
134
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
135
            return true;
136
        }
137
138
        return parent::canEdit($member);
139
    }
140
141
    /**
142
     * Standard SS method.
143
     *
144
     * @param Member $member
0 ignored issues
show
Should the type for parameter $member not be Member|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
145
     *
146
     * @return bool
147
     */
148
    public function canDelete($member = null)
149
    {
150
        return false;
151
    }
152
153
    /**
154
     * Standard SS method.
155
     *
156
     * @param Member $member
0 ignored issues
show
Should the type for parameter $member not be Member|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
157
     *
158
     * @return bool
159
     */
160
    public function canPublish($member = null)
161
    {
162
        return $this->canEdit($member);
163
    }
164
165
    public function customFieldLabels()
166
    {
167
        $newLabels = array(
168
            'StartNewOrderLinkLabel' => _t('OrderConfirmationPage.STARTNEWORDERLINKLABEL', 'Label for starting new order - e.g. click here to start new order.'),
169
            '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.'),
170
            'OrderCancelledHeader' => _t('OrderConfirmationPage.ORDERCANCELLEDHEADER', 'Header showing when order has been cancelled.'),
171
            'PaymentSuccessfulHeader' => _t('OrderConfirmationPage.PAYMENTSUCCESSFULHEADER', 'Header showing when order has been paid in full.'),
172
            'PaymentNotSuccessfulHeader' => _t('OrderConfirmationPage.PAYMENTNOTSUCCESSFULHEADER', 'Header showing when the order has not been paid in full.'),
173
            'PaymentPendingHeader' => _t('OrderConfirmationPage.PAYMENTPENDINGHEADER', 'Header showing when the order has not been paid in full - but the payment is pending.'),
174
            'OrderCancelledMessage' => _t('OrderConfirmationPage.ORDERCANCELLEDMESSAGE', 'Message showing when order has been paid cancelled.'),
175
            'PaymentSuccessfulMessage' => _t('OrderConfirmationPage.PAYMENTSUCCESSFULMESSAGE', 'Message showing when order has been paid in full.'),
176
            'PaymentNotSuccessfulMessage' => _t('OrderConfirmationPage.PAYMENTNOTSUCCESSFULMESSAGE', 'Message showing when the order has not been paid in full.'),
177
            'PaymentPendingMessage' => _t('OrderConfirmationPage.PAYMENTPENDINGMESSAGE', 'Message showing when the order has not been paid in full - but the payment is pending.'),
178
            'EnableGoogleAnalytics' => _t('OrderConfirmationPage.ENABLEGOOGLEANALYTICS', 'Enable E-commerce Google Analytics.  Make sure it is turned on in your Google Analytics account.'),
179
            'IsFeedbackEnabled' => _t('OrderConfirmationPage.ISFEEDBACKENABLED', 'Enable Feedback Form'),
180
            'FeedbackFormLinkText' => _t('OrderConfirmationPage.FEEDBACKFORMLINKTEXT', 'Email Link Text'),
181
            'FeedbackHeader' => _t('OrderConfirmationPage.FEEDBACKHEADER', 'Feedback Form Header'),
182
            'FeedbackValuesFieldLabel' => _t('OrderConfirmationPage.FEEDBACKVALUESFIELDLABEL', 'Feedback Form Options Label'),
183
            'FeedbackValuesOptions' => _t('OrderConfirmationPage.FEEDBACKVALUESOPTIONS', 'Feedback Form Options'),
184
            'FeedbackNotesFieldLabel' => _t('OrderConfirmationPage.FEEDBACKVALUESFIELDLABEL', 'Feedback Form Notes Label'),
185
            'FeedbackFormSubmitLabel' => _t('OrderConfirmationPage.FEEDBACKFORMSUBMITLABEL', 'Feedback Form Submit Button Text'),
186
            'FeedbackFormThankYou' => _t('OrderConfirmationPage.FEEDBACKFORMTHANKYOU', 'Feedback Form Thank you Message')
187
        );
188
189
        return $newLabels;
190
    }
191
192
    /**
193
     * standard SS method for decorators.
194
     *
195
     * @param bool - $includerelations: array of fields to start with
196
     *
197
     * @return array
198
     */
199
    public function fieldLabels($includerelations = true)
200
    {
201
        $defaultLabels = parent::fieldLabels();
202
        $newLabels = $this->customFieldLabels();
203
        $labels = array_merge($defaultLabels, $newLabels);
204
        $extendedArray = $this->extend('updateFieldLabels', $labels);
205
        if ($extendedArray !== null && is_array($extendedArray) && count($extendedArray)) {
206
            foreach ($extendedArray as $extendedResult) {
207
                $labels = array_merge($labels, $extendedResult);
208
            }
209
        }
210
211
        return $labels;
212
    }
213
214
    /**
215
     *@return FieldList
216
     **/
217
    public function getCMSFields()
218
    {
219
        $fields = parent::getCMSFields();
220
        $fields->removeFieldFromTab('Root.Messages.Messages.Actions', 'ProceedToCheckoutLabel');
221
        $fields->removeFieldFromTab('Root.Messages.Messages.Actions', 'ContinueShoppingLabel');
222
        $fields->removeFieldFromTab('Root.Messages.Messages.Actions', 'ContinuePageID');
223
        $fields->removeFieldFromTab('Root.Messages.Messages.Actions', 'SaveOrderLinkLabel');
224
        $fields->removeFieldFromTab('Root.Messages.Messages.Errors', 'NoItemsInOrderMessage');
225
        $fieldLabels = $this->fieldLabels();
226
        $fields->addFieldToTab('Root.Messages.Messages.Actions', new TextField('StartNewOrderLinkLabel', $fieldLabels['StartNewOrderLinkLabel']));
227
        $fields->addFieldToTab('Root.Messages.Messages.Actions', new TextField('CopyOrderLinkLabel', $fieldLabels['CopyOrderLinkLabel']));
228
        $fields->addFieldsToTab('Root.Messages.Messages.Payment', array(
229
            HeaderField::create('Successful'),
230
            TextField::create('PaymentSuccessfulHeader', $fieldLabels['PaymentSuccessfulHeader']),
231
            HTMLEditorField::create('PaymentSuccessfulMessage', $fieldLabels['PaymentSuccessfulMessage'])->setRows(3),
232
            HeaderField::create('Unsuccessful'),
233
            TextField::create('PaymentNotSuccessfulHeader', $fieldLabels['PaymentNotSuccessfulHeader']),
234
            HTMLEditorField::create('PaymentNotSuccessfulMessage', $fieldLabels['PaymentNotSuccessfulMessage'])->setRows(3),
235
            HeaderField::create('Pending'),
236
            TextField::create('PaymentPendingHeader', $fieldLabels['PaymentPendingHeader']),
237
            HTMLEditorField::create('PaymentPendingMessage', $fieldLabels['PaymentPendingMessage'])->setRows(3),
238
            HeaderField::create('Cancelled'),
239
            TextField::create('OrderCancelledHeader', $fieldLabels['OrderCancelledHeader']),
240
            HTMLEditorField::create('OrderCancelledMessage', $fieldLabels['OrderCancelledMessage'])->setRows(3),
241
        ));
242
        $fields->addFieldToTab('Root.Analytics', new CheckboxField('EnableGoogleAnalytics', $fieldLabels['EnableGoogleAnalytics']));
243
        $fields->addFieldsToTab(
244
            'Root.FeedbackForm',
245
            array(
246
                CheckboxField::create('IsFeedbackEnabled', $fieldLabels['IsFeedbackEnabled'])
247
                    ->setDescription('Enabling this option will display a feedback form on the order confirmation page and include links to the form in all order emails'),
248
                TextField::create('FeedbackHeader', $fieldLabels['FeedbackHeader'])
249
                    ->setRightTitle('Heading text shown above the form on the order confirmation page'),
250
                TextField::create('FeedbackValuesFieldLabel', $fieldLabels['FeedbackValuesFieldLabel'])
251
                    ->setRightTitle('Text for feedback options field label'),
252
                TextField::create('FeedbackValuesOptions', $fieldLabels['FeedbackValuesOptions'])
253
                    ->setRightTitle('Comma separated list of feedback rating options (eg Good, Neutral, Bad)'),
254
                TextField::create('FeedbackNotesFieldLabel', $fieldLabels['FeedbackNotesFieldLabel'])
255
                    ->setRightTitle('Text for feedback notes field label'),
256
                TextField::create('FeedbackFormSubmitLabel', $fieldLabels['FeedbackFormSubmitLabel'])
257
                    ->setRightTitle('Text shown on the feedback form submit button'),
258
                TextField::create('FeedbackFormThankYou', $fieldLabels['FeedbackFormThankYou'])
259
                    ->setRightTitle('Thank you message displayed to user after submitting the feedback form'),
260
                TextField::create('FeedbackFormLinkText', $fieldLabels['FeedbackFormLinkText'])
261
                    ->setRightTitle('This is the text shown for the <strong>request feedback link</strong> included in order emails')
262
            )
263
        );
264
        return $fields;
265
    }
266
267
    /**
268
     * Returns the link or the Link to the OrderConfirmationPage page on this site.
269
     * @param string $action [optional]
270
     * @return string (URLSegment)
271
     */
272
    public static function find_link($action = null)
273
    {
274
        if ($page = OrderConfirmationPage::get()->filter(array('ClassName' => 'OrderConfirmationPage'))->First()) {
275
            return $page->Link($action);
276
        } elseif ($page = OrderConfirmationPage::get()->First()) {
277
            return $page->Link($action);
278
        }
279
280
        return CartPage::find_link();
281
    }
282
283
    /**
284
     * Return a link to view the order on this page.
285
     *
286
     * @param int|string $orderID ID of the order
287
     *
288
     * @return string (URLSegment)
289
     */
290
    public static function get_order_link($orderID)
291
    {
292
        return OrderConfirmationPage::find_link().'showorder/'.$orderID.'/';
293
    }
294
295
    /**
296
     * Return a link to view the order on this page.
297
     *
298
     * @param int|string $orderID                ID of the order
299
     * @param string     $type                   - the type of email you want to send.
300
     * @param bool       $actuallySendEmail      - do we actually send the email
301
     * @param int        $alternativeOrderStepID - OrderStep to use
302
     *
303
     * @return string (URLSegment)
304
     */
305
    public static function get_email_link($orderID, $emailClassName = 'Order_StatusEmail', $actuallySendEmail = false, $alternativeOrderStepID = 0)
306
    {
307
        $link = OrderConfirmationPage::find_link().'sendemail/'.$orderID.'/'.$emailClassName;
308
        $getParams = array();
309
        if ($actuallySendEmail) {
310
            $getParams['send'] = 1;
311
        }
312
        if ($alternativeOrderStepID) {
313
            $getParams['test'] = $alternativeOrderStepID;
314
        }
315
        $getParams = http_build_query($getParams);
316
        $link .= '?'.$getParams;
317
318
        return $link;
319
    }
320
321
    /**
322
     * Return a link to view the order on this page.
323
     *
324
     * @param int|string $orderID ID of the order
325
     *
326
     * @return string (URLSegment)
327
     */
328
    public function getOrderLink($orderID)
329
    {
330
        return OrderConfirmationPage::get_order_link($orderID);
331
    }
332
333
    /**
334
     * returns the Checkout_StepDescription assocatiated with the final step: the order confirmation.
335
     *
336
     * @param bool $isCurrentStep
337
     *
338
     * @return Checkout_StepDescription
339
     */
340
    public function CurrentCheckoutStep($isCurrentStep = false)
341
    {
342
        $do = new CheckoutPage_StepDescription();
343
        $do->Link = $this->Link;
344
        $do->Heading = $this->MenuTitle;
345
        $do->Code = $this->URLSegment;
346
        $do->LinkingMode = 'notCompleted';
347
        if ($isCurrentStep) {
348
            $do->LinkingMode .= ' current';
349
        }
350
        $do->Completed = 0;
351
        $do->ID = 99;
352
353
        return $do;
354
    }
355
356
    /**
357
     * standard SS method for use in templates
358
     * we are overriding the code from the Cart Page here.
359
     *
360
     * @return string
361
     */
362
    public function LinkingMode()
363
    {
364
        return parent::LinkingMode();
365
    }
366
367
    /**
368
     * standard SS method for use in templates
369
     * we are overriding the code from the Cart Page here.
370
     *
371
     * @return string
372
     */
373
    public function LinkOrSection()
374
    {
375
        return parent::LinkOrSection();
376
    }
377
378
    /**
379
     * standard SS method for use in templates
380
     * we are overriding the code from the Cart Page here.
381
     *
382
     * @return string
383
     */
384
    public function LinkOrCurrent()
385
    {
386
        return parent::LinkOrCurrent();
387
    }
388
389
    public function requireDefaultRecords()
390
    {
391
        parent::requireDefaultRecords();
392
        $checkoutPage = CheckoutPage::get()->first();
393
        if ($checkoutPage) {
394
            $orderConfirmationPage = OrderConfirmationPage::get()->first();
395
            if (!$orderConfirmationPage) {
396
                $orderConfirmationPage = OrderConfirmationPage::create();
397
                $orderConfirmationPage->Title = 'Order Confirmation';
398
                $orderConfirmationPage->MenuTitle = 'Order Confirmation';
399
                $orderConfirmationPage->URLSegment = 'order-confirmation';
400
                $orderConfirmationPage->writeToStage('Stage');
401
                $orderConfirmationPage->publish('Stage', 'Live');
402
            }
403
        }
404
    }
405
}
406
407
class OrderConfirmationPage_Controller extends CartPage_Controller
408
{
409
    /**
410
     * @static array
411
     * standard SS variable
412
     * it is important that we list all the options here
413
     */
414
    private static $allowed_actions = array(
415
        'saveorder',
416
        'CreateAccountForm',
417
        'retrieveorder',
418
        'loadorder',
419
        'startneworder',
420
        'showorder',
421
        'copyorder',
422
        'sendemail',
423
        'CancelForm',
424
        'FeedbackForm',
425
        'PaymentForm',
426
    );
427
428
    /**
429
     * standard controller function.
430
     **/
431
    public function init()
432
    {
433
        //we retrieve the order in the parent page
434
        //the parent page also takes care of the security
435
        if ($sessionOrderID = Session::get('CheckoutPageCurrentOrderID')) {
436
            $this->currentOrder = Order::get()->byID($sessionOrderID);
437
            if ($this->currentOrder) {
438
                $this->overrideCanView = true;
439
                //more than an hour has passed...
440
                if (strtotime($this->currentOrder->LastEdited) < (strtotime('Now') - 60 * 60)) {
441
                    Session::clear('CheckoutPageCurrentOrderID');
442
                    Session::clear('CheckoutPageCurrentOrderID');
443
                    Session::set('CheckoutPageCurrentOrderID', 0);
444
                    Session::save();
445
                    $this->overrideCanView = false;
446
                    $this->currentOrder = null;
447
                }
448
            }
449
        }
450
        parent::init();
451
        Requirements::themedCSS('Order', 'ecommerce');
452
        Requirements::themedCSS('Order_Print', 'ecommerce', 'print');
453
        Requirements::themedCSS('CheckoutPage', 'ecommerce');
454
        Requirements::javascript('ecommerce/javascript/EcomPayment.js');
455
        Requirements::javascript('ecommerce/javascript/EcomPrintAndMail.js');
456
        $this->includeGoogleAnalyticsCode();
457
    }
458
459
    /**
460
     * This method exists just so that template
461
     * sets CurrentOrder variable.
462
     *
463
     * @param HTTPRequest
464
     *
465
     * @return array
466
     **/
467
    public function showorder(SS_HTTPRequest $request)
468
    {
469
        isset($project) ? $themeBaseFolder = $project : $themeBaseFolder = 'mysite';
470
        if (isset($_REQUEST['print'])) {
471
            Requirements::clear();
472
            Requirements::themedCSS('typography', $themeBaseFolder); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
473
            Requirements::themedCSS('OrderReport', 'ecommerce'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
474
            Requirements::themedCSS('Order_Invoice', 'ecommerce'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
475
            Requirements::themedCSS('Order_Invoice_Print_Only', 'ecommerce', 'print'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
476
            Config::nest();
477
            Config::inst()->update('SSViewer', 'theme_enabled', true);
478
            $html = $this->renderWith('Invoice');
479
            Config::unnest();
480
481
            return $html;
482
        } elseif (isset($_REQUEST['packingslip'])) {
483
            Requirements::clear();
484
            Requirements::themedCSS('typography', $themeBaseFolder); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
485
            Requirements::themedCSS('OrderReport', 'ecommerce'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
486
            Requirements::themedCSS('Order_PackingSlip', 'ecommerce'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE
487
            Config::nest();
488
            Config::inst()->update('SSViewer', 'theme_enabled', true);
489
            $html = $this->renderWith('PackingSlip');
490
            Config::unnest();
491
492
            return $html;
493
        }
494
495
        return array();
496
    }
497
498
    /**
499
     * This is an additional way to look at an order.
500
     * The order is already retrieved from the init function.
501
     *
502
     * @return array
503
     **/
504
    public function retrieveorder(SS_HTTPRequest $request)
505
    {
506
        return array();
507
    }
508
509
    /**
510
     * copies either the current order into the shopping cart.
511
     *
512
     * TO DO: untested
513
     * TO DO: what to do with old order
514
     *
515
     * @param SS_HTTPRequest
516
     *
517
     * @return array
518
     */
519
    public function copyorder(SS_HTTPRequest $request)
520
    {
521
        self::set_message(_t('CartPage.ORDERLOADED', 'Order has been loaded.'));
522
        ShoppingCart::singleton()->copyOrder($this->currentOrder->ID);
523
524
        return $this->redirect(CheckoutPage::find_link());
525
    }
526
527
    /**
528
     * Returns a dataobject set of the checkout steps if
529
     * the OrderConfirmationPage is shown as part of the checkout process
530
     * We repeat these here so that you can show the user that (s)he has reached the last step.
531
     *
532
     * @param int $number - if set, it returns that one step.
533
     */
534
    public function CheckoutSteps($number = 0)
535
    {
536
        $where = '';
537
        if ($number) {
538
            $where = "\"CheckoutPage_StepDescription\".\"ID\" = $number";
539
        }
540
        if (EcommerceConfig::get('OrderConfirmationPage_Controller', 'include_as_checkout_step')) {
541
            if ($this->currentOrder->IsInSession()) {
542
                $dos = CheckoutPage_StepDescription::get()->where($where)->sort('ID', 'ASC');
543
                if ($number) {
544
                    if ($dos && $dos->count()) {
545
                        return $dos->First();
546
                    }
547
                }
548
                $arrayList = new ArrayList(array());
549
                foreach ($dos as $do) {
550
                    $do->LinkingMode = 'link completed';
551
                    $do->Completed = 1;
552
                    $do->Link = '';
553
                    $arrayList->push($do);
554
                }
555
                $do = $this->CurrentCheckoutStep(true);
556
                if ($do) {
557
                    $arrayList->push($do);
558
                }
559
560
                return $arrayList;
561
            }
562
        }
563
    }
564
565
    /**
566
     * returns the percentage of checkout steps done (0 - 100).
567
     *
568
     * @return int
569
     */
570
    public function PercentageDone()
571
    {
572
        return 100;
573
    }
574
575
    /**
576
     * @return string
577
     */
578
    public function PaymentHeader()
579
    {
580
        if ($order = $this->Order()) {
581
            if ($this->OrderIsCancelled()) {
582
                return $this->OrderCancelledHeader;
583
            } elseif ($this->PaymentIsPending()) {
584
                return $this->PaymentPendingHeader;
585
            } elseif ($this->IsPaid()) {
586
                return $this->PaymentSuccessfulHeader;
587
            } else {
588
                return $this->PaymentNotSuccessfulHeader;
589
            }
590
        }
591
    }
592
593
    /**
594
     * @return string | null
595
     */
596
    public function PaymentMessage()
597
    {
598
        if ($order = $this->Order()) {
599
            if ($this->OrderIsCancelled()) {
600
                return $this->OrderCancelledMessage;
601
            } elseif ($this->PaymentIsPending()) {
602
                return $this->PaymentPendingMessage;
603
            } elseif ($this->IsPaid()) {
604
                return $this->PaymentSuccessfulMessage;
605
            } else {
606
                return $this->PaymentNotSuccessfulMessage;
607
            }
608
        }
609
    }
610
611
    /**
612
     * @return string | null
613
     */
614
    public function PaymentMessageType()
615
    {
616
        if ($order = $this->Order()) {
617
            if ($this->OrderIsCancelled()) {
618
                return "bad";
619
            } elseif ($this->PaymentIsPending()) {
620
                return "warning";
621
            } elseif ($this->IsPaid()) {
622
                return "good";
623
            } else {
624
                return "bad";
625
            }
626
        }
627
    }
628
629
    /**
630
     * @return bool
631
     */
632
    public function OrderIsCancelled()
633
    {
634
        if ($order = $this->Order()) {
635
            return $order->getIsCancelled();
636
        }
637
    }
638
639
    /**
640
     * Is the Order paid?
641
     * This can be useful for choosing what header to show.
642
     *
643
     * @return bool
644
     */
645
    public function IsPaid()
646
    {
647
        if ($order = $this->Order()) {
648
            return $order->IsPaid();
649
        }
650
    }
651
652
    /**
653
     * Are there any order Payments Pending
654
     * This can be useful for choosing what header to show.
655
     *
656
     * @return bool
657
     */
658
    public function PaymentIsPending()
659
    {
660
        if ($order = $this->Order()) {
661
            return $order->PaymentIsPending();
662
        }
663
    }
664
665
    /**
666
     * Returns the form to cancel the current order,
667
     * checking to see if they can cancel their order
668
     * first of all.
669
     *
670
     * @return OrderForm_Cancel
671
     */
672
    public function CancelForm()
673
    {
674
        if ($this->Order()) {
675
            if ($this->currentOrder->canCancel()) {
676
                return OrderForm_Cancel::create($this, 'CancelForm', $this->currentOrder);
677
            }
678
        }
679
        //once cancelled, you will be redirected to main page - hence we need this...
680
        if ($this->orderID) {
681
            return array();
682
        }
683
    }
684
685
    /**
686
     * Returns the form for providing feedback about current order,
687
     * checking to see if IsFeedbackEnabled is true
688
     * first of all.
689
     *
690
     * @return OrderForm_Feedback
691
     */
692
    public function FeedbackForm()
693
    {
694
        if ($this->Order()) {
695
            if ($this->IsFeedbackEnabled) {
696
                return OrderForm_Feedback::create($this, 'FeedbackForm', $this->currentOrder);
697
            }
698
        }
699
    }
700
701
    /**
702
     * show the payment form.
703
     *
704
     * @return Form (OrderForm_Payment) or Null
705
     **/
706
    public function PaymentForm()
707
    {
708
        if ($this->currentOrder) {
709
            if ($this->currentOrder->canPay()) {
710
                Requirements::javascript('ecommerce/javascript/EcomPayment.js');
711
712
                return OrderForm_Payment::create($this, 'PaymentForm', $this->currentOrder);
713
            }
714
        }
715
716
        return array();
717
    }
718
719
    /**
720
     * Can this page only show Submitted Orders (e.g. OrderConfirmationPage) ?
721
     *
722
     * @return bool
723
     */
724
    protected function onlyShowSubmittedOrders()
725
    {
726
        return true;
727
    }
728
729
    /**
730
     * Can this page only show Unsubmitted Orders (e.g. CartPage) ?
731
     *
732
     * @return bool
733
     */
734
    protected function onlyShowUnsubmittedOrders()
735
    {
736
        return false;
737
    }
738
739
    /**
740
     * sends an order email, which can be specified in the URL
741
     * and displays a sample email
742
     * typically this link is opened in a new window.
743
     *
744
     * @param SS_HTTPRequest $request
745
     *
746
     * @return HTML
747
     **/
748
    public function sendemail(SS_HTTPRequest $request)
749
    {
750
        if ($this->currentOrder) {
751
            $subject = '';
752
            $message = '';
753
            $emailClassName = 'Order_ReceiptEmail';
754
            if (class_exists($request->param('OtherID'))) {
755
                if (is_a(singleton($request->param('OtherID')), Object::getCustomClass('Order_Email'))) {
756
                    $emailClassName = $request->param('OtherID');
757
                }
758
            }
759
            if ($statusID = intval($request->getVar('test'))) {
760
                $step = OrderStep::get()->byID($statusID);
761
                $subject = $step->EmailSubject;
762
                $message = $step->CustomerMessage;
763
                if ($step) {
764
                    $emailClassName = $step->getEmailClassName();
765
                }
766
                if ($request->getVar('send')) {
767
                    $email = filter_var($request->getVar('send'), FILTER_SANITIZE_EMAIL);
768
                    if(! $email) {
769
                        $email = true;
770
                    }
771
                    $this->currentOrder->sendEmail(
772
                        $emailClassName,
773
                        _t('Account.TEST_ONLY', '--- TEST ONLY ---') . ' ' . $subject,
774
                        $message,
775
                        $resend = true,
776
                        $adminOnlyOrToEmail = $email
777
                    );
778
                }
779
            }
780
            elseif ($request->getVar('send')) {
781
                if ($email = $this->currentOrder->getOrderEmail()) {
782
                    $step = OrderStep::get()->byID($this->currentOrder->StatusID);
783
                    $ecomConfig = $this->EcomConfig();
784
                    $subject = $ecomConfig->InvoiceTitle ? $ecomConfig->InvoiceTitle : _t('OrderConfirmationPage.INVOICE', 'Invoice');
785
                    $message = $ecomConfig->InvoiceMessage ? $ecomConfig->InvoiceMessage : _t('OrderConfirmationPage.MESSAGE', '<p>Thank you for your order.</p>');
786
                    $emailClassName = 'Order_InvoiceEmail';
787
                    if (
788
                        $this->currentOrder->sendEmail(
789
                            $emailClassName,
790
                            $subject,
791
                            $message,
792
                            $resend = true,
793
                            $adminOnlyOrToEmail = false
794
                        )
795
                    ) {
796
                        $message = _t('OrderConfirmationPage.RECEIPTSENT', 'An email has been sent to: ').$email.'.';
797
                    } else {
798
                        $message = _t('OrderConfirmationPage.RECEIPT_NOT_SENT', 'Email could NOT be sent to: ').$email;
799
                    }
800
                } else {
801
                    $message = _t('OrderConfirmationPage.RECEIPTNOTSENTNOEMAIL', 'No customer details found.  EMAIL NOT SENT.');
802
                }
803
            }
804
            //display same data...
805
            Requirements::clear();
806
            return $this->currentOrder->renderOrderInEmailFormat(
807
                $emailClassName,
808
                $subject,
809
                $message
810
            );
811
        } else {
812
            return _t('OrderConfirmationPage.RECEIPTNOTSENTNOORDER', 'Order could not be found.');
813
        }
814
    }
815
816
    protected function includeGoogleAnalyticsCode()
817
    {
818
        if ($this->EnableGoogleAnalytics && $this->currentOrder && Director::isLive()) {
819
            $currencyUsedObject = $this->currentOrder->CurrencyUsed();
820
            if ($currencyUsedObject) {
821
                $currencyUsedString = $currencyUsedObject->Code;
822
            }
823
            if (empty($currencyUsedString)) {
824
                $currencyUsedString = EcommerceCurrency::default_currency_code();
825
            }
826
            $js = '
827
            jQuery(document).ready(
828
                function(){
829
                    _gaq(\'require\', \'ecommerce\');
830
                    _gaq(
831
                        \'ecommerce:addTransaction\',
832
                        {
833
                            \'id\': \''.$this->currentOrder->ID.'\',
834
                            \'revenue\': \''.$this->currentOrder->getSubTotal().'\',
835
                            \'currency\': \''.$currencyUsedString.'\'
836
                        }
837
                    );
838
                    _gaq(\'ecommerce:send\');
839
                }
840
            );
841
';
842
            Requirements::customScript($js, 'GoogleAnalyticsEcommerce');
843
        }
844
    }
845
}
846