Completed
Push — master ( 7483cb...a139b5 )
by Vítězslav
03:58
created

FlexiBee::saveToFlexiBee()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 12
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 12
loc 12
ccs 0
cts 7
cp 0
rs 9.4285
cc 2
eloc 6
nc 2
nop 1
crap 6
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
     * Třída pro práci s FlexiBee.
149
     *
150
     * @param string $init výchozí selektor dat
151
     */
152 28
    public function __construct($init = null)
153
    {
154 28
        $this->init = $init;
155
156 28
        parent::__construct();
157 28
        $this->curlInit();
158 28
    }
159
160 28
    public function curlInit()
161
    {
162 28
        $this->curl = \curl_init(); // create curl resource
163 28
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); // return content as a string from curl_exec
164 28
        curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); // follow redirects (compatibility for future changes in FlexiBee)
165 28
        curl_setopt($this->curl, CURLOPT_HTTPAUTH, true);       // HTTP authentication
166 28
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); // FlexiBee by default uses Self-Signed certificates
167 28
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
168 28
        curl_setopt($this->curl, CURLOPT_VERBOSE, true); // For debugging
169 28
        curl_setopt($this->curl, CURLOPT_USERPWD,
170 28
            $this->user.':'.$this->password); // set username and password
171 28
    }
172
173
    /**
174
     * Nastaví Agendu pro Komunikaci.
175
     *
176
     * @param string $evidence
177
     */
178 14
    public function setEvidence($evidence)
179
    {
180 14
        $this->evidence = $evidence;
181 14
    }
182
183
    /**
184
     * Převede rekurzivně Objekt na pole.
185
     *
186
     * @param object|array $object
187
     *
188
     * @return array
189
     */
190 14
    public static function object2array($object)
191
    {
192 14
        $result = null;
193 14
        if (is_object($object)) {
194 14
            $objectData = get_object_vars($object);
195 14
            if (is_array($objectData) && count($objectData)) {
196 14
                $result = array_map('self::object2array', $objectData);
197 14
            }
198 14
        } else {
199 14
            if (is_array($object)) {
200 14
                foreach ($object as $item => $value) {
201 14
                    $result[$item] = self::object2array($value);
202 14
                }
203 14
            } else {
204 14
                $result = $object;
205
            }
206
        }
207
208 14
        return $result;
209
    }
210
211
    /**
212
     * Funkce, která provede I/O operaci a vyhodnotí výsledek.
213
     *
214
     * @param string $urlSuffix část URL za identifikátorem firmy.
215
     * @param string $method    HTTP/REST metoda
216
     * @param string $format    Requested format
217
     */
218 14
    public function performRequest($urlSuffix = null, $method = 'GET',
219
                                   $format = null)
220
    {
221 14
        if (is_null($format)) {
222 14
            $format = $this->format;
223 14
        }
224 14
        if (is_null($urlSuffix)) {
225 3
            $urlSuffix = $this->evidence.'.'.$format;
226 3
        }
227 14
        $url = $this->url.$this->prefix.$this->company.'/'.$urlSuffix;
228 14
        curl_setopt($this->curl, CURLOPT_URL, $url);
229
// Nastavení samotné operace
230 14
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $method);
231
232
// Proveď samotnou operaci
233 14
        $response = curl_exec($this->curl);
234
235 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...
236
237 14
        $responseCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
238
239 14
        if ($responseCode != 200 && $responseCode != 201) {
240 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...
241 14
            $response    = (json_encode(json_decode($response, true, 10),
242 14
                    JSON_PRETTY_PRINT));
243
244 14
            $response = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/',
245 14
                function ($match) {
246 14
                return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8',
247 14
                    'UCS-2BE');
248 14
            }, $response);
249
250 14
            if ($responseCode == 400) {
251 1
                $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...
252 1
            } else {
253 14
                $this->addStatusMessage(sprintf('Error (HTTP %d): <pre>%s</pre> %s',
254 14
                        curl_getinfo($this->curl, CURLINFO_HTTP_CODE),
255 14
                        stripslashes($response), $this->error), 'error');
256 14
                $this->addStatusMessage($url);
257
            }
258 14
            if ($response == 'null') {
259
                return;
260
            }
261
262 14
            return self::object2array(current(json_decode($response)));
263
        }
264
265
        // Parse response
266
        switch ($format) {
267 13
            case 'json':
268 13
                $decoded = json_decode($response, true, 10);
269 13
                if (($method == 'PUT') && isset($decoded[$this->nameSpace][$this->resultField][0]['id'])) {
270
                    $this->lastInsertedID = $decoded[$this->nameSpace][$this->resultField][0]['id'];
271
                } else {
272 13
                    $this->lastInsertedID = null;
273
                }
274
//                $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...
275
//                $this->addStatusMessage($decodeError);
276
277 13
                break;
278 3
            case 'xml':
279 3
                $decoded = self::xml2array($response);
280 3
                break;
281
        }
282
283
        // Get response body root automatically
284 13
        if (isset($decoded[$this->nameSpace])) {
285 13
            $decoded = $decoded[$this->nameSpace];
286 13
        }
287
288 13
        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...
289
    }
290
291
    /**
292
     * Give you last inserted record ID.
293
     * 
294
     * @return int
295
     */
296
    public function getLastInsertedId()
297
    {
298
        return $this->lastInsertedID;
299
    }
300
301
    /**
302
     * Convert XML to array.
303
     * 
304
     * @param string $xml
305
     *
306
     * @return array
307
     */
308 14
    public static function xml2array($xml)
309
    {
310 14
        $arr = [];
311
312 14
        if (is_string($xml)) {
313 14
            $xml = simplexml_load_string($xml);
314 14
        }
315
316 14
        foreach ($xml->children() as $r) {
317 14
            $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...
318 14
            if (count($r->children()) == 0) {
319 14
                $arr[$r->getName()] = strval($r);
320 14
            } else {
321 14
                $arr[$r->getName()][] = self::xml2array($r);
322
            }
323 14
        }
324
325 14
        return $arr;
326
    }
327
328
    /**
329
     * Odpojení od FlexiBee.
330
     */
331 15
    public function disconnect()
332
    {
333 15
        if (is_resource($this->curl)) {
334 15
            curl_close($this->curl);
335 15
        }
336 15
        $this->curl = null;
337 15
    }
338
339 15
    public function __destruct()
340
    {
341 15
        $this->disconnect();
342 15
    }
343
344
    /**
345
     * Načte data z FlexiBee.
346
     *
347
     * @param string $suffix dotaz
348
     */
349
    public function loadFlexiData($suffix = null)
350
    {
351
        return $this->takeData($this->getFlexiData($suffix));
352
    }
353
354
    /**
355
     * Načte řádek dat z FlexiBee.
356
     *
357
     * @param int $recordID id požadovaného záznamu
358
     *
359
     * @return array
360
     */
361 14
    public function getFlexiRow($recordID)
362
    {
363 14
        $record   = null;
364 14
        $response = $this->performRequest($this->evidence.'/'.$recordID.'.json');
365 14
        if (isset($response[$this->evidence])) {
366 9
            $record = $response[$this->evidence][0];
367 9
        }
368
369 14
        return $record;
370
    }
371
372
    /**
373
     * Načte data z FlexiBee.
374
     *
375
     * @param string $suffix     dotaz
376
     * @param string $conditions Volitelný filtrovací výraz
377
     */
378 13
    public function getFlexiData($suffix = null, $conditions = null)
379
    {
380 13
        if (!is_null($conditions)) {
381 10
            if ($conditions[0] != '/') {
382 10
                $conditions = '/'.rawurlencode('('.($conditions).')');
383 10
            }
384 10
        } else {
385 13
            $conditions = '';
386
        }
387 13
        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...
388
            $transactions = $this->performRequest($this->evidence.$conditions.'.'.$this->format.'?'.$suffix,
389
                'GET');
390
        } else {
391 13
            $transactions = $this->performRequest($this->evidence.$conditions.'.'.$this->format,
392 13
                'GET');
393
        }
394 13
        if (isset($transactions[$this->evidence])) {
395 10
            $result = $transactions[$this->evidence];
396 10
        } else {
397 3
            $result = $transactions;
398
        }
399
400 13
        return $result;
401
    }
402
403
    /**
404
     * Načte záznam z FlexiBee.
405
     *
406
     * @param int $id ID záznamu
407
     *
408
     * @return int počet načtených položek
409
     */
410 14
    public function loadFromFlexiBee($id = null)
411
    {
412 14
        if (is_null($id)) {
413 14
            $id = $this->getMyKey();
414 14
        }
415
416 14
        return $this->takeData($this->getFlexiData('/'.$id));
417
    }
418
419
    /**
420
     * Uloží data do FlexiBee.
421
     *
422
     * @param array $data
423
     *
424
     * @return array výsledek
425
     */
426 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...
427
    {
428
        if (is_null($data)) {
429
            $data = $this->getData();
430
        }
431
432
        $jsonizedData = $this->jsonizeData($data);
433
434
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $jsonizedData);
435
436
        return $this->performRequest($this->evidence.'.'.$this->format, 'PUT');
437
    }
438
439
    /**
440
     * Převede data do Json formátu pro FlexiBee.
441
     *
442
     * @param array $data
443
     *
444
     * @return string
445
     */
446 14
    public function jsonizeData($data)
447
    {
448
        $jsonize = [
449 14
            $this->nameSpace => [
450 14
                '@version' => $this->protoVersion,
451 14
                $this->evidence => $data,
452 14
            ],
453 14
        ];
454
455 14
        return json_encode($jsonize);
456
    }
457
458
    /**
459
     * Uloží záznam.
460
     *
461
     * @param array $data
462
     *
463
     * @return array odpověď
464
     */
465 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...
466
    {
467
        if (is_null($data)) {
468
            $data = $this->getData();
469
        }
470
        $jsonizedData = $this->jsonizeData($data);
471
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $jsonizedData);
472
473
        return $this->performRequest($this->evidence.'.'.$this->format, 'PUT');
474
    }
475
476
    /**
477
     * Test if given record ID exists in FlexiBee.
478
     *
479
     * @param string|int $identifer
480
     */
481
    public function idExists($identifer = null)
482
    {
483
        if (is_null($identifer)) {
484
            $identifer = $this->getMyKey();
485
        }
486
        $flexiData = $this->getFlexiData(
487
            'detail=custom:'.$this->getmyKeyColumn(), $identifer);
488
489
        return $flexiData;
490
    }
491
492
    /**
493
     * Test if given record exists in FlexiBee.
494
     *
495
     * @param array $data
496
     */
497
    public function recordExists($data = null)
498
    {
499
        if (is_null($data)) {
500
            $data = $this->getData();
501
        }
502
503
        $res = $this->getColumnsFromFlexibee([$this->myKeyColumn],
504
            self::flexiUrl($data));
505
506
        return $res;
507
    }
508
509
    /**
510
     * Vrací z FlexiBee sloupečky podle podmínek.
511
     *
512
     * @param array|int|string $conditions pole podmínek nebo ID záznamu
513
     * @param array|string     $orderBy    třídit dle
514
     * @param string           $indexBy    klice vysledku naplnit hodnotou ze
515
     *                                     sloupečku
516
     * @param int              $limit      maximální počet vrácených záznamů
517
     *
518
     * @return array
519
     */
520
    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...
521
                                       $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...
522
    {
523
        if (is_int($conditions)) {
524
            $conditions = [$this->getmyKeyColumn() => $conditions];
525
        }
526
527
        $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...
528
529 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...
530
            $flexiData2 = [];
531
            foreach ($flexiData as $dataID => $data) {
532
                $flexiData2[$data[$indexBy]] = $data;
533
            }
534
            $flexiData = $flexiData2;
535
        }
536
537
        return $flexiData;
538
    }
539
540
    /**
541
     * Vrací z FlexiBee sloupečky podle podmínek.
542
     *
543
     * @param string[]         $columnsList seznam položek
544
     * @param array|int|string $conditions  pole podmínek nebo ID záznamu
545
     * @param array|string     $orderBy     třídit dle
546
     * @param string           $indexBy     klice vysledku naplnit hodnotou ze
547
     *                                      sloupečku
548
     * @param int              $limit       maximální počet vrácených záznamů
549
     *
550
     * @return array
551
     */
552
    public function getColumnsFromFlexibee($columnsList, $conditions = null,
553
                                           $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...
554
                                           $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...
555
    {
556
        if (($columnsList != '*') && !count($columnsList)) {
557
            $this->error('getColumnsFromFlexiBee: Missing ColumnList');
558
559
            return;
560
        }
561
562
        if (is_int($conditions)) {
563
            $conditions = [$this->getmyKeyColumn() => $conditions];
564
        }
565
566
        if (is_array($columnsList)) {
567
            $columns = implode(',', array_unique($columnsList));
568
        } else {
569
            $columns = $columnsList;
570
        }
571
572
        $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...
573
574 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...
575
            $flexiData2 = [];
576
            foreach ($flexiData as $dataID => $data) {
577
                $flexiData2[$data[$indexBy]] = $data;
578
            }
579
            $flexiData = $flexiData2;
580
        }
581
582
        return $flexiData;
583
    }
584
585
    /**
586
     * Vrací kód záznamu.
587
     *
588
     * @param mixed $data
589
     *
590
     * @todo papat i string
591
     *
592
     * @return string
593
     */
594 14
    public function getKod($data = null, $unique = true)
595
    {
596 14
        $kod = null;
597
598 14
        if (is_null($data)) {
599 14
            $data = $this->getData();
600 14
        }
601
602 14
        if (is_string($data)) {
603 14
            $data = [$this->nameColumn => $data];
604 14
        }
605
606 14
        if (isset($data['kod'])) {
607 14
            $kod = $data['kod'];
608 14
        } else {
609 14
            if (isset($data[$this->nameColumn])) {
610 14
                $kod = preg_replace('/[^a-zA-Z0-9]/', '',
611 14
                    \Ease\Sand::rip($data[$this->nameColumn]));
612 14
            } else {
613 14
                if (isset($data[$this->myKeyColumn])) {
614 14
                    $kod = \Ease\Sand::rip($data[$this->myKeyColumn]);
615 14
                }
616
            }
617
        }
618
619 14
        if (!strlen($kod)) {
620 14
            $kod = 'NOTSET';
621 14
        }
622
623 14
        if (strlen($kod) > 18) {
624 14
            $kodfinal = strtoupper(substr($kod, 0, 18));
625 14
        } else {
626 14
            $kodfinal = strtoupper($kod);
627
        }
628
629 14
        if ($unique) {
630 14
            $counter = 0;
631 14
            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...
632 14
                foreach ($this->codes as $codesearch => $keystring) {
633 14
                    if (strstr($codesearch, $kodfinal)) {
634 14
                        ++$counter;
635 14
                    }
636 14
                }
637 14
            }
638 14
            if ($counter) {
639 14
                $kodfinal = $kodfinal.$counter;
640 14
            }
641
642 14
            $this->codes[$kodfinal] = $kod;
643 14
        }
644
645 14
        return $kodfinal;
646
    }
647
648
    /**
649
     * Vyhledavani v záznamech objektu FlexiBee.
650
     *
651
     * @param string $what hledaný výraz
652
     *
653
     * @return array pole výsledků
654
     */
655
    public function searchString($what)
656
    {
657
        $results   = [];
658
        $conds     = [];
659
        $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...
660
        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...
661
            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...
662
                == true)) {
663
                if ($keyword == $this->nameColumn) {
664
                    $this->nameColumn = $this->myKeyColumn;
665
                }
666
                continue;
667
            }
668
            switch ($keywordInfo) {
669
                case 'INT':
670 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...
671
                    if (is_numeric($what)) {
672
                        $conds[]   = "($keyword = ".$what.')';
673
                        $columns[] = "$keyword";
674
                    }
675
                    break;
676
                case 'TEXT':
677 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...
678
                    if (is_string($what)) {
679
                        $conds[]   = "( $keyword like '".$what."')";
680
                        $columns[] = "$keyword";
681
                    }
682
                    break;
683
                default:
684
                    break;
685
            }
686
        }
687
688
//        $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...
689
690
        $res = $this->getColumnsFromFlexibee($columns, implode(' or ', $conds));
691
692
        foreach ($res as $result) {
693
            $occurences = '';
694
            foreach ($result as $key => $value) {
695
                if (is_array($value)) {
696
                    continue;
697
                }
698
                if (mb_stristr($value, $what)) {
699
                    $occurences .= '('.$key.': '.$value.')';
700
                }
701
            }
702
            $results[$result[$this->myKeyColumn]] = [$this->nameColumn => $result[$this->nameColumn],
703
                'what' => $occurences,];
704
        }
705
706
        return $results;
707
    }
708
709
    /**
710
     * Write Operation Result.
711
     * 
712
     * @param array  $resultData
713
     * @param string $url        URL
714
     */
715 14
    public function logResult($resultData, $url = null)
716
    {
717 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...
718 14
            $this->logger->addStatusMessage($url);
719 14
        }
720
721 14
        if (isset($resultData['results'])) {
722 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...
723 14
            if ($resultData['success'] == 'false') {
724 14
                $status = 'error';
725 14
            } else {
726 14
                $status = 'success';
727
            }
728 14
            foreach ($resultData['results'] as $result) {
729 14
                if (isset($result['request-id'])) {
730 14
                    $rid = $result['request-id'];
731 14
                } else {
732 14
                    $rid = '';
733
                }
734 14
                if (isset($result['errors'])) {
735 14
                    foreach ($result['errors'] as $error) {
736 14
                        $this->logger->addStatusMessage($rid.': '.$error['message'],
737 14
                            $status);
738 14
                    }
739 14
                }
740 14
            }
741 14
        }
742 14
        if (is_object($this->logger)) {
743 14
            $this->logger->flush(get_class($this));
0 ignored issues
show
Bug introduced by
The method flush() does not seem to exist on object<Ease\Logger>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
744 14
        }
745 14
    }
746
747
    /**
748
     * Generuje fragment url pro filtrování.
749
     *
750
     * @see https://www.flexibee.eu/api/dokumentace/ref/filters
751
     *
752
     * @param array  $data
753
     * @param string $operator and/or
754
     *
755
     * @return string
756
     */
757 14
    public static function flexiUrl(array $data, $operator = 'and')
758
    {
759 14
        $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...
760 14
        $parts    = [];
761
762 14
        foreach ($data as $column => $value) {
763 14
            if (is_numeric($data[$column])) {
764 14
                $parts[$column] = $column.' = '.$data[$column];
765 14
            } else {
766 14
                $parts[$column] = $column." = '".$data[$column]."'";
767
            }
768 14
        }
769
770 14
        $flexiUrl = implode(' '.$operator.' ', $parts);
771
772 14
        return $flexiUrl;
773
    }
774
}