Passed
Pull Request — master (#31)
by Nic
02:03
created

Transaction::hasID()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Dynamic\Foxy\Orders\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\Foxy
15
 */
16
class Transaction
17
{
18
    use Injectable;
19
    use Configurable;
20
21
    /**
22
     * @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...
23
     */
24
    private $transaction;
25
26
    /**
27
     * @var ArrayData
28
     */
29
    private $transaction_data;
30
31
    /**
32
     * @var ArrayList
33
     */
34
    private $discount_data;
35
36
    /**
37
     * @var ArrayList
38
     */
39
    private $product_data;
40
41
    /**
42
     * Transaction constructor.
43
     * @param $data string encrypted foxy response data from the xml data feed
44
     * @throws ValidationException
45
     */
46
    public function __construct($data)
47
    {
48
        $this->setTransaction($data);
49
    }
50
51
    /**
52
     * Set the decrypted transaction data to use.
53
     *
54
     * @param $data
55
     * @return $this
56
     * @throws ValidationException
57
     */
58
    public function setTransaction($data)
59
    {
60
        $decryptedData = $this->getDecryptedData($data);
61
62
        foreach ($decryptedData->transactions->transaction as $transaction) {
63
            if ($this->hasID($transaction)) {
64
                $this->transaction = $transaction;
65
                break;
66
            }
67
        }
68
69
        if (!$this->transaction) {
70
            $this->transaction = false;
71
        }
72
73
        return $this;
74
    }
75
76
    /**
77
     * Check if there is a transaction ID for the given decrypted transaction data.
78
     *
79
     * @param $transaction
80
     * @return bool
81
     */
82
    protected function hasID($transaction)
83
    {
84
        return (int)$transaction->id > 0;
85
    }
86
87
    /**
88
     * Return the decrypted transaction xml data.
89
     *
90
     * @return mixed
91
     */
92
    protected function getTransaction()
93
    {
94
        return $this->transaction;
95
    }
96
97
    /**
98
     * Return an ArrayData containing transaction, products and discounts data.
99
     *
100
     * @return ArrayData
101
     */
102
    public function getParsedTransactionData()
103
    {
104
        /**
105
         *
106
         */
107
        return ArrayData::create([
108
            'transaction' => $this->getTransactionData(),
109
            'products' => $this->getProductData(),
110
            'discounts' => $this->getDiscountData(),
111
        ]);
112
    }
113
114
    /**
115
     * Set the base transaction data in an ArrayData object.
116
     *
117
     * @return $this
118
     */
119
    private function setTransactionData()
120
    {
121
        $this->transaction_data = $this->getObject(
122
            $this->getTransaction(),
123
            $this->config()->get('transaction_mapping')
124
        );
125
126
        return $this;
127
    }
128
129
    /**
130
     * Return base transaction data.
131
     *
132
     * @return ArrayData
133
     */
134
    protected function getTransactionData()
135
    {
136
        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...
137
            $this->setTransactionData();
138
        }
139
140
        return $this->transaction_data;
141
    }
142
143
    /**
144
     * Return discounts data from Foxy.io xml data feed if any.
145
     *
146
     * @return ArrayList
147
     */
148
    protected function getDiscountData()
149
    {
150
        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...
151
            $this->setDiscountData();
152
        }
153
154
        return $this->discount_data;
155
    }
156
157
    /**
158
     * Set an ArrayList with possible discount data as ArrayData objects.
159
     *
160
     * @return $this
161
     */
162
    protected function setDiscountData()
163
    {
164
        $discounts = $this->getTransaction()->discounts;
165
        $discountsList = ArrayList::create();
166
167
        foreach ($discounts as $discount) {
168
            $discountsList->push($this->getObject($discount, $this->config()->get('discounts_mapping')));
169
        }
170
171
        $this->discount_data = $discountsList;
172
173
        return $this;
174
    }
175
176
    /**
177
     * Return transaction_details data from Foxy.io xml data feed if any.
178
     *
179
     * @return ArrayList
180
     */
181
    protected function getProductData()
182
    {
183
        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...
184
            $this->setProductData();
185
        }
186
187
        return $this->product_data;
188
    }
189
190
    /**
191
     * Set an ArrayList with possible transaction_detail data as ArrayData objects.
192
     *
193
     * @return $this
194
     */
195
    protected function setProductData()
196
    {
197
        $details = $this->getTransaction()->transaction_details->transaction_detail;
198
        $detailsList = ArrayList::create();
199
200
        foreach ($details as $detail) {
201
            $product = $this->getObject($detail, $this->config()->get('transaction_detail_mapping'));
202
203
            $product->transaction_detail_options = $this->getProductOptions($detail->transaction_detail_options->transaction_detail_option);
204
205
            $detailsList->push($product);
206
        }
207
208
        $this->product_data = $detailsList;
209
210
        return $this;
211
    }
212
213
    /**
214
     * Returns an ArrayList containing possible transaction_detail_option data as ArrayData objects.
215
     *
216
     * @param $data
217
     * @return ArrayList
218
     */
219
    protected function getProductOptions($data)
220
    {
221
        $options = ArrayList::create();
222
223
        foreach ($data as $option) {
224
            $options->push($this->getObject($option, $this->config()->get('transaction_detail_option_mapping')));
225
        }
226
227
        return $options;
228
    }
229
230
231
    /**
232
     * Returns an ArrayData object based on the given iterable data and a key/val config array. Used
233
     * to type hint data from the Foxy.io xml data feed.
234
     *
235
     * @param $data
236
     * @param array $config
237
     * @return ArrayData
238
     */
239
    protected function getObject($data, $config = [])
240
    {
241
        $object = ArrayData::create();
242
243
        foreach ($config as $name => $type) {
244
            switch ($type) {
245
                case 'int':
246
                    $object->{$name} = (int)$data->{$name};
247
                    break;
248
                case 'float':
249
                    $object->{$name} = (float)$data->{$name};
250
                    break;
251
                case 'string':
252
                default:
253
                    $object->{$name} = (string)$data->{$name};
254
                    break;
255
            }
256
        }
257
258
        return $object;
259
    }
260
261
    /**
262
     * @return bool
263
     */
264
    public function exists()
265
    {
266
        return $this->getTransaction() != false && !empty($this->getTransaction());
267
    }
268
269
    /**
270
     * @param $data
271
     * @return \SimpleXMLElement
272
     * @throws \SilverStripe\ORM\ValidationException
273
     */
274
    private function getDecryptedData($data)
275
    {
276
        $helper = new FoxyHelper();
277
278
        return new \SimpleXMLElement(\rc4crypt::decrypt($helper->config()->get('secret'), $data));
279
    }
280
}
281