Completed
Push — master ( 59734f...449770 )
by Vítězslav
21:32
created

FlexiBeeRW::parseError()   C

Complexity

Conditions 14
Paths 3

Size

Total Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
nc 3
nop 1
dl 0
loc 38
rs 6.2666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * FlexiPeeHP - Třída pro zápis do FlexiBee.
5
 *
6
 * @author     Vítězslav Dvořák <[email protected]>
7
 * @copyright  (C) 2015-2017 Spoje.Net
8
 */
9
10
namespace FlexiPeeHP;
11
12
/**
13
 * Základní třída pro zápis do FlexiBee
14
 *
15
 * @url https://demo.flexibee.eu/devdoc/http-operations
16
 */
17
class FlexiBeeRW extends FlexiBeeRO {
18
19
    /**
20
     * Sloupeček obsahující datum vložení záznamu do shopu.
21
     *
22
     * @var string
23
     */
24
    public $myCreateColumn = 'false';
25
26
    /**
27
     * Slopecek obsahujici datum poslení modifikace záznamu do shopu.
28
     *
29
     * @var string
30
     */
31
    public $myLastModifiedColumn = 'lastUpdate';
32
33
    /**
34
     * Last Inserted ID.
35
     *
36
     * @var int
37
     */
38
    public $lastInsertedID = null;
39
40
    /**
41
     * Array of fields for next curl POST operation
42
     * 
43
     * @var string
44
     */
45
    public $postFields = null;
46
47
    /**
48
     * Transaction processing mode
49
     * 
50
     * @link https://www.flexibee.eu/api/dokumentace/ref/tx/ Transakční zpracování
51
     * @var boolean
52
     */
53
    public $atomic = null;
54
55
    /**
56
     * Record Copy helper
57
     * 
58
     * @var int 
59
     */
60
    private $sourceId = null;
61
62
    /**
63
     * SetUp Object to be ready for work
64
     *
65
     * @param array $options Object Options (authSessionId,user,password,
66
     *                                       url,company,evidence,companyUrl
67
     *                                       prefix,defaultUrlParams,debug,ver
68
     *                                       detail,offline,atomic,filter,ignore404
69
     */
70
    public function setUp($options = array()) {
71
        if (array_key_exists('atomic', $options)) {
72
            $this->atomic = (boolean) $options['atomic'];
73
        }
74
        return parent::setUp($options);
75
    }
76
77
    /**
78
     * Save record (if evidence allow to).
79
     * Uloží záznam (pokud to evidence dovoluje)
80
     *
81
     * @param array $data Data to save
82
     * @throws Exception Evidence does not support Import
83
     *
84
     * @return array odpověď
85
     */
86
    public function insertToFlexiBee($data = null) {
87
        if (is_null($data)) {
88
            $data = $this->getData();
89
        }
90
        $this->postFields = $this->getJsonizedData($data,
91
                $this->debug ? JSON_PRETTY_PRINT : 0);
92
        return $this->performRequest(null, 'PUT');
93
    }
94
95
    /**
96
     * Parse Response array
97
     *
98
     * @param array $responseDecoded
99
     * @param int $responseCode Request Response Code
100
     *
101
     * @return array main data part of response
102
     */
103
    public function parseResponse($responseDecoded, $responseCode) {
104
        $parsedData = parent::parseResponse($responseDecoded, $responseCode);
105
        switch ($responseCode) {
106
            case 201: //Success Write
107
                if (is_array($responseDecoded)) {
108
                    $this->responseStats = array_key_exists('stats',
0 ignored issues
show
Documentation Bug introduced by
It seems like array_key_exists('stats'...ecoded['stats']) : null can be null. However, the property $responseStats is declared as array. Maybe change the type of the property to array|null or add a type check?

Our type inference engine has found an assignment of a scalar value (like a string, an integer or null) to a property which is an array.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.

To type hint that a parameter can be either an array or null, you can set a type hint of array and a default value of null. The PHP interpreter will then accept both an array or null for that parameter.

function aContainsB(array $needle = null, array  $haystack) {
    if (!$needle) {
        return false;
    }

    return array_intersect($haystack, $needle) == $haystack;
}

The function can be called with either null or an array for the parameter $needle but will only accept an array as $haystack.

Loading history...
109
                                    $responseDecoded) ? (isset($responseDecoded['stats'][0]) ? array_map('intval', $responseDecoded['stats'][0]) : array_map('intval', $responseDecoded['stats'])) : null;
110
                    if (isset($responseDecoded[$this->resultField][0]['id'])) {
111
                        $this->lastInsertedID = $responseDecoded[$this->resultField][0]['id'];
112
                        $this->setMyKey($this->lastInsertedID);
113
                    } else {
114
                        $this->lastInsertedID = null;
115
                    }
116
                    if (count($this->chained)) {
117
                        $this->assignResultIDs($this->extractResultIDs($responseDecoded[$this->resultField]));
118
                    }
119
                }
120
                $parsedData = $responseDecoded['results'];
121
        }
122
        return $parsedData;
123
    }
124
125
    /**
126
     * Parse error message response
127
     *
128
     * @param array $responseDecoded
129
     * 
130
     * @return int number of errors processed
131
     */
132
    public function parseError(array $responseDecoded) {
133
        if (array_key_exists('results', $responseDecoded)) {
134
135
            if (array_key_exists(0, $responseDecoded['results'])) {
136
                foreach ($responseDecoded['results'] as $result) {
137
                    
138
                    if (array_key_exists('request-id', $result)) {
139
                        unset($result['request-id']);
140
                    }
141
                    
142
                    if (array_key_exists('errors', $result)) {
143
                        foreach ($result as $error) {
144
                            $this->errors[] = current($error);
145
                        }
146
                    }
147
                }
148
            } else {
149
                foreach ($responseDecoded['results'][0]['result'] as $result) {
150
                    if (array_key_exists('errors', $result)) {
151
                        foreach ($result as $error) {
152
                            $this->errors[] = current($error);
153
                        }
154
                    }
155
                }
156
            }
157
158
            foreach ($this->errors as $errorInfo) {
159
                $this->addStatusMessage(array_key_exists('error', $errorInfo) ? $errorInfo['error'] : $errorInfo['message'], 'error');
160
                if ($this->debug && array_key_exists('for', $errorInfo)) {
161
                    unset($errorInfo['message']);
162
                    $this->addStatusMessage(json_encode($errorInfo), 'debug');
163
                }
164
            }
165
        } else {
166
            parent::parseError($responseDecoded);
167
        }
168
        return count($this->errors);
169
    }
170
171
    /**
172
     * Assign result IDs to its source objects
173
     * 
174
     * @param array $candidates FlexiBee insert IDs  prepared by extractResultIDs()
175
     */
176
    public function assignResultIDs($candidates) {
177
        foreach ($this->chained as $chid => $chained) {
178
            $chainedEvidence = $chained->getEvidence();
179
            $chainedExtid = $chained->getRecordID();
180
            if (is_array($chainedExtid)) { //if there are more IDs
181
                foreach ($chainedExtid as $extId) { //find external ID in format ext:.....
182
                    if (stripos($extId, 'ext:') === 0) {
183
                        $chainedExtid = $extId;
184
                        break;
185
                    }
186
                }
187
            }
188
            $chained->getData();
189
            if (isset($candidates[$chainedEvidence][$chainedExtid])) {
190
                $chained->setMyKey($candidates[$chainedEvidence][$chainedExtid]);
191
                $chained->setDataValue('external-ids', [$chainedExtid]);
192
            }
193
            if (count($this->chained[$chid]->chained)) {
194
                $this->chained[$chid]->assignResultIDs($candidates);
195
            }
196
        }
197
    }
198
199
    /**
200
     * Extract IDs from FlexiBee response Array
201
     * 
202
     * @param array $resultInfo FlexiBee response
203
     * 
204
     * @return array List of [ 'evidence1'=>[ 'original-id'=>numericID,'original-id2'=>numericID2 ], 'evidence2'=> ... ]
205
     */
206
    public function extractResultIDs($resultInfo) {
207
        $candidates = [];
208
        foreach ($resultInfo as $insertResult) {
209
            $newID = $insertResult['id'];
210
            if (array_key_exists('request-id', $insertResult)) {
211
                $extid = $insertResult['request-id'];
212
            } else {
213
                $extid = null;
214
            }
215
            $evidence = explode('/', $insertResult['ref'])[3];
216
            $candidates[$evidence][$extid] = $newID;
217
        }
218
        return $candidates;
219
    }
220
221
    /**
222
     * Give you last inserted record ID.
223
     * 
224
     * @return int
225
     */
226
    public function getLastInsertedId() {
227
        return $this->lastInsertedID;
228
    }
229
230
    /**
231
     * Smaže záznam
232
     * Delete record in FlexiBee
233
     *
234
     * @param int|string $id identifikátor záznamu
235
     * 
236
     * @return boolean Response code is 200 ?
237
     */
238
    public function deleteFromFlexiBee($id = null) {
239
        if (is_null($id)) {
240
            $id = $this->getMyKey();
241
        }
242
243
        $this->performRequest($this->getEvidenceUrl() . '/' . self::urlizeId($id),
244
                'DELETE');
245
        return $this->lastResponseCode == 200;
246
    }
247
248
    /**
249
     * Control for existing column names in evidence and take data
250
     *
251
     * @param array $data Data to keep
252
     * 
253
     * @return int number of records taken
254
     */
255
    public function takeData($data) {
256
        if ($this->debug === true) {
257
            $fbRelations = [];
258
            $fbColumns = $this->getColumnsInfo();
259
            foreach ($this->getRelationsInfo() as $relation) {
260
                if (is_array($relation) && isset($relation['url'])) {
261
                    $fbRelations[$relation['url']] = $relation['url'];
262
                }
263
            }
264
            if (count($fbColumns)) {
265
                foreach ($data as $key => $value) {
266
                    if (!array_key_exists($key, $fbColumns)) {
267
268
                        if (!array_key_exists($key, $fbRelations)) {
269
                            $this->addStatusMessage(sprintf('unknown column %s for evidence %s',
270
                                            $key, $this->getEvidence()), 'warning');
271
                        } else {
272
                            if (!is_array($value)) {
273
                                $this->addStatusMessage(sprintf('subevidence %s in evidence %s must bee an array',
274
                                                $key, $this->getEvidence()), 'warning');
275
                            }
276
                        }
277
                    }
278
                }
279
            }
280
        }
281
        return parent::takeData($data);
282
    }
283
284
    /**
285
     * Control data for mandatory columns presence.
286
     *
287
     * @deprecated since version 1.8.7
288
     * 
289
     * @param array $data
290
     * 
291
     * @return array List of missing columns. Empty if all is ok
292
     */
293
    public function controlMandatoryColumns($data = null) {
294
        if (is_null($data)) {
295
            $data = $this->getData();
296
        }
297
        $missingMandatoryColumns = [];
298
        if (!empty($data) && count($data)) {
299
            $fbColumns = $this->getColumnsInfo();
300
            if (count($fbColumns)) {
301
                foreach ($fbColumns as $columnName => $columnInfo) {
302
                    $mandatory = ($columnInfo['mandatory'] == 'true');
303
                    if ($mandatory && !array_key_exists($columnName, $data)) {
304
                        $missingMandatoryColumns[$columnName] = $columnInfo['name'];
305
                    }
306
                }
307
            }
308
        }
309
        return $missingMandatoryColumns;
310
    }
311
312
    /**
313
     * Control data for readonly columns presence.
314
     *
315
     * @param array $data
316
     * 
317
     * @return array List of ReadOnly columns. Empty if all is ok
318
     */
319
    public function controlReadOnlyColumns($data = null) {
320
        if (is_null($data)) {
321
            $data = $this->getData();
322
        }
323
324
        $readonlyColumns = [];
325
326
        $fbColumns = $this->getColumnsInfo();
327
        if (!empty($fbColumns) && count($fbColumns)) {
328
            foreach ($fbColumns as $columnName => $columnInfo) {
329
                $writable = ($columnInfo['isWritable'] == 'true');
330
                if (!$writable && !array_key_exists($columnName, $data)) {
331
                    $readonlyColumns[$columnName] = $columnInfo['name'];
332
                }
333
            }
334
        }
335
        return $readonlyColumns;
336
    }
337
338
    /**
339
     * Convert Timestamp to FlexiBee Date format.
340
     *
341
     * @param int $timpestamp
342
     *
343
     * @return string FlexiBee Date or NULL
344
     */
345
    public static function timestampToFlexiDate($timpestamp = null) {
346
        $flexiDate = null;
347
        if (!is_null($timpestamp)) {
348
            $date = new \DateTime();
349
            $date->setTimestamp($timpestamp);
350
            $flexiDate = $date->format('Y-m-d');
351
        }
352
        return $flexiDate;
353
    }
354
355
    /**
356
     * Convert Timestamp to Flexi DateTime format.
357
     *
358
     * @param int $timpestamp
359
     *
360
     * @return string FlexiBee DateTime or NULL
361
     */
362
    public static function timestampToFlexiDateTime($timpestamp = null) {
363
        $flexiDateTime = null;
364
        if (!is_null($timpestamp)) {
365
            $date = new \DateTime();
366
            $date->setTimestamp($timpestamp);
367
            $flexiDateTime = $date->format('Y-m-dTH:i:s');
368
        }
369
        return $flexiDateTime;
370
    }
371
372
    /**
373
     * Add Data to evidence Branch
374
     * Přidá data do větve
375
     *
376
     * @thanksto Karel Běl
377
     *
378
     * @see Relations
379
     *
380
     * @param array   $data pole dat
381
     * @param string  $relationPath path evidence (relation) pro vkládaná data
382
     * @param boolean $removeAll
383
     *
384
     * @return boolean Operation success
385
     */
386
    public function addArrayToBranch($data, $relationPath = 'polozkyDokladu',
387
            $removeAll = false) {
388
        $currentBranchData = $this->getDataValue($relationPath);
389
        $branchData = $currentBranchData;
390
        $branchData[] = $data;
391
        if (is_array($this->getEvidence()) && array_key_exists('bezPolozek',
392
                        $this->getColumnsInfo())) {
393
            $this->setDataValue('bezPolozek', false);
394
        }
395
        if ($removeAll === true) {
396
            $this->setDataValue($relationPath . '@removeAll', true);
397
        }
398
        return $this->setDataValue($relationPath, $branchData);
399
    }
400
401
    /**
402
     * Vloží do větve data z objektu
403
     *
404
     * @param FlexiBeeRO $object    objekt evidence
405
     * @param boolean    $removeAll flush older items 
406
     */
407
    public function addObjectToBranch($object, $removeAll = false) {
408
        $this->addArrayToBranch([$object->getEvidence() => $object->getData()],
409
                'polozkyDokladu', $removeAll);
410
    }
411
412
    /**
413
     * Přidá uživatelskou vazbu
414
     *
415
     * @see https://www.flexibee.eu/api/dokumentace/ref/uzivatelske-vazby/
416
     * @param string $vazba
417
     */
418
    public function vazbaAdd($vazba) {
419
        $this->addArrayToBranch(['uzivatelska-vazba' => $vazba],
420
                'uzivatelske-vazby');
421
    }
422
423
    /**
424
     * Smaže uživatelskou vazbu
425
     *
426
     * @see https://www.flexibee.eu/api/dokumentace/ref/uzivatelske-vazby/
427
     * @param string $vazba
428
     */
429
    public function vazbaDel($vazba) {
430
        $this->setDataValue('uzivatelska-vazba@action', 'delete');
431
        $this->addArrayToBranch(['uzivatelska-vazba' => $vazba],
432
                'uzivatelske-vazby');
433
    }
434
435
    /**
436
     * Převede data do Json formátu pro FlexiBee.
437
     * Pokud jsou štítky pole, jsou převedeny na seznam oddělený čárkou.
438
     * Convert data to FlexiBee like Json format.
439
     * Array of Labels is converted to coma separated list
440
     *
441
     * @param array $data
442
     * @param int   $options json_encode options like JSON_PRETTY_PRINT etc 
443
     *
444
     * @return string
445
     */
446
    public function getJsonizedData($data = null, $options = 0) {
447
        if (is_null($data)) {
448
            $data = $this->getData();
449
        }
450
451
        if (array_key_exists('stitky', $data)) {
452
            if (is_array($data['stitky'])) {
453
                $data['stitky'] = implode(',', $data['stitky']);
454
            }
455
        }
456
        $dataToJsonize = parent::getJsonizedData($data, $options);
457
        return $dataToJsonize;
458
    }
459
460
    /**
461
     * Get Data Fragment specific for current object
462
     * 
463
     * @param array $data
464
     * 
465
     * @return array
466
     */
467
    public function getDataForJSON($data = null) {
468
        if (is_null($data)) {
469
            $data = $this->getData();
470
        }
471
        $dataForJSON = parent::getDataForJSON($data);
472
        if (!is_null($this->atomic)) {
473
            $dataForJSON['@atomic'] = $this->atomic;
474
        }
475
        if (isset($this->sourceId)) {
476
            $dataForJSON['@sourceId'] = $this->sourceId;
477
            $this->sourceId = null;
478
        }
479
        return $dataForJSON;
480
    }
481
482
    /**
483
     * Insert current data into FlexiBee and load actual record data back
484
     *
485
     * @param array $data Initial data to save
486
     * 
487
     * @return boolean Operation success
488
     */
489
    public function sync($data = null) {
490
        $this->insertToFlexiBee($data);
491
        $insertResult = $this->lastResponseCode;
492
        if ($insertResult == 201) {
493
            $this->reload();
494
        }
495
        $loadResult = $this->lastResponseCode;
496
        return ($insertResult + $loadResult) == 401;
497
    }
498
499
    /**
500
     * Make Copy of given record with optional modifiactions
501
     * 
502
     * !!!Experimental Feature!!!
503
     * 
504
     * @param int  $source
505
     * @param array $overrides
506
     * 
507
     * @return FlexiBeeRW|null copied record object or null in case of failure
508
     */
509
    public function copy($source, $overrides = []) {
510
        $this->sourceId = $source;
511
        return $this->sync($overrides) ? $this : null;
512
    }
513
514
    /**
515
     * Perform given action (if availble) on current evidence/record
516
     * @url https://demo.flexibee.eu/devdoc/actions
517
     *
518
     * @param string $action one of evidence actions
519
     * @param string $method ext|int External method call operation in URL.
520
     *                               Internal add the @action element to request body
521
     *
522
     * @return boolean operation success
523
     */
524
    public function performAction($action, $method = 'int') {
525
        $actionsAvailble = $this->getActionsInfo();
526
527
        if (is_array($actionsAvailble) && array_key_exists($action,
528
                        $actionsAvailble)) {
529
            switch ($actionsAvailble[$action]['actionMakesSense']) {
530
                case 'ONLY_WITH_INSTANCE_AND_NOT_IN_EDIT':
531
                case 'ONLY_WITH_INSTANCE': //Add instance
532
                    $urlSuffix = '/' . $this->__toString() . '/' . $action;
533
                    break;
534
535
                default:
536
                    $urlSuffix = '/' . $action;
537
                    break;
538
            }
539
540
            switch ($method) {
541
                case 'int':
542
                    $this->setAction($action);
543
                    $this->setPostFields($this->getJsonizedData(['id' => $this]));
544
                    $this->performRequest(null, 'POST');
545
                    $result = $this->lastResponseCode == 201;
546
                    break;
547
548
                default:
549
                    $result = $this->performRequest($this->evidenceUrlWithSuffix($urlSuffix),
550
                            'GET');
551
                    break;
552
            }
553
        } else {
554
            throw new \Exception(sprintf(_('Unsupported action %s for evidence %s'),
555
                            $action, $this->getEvidence()));
556
        }
557
558
        return $result;
559
    }
560
561
    /**
562
     * Add External ID to Current Record
563
     * 
564
     * @param string $extId ext:whatever:123 or simplay whatever:123
565
     * 
566
     * @return array Insert result
567
     */
568
    public function addExternalID($extId) {
569
        return $this->insertToFlexiBee(['id' => [$this->getRecordID(), 'ext:' . preg_replace('/^ext:/',
570
                                '', $extId)]]);
571
    }
572
573
    /**
574
     * Change Value of external id identified by selector. Add new if not exists
575
     * 
576
     * @param string     $selector ext:$selector:$newValue
577
     * @param string|int $newValue string or number
578
     * @param string|int $forID    Other than current record id
579
     * 
580
     * @return array operation result
581
     */
582
    public function changeExternalID($selector, $newValue, $forID = null) {
583
        $change['@removeExternalIds'] = 'ext:' . $selector . ':';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$change was never initialized. Although not strictly required by PHP, it is generally a good practice to add $change = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
584
        $change['id'] = [is_null($forID) ? $this->getRecordID() : $forID,
585
            'ext:' . $selector . ':' . $newValue];
586
        return $this->insertToFlexiBee($change);
587
    }
588
589
    /**
590
     * Send all unsent Documents by eMail
591
     *
592
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
593
     * 
594
     * @return int http response code
595
     */
596
    public function sendUnsent() {
597
        $this->performRequest('automaticky-odeslat-neodeslane', 'PUT', 'xml');
598
        return $this->lastResponseCode == 202;
599
    }
600
601
}
602