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

code/OrderConfirmationPage.php (4 issues)

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