Completed
Pull Request — master (#10)
by Franco
02:01
created

DMSDocumentCartCheckoutPage_Controller   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 214
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 13

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 13
dl 0
loc 214
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
B DMSDocumentRequestForm() 0 40 4
B send() 0 27 3
A doRequestSend() 0 11 1
A complete() 0 10 1
A trackTimestampedPrintRequest() 0 9 2
A getCart() 0 4 1
B updateCartItems() 0 13 5
A updateCartReceiverInfo() 0 5 1
1
<?php
2
3
class DMSDocumentCartCheckoutPage_Controller extends Page_Controller
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...
4
{
5
    private static $allowed_actions = array(
0 ignored issues
show
Unused Code introduced by
The property $allowed_actions is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
6
        'DMSDocumentRequestForm',
7
        'complete'
8
    );
9
10
    /**
11
     * An array containing the recipients basic information
12
     *
13
     * @var array
14
     */
15
    public static $receiverInfo = array(
16
        'ReceiverName'            => '',
17
        'ReceiverPhone'           => '',
18
        'ReceiverEmail'           => '',
19
        'DeliveryAddressLine1'    => '',
20
        'DeliveryAddressLine2'    => '',
21
        'DeliveryAddressCountry'  => '',
22
        'DeliveryAddressPostCode' => '',
23
    );
24
25
    /**
26
     * Gets and displays an editable list of items within the cart, as well as a contact form with entry
27
     * fields for the recipients information.
28
     *
29
     * To extend use the following from within an Extension subclass:
30
     *
31
     * <code>
32
     * public function updateDMSDocumentRequestForm($form)
33
     * {
34
     *     // Do something here
35
     * }
36
     * </code>
37
     *
38
     * @return Form
39
     */
40
    public function DMSDocumentRequestForm()
41
    {
42
        $fields = DMSDocumentCartSubmission::create()->scaffoldFormFields();
43
        $fields->replaceField('DeliveryAddressLine2', TextField::create('DeliveryAddressLine2', ''));
44
        $fields->replaceField('DeliveryAddressCountry', CountryDropdownField::create(
45
            'DeliveryAddressCountry',
46
            _t('DMSDocumentCartCheckoutPage.RECEIVER_COUNTRY', 'Country')
47
        )->setValue('NZ'));
48
49
        $requiredFields = array(
50
            'ReceiverName',
51
            'ReceiverPhone',
52
            'ReceiverEmail',
53
            'DeliveryAddressLine1',
54
            'DeliveryAddressCountry',
55
            'DeliveryAddressPostCode',
56
        );
57
        foreach ($fields as $field) {
58
            if (in_array($field->name, $requiredFields)) {
59
                $field->addExtraClass('requiredField');
60
            }
61
        }
62
        $validator = new RequiredFields($requiredFields);
63
        $actions = FieldList::create(
64
            new FormAction(
65
                'doRequestSend',
66
                _t('DMSDocumentCartCheckoutPage.SEND_ACTION', 'Send your request')
67
            )
68
        );
69
70
        $form = Form::create($this, 'DMSDocumentRequestForm', $fields, $actions, $validator);
71
        if ($receiverInfo = $this->getCart()->getReceiverInfo()) {
72
            $form->loadDataFrom($receiverInfo);
73
        }
74
75
        $form->setTemplate('DMSDocumentRequestForm');
76
        $this->extend('updateDMSDocumentRequestForm', $form);
77
78
        return $form;
79
    }
80
81
    /**
82
     * Sends an email to both the configured recipient as well as the requester. The
83
     * configured recipient is bcc'ed to the email in order to fulfill it.
84
     *
85
     * To extend use the following from within an Extension subclass:
86
     *
87
     * <code>
88
     * public function updateSend($email)
89
     * {
90
     *     // Do something here
91
     * }
92
     * </code>
93
     * @return mixed
94
     *
95
     * @throws DMSDocumentCartException
96
     */
97
    public function send()
98
    {
99
        $member = $this->CartEmailRecipient();
100
        if ($member->exists()) {
101
            $cart = $this->getCart();
102
            $from = Config::inst()->get('Email', 'admin_email');
103
            $emailAddress = ($info = $cart->getReceiverInfo()) ? $info['ReceiverEmail'] : $from;
104
            $email = Email::create(
105
                $from,
106
                $emailAddress,
107
                _t('DMSDocumentCartCheckoutPage.EMAIL_SUBJECT', 'Request for Printed Publications')
108
            );
109
            $email->setBcc($member->Email);
110
            $renderedCart = $cart->renderWith('DocumentCart_email');
111
            $body = _t(
112
                'DMSDocumentCartCheckoutPage.EMAIL_BODY',
113
                '<p>A request for printed publications has been submitted with the following details:</p>'
114
            );
115
            $body .= $renderedCart->getValue();
116
            $email->setBody($body)->setReplyTo($emailAddress);
117
            $this->extend('updateSend', $email);
118
119
            return $email->send();
120
        } else {
121
            throw new DMSDocumentCartException('No recipient has been configured. Please do so from the CMS');
122
        }
123
    }
124
125
    /**
126
     * Handles form submission.
127
     * Totals requested are updated, delivery details added, email sent for fulfillment
128
     * and print request totals updated.
129
     *
130
     * @param array          $data
131
     * @param Form           $form
132
     * @param SS_HTTPRequest $request
133
     *
134
     * @return SS_HTTPResponse
135
     */
136
    public function doRequestSend($data, Form $form, SS_HTTPRequest $request)
137
    {
138
        $this->updateCartItems($data);
139
        $this->updateCartReceiverInfo($data);
140
        $this->send();
141
        $this->trackTimestampedPrintRequest();
142
        $this->getCart()->saveSubmission($form);
143
        $this->getCart()->emptyCart();
144
145
        return $this->redirect($this->Link('complete'));
146
    }
147
148
    /**
149
     * Displays the preconfigured thank you message to the user upon completion
150
     *
151
     * @return ViewableData_Customised
152
     */
153
    public function complete()
154
    {
155
        return $this->customise(
156
            ArrayData::create(
157
                array(
158
                    'Content' => $this->ThanksMessage,
159
                )
160
            )
161
        );
162
    }
163
164
    /**
165
     * Increments the print counts of all documents which were successfully sent.
166
     */
167
    public function trackTimestampedPrintRequest()
168
    {
169
        /** @var DMSRequestItem $item */
170
        foreach ($this->getCart()->getItems() as $item) {
171
            /** @var DMSDocument|DMSDocumentCartExtension $doc */
172
            $doc = $item->getDocument();
173
            $doc->incrementPrintRequest();
0 ignored issues
show
Bug introduced by
The method incrementPrintRequest does only exist in DMSDocumentCartExtension, but not in DMSDocument.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
174
        }
175
    }
176
177
    /**
178
     * Retrieves a {@link DMSDocumentCart} instance
179
     *
180
     * @return DMSDocumentCart
181
     */
182
    public function getCart()
183
    {
184
        return singleton('DMSDocumentCart');
185
    }
186
187
    /**
188
     * Updates the document quantities just before the request is sent.
189
     *
190
     * @param array $data
191
     */
192
    public function updateCartItems($data)
193
    {
194
        if (isset($data['ItemQuantity']) && !empty($data['ItemQuantity'])) {
195
            foreach ($data['ItemQuantity'] as $itemID => $quantity) {
196
                // Only update if quantity has changed
197
                $item = $this->getCart()->getItem($itemID);
198
                if ($item->getQuantity() == $quantity) {
199
                    continue;
200
                }
201
                $this->getCart()->updateItemQuantity($itemID, $quantity - 1);
202
            }
203
        }
204
    }
205
206
    /**
207
     * Updates the cart receiver info just before the request is sent.
208
     *
209
     * @param array $data
210
     */
211
    public function updateCartReceiverInfo($data)
212
    {
213
        $info = array_merge(self::$receiverInfo, $data);
214
        $this->getCart()->setReceiverInfo($info);
215
    }
216
}
217