Transaction   A
last analyzed

Complexity

Total Complexity 38

Size/Duplication

Total Lines 331
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 94
c 4
b 0
f 0
dl 0
loc 331
rs 9.36
wmc 38

19 Methods

Rating   Name   Duplication   Size   Complexity  
A getTransactionData() 0 7 2
A setCustomFieldsData() 0 16 3
A __construct() 0 4 1
A getEncryptedData() 0 3 1
A getDiscountData() 0 7 2
A setDiscountData() 0 12 2
A getCustomFieldsData() 0 7 2
A setEncryptedData() 0 5 1
B getObject() 0 24 7
A getParsedTransactionData() 0 10 1
A hasID() 0 3 1
A setTransaction() 0 16 4
A getDecryptedData() 0 5 1
A exists() 0 3 2
A setProductData() 0 17 2
A setTransactionData() 0 8 1
A getProductOptions() 0 9 2
A getTransaction() 0 3 1
A getProductData() 0 7 2
1
<?php
2
3
namespace Dynamic\Foxy\Parser\Foxy;
4
5
use Dynamic\Foxy\Model\FoxyHelper;
6
use SilverStripe\Core\Config\Configurable;
7
use SilverStripe\Core\Injector\Injectable;
8
use SilverStripe\ORM\ArrayList;
9
use SilverStripe\ORM\ValidationException;
10
use SilverStripe\View\ArrayData;
11
12
/**
13
 * Class Transaction
14
 * @package Dynamic\Foxy\Parser\Foxy
15
 */
16
class Transaction
17
{
18
    use Injectable;
19
    use Configurable;
20
21
    /**
22
     * @var string Encrypted response from Foxy
23
     */
24
    private $encrypted_data;
25
26
    /**
27
     * @var "Foxy.io transaction xml record"
0 ignored issues
show
Documentation Bug introduced by
The doc comment "Foxy.io at position 0 could not be parsed: Unknown type name '"Foxy.io' at position 0 in "Foxy.io.
Loading history...
28
     */
29
    private $transaction;
30
31
    /**
32
     * @var ArrayData
33
     */
34
    private $transaction_data;
35
36
    /**
37
     * @var ArrayList
38
     */
39
    private $discount_data;
40
41
    /**
42
     * @var ArrayList
43
     */
44
    private $product_data;
45
46
    /**
47
     * @var ArrayList
48
     */
49
    private $custom_fields_data;
50
51
    /**
52
     * Transaction constructor.
53
     * @param $data string encrypted foxy response data from the xml data feed
54
     * @throws ValidationException
55
     */
56
    public function __construct($data)
57
    {
58
        $this->setEncryptedData($data);
59
        $this->setTransaction($data);
60
    }
61
62
    /**
63
     * @param $data
64
     * @return $this
65
     */
66
    public function setEncryptedData($data)
67
    {
68
        $this->encrypted_data = $data;
69
70
        return $this;
71
    }
72
73
    /**
74
     * @return string
75
     */
76
    public function getEncryptedData()
77
    {
78
        return $this->encrypted_data;
79
    }
80
81
    /**
82
     * Set the decrypted transaction data to use.
83
     *
84
     * @param $data
85
     * @return $this
86
     * @throws ValidationException
87
     */
88
    public function setTransaction($data)
89
    {
90
        $decryptedData = $this->getDecryptedData($data);
91
92
        foreach ($decryptedData->transactions->transaction as $transaction) {
93
            if ($this->hasID($transaction)) {
94
                $this->transaction = $transaction;
95
                break;
96
            }
97
        }
98
99
        if (!$this->transaction) {
100
            $this->transaction = false;
101
        }
102
103
        return $this;
104
    }
105
106
    /**
107
     * Check if there is a transaction ID for the given decrypted transaction data.
108
     *
109
     * @param $transaction
110
     * @return bool
111
     */
112
    protected function hasID($transaction)
113
    {
114
        return (int)$transaction->id > 0;
115
    }
116
117
    /**
118
     * Return the decrypted transaction xml data.
119
     *
120
     * @return mixed
121
     */
122
    protected function getTransaction()
123
    {
124
        return $this->transaction;
125
    }
126
127
    /**
128
     * Return an ArrayData containing transaction, products and discounts data.
129
     *
130
     * @return ArrayData
131
     */
132
    public function getParsedTransactionData()
133
    {
134
        /**
135
         *
136
         */
137
        return ArrayData::create([
138
            'transaction' => $this->getTransactionData(),
139
            'products' => $this->getProductData(),
140
            'discounts' => $this->getDiscountData(),
141
            'custom_fields' => $this->getCustomFieldsData(),
142
        ]);
143
    }
144
145
    /**
146
     * Set the base transaction data in an ArrayData object.
147
     *
148
     * @return $this
149
     */
150
    private function setTransactionData()
151
    {
152
        $this->transaction_data = $this->getObject(
153
            $this->getTransaction(),
154
            $this->config()->get('transaction_mapping')
155
        );
156
157
        return $this;
158
    }
159
160
    /**
161
     * Return base transaction data.
162
     *
163
     * @return ArrayData
164
     */
165
    protected function getTransactionData()
166
    {
167
        if (!$this->transaction_data instanceof ArrayData) {
0 ignored issues
show
introduced by
$this->transaction_data is always a sub-type of SilverStripe\View\ArrayData.
Loading history...
168
            $this->setTransactionData();
169
        }
170
171
        return $this->transaction_data;
172
    }
173
174
    /**
175
     * Return discounts data from Foxy.io xml data feed if any.
176
     *
177
     * @return ArrayList
178
     */
179
    protected function getDiscountData()
180
    {
181
        if (!$this->discount_data instanceof ArrayList) {
0 ignored issues
show
introduced by
$this->discount_data is always a sub-type of SilverStripe\ORM\ArrayList.
Loading history...
182
            $this->setDiscountData();
183
        }
184
185
        return $this->discount_data;
186
    }
187
188
    /**
189
     * Set an ArrayList with possible discount data as ArrayData objects.
190
     *
191
     * @return $this
192
     */
193
    protected function setDiscountData()
194
    {
195
        $discounts = $this->getTransaction()->discounts;
196
        $discountsList = ArrayList::create();
197
198
        foreach ($discounts as $discount) {
199
            $discountsList->push($this->getObject($discount->discount, $this->config()->get('discounts_mapping')));
200
        }
201
202
        $this->discount_data = $discountsList;
203
204
        return $this;
205
    }
206
207
    /**
208
     * Return transaction_details data from Foxy.io xml data feed if any.
209
     *
210
     * @return ArrayList
211
     */
212
    protected function getProductData()
213
    {
214
        if (!$this->product_data instanceof ArrayList) {
0 ignored issues
show
introduced by
$this->product_data is always a sub-type of SilverStripe\ORM\ArrayList.
Loading history...
215
            $this->setProductData();
216
        }
217
218
        return $this->product_data;
219
    }
220
221
    /**
222
     * Set an ArrayList with possible transaction_detail data as ArrayData objects.
223
     *
224
     * @return $this
225
     */
226
    protected function setProductData()
227
    {
228
        $details = $this->getTransaction()->transaction_details->transaction_detail;
229
        $detailsList = ArrayList::create();
230
231
        foreach ($details as $detail) {
232
            $product = $this->getObject($detail, $this->config()->get('transaction_detail_mapping'));
233
234
            $product->transaction_detail_options =
235
                $this->getProductOptions($detail->transaction_detail_options->transaction_detail_option);
236
237
            $detailsList->push($product);
238
        }
239
240
        $this->product_data = $detailsList;
241
242
        return $this;
243
    }
244
245
    /**
246
     * Returns an ArrayList containing possible transaction_detail_option data as ArrayData objects.
247
     *
248
     * @param $data
249
     * @return ArrayList
250
     */
251
    protected function getProductOptions($data)
252
    {
253
        $options = ArrayList::create();
254
255
        foreach ($data as $option) {
256
            $options->push($this->getObject($option, $this->config()->get('transaction_detail_option_mapping')));
257
        }
258
259
        return $options;
260
    }
261
262
    /**
263
     * @return ArrayList
264
     */
265
    protected function getCustomFieldsData()
266
    {
267
        if (!$this->custom_fields_data instanceof ArrayList) {
0 ignored issues
show
introduced by
$this->custom_fields_data is always a sub-type of SilverStripe\ORM\ArrayList.
Loading history...
268
            $this->setCustomFieldsData();
269
        }
270
271
        return $this->custom_fields_data;
272
    }
273
274
    /**
275
     * @return $this
276
     */
277
    protected function setCustomFieldsData()
278
    {
279
        $customFields = $this->getTransaction()->custom_fields;
280
        $customFieldsList = ArrayList::create();
281
282
        foreach ($customFields as $customFieldArray) {
283
            foreach ($customFieldArray as $customField) {
284
                $customFieldsList->push($this->getObject(
285
                    $customField,
286
                    $this->config()->get('custom_fields_mapping')
287
                ));
288
            }
289
        }
290
291
        $this->custom_fields_data = $customFieldsList;
292
        return $this;
293
    }
294
295
    /**
296
     * Returns an ArrayData object based on the given iterable data and a key/val config array. Used
297
     * to type hint data from the Foxy.io xml data feed.
298
     *
299
     * @param $data
300
     * @param array $config
301
     * @return ArrayData
302
     */
303
    protected function getObject($data, $config = [])
304
    {
305
        $dataArray = [];
306
307
        foreach ($config as $name => $type) {
308
            switch ($type) {
309
                case 'int':
310
                    $dataArray[$name] = (int)$data->{$name};
311
                    break;
312
                case 'float':
313
                    $dataArray[$name] = (float)$data->{$name};
314
                    break;
315
                case 'bool':
316
                case 'boolean':
317
                    $dataArray[$name] = (bool)$data->{$name};
318
                    break;
319
                case 'string':
320
                default:
321
                    $dataArray[$name] = (string)$data->{$name};
322
                    break;
323
            }
324
        }
325
326
        return ArrayData::create($dataArray);
327
    }
328
329
    /**
330
     * @return bool
331
     */
332
    public function exists()
333
    {
334
        return $this->getTransaction() != false && !empty($this->getTransaction());
335
    }
336
337
    /**
338
     * @param $data
339
     * @return \SimpleXMLElement
340
     * @throws \SilverStripe\ORM\ValidationException
341
     */
342
    private function getDecryptedData($data)
343
    {
344
        $helper = new FoxyHelper();
345
346
        return new \SimpleXMLElement(\rc4crypt::decrypt($helper->config()->get('secret'), $data));
347
    }
348
}
349