Test Failed
Push — master ( 3bbada...6bf191 )
by Vítězslav
07:41
created

FlexiBeeRW   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 307
Duplicated Lines 18.24 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 3
Bugs 0 Features 0
Metric Value
dl 56
loc 307
rs 8.3999
c 3
b 0
f 0
wmc 46
lcom 1
cbo 2

14 Methods

Rating   Name   Duplication   Size   Complexity  
D insertToFlexiBee() 0 37 9
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 4 1
A jsonizeData() 0 9 3
A refresh() 0 5 1

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
     * Save record (if evidence allow to).
48
     * Uloží záznam (pokud to evidence dovoluje)
49
     *
50
     * @param array $data Data to save
51
     * @throws Exception Evidence does not support Import
52
     *
53
     * @return array odpověď
54
     */
55
    public function insertToFlexiBee($data = null)
56
    {
57
        $info = $this->getEvidenceInfo();
58
        switch ($info['importStatus']) {
59
            case 'DISALLOWED':
60
                throw new \Exception(sprintf('Inserting data to r/o evidence %s',
61
                    $this->getEvidence()));
62
            case 'NOT_DIRECT':
63
                throw new \Exception(sprintf('Inserting data to slave only evidence %s',
64
                    $this->getEvidence()));
65
            case 'NOT_DOCUMENTED':
66
                if ($this->debug === true) {
67
                    $this->addStatusMessage(sprintf('Inserting data to undocumneted evidence %s',
68
                            $this->getEvidence()));
69
                }
70
71
                break;
72
            case 'SUPPORTED':
73
            default:
74
                break;
75
        }
76
77
        if (is_null($data)) {
78
            $data = $this->getData();
79
        }
80
        if ($this->debug === true) {
81
            $missingColumns = $this->controlMandatoryColumns($data);
82
            if (count($missingColumns)) {
83
                $this->addStatusMessage(sprintf('Given data does not contain requied Columns: %s',
84
                        '['.implode(',', array_keys($missingColumns)).'] '.implode(',',
85
                            $missingColumns))
86
                    , 'warning');
87
            }
88
        }
89
        $this->postFields = $this->jsonizeData($data);
90
        return $this->performRequest($this->evidence.'.'.$this->format, 'PUT');
91
    }
92
93
    /**
94
     * Give you last inserted record ID.
95
     * 
96
     * @return int
97
     */
98
    public function getLastInsertedId()
99
    {
100
        return $this->lastInsertedID;
101
    }
102
103
    /**
104
     * Smaže záznam
105
     * Delete record in FlexiBee
106
     *
107
     * @param int|string $id identifikátor záznamu
108
     * @return boolean Response code is 200 ?
109
     */
110
    public function deleteFromFlexiBee($id = null)
111
    {
112
        if (is_null($id)) {
113
            $id = $this->getMyKey();
114
        }
115
        $this->performRequest($this->evidence.'/'.$id.'.'.$this->format,
116
            'DELETE');
117
        return $this->lastResponseCode == 200;
118
    }
119
120
    /**
121
     * Control for existing column names in evidence and take data
122
     *
123
     * @param array $data Data to keep
124
     * @return int number of records taken
125
     */
126
    public function takeData($data)
127
    {
128
        if ($this->debug === true) {
129
            $fbColumns = $this->getColumnsInfo();
130
            foreach ($this->getRelationsInfo() as $relation) {
131
                if (is_array($relation) && isset($relation['url'])) {
132
                    $fbRelations[$relation['url']] = $relation['url'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$fbRelations was never initialized. Although not strictly required by PHP, it is generally a good practice to add $fbRelations = 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...
133
                }
134
            }
135
136
            if (count($fbColumns)) {
137
                foreach ($data as $key => $value) {
138
                    if (!array_key_exists($key, $fbColumns)) {
139
140
                        if (!array_key_exists($key, $fbRelations)) {
0 ignored issues
show
Bug introduced by
The variable $fbRelations does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
141
                            $this->addStatusMessage(sprintf('unknown column %s for evidence %s',
142
                                    $key, $this->getEvidence()), 'warning');
143
                        } else {
144
                            if (!is_array($value)) {
145
                                $this->addStatusMessage(sprintf('subevidence %s in evidence %s must bee an array',
146
                                        $key, $this->getEvidence()), 'warning');
147
                            }
148
                        }
149
                    }
150
                }
151
            }
152
        }
153
        return parent::takeData($data);
154
    }
155
156
    /**
157
     * Control data for mandatory columns presence.
158
     *
159
     * @param array $data
160
     * @return array List of missing columns. Empty if all is ok
161
     */
162 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...
163
    {
164
        if (is_null($data)) {
165
            $data = $this->getData();
166
        }
167
168
        $missingMandatoryColumns = [];
169
170
        $fbColumns = $this->getColumnsInfo();
171
        foreach ($fbColumns as $columnName => $columnInfo) {
172
            $mandatory = ($columnInfo['mandatory'] == 'true');
173
            if ($mandatory && !array_key_exists($columnName, $data)) {
174
                $missingMandatoryColumns[$columnName] = $columnInfo['name'];
175
            }
176
        }
177
178
        return $missingMandatoryColumns;
179
    }
180
181
    /**
182
     * Control data for readonly columns presence.
183
     *
184
     * @param array $data
185
     * @return array List of ReadOnly columns. Empty if all is ok
186
     */
187 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...
188
    {
189
        if (is_null($data)) {
190
            $data->getData();
0 ignored issues
show
Bug introduced by
The method getData cannot be called on $data (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
191
        }
192
193
        $readonlyColumns = [];
194
195
        $fbColumns = $this->getColumnsInfo();
196
        foreach ($fbColumns as $columnName => $columnInfo) {
197
            $writable = ($columnInfo['isWritable'] == 'true');
198
            if (!$writable && !array_key_exists($columnName, $data)) {
199
                $readonlyColumns[$columnName] = $columnInfo['name'];
200
            }
201
        }
202
203
        return $readonlyColumns;
204
    }
205
206
    /**
207
     * Convert Timestamp to FlexiBee Date format.
208
     *
209
     * @param int $timpestamp
210
     *
211
     * @return string FlexiBee Date or NULL
212
     */
213 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...
214
    {
215
        $flexiDate = null;
216
        if (!is_null($timpestamp)) {
217
            $date      = new \DateTime();
218
            $date->setTimestamp($timpestamp);
219
            $flexiDate = $date->format('Y-m-d');
220
        }
221
        return $flexiDate;
222
    }
223
224
    /**
225
     * Convert Timestamp to Flexi DateTime format.
226
     *
227
     * @param int $timpestamp
228
     *
229
     * @return string FlexiBee DateTime or NULL
230
     */
231 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...
232
    {
233
        $flexiDateTime = null;
234
        if (!is_null($timpestamp)) {
235
            $date          = new \DateTime();
236
            $date->setTimestamp($timpestamp);
237
            $flexiDateTime = $date->format('Y-m-dTH:i:s');
238
        }
239
        return $flexiDateTime;
240
    }
241
242
    /**
243
     * Add Data to evidence Branch
244
     * Přidá data do větve
245
     *
246
     * @thanksto Karel Běl
247
     * @param array  $data pole dat
248
     * @param string $relationPath path evidence (relation) pro vkládaná data 
249
     * @see Relations
250
     */
251
    public function addArrayToBranch($data, $relationPath)
252
    {
253
        if ($this->debug === true) {
254
            $relationsByUrl = \Ease\Sand::reindexArrayBy($this->getRelationsInfo(),
255
                    'url');
256
            if (!array_key_exists($relationPath, $relationsByUrl)) {
257
                $this->addStatusMessage("Relation to $relationPath does not exist for evidence ".$this->getEvidence(),
258
                    'warning');
259
            }
260
        }
261
        $currentBranchData = $this->getDataValue($relationPath);
262
        $branchData        = $currentBranchData;
263
        $branchData[]      = $data;
264
        $this->setDataValue($relationPath, $branchData);
265
    }
266
267
    /**
268
     * Vloží do větve data z objektu
269
     *
270
     * @param FlexiBeeRO $object objekt evidence
271
     */
272
    public function addObjectToBranch($object)
273
    {
274
        $this->addArrayToBranch($object->getData(), $object->getEvidence());
275
    }
276
277
    /**
278
     * @see https://www.flexibee.eu/api/dokumentace/ref/uzivatelske-vazby/
279
     */
280
    public function vazbaAdd()
281
    {
282
        $this->addArrayToBranch(['uzivatelska-vazba' => $vazba],
0 ignored issues
show
Bug introduced by
The variable $vazba does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
283
            'uzivatelske-vazby');
284
    }
285
286
    /**
287
     * @
288
     */
289
    public function vazbaDel()
290
    {
291
        
292
    }
293
294
    /**
295
     * Převede data do Json formátu pro FlexiBee.
296
     * Pokud jsou štítky pole, jsou převedeny na seznam oddělený čárkou.
297
     * Convert data to FlexiBee like Json format.
298
     * Array of Labels is converted to coma separated list
299
     *
300
     * @param array $data
301
     *
302
     * @return string
303
     */
304
    public function jsonizeData($data)
305
    {
306
        if (array_key_exists('stitky', $data)) {
307
            if (is_array($data['stitky'])) {
308
                $data['stitky'] = implode(',', $data['stitky']);
309
            }
310
        }
311
        return parent::jsonizeData($data);
312
    }
313
314
    /**
315
     * Insert current data into FlexiBee and load actual record data back
316
     */
317
    public function refresh()
318
    {
319
        $this->insertToFlexiBee();
320
        $this->loadFromFlexiBee();
321
    }
322
}
323