Completed
Push — master ( 18a32e...28949e )
by Vítězslav
03:50
created

FlexiBee::performRequest()   D

Complexity

Conditions 16
Paths 112

Size

Total Lines 86
Code Lines 57

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 40
CRAP Score 16.351

Importance

Changes 6
Bugs 0 Features 1
Metric Value
cc 16
eloc 57
c 6
b 0
f 1
nc 112
nop 3
dl 0
loc 86
ccs 40
cts 45
cp 0.8889
crap 16.351
rs 4.681

How to fix   Long Method    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
 * FlexiPeeHP - Třída pro práci s FlexiBee.
4
 *
5
 * @author     Vítězslav Dvořák <[email protected]>
6
 * @copyright  (C) 2015,2016 Spoje.Net
7
 */
8
9
namespace FlexiPeeHP;
10
11
class FlexiBee extends \Ease\Brick
12
{
13
    /**
14
     * Základní namespace pro komunikaci s FlexiBEE.
15
     *
16
     * @var string Jmený prostor datového bloku odpovědi
17
     */
18
    public $nameSpace = 'winstrom';
19
20
    /**
21
     * Datový blok v poli odpovědi.
22
     *
23
     * @var string
24
     */
25
    public $resultField = 'results';
26
27
    /**
28
     * Verze protokolu použitého pro komunikaci.
29
     *
30
     * @var string Verze použitého API
31
     */
32
    public $protoVersion = '1.0';
33
34
    /**
35
     * Evidence užitá objektem.
36
     *
37
     * @var string
38
     */
39
    public $evidence = null;
40
41
    /**
42
     * Výchozí formát pro komunikaci.
43
     *
44
     * @link https://www.flexibee.eu/api/dokumentace/ref/format-types Přehled možných formátů
45
     *
46
     * @var string json|xml|...
47
     */
48
    public $format = 'json';
49
50
    /**
51
     * Curl Handle.
52
     *
53
     * @var resource
54
     */
55
    public $curl = null;
56
57
    /**
58
     * @var type
59
     */
60
    public $company = FLEXIBEE_COMPANY;
61
62
    /**
63
     * @var string
64
     */
65
    public $url = FLEXIBEE_URL;
66
67
    /**
68
     * @var string
69
     */
70
    public $user = FLEXIBEE_LOGIN;
71
72
    /**
73
     * @var string
74
     */
75
    public $password = FLEXIBEE_PASSWORD;
76
77
    /**
78
     * Identifikační řetězec.
79
     *
80
     * @var string
81
     */
82
    public $init = null;
83
84
    /**
85
     * Sloupeček s názvem.
86
     *
87
     * @var string
88
     */
89
    public $nameColumn = 'nazev';
90
91
    /**
92
     * Sloupeček obsahující datum vložení záznamu do shopu.
93
     *
94
     * @var string
95
     */
96
    public $myCreateColumn = 'false';
97
98
    /**
99
     * Slopecek obsahujici datum poslení modifikace záznamu do shopu.
100
     *
101
     * @var string
102
     */
103
    public $myLastModifiedColumn = 'lastUpdate';
104
105
    /**
106
     * Klíčový idendifikátor záznamu.
107
     *
108
     * @var string
109
     */
110
    public $fbKeyColumn = 'id';
111
112
    /**
113
     * Informace o posledním HTTP requestu.
114
     *
115
     * @var array
116
     */
117
    public $info;
118
119
    /**
120
     * Informace o poslední HTTP chybě.
121
     *
122
     * @var array
123
     */
124
    public $error;
125
126
    /**
127
     * Used codes storage.
128
     *
129
     * @var array
130
     */
131
    public $codes = null;
132
133
    /**
134
     * Last Inserted ID.
135
     *
136
     * @var int
137
     */
138
    public $lastInsertedID = null;
139
140
    /**
141
     * Default Line Prefix.
142
     *
143
     * @var string
144
     */
145
    public $prefix = '/c/';
146
147
    /**
148
     * HTTP Response code of last request
149
     * 
150
     * @var int
151
     */
152 28
    public $lastResponseCode = null;
153
154 28
    /**
155
     * Třída pro práci s FlexiBee.
156 28
     *
157 28
     * @param string $init výchozí selektor dat
158 28
     */
159
    public function __construct($init = null)
160 28
    {
161
        $this->init = $init;
162 28
163 28
        parent::__construct();
164 28
        $this->curlInit();
165 28
    }
166 28
167 28
    public function curlInit()
168 28
    {
169 28
        $this->curl = \curl_init(); // create curl resource
170 28
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); // return content as a string from curl_exec
171 28
        curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); // follow redirects (compatibility for future changes in FlexiBee)
172
        curl_setopt($this->curl, CURLOPT_HTTPAUTH, true);       // HTTP authentication
173
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); // FlexiBee by default uses Self-Signed certificates
174
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
175
        curl_setopt($this->curl, CURLOPT_VERBOSE, true); // For debugging
176
        curl_setopt($this->curl, CURLOPT_USERPWD,
177
            $this->user.':'.$this->password); // set username and password
178 14
    }
179
180 14
    /**
181 14
     * Nastaví Agendu pro Komunikaci.
182
     *
183
     * @param string $evidence
184
     */
185
    public function setEvidence($evidence)
186
    {
187
        $this->evidence = $evidence;
188
    }
189
190 14
    /**
191
     * Převede rekurzivně Objekt na pole.
192 14
     *
193 14
     * @param object|array $object
194 14
     *
195 14
     * @return array
196 14
     */
197 14
    public static function object2array($object)
198 14
    {
199 14
        $result = null;
200 14
        if (is_object($object)) {
201 14
            $objectData = get_object_vars($object);
202 14
            if (is_array($objectData) && count($objectData)) {
203 14
                $result = array_map('self::object2array', $objectData);
204 14
            }
205
        } else {
206
            if (is_array($object)) {
207
                foreach ($object as $item => $value) {
208 14
                    $result[$item] = self::object2array($value);
209
                }
210
            } else {
211
                $result = $object;
212
            }
213
        }
214
215
        return $result;
216
    }
217
218 14
    /**
219
     * Funkce, která provede I/O operaci a vyhodnotí výsledek.
220
     *
221 14
     * @param string $urlSuffix část URL za identifikátorem firmy.
222 14
     * @param string $method    HTTP/REST metoda
223 14
     * @param string $format    Requested format
224 14
     */
225 3
    public function performRequest($urlSuffix = null, $method = 'GET',
226 3
                                   $format = null)
227 14
    {
228 14
        if (is_null($format)) {
229
            $format = $this->format;
230 14
        }
231
        if (is_null($urlSuffix)) {
232
            $urlSuffix = $this->evidence.'.'.$format;
233 14
        }
234
        $url = $this->url.$this->prefix.$this->company.'/'.$urlSuffix;
235 14
        curl_setopt($this->curl, CURLOPT_URL, $url);
236
// Nastavení samotné operace
237 14
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $method);
238
239 14
// Proveď samotnou operaci
240 14
        $response = curl_exec($this->curl);
241 14
242 14
        $this->info = curl_getinfo($this->curl);
0 ignored issues
show
Documentation Bug introduced by
It seems like curl_getinfo($this->curl) of type * is incompatible with the declared type array of property $info.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

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

Loading history...
243
244 14
        $this->lastResponseCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
245 14
246 14
        if ($this->lastResponseCode != 200 && $this->lastResponseCode != 201) {
247 14
            $this->error = curl_error($this->curl);
0 ignored issues
show
Documentation Bug introduced by
It seems like curl_error($this->curl) of type string is incompatible with the declared type array of property $error.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

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

Loading history...
248 14
            switch ($format) {
249
                case 'json':
250 14
                    $response = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/',
251 1
                        function ($match) {
252 1
                        return mb_convert_encoding(pack('H*', $match[1]),
253 14
                            'UTF-8', 'UCS-2BE');
254 14
                    }, $response);
255 14
                    $response = (json_encode(json_decode($response, true, 10),
256 14
                            JSON_PRETTY_PRINT));
257
                    break;
258 14
                case 'xml':
259
                    $response = self::xml2array($response);
260
                    break;
261
            }
262 14
263
264
            if ($this->lastResponseCode == 400) {
265
                $this->logResult(self::object2array(current(json_decode($response))));
0 ignored issues
show
Bug introduced by
It seems like self::object2array(curre...son_decode($response))) targeting FlexiPeeHP\FlexiBee::object2array() can also be of type null; however, FlexiPeeHP\FlexiBee::logResult() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
266
            } else {
267 13
                $this->addStatusMessage(sprintf('Error (HTTP %d): <pre>%s</pre> %s',
268 13
                        curl_getinfo($this->curl, CURLINFO_HTTP_CODE),
269 13
                        http_build_query($response), $this->error), 'error');
270
                $this->addStatusMessage($url);
271
            }
272 13
            if ($response == 'null') {
273
                $response = null;
274
            } else {
275
                if (is_string($response)) {
276
                    $response = self::object2array(current(json_decode($response)));
277 13
                }
278 3
            }
279 3
            return $response;
280 3
        }
281
282
        // Parse response
283
        switch ($format) {
284 13
            case 'json':
285 13
                $decoded = json_decode($response, true, 10);
286 13
                if (($method == 'PUT') && isset($decoded[$this->nameSpace][$this->resultField][0]['id'])) {
287
                    $this->lastInsertedID = $decoded[$this->nameSpace][$this->resultField][0]['id'];
288 13
                } else {
289
                    $this->lastInsertedID = null;
290
                }
291
//                $decodeError = json_last_error_msg();
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
292
//                $this->addStatusMessage($decodeError);
293
294
                break;
295
            case 'xml':
296
                if (strlen($response)) {
297
                    $decoded = self::xml2array($response);
298
                } else {
299
                    $decoded = null;
300
                }
301
                break;
302
        }
303
304
        // Get response body root automatically
305
        if (isset($decoded[$this->nameSpace])) {
306
            $decoded = $decoded[$this->nameSpace];
307
        }
308 14
309
        return $decoded;
0 ignored issues
show
Bug introduced by
The variable $decoded 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...
310 14
    }
311
312 14
    /**
313 14
     * Give you last inserted record ID.
314 14
     * 
315
     * @return int
316 14
     */
317 14
    public function getLastInsertedId()
318 14
    {
319 14
        return $this->lastInsertedID;
320 14
    }
321 14
322
    /**
323 14
     * Convert XML to array.
324
     * 
325 14
     * @param string $xml
326
     *
327
     * @return array
328
     */
329
    public static function xml2array($xml)
330
    {
331 15
        $arr = [];
332
333 15
        if (is_string($xml)) {
334 15
            $xml = simplexml_load_string($xml);
335 15
        }
336 15
337 15
        foreach ($xml->children() as $r) {
338
            $t = [];
0 ignored issues
show
Unused Code introduced by
$t is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
339 15
            if (count($r->children()) == 0) {
340
                $arr[$r->getName()] = strval($r);
341 15
            } else {
342 15
                $arr[$r->getName()][] = self::xml2array($r);
343
            }
344
        }
345
346
        return $arr;
347
    }
348
349
    /**
350
     * Odpojení od FlexiBee.
351
     */
352
    public function disconnect()
353
    {
354
        if (is_resource($this->curl)) {
355
            curl_close($this->curl);
356
        }
357
        $this->curl = null;
358
    }
359
360
    public function __destruct()
361 14
    {
362
        $this->disconnect();
363 14
    }
364 14
365 14
    /**
366 9
     * Načte data z FlexiBee.
367 9
     *
368
     * @param string $suffix dotaz
369 14
     */
370
    public function loadFlexiData($suffix = null)
371
    {
372
        return $this->takeData($this->getFlexiData($suffix));
373
    }
374
375
    /**
376
     * Načte řádek dat z FlexiBee.
377
     *
378 13
     * @param int $recordID id požadovaného záznamu
379
     *
380 13
     * @return array
381 10
     */
382 10
    public function getFlexiRow($recordID)
383 10
    {
384 10
        $record   = null;
385 13
        $response = $this->performRequest($this->evidence.'/'.$recordID.'.json');
386
        if (isset($response[$this->evidence])) {
387 13
            $record = $response[$this->evidence][0];
388
        }
389
390
        return $record;
391 13
    }
392 13
393
    /**
394 13
     * Načte data z FlexiBee.
395 10
     *
396 10
     * @param string $suffix     dotaz
397 3
     * @param string $conditions Volitelný filtrovací výraz
398
     */
399
    public function getFlexiData($suffix = null, $conditions = null)
400 13
    {
401
        if (!is_null($conditions)) {
402
            if ($conditions[0] != '/') {
403
                $conditions = '/'.rawurlencode('('.($conditions).')');
404
            }
405
        } else {
406
            $conditions = '';
407
        }
408
        if ($suffix) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $suffix of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
409
            $transactions = $this->performRequest($this->evidence.$conditions.'.'.$this->format.'?'.$suffix,
410 14
                'GET');
411
        } else {
412 14
            $transactions = $this->performRequest($this->evidence.$conditions.'.'.$this->format,
413 14
                'GET');
414 14
        }
415
        if (isset($transactions[$this->evidence])) {
416 14
            $result = $transactions[$this->evidence];
417
        } else {
418
            $result = $transactions;
419
        }
420
421
        return $result;
422
    }
423
424
    /**
425
     * Načte záznam z FlexiBee.
426
     *
427
     * @param int $id ID záznamu
428
     *
429
     * @return int počet načtených položek
430
     */
431
    public function loadFromFlexiBee($id = null)
432
    {
433
        if (is_null($id)) {
434
            $id = $this->getMyKey();
435
        }
436
437
        return $this->takeData($this->getFlexiData('/'.$id));
438
    }
439
440
    /**
441
     * Uloží data do FlexiBee.
442
     *
443
     * @param array $data
444
     *
445
     * @return array výsledek
446 14
     */
447 View Code Duplication
    public function saveToFlexiBee($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...
448
    {
449 14
        if (is_null($data)) {
450 14
            $data = $this->getData();
451 14
        }
452 14
453 14
        $jsonizedData = $this->jsonizeData($data);
454
455 14
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $jsonizedData);
456
457
        return $this->performRequest($this->evidence.'.'.$this->format, 'PUT');
458
    }
459
460
    /**
461
     * Převede data do Json formátu pro FlexiBee.
462
     *
463
     * @param array $data
464
     *
465
     * @return string
466
     */
467
    public function jsonizeData($data)
468
    {
469
        $jsonize = [
470
            $this->nameSpace => [
471
                '@version' => $this->protoVersion,
472
                $this->evidence => $data,
473
            ],
474
        ];
475
476
        return json_encode($jsonize);
477
    }
478
479
    /**
480
     * Uloží záznam.
481
     *
482
     * @param array $data
483
     *
484
     * @return array odpověď
485
     */
486 View Code Duplication
    public function insertToFlexiBee($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...
487
    {
488
        if (is_null($data)) {
489
            $data = $this->getData();
490
        }
491
        $jsonizedData = $this->jsonizeData($data);
492
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $jsonizedData);
493
494
        return $this->performRequest($this->evidence.'.'.$this->format, 'PUT');
495
    }
496
497
    /**
498
     * Test if given record ID exists in FlexiBee.
499
     *
500
     * @param string|int $identifer
501
     */
502
    public function idExists($identifer = null)
503
    {
504
        if (is_null($identifer)) {
505
            $identifer = $this->getMyKey();
506
        }
507
        $flexiData = $this->getFlexiData(
508
            'detail=custom:'.$this->getmyKeyColumn(), $identifer);
509
510
        return $flexiData;
511
    }
512
513
    /**
514
     * Test if given record exists in FlexiBee.
515
     *
516
     * @param array $data
517
     */
518
    public function recordExists($data = null)
519
    {
520
        if (is_null($data)) {
521
            $data = $this->getData();
522
        }
523
524
        $res = $this->getColumnsFromFlexibee([$this->myKeyColumn],
525
            self::flexiUrl($data));
526
527
        return $res;
528
    }
529
530
    /**
531
     * Vrací z FlexiBee sloupečky podle podmínek.
532
     *
533
     * @param array|int|string $conditions pole podmínek nebo ID záznamu
534
     * @param array|string     $orderBy    třídit dle
535
     * @param string           $indexBy    klice vysledku naplnit hodnotou ze
536
     *                                     sloupečku
537
     * @param int              $limit      maximální počet vrácených záznamů
538
     *
539
     * @return array
540
     */
541
    public function getAllFromFlexibee($conditions = null, $orderBy = null,
0 ignored issues
show
Unused Code introduced by
The parameter $orderBy is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
542
                                       $indexBy = null, $limit = null)
0 ignored issues
show
Unused Code introduced by
The parameter $limit is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
543
    {
544
        if (is_int($conditions)) {
545
            $conditions = [$this->getmyKeyColumn() => $conditions];
546
        }
547
548
        $flexiData = $this->getFlexiData('', $conditions);
0 ignored issues
show
Bug introduced by
It seems like $conditions can also be of type array; however, FlexiPeeHP\FlexiBee::getFlexiData() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
549
550 View Code Duplication
        if ($indexBy) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $indexBy of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
Duplication introduced by
This code seems to be duplicated across 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...
551
            $flexiData2 = [];
552
            foreach ($flexiData as $dataID => $data) {
553
                $flexiData2[$data[$indexBy]] = $data;
554
            }
555
            $flexiData = $flexiData2;
556
        }
557
558
        return $flexiData;
559
    }
560
561
    /**
562
     * Vrací z FlexiBee sloupečky podle podmínek.
563
     *
564
     * @param string[]         $columnsList seznam položek
565
     * @param array|int|string $conditions  pole podmínek nebo ID záznamu
566
     * @param array|string     $orderBy     třídit dle
567
     * @param string           $indexBy     klice vysledku naplnit hodnotou ze
568
     *                                      sloupečku
569
     * @param int              $limit       maximální počet vrácených záznamů
570
     *
571
     * @return array
572
     */
573
    public function getColumnsFromFlexibee($columnsList, $conditions = null,
574
                                           $orderBy = null, $indexBy = null,
0 ignored issues
show
Unused Code introduced by
The parameter $orderBy is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
575
                                           $limit = null)
0 ignored issues
show
Unused Code introduced by
The parameter $limit is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
576
    {
577
        if (($columnsList != '*') && !count($columnsList)) {
578
            $this->error('getColumnsFromFlexiBee: Missing ColumnList');
579
580
            return;
581
        }
582
583
        if (is_int($conditions)) {
584
            $conditions = [$this->getmyKeyColumn() => $conditions];
585
        }
586
587
        if (is_array($columnsList)) {
588
            $columns = implode(',', array_unique($columnsList));
589
        } else {
590
            $columns = $columnsList;
591
        }
592
593
        $flexiData = $this->getFlexiData('detail=custom:'.$columns, $conditions);
0 ignored issues
show
Bug introduced by
It seems like $conditions can also be of type array; however, FlexiPeeHP\FlexiBee::getFlexiData() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
594 14
595 View Code Duplication
        if ($indexBy) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $indexBy of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
Duplication introduced by
This code seems to be duplicated across 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...
596 14
            $flexiData2 = [];
597
            foreach ($flexiData as $dataID => $data) {
598 14
                $flexiData2[$data[$indexBy]] = $data;
599 14
            }
600 14
            $flexiData = $flexiData2;
601
        }
602 14
603 14
        return $flexiData;
604 14
    }
605
606 14
    /**
607 14
     * Vrací kód záznamu.
608 14
     *
609 14
     * @param mixed $data
610 14
     *
611 14
     * @todo papat i string
612 14
     *
613 14
     * @return string
614 14
     */
615 14
    public function getKod($data = null, $unique = true)
616
    {
617
        $kod = null;
618
619 14
        if (is_null($data)) {
620 14
            $data = $this->getData();
621 14
        }
622
623 14
        if (is_string($data)) {
624 14
            $data = [$this->nameColumn => $data];
625 14
        }
626 14
627
        if (isset($data['kod'])) {
628
            $kod = $data['kod'];
629 14
        } else {
630 14
            if (isset($data[$this->nameColumn])) {
631 14
                $kod = preg_replace('/[^a-zA-Z0-9]/', '',
632 14
                    \Ease\Sand::rip($data[$this->nameColumn]));
633 14
            } else {
634 14
                if (isset($data[$this->myKeyColumn])) {
635 14
                    $kod = \Ease\Sand::rip($data[$this->myKeyColumn]);
636 14
                }
637 14
            }
638 14
        }
639 14
640 14
        if (!strlen($kod)) {
641
            $kod = 'NOTSET';
642 14
        }
643 14
644
        if (strlen($kod) > 18) {
645 14
            $kodfinal = strtoupper(substr($kod, 0, 18));
646
        } else {
647
            $kodfinal = strtoupper($kod);
648
        }
649
650
        if ($unique) {
651
            $counter = 0;
652
            if ($this->codes) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->codes of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
653
                foreach ($this->codes as $codesearch => $keystring) {
654
                    if (strstr($codesearch, $kodfinal)) {
655
                        ++$counter;
656
                    }
657
                }
658
            }
659
            if ($counter) {
660
                $kodfinal = $kodfinal.$counter;
661
            }
662
663
            $this->codes[$kodfinal] = $kod;
664
        }
665
666
        return $kodfinal;
667
    }
668
669
    /**
670
     * Vyhledavani v záznamech objektu FlexiBee.
671
     *
672
     * @param string $what hledaný výraz
673
     *
674
     * @return array pole výsledků
675
     */
676
    public function searchString($what)
677
    {
678
        $results   = [];
679
        $conds     = [];
680
        $columns[] = $this->myKeyColumn;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$columns was never initialized. Although not strictly required by PHP, it is generally a good practice to add $columns = 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...
681
        foreach ($this->useKeywords as $keyword => $keywordInfo) {
0 ignored issues
show
Bug introduced by
The property useKeywords does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
682
            if (isset($this->keywordsInfo[$keyword]['virtual']) && ($this->keywordsInfo[$keyword]['virtual']
0 ignored issues
show
Bug introduced by
The property keywordsInfo does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
683
                == true)) {
684
                if ($keyword == $this->nameColumn) {
685
                    $this->nameColumn = $this->myKeyColumn;
686
                }
687
                continue;
688
            }
689
            switch ($keywordInfo) {
690
                case 'INT':
691 View Code Duplication
                case 'FLOAT':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
692
                    if (is_numeric($what)) {
693
                        $conds[]   = "($keyword = ".$what.')';
694
                        $columns[] = "$keyword";
695
                    }
696
                    break;
697
                case 'TEXT':
698 View Code Duplication
                case 'STRING':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
699
                    if (is_string($what)) {
700
                        $conds[]   = "( $keyword like '".$what."')";
701
                        $columns[] = "$keyword";
702
                    }
703
                    break;
704
                default:
705
                    break;
706
            }
707
        }
708
709
//        $res = \Ease\Shared::db()->queryToArray('SELECT ' . implode(',', $columns) . ',' . $this->nameColumn . ' FROM ' . $this->myTable . ' WHERE ' . implode(' OR ', $conds) . ' ORDER BY ' . $this->nameColumn, $this->myKeyColumn);
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
710
711
        $res = $this->getColumnsFromFlexibee($columns, implode(' or ', $conds));
712
713
        foreach ($res as $result) {
714
            $occurences = '';
715 14
            foreach ($result as $key => $value) {
716
                if (is_array($value)) {
717 14
                    continue;
718 14
                }
719 14
                if (mb_stristr($value, $what)) {
720
                    $occurences .= '('.$key.': '.$value.')';
721 14
                }
722 14
            }
723 14
            $results[$result[$this->myKeyColumn]] = [$this->nameColumn => $result[$this->nameColumn],
724 14
                'what' => $occurences,];
725 14
        }
726 14
727
        return $results;
728 14
    }
729 14
730 14
    /**
731 14
     * Write Operation Result.
732 14
     * 
733
     * @param array  $resultData
734 14
     * @param string $url        URL
735 14
     */
736 14
    public function logResult($resultData, $url = null)
737 14
    {
738 14
        if ($url) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $url of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
739 14
            $this->logger->addStatusMessage($url);
740 14
        }
741 14
742 14
        if (isset($resultData['results'])) {
743 14
            $status = null;
0 ignored issues
show
Unused Code introduced by
$status is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
744 14
            if ($resultData['success'] == 'false') {
745 14
                $status = 'error';
746
            } else {
747
                $status = 'success';
748
            }
749
            foreach ($resultData['results'] as $result) {
750
                if (isset($result['request-id'])) {
751
                    $rid = $result['request-id'];
752
                } else {
753
                    $rid = '';
754
                }
755
                if (isset($result['errors'])) {
756
                    foreach ($result['errors'] as $error) {
757 14
                        $message = $error['message'];
758
                        if (isset($error['for'])) {
759 14
                            $message.=' for: '.$error['for'];
760 14
                        }
761
                        if (isset($error['value'])) {
762 14
                            $message.=' value:'.$error['value'];
763 14
                        }
764 14
                        if (isset($error['code'])) {
765 14
                            $message.=' code:'.$error['code'];
766 14
                        }
767
                        $this->logger->addStatusMessage($rid.': '.$message,
768 14
                            $status);
769
                    }
770 14
                }
771
            }
772 14
        }
773
        if (is_object($this->logger)) {
774
            $this->logger->flush(get_class($this));
775
        }
776
    }
777
778
    /**
779
     * Generuje fragment url pro filtrování.
780
     *
781
     * @see https://www.flexibee.eu/api/dokumentace/ref/filters
782
     *
783
     * @param array  $data
784
     * @param string $operator and/or
785
     *
786
     * @return string
787
     */
788
    public static function flexiUrl(array $data, $operator = 'and')
789
    {
790
        $flexiUrl = '';
0 ignored issues
show
Unused Code introduced by
$flexiUrl is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
791
        $parts    = [];
792
793
        foreach ($data as $column => $value) {
794
            if (is_numeric($data[$column])) {
795
                $parts[$column] = $column.' = '.$data[$column];
796
            } else {
797
                $parts[$column] = $column." = '".$data[$column]."'";
798
            }
799
        }
800
801
        $flexiUrl = implode(' '.$operator.' ', $parts);
802
803
        return $flexiUrl;
804
    }
805
806
    /**
807
     * Smaže záznam
808
     *
809
     * @param int|string $id identifikátor záznamu
810
     */
811
    public function deleteFromFlexiBee($id)
812
    {
813
        $this->performRequest($this->evidence.'/'.$id.'.'.$this->format);
814
    }
815
}