Completed
Push — master ( 1f74b8...bc3692 )
by Vítězslav
03:32
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
 * System.Spoje.Net - 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
     * Agenda užitá objektem.
36
     *
37
     * @var string
38
     */
39
    public $agenda = 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 26
    public function __construct($init = null)
153
    {
154 26
        $this->init = $init;
155
156 26
        parent::__construct();
157 26
        $this->curlInit();
158 26
    }
159
160 26
    public function curlInit()
161
    {
162 26
        $this->curl = \curl_init(); // create curl resource
163 26
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); // return content as a string from curl_exec
164 26
        curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); // follow redirects (compatibility for future changes in FlexiBee)
165 26
        curl_setopt($this->curl, CURLOPT_HTTPAUTH, true);       // HTTP authentication
166 26
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); // FlexiBee by default uses Self-Signed certificates
167 26
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
168 26
        curl_setopt($this->curl, CURLOPT_VERBOSE, true); // For debugging
169 26
        curl_setopt($this->curl, CURLOPT_USERPWD,
170 26
            $this->user.':'.$this->password); // set username and password
171 26
    }
172
173
    /**
174
     * Nastaví Agendu pro Komunikaci.
175
     *
176
     * @param string $agenda
177
     */
178 13
    public function setAgenda($agenda)
179
    {
180 13
        $this->agenda = $agenda;
181 13
    }
182
183
    /**
184
     * Převede rekurzivně Objekt na pole.
185
     *
186
     * @param object|array $object
187
     *
188
     * @return array
189
     */
190 13
    public static function object2array($object)
191
    {
192 13
        $result = null;
193 13
        if (is_object($object)) {
194 13
            $objectData = get_object_vars($object);
195 13
            if (is_array($objectData) && count($objectData)) {
196 13
                $result = array_map('self::object2array', $objectData);
197 13
            }
198 13
        } else {
199 13
            if (is_array($object)) {
200 13
                foreach ($object as $item => $value) {
201 13
                    $result[$item] = self::object2array($value);
202 13
                }
203 13
            } else {
204 13
                $result = $object;
205
            }
206
        }
207
208 13
        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 13
    public function performRequest($urlSuffix = null, $method = 'GET',
219
                                   $format = null)
220
    {
221 13
        if (is_null($format)) {
222 13
            $format = $this->format;
223 13
        }
224 13
        if (is_null($urlSuffix)) {
225 2
            $urlSuffix = $this->agenda.'.'.$format;
226 2
        }
227 13
        $url = $this->url.$this->prefix.$this->company.'/'.$urlSuffix;
228 13
        curl_setopt($this->curl, CURLOPT_URL, $url);
229
// Nastavení samotné operace
230 13
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $method);
231
232
// Proveď samotnou operaci
233 13
        $response = curl_exec($this->curl);
234
235 13
        $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 13
        $responseCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
238
239 13
        if ($responseCode != 200 && $responseCode != 201) {
240 13
            $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 13
            $response    = (json_encode(json_decode($response, true, 10),
242 13
                    JSON_PRETTY_PRINT));
243
244 13
            $response = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/',
245 13
                function ($match) {
246 13
                return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8',
247 13
                    'UCS-2BE');
248 13
            }, $response);
249
250 13
            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 13
                $this->addStatusMessage(sprintf('Error (HTTP %d): <pre>%s</pre> %s',
254 13
                        curl_getinfo($this->curl, CURLINFO_HTTP_CODE),
255 13
                        stripslashes($response), $this->error), 'error');
256 13
                $this->addStatusMessage($url);
257
            }
258 13
            if ($response == 'null') {
259
                return;
260
            }
261
262 13
            return self::object2array(current(json_decode($response)));
263
        }
264
265
        // Parse response
266
        switch ($format) {
267 12
            case 'json':
268 12
                $decoded = json_decode($response, true, 10);
269 12
                if (($method == 'PUT') && isset($decoded[$this->nameSpace][$this->resultField][0]['id'])) {
270
                    $this->lastInsertedID = $decoded[$this->nameSpace][$this->resultField][0]['id'];
271
                } else {
272 12
                    $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 12
                break;
278 2
            case 'xml':
279 2
                $decoded = self::xml2array($response);
280 2
                break;
281
        }
282
283
        // Get response body root automatically
284 12
        if (isset($decoded[$this->nameSpace])) {
285 12
            $decoded = $decoded[$this->nameSpace];
286 12
        }
287
288 12
        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 13
    public static function xml2array($xml)
309
    {
310 13
        $arr = [];
311
312 13
        if (is_string($xml)) {
313 13
            $xml = simplexml_load_string($xml);
314 13
        }
315
316 13
        foreach ($xml->children() as $r) {
317 13
            $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 13
            if (count($r->children()) == 0) {
319 13
                $arr[$r->getName()] = strval($r);
320 13
            } else {
321 13
                $arr[$r->getName()][] = self::xml2array($r);
322
            }
323 13
        }
324
325 13
        return $arr;
326
    }
327
328
    /**
329
     * Odpojení od FlexiBee.
330
     */
331 14
    public function disconnect()
332
    {
333 14
        if (is_resource($this->curl)) {
334 14
            curl_close($this->curl);
335 14
        }
336 14
        $this->curl = null;
337 14
    }
338
339 14
    public function __destruct()
340
    {
341 14
        $this->disconnect();
342 14
    }
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 13
    public function getFlexiRow($recordID)
362
    {
363 13
        $record   = null;
364 13
        $response = $this->performRequest($this->agenda.'/'.$recordID.'.json');
365 13
        if (isset($response[$this->agenda])) {
366 9
            $record = $response[$this->agenda][0];
367 9
        }
368
369 13
        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 12
    public function getFlexiData($suffix = null, $conditions = null)
379
    {
380 12
        if (!is_null($conditions)) {
381 10
            if ($conditions[0] != '/') {
382 10
                $conditions = '/'.rawurlencode('('.($conditions).')');
383 10
            }
384 10
        } else {
385 12
            $conditions = '';
386
        }
387 12
        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->agenda.$conditions.'.'.$this->format.'?'.$suffix,
389
                'GET');
390
        } else {
391 12
            $transactions = $this->performRequest($this->agenda.$conditions.'.'.$this->format,
392 12
                'GET');
393
        }
394 12
        if (isset($transactions[$this->agenda])) {
395 10
            $result = $transactions[$this->agenda];
396 10
        } else {
397 2
            $result = $transactions;
398
        }
399
400 12
        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 13
    public function loadFromFlexiBee($id = null)
411
    {
412 13
        if (is_null($id)) {
413 13
            $id = $this->getMyKey();
414 13
        }
415
416 13
        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->agenda.'.'.$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 13
    public function jsonizeData($data)
447
    {
448
        $jsonize = [
449 13
            $this->nameSpace => [
450 13
                '@version' => $this->protoVersion,
451 13
                $this->agenda => $data,
452 13
            ],
453 13
        ];
454
455 13
        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->agenda.'.'.$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 13
    public function getKod($data = null, $unique = true)
595
    {
596 13
        $kod = null;
597
598 13
        if (is_null($data)) {
599 13
            $data = $this->getData();
600 13
        }
601
602 13
        if (is_string($data)) {
603 13
            $data = [$this->nameColumn => $data];
604 13
        }
605
606 13
        if (isset($data['kod'])) {
607 13
            $kod = $data['kod'];
608
        } else {
609 13
            if (isset($data[$this->nameColumn])) {
610 13
                $kod = preg_replace('/[^a-zA-Z0-9]/', '',
611 13
                    \Ease\Sand::rip($data[$this->nameColumn]));
612 13
            } else {
613 13
                if (isset($data[$this->myKeyColumn])) {
614 13
                    $kod = \Ease\Sand::rip($data[$this->myKeyColumn]);
615 13
                }
616
            }
617
        }
618
619 13
        if (!strlen($kod)) {
620 13
            $kod = 'NOTSET';
621 13
        }
622 13
623
        if (strlen($kod) > 18) {
624
            $kodfinal = strtoupper(substr($kod, 0, 18));
625 13
        } else {
626 13
            $kodfinal = strtoupper($kod);
627 13
        }
628 13
629 13
        if ($unique) {
630
            $counter = 0;
631
            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 13
                foreach ($this->codes as $codesearch => $keystring) {
633 13
                    if (strstr($codesearch, $kodfinal)) {
634 13
                        ++$counter;
635 13
                    }
636 13
                }
637 13
            }
638 13
            if ($counter) {
639 13
                $kodfinal = $kodfinal.$counter;
640
            }
641 13
642 13
            $this->codes[$kodfinal] = $kod;
643
        }
644 13
645
        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 13
     */
715
    public function logResult($resultData, $url = null)
716 13
    {
717 13
        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 13
            $this->logger->addStatusMessage($url);
719
        }
720 13
721 13
        if (isset($resultData['results'])) {
722 13
            $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 13
            if ($resultData['success'] == 'false') {
724 13
                $status = 'error';
725 13
            } else {
726
                $status = 'success';
727 13
            }
728 13
            foreach ($resultData['results'] as $result) {
729 13
                if (isset($result['request-id'])) {
730 13
                    $rid = $result['request-id'];
731 13
                } else {
732
                    $rid = '';
733 13
                }
734 13
                if (isset($result['errors'])) {
735 13
                    foreach ($result['errors'] as $error) {
736 13
                        $this->logger->addStatusMessage($rid.': '.$error['message'],
737 13
                            $status);
738 13
                    }
739 13
                }
740 13
            }
741 13
        }
742 13
        if (is_object($this->logger)) {
743 13
            $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 13
        }
745
    }
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 13
     */
757
    public static function flexiUrl(array $data, $operator = 'and')
758 13
    {
759 13
        $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
        $parts    = [];
761 13
762 13
        foreach ($data as $column => $value) {
763 13
            if (is_numeric($data[$column])) {
764 13
                $parts[$column] = $column.' = '.$data[$column];
765 13
            } else {
766
                $parts[$column] = $column." = '".$data[$column]."'";
767 13
            }
768
        }
769 13
770
        $flexiUrl = implode(' '.$operator.' ', $parts);
771 13
772
        return $flexiUrl;
773
    }
774
}