Test Failed
Push — master ( 584f1e...4dba2e )
by Vítězslav
02:32
created

FlexiBeeRW   C

Complexity

Total Complexity 57

Size/Duplication

Total Lines 413
Duplicated Lines 13.56 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 35.12%

Importance

Changes 0
Metric Value
dl 56
loc 413
ccs 59
cts 168
cp 0.3512
rs 6.433
c 0
b 0
f 0
wmc 57
lcom 1
cbo 2

17 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 7 2
C insertToFlexiBee() 0 28 7
A getLastInsertedId() 0 4 1
A deleteFromFlexiBee() 0 9 2
D takeData() 0 29 10
B controlMandatoryColumns() 18 18 5
B controlReadOnlyColumns() 18 18 5
A timestampToFlexiDate() 10 10 2
A timestampToFlexiDateTime() 10 10 2
A addArrayToBranch() 0 15 3
A addObjectToBranch() 0 4 1
A vazbaAdd() 0 5 1
A vazbaDel() 0 6 1
A getJsonizedData() 0 14 4
A getDataForJSON() 0 11 3
A refresh() 0 10 2
B performAction() 0 37 6

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like FlexiBeeRW often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FlexiBeeRW, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * FlexiPeeHP - Třída pro zápis do FlexiBee.
4
 *
5
 * @author     Vítězslav Dvořák <[email protected]>
6
 * @copyright  (C) 2015-2017 Spoje.Net
7
 */
8
9
namespace FlexiPeeHP;
10
11
/**
12
 * Základní třída pro zápis do FlexiBee
13
 *
14
 * @url https://demo.flexibee.eu/devdoc/http-operations
15
 */
16
class FlexiBeeRW extends FlexiBeeRO
17
{
18
    /**
19
     * Sloupeček obsahující datum vložení záznamu do shopu.
20
     *
21
     * @var string
22
     */
23
    public $myCreateColumn = 'false';
24
25
    /**
26
     * Slopecek obsahujici datum poslení modifikace záznamu do shopu.
27
     *
28
     * @var string
29
     */
30
    public $myLastModifiedColumn = 'lastUpdate';
31
32
    /**
33
     * Last Inserted ID.
34
     *
35
     * @var int
36
     */
37
    public $lastInsertedID = null;
38
39
    /**
40
     * Array of fields for next curl POST operation
41
     * 
42
     * @var string
43
     */
44
    public $postFields = null;
45
46
    /**
47
     * Transaction processing mode
48
     * 
49
     * @link https://www.flexibee.eu/api/dokumentace/ref/tx/ Transakční zpracování
50
     * @var boolean
51
     */
52
    public $atomic = null;
53
54
    /**
55 17
     * SetUp Object to be ready for work
56
     *
57 17
     * @param array $options Object Options (company,url,user,password,evidence,
58 17
     *                                       prefix,defaultUrlParams,debug,
59 17
     *                                       detail,offline,atomic
60
     */
61
    public function setUp($options = array())
62 17
    {
63
        if (array_key_exists('atomic', $options)) {
64
            $this->atomic = (boolean) $options['atomic'];
65 17
        }
66 7
        return parent::setUp($options);
67
    }
68
69
    /**
70
     * Save record (if evidence allow to).
71 7
     * Uloží záznam (pokud to evidence dovoluje)
72 10
     *
73 10
     * @param array $data Data to save
74 10
     * @throws Exception Evidence does not support Import
75 17
     *
76
     * @return array odpověď
77 17
     */
78
    public function insertToFlexiBee($data = null)
79
    {
80 17
        $info = $this->getEvidenceInfo();
81 17
        switch ($info['importStatus']) {
82
            case 'DISALLOWED':
83
                throw new \Exception(sprintf('Inserting data to r/o evidence %s',
84
                        $this->getEvidence()));
85
            case 'NOT_DIRECT':
86
                throw new \Exception(sprintf('Inserting data to slave only evidence %s',
87
                        $this->getEvidence()));
88
            case 'NOT_DOCUMENTED':
89
                if ($this->debug === true) {
90
                    $this->addStatusMessage(sprintf('Inserting data to undocumneted evidence %s',
91
                            $this->getEvidence()));
92
                }
93
94
                break;
95
            case 'SUPPORTED':
96
            default:
97
                break;
98
        }
99
100
        if (is_null($data)) {
101
            $data = $this->getData();
102
        }
103
        $this->postFields = $this->getJsonizedData($data);
104
        return $this->performRequest(null, 'PUT');
105
    }
106
107
    /**
108
     * Give you last inserted record ID.
109
     * 
110
     * @return int
111
     */
112
    public function getLastInsertedId()
113
    {
114
        return $this->lastInsertedID;
115
    }
116
117
    /**
118
     * Smaže záznam
119
     * Delete record in FlexiBee
120
     *
121
     * @param int|string $id identifikátor záznamu
122
     * @return boolean Response code is 200 ?
123
     */
124
    public function deleteFromFlexiBee($id = null)
125
    {
126
        if (is_null($id)) {
127
            $id = $this->getMyKey();
128
        }
129
        $this->performRequest($this->getEvidenceUrl().'/'.$id.'.'.$this->format,
130
            'DELETE');
131
        return $this->lastResponseCode == 200;
132
    }
133
134
    /**
135
     * Control for existing column names in evidence and take data
136
     *
137
     * @param array $data Data to keep
138
     * @return int number of records taken
139
     */
140
    public function takeData($data)
141
    {
142
        if ($this->debug === true) {
143
            $fbRelations = [];
144
            $fbColumns   = $this->getColumnsInfo();
145
            foreach ($this->getRelationsInfo() as $relation) {
146
                if (is_array($relation) && isset($relation['url'])) {
147
                    $fbRelations[$relation['url']] = $relation['url'];
148
                }
149
            }
150
            if (count($fbColumns)) {
151
                foreach ($data as $key => $value) {
152
                    if (!array_key_exists($key, $fbColumns)) {
153
154
                        if (!array_key_exists($key, $fbRelations)) {
155
                            $this->addStatusMessage(sprintf('unknown column %s for evidence %s',
156
                                    $key, $this->getEvidence()), 'warning');
157
                        } else {
158
                            if (!is_array($value)) {
159
                                $this->addStatusMessage(sprintf('subevidence %s in evidence %s must bee an array',
160
                                        $key, $this->getEvidence()), 'warning');
161
                            }
162
                        }
163
                    }
164
                }
165
            }
166
        }
167
        return parent::takeData($data);
168
    }
169
170
    /**
171
     * Control data for mandatory columns presence.
172
     *
173
     * @param array $data
174
     * @return array List of missing columns. Empty if all is ok
175
     */
176 View Code Duplication
    public function controlMandatoryColumns($data = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
177
    {
178
        if (is_null($data)) {
179
            $data = $this->getData();
180
        }
181
182
        $missingMandatoryColumns = [];
183
184
        $fbColumns = $this->getColumnsInfo();
185
        foreach ($fbColumns as $columnName => $columnInfo) {
186
            $mandatory = ($columnInfo['mandatory'] == 'true');
187
            if ($mandatory && !array_key_exists($columnName, $data)) {
188
                $missingMandatoryColumns[$columnName] = $columnInfo['name'];
189
            }
190
        }
191
192
        return $missingMandatoryColumns;
193
    }
194
195
    /**
196
     * Control data for readonly columns presence.
197
     *
198
     * @param array $data
199
     * @return array List of ReadOnly columns. Empty if all is ok
200
     */
201 View Code Duplication
    public function controlReadOnlyColumns($data = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
202
    {
203
        if (is_null($data)) {
204 17
            $data = $this->getData();
205
        }
206 17
207 17
        $readonlyColumns = [];
208 17
209 17
        $fbColumns = $this->getColumnsInfo();
210 17
        foreach ($fbColumns as $columnName => $columnInfo) {
211 17
            $writable = ($columnInfo['isWritable'] == 'true');
212 17
            if (!$writable && !array_key_exists($columnName, $data)) {
213
                $readonlyColumns[$columnName] = $columnInfo['name'];
214
            }
215
        }
216
217
        return $readonlyColumns;
218
    }
219
220
    /**
221
     * Convert Timestamp to FlexiBee Date format.
222 17
     *
223
     * @param int $timpestamp
224 17
     *
225 17
     * @return string FlexiBee Date or NULL
226 17
     */
227 17 View Code Duplication
    public static function timestampToFlexiDate($timpestamp = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
228 17
    {
229 17
        $flexiDate = null;
230 17
        if (!is_null($timpestamp)) {
231
            $date      = new \DateTime();
232
            $date->setTimestamp($timpestamp);
233
            $flexiDate = $date->format('Y-m-d');
234
        }
235
        return $flexiDate;
236
    }
237
238
    /**
239
     * Convert Timestamp to Flexi DateTime format.
240
     *
241
     * @param int $timpestamp
242
     *
243
     * @return string FlexiBee DateTime or NULL
244
     */
245 View Code Duplication
    public static function timestampToFlexiDateTime($timpestamp = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
246
    {
247
        $flexiDateTime = null;
248
        if (!is_null($timpestamp)) {
249
            $date          = new \DateTime();
250
            $date->setTimestamp($timpestamp);
251
            $flexiDateTime = $date->format('Y-m-dTH:i:s');
252
        }
253
        return $flexiDateTime;
254
    }
255
256
    /**
257
     * Add Data to evidence Branch
258
     * Přidá data do větve
259
     *
260
     * @thanksto Karel Běl
261
     *
262
     * @see Relations
263
     *
264
     * @param array  $data pole dat
265
     * @param string $relationPath path evidence (relation) pro vkládaná data
266
     *
267
     * @return boolean Operation success
268
     */
269
    public function addArrayToBranch($data, $relationPath)
270
    {
271
        if ($this->debug === true) {
272
            $relationsByUrl = \Ease\Sand::reindexArrayBy($this->getRelationsInfo(),
273
                    'url');
274
            if (!array_key_exists($relationPath, $relationsByUrl)) {
275
                $this->addStatusMessage("Relation to $relationPath does not exist for evidence ".$this->getEvidence(),
276
                    'warning');
277
            }
278
        }
279
        $currentBranchData = $this->getDataValue($relationPath);
280
        $branchData        = $currentBranchData;
281
        $branchData[]      = $data;
282
        return $this->setDataValue($relationPath, $branchData);
283
    }
284
285
    /**
286
     * Vloží do větve data z objektu
287
     *
288
     * @param FlexiBeeRO $object objekt evidence
289
     */
290
    public function addObjectToBranch($object)
291
    {
292
        $this->addArrayToBranch($object->getData(), $object->getEvidence());
293
    }
294
295
    /**
296
     * Přidá uživatelskou vazbu
297
     *
298
     * @see https://www.flexibee.eu/api/dokumentace/ref/uzivatelske-vazby/
299
     * @param string $vazba
300
     */
301
    public function vazbaAdd($vazba)
302
    {
303
        $this->addArrayToBranch(['uzivatelska-vazba' => $vazba],
304
            'uzivatelske-vazby');
305
    }
306
307
    /**
308
     * Smaže uživatelskou vazbu
309
     *
310
     * @see https://www.flexibee.eu/api/dokumentace/ref/uzivatelske-vazby/
311
     * @param string $vazba
312
     */
313
    public function vazbaDel($vazba)
314
    {
315
        $this->setDataValue('uzivatelska-vazba@action', 'delete');
316
        $this->addArrayToBranch(['uzivatelska-vazba' => $vazba],
317
            'uzivatelske-vazby');
318
    }
319
320
    /**
321
     * Převede data do Json formátu pro FlexiBee.
322
     * Pokud jsou štítky pole, jsou převedeny na seznam oddělený čárkou.
323
     * Convert data to FlexiBee like Json format.
324
     * Array of Labels is converted to coma separated list
325
     *
326
     * @param array $data
327
     * @param int   $options json_encode options like JSON_PRETTY_PRINT etc 
328
     *
329
     * @return string
330
     */
331
    public function getJsonizedData($data = null, $options = 0)
332
    {
333
        if (is_null($data)) {
334
            $data = $this->getData();
335
        }
336
337
        if (array_key_exists('stitky', $data)) {
338
            if (is_array($data['stitky'])) {
339
                $data['stitky'] = implode(',', $data['stitky']);
340
            }
341
        }
342
        $dataToJsonize = parent::getJsonizedData($data, $options);
343 17
        return $dataToJsonize;
344
    }
345 17
346
    /**
347 17
     * Get Data Fragment specific for current object
348 17
     * 
349 15
     * @param array $data
350 15
     * 
351 15
     * @return array
352 4
     */
353 4
    public function getDataForJSON($data = null)
354
    {
355 15
        if (is_null($data)) {
356 15
            $data = $this->getData();
357 15
        }
358 15
        $dataForJSON = parent::getDataForJSON($data);
359
        if (!is_null($this->atomic)) {
360
            $dataForJSON['@atomic'] = $this->atomic;
361 15
        }
362 4
        return $dataForJSON;
363 4
    }
364 4
365 4
    /**
366 4
     * Insert current data into FlexiBee and load actual record data back
367
     *
368 15
     * @return boolean Operation success
369 15
     */
370 15
    public function refresh()
371 15
    {
372 15
        $this->insertToFlexiBee();
373 15
        $insertResult = $this->lastResponseCode;
374 17
        $id           = $this->getRecordID();
375 17
        $this->dataReset();
376
        $this->loadFromFlexiBee($id);
377
        $loadResult   = $this->lastResponseCode;
378 15
        return (($insertResult == 201) && ($loadResult == 200));
379
    }
380
381
    /**
382
     * Perform given action (if availble) on current evidence/record
383
     * @url https://demo.flexibee.eu/devdoc/actions
384
     *
385
     * @param string $action one of evidence actions
386
     * @param string $method ext|int External method call operation in URL.
387
     *                               Internal add the @action element to request body
388
     *
389
     * @return boolean operation success
390
     */
391
    public function performAction($action, $method = 'int')
392
    {
393
        $actionsAvailble = $this->getActionsInfo();
394
395
        if (is_array($actionsAvailble) && array_key_exists($action,
396
                $actionsAvailble)) {
397
            switch ($actionsAvailble[$action]['actionMakesSense']) {
398
                case 'ONLY_WITH_INSTANCE_AND_NOT_IN_EDIT':
399
                case 'ONLY_WITH_INSTANCE': //Add instance
400
                    $urlSuffix = '/'.$this->__toString().'/'.$action;
401
                    break;
402
403
                default:
404
                    $urlSuffix = '/'.$action;
405
                    break;
406
            }
407
408
            switch ($method) {
409
                case 'int':
410
                    $this->setAction($action);
411
                    $this->setPostFields($this->getJsonizedData(['id' => $this]));
412
                    $this->performRequest(null, 'POST');
413
                    $result = $this->lastResponseCode == 201;
414
                    break;
415
416
                default:
417
                    $result = $this->performRequest($this->evidenceUrlWithSuffix($urlSuffix),
418
                        'GET');
419
                    break;
420
            }
421
        } else {
422
            throw new \Exception(sprintf(_('Unsupported action %s for evidence %s'),
423
                    $action, $this->getEvidence()));
424
        }
425
426
        return $result;
427
    }
428
}
429