Completed
Push — master ( f66589...2c8c36 )
by Vítězslav
03:30
created

FlexiBee::curlInit()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
ccs 11
cts 11
cp 1
rs 9.4285
cc 1
eloc 10
nc 1
nop 0
crap 1
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 13
    public function __construct($init = null)
153
    {
154 13
        $this->init = $init;
155
156 13
        parent::__construct();
157 13
        $this->curlInit();
158 13
    }
159
160 13
    public function curlInit()
161
    {
162 13
        $this->curl = \curl_init(); // create curl resource
163 13
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); // return content as a string from curl_exec
164 13
        curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); // follow redirects (compatibility for future changes in FlexiBee)
165 13
        curl_setopt($this->curl, CURLOPT_HTTPAUTH, true);       // HTTP authentication
166 13
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); // FlexiBee by default uses Self-Signed certificates
167 13
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
168 13
        curl_setopt($this->curl, CURLOPT_VERBOSE, true); // For debugging
169 13
        curl_setopt($this->curl, CURLOPT_USERPWD,
170 13
            $this->user.':'.$this->password); // set username and password
171 13
    }
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
            $result = $object;
200
        }
201
202 13
        return $result;
203
    }
204
205
    /**
206
     * Funkce, která provede I/O operaci a vyhodnotí výsledek.
207
     *
208
     * @param string $urlSuffix část URL za identifikátorem firmy.
209
     * @param string $method    HTTP/REST metoda
210
     * @param string $format    Requested format
211
     */
212 13
    public function performRequest($urlSuffix = null, $method = 'GET',
213
                                   $format = null)
214
    {
215 13
        if (is_null($format)) {
216 13
            $format = $this->format;
217 13
        }
218 13
        if (is_null($urlSuffix)) {
219 2
            $urlSuffix = $this->agenda.'.'.$format;
220 2
        }
221 13
        $url = $this->url.$this->prefix.$this->company.'/'.$urlSuffix;
222 13
        curl_setopt($this->curl, CURLOPT_URL, $url);
223
// Nastavení samotné operace
224 13
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $method);
225
226
// Proveď samotnou operaci
227 13
        $response = curl_exec($this->curl);
228
229 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...
230
231 13
        $responseCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
232
233 13
        if ($responseCode != 200 && $responseCode != 201) {
234 1
            $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...
235 1
            $response = (json_encode(json_decode($response, true, 10),
236 1
                    JSON_PRETTY_PRINT));
237
238 1
            $response = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/',
239 1
                function ($match) {
240
                return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8',
241
                    'UCS-2BE');
242 1
            }, $response);
243
244 1
            if ($responseCode == 400) {
245 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...
246 1
            } else {
247
                $this->addStatusMessage(sprintf(_('Při operaci nastala chyba (HTTP %d): <pre>%s</pre> %s'),
248
                        curl_getinfo($this->curl, CURLINFO_HTTP_CODE),
249
                        stripslashes($response), $this->error), 'error');
250
                $this->addStatusMessage($url);
251
            }
252 1
            if ($response == 'null') {
253
                return;
254
            }
255
256 1
            return self::object2array(current(json_decode($response)));
257
        }
258
259
        // Parse response
260
        switch ($format) {
261 12
            case 'json':
262 12
                $decoded = json_decode($response, true, 10);
263 12
                if (($method == 'post') && isset($decoded[$this->nameSpace][$this->resultField][0]['id'])) {
264
                    $this->lastInsertedID = $decoded[$this->nameSpace][$this->resultField][0]['id'];
265
                } else {
266 12
                    $this->lastInsertedID = null;
267
                }
268
//                $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...
269
//                $this->addStatusMessage($decodeError);
270
271 12
                break;
272 2
            case 'xml':
273 2
                $decoded = simplexml_load_string($response);
274 2
                $decoded = self::xml2array($decoded);
275 2
                break;
276
        }
277
278
        // Get response body root automatically
279 12
        if (isset($decoded[$this->nameSpace])) {
280 12
            $decoded = $decoded[$this->nameSpace];
281 12
        }
282
283 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...
284
    }
285
286
    /**
287
     * Give you last inserted record ID.
288
     * 
289
     * @return int
290
     */
291
    public function getLastImportId()
292
    {
293
        return $this->lastInsertedID;
294
    }
295
296
    /**
297
     * Convert XML to array.
298
     * 
299
     * @param string $xml
300
     *
301
     * @return array
302
     */
303
    public static function xml2array($xml)
304
    {
305
        $arr = [];
306
        foreach ($xml->children() as $r) {
0 ignored issues
show
Bug introduced by
The method children cannot be called on $xml (of type string).

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

Loading history...
307
            $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...
308
            if (count($r->children()) == 0) {
309
                $arr[$r->getName()] = strval($r);
310
            } else {
311
                $arr[$r->getName()][] = self::xml2array($r);
312
            }
313
        }
314
315
        return $arr;
316
    }
317
318
    /**
319
     * Odpojení od FlexiBee.
320
     */
321 1
    public function disconnect()
322
    {
323 1
        if (is_resource($this->curl)) {
324 1
            curl_close($this->curl);
325 1
        }
326 1
    }
327
328 1
    public function __destruct()
329
    {
330 1
        $this->disconnect();
331 1
    }
332
333
    /**
334
     * Načte data z FlexiBee.
335
     *
336
     * @param string $suffix dotaz
337
     */
338
    public function loadFlexiData($suffix = null)
339
    {
340
        return $this->takeData($this->getFlexiData($suffix));
341
    }
342
343
    /**
344
     * Načte řádek dat z FlexiBee.
345
     *
346
     * @param int $recordID
347
     *
348
     * @return array
349
     */
350
    public function getFlexiRow($recordID)
351
    {
352
        $record = null;
353
        $response = $this->performRequest($this->agenda.'/'.$recordID.'.json');
354
        if (isset($response[$this->agenda])) {
355
            $record = $response[$this->agenda][0];
356
        }
357
358
        return $record;
359
    }
360
361
    /**
362
     * Načte data z FlexiBee.
363
     *
364
     * @param string $suffix     dotaz
365
     * @param string $conditions Volitelný filtrovací výraz
366
     */
367 13
    public function getFlexiData($suffix = null, $conditions = null)
368
    {
369 13
        if (!is_null($conditions)) {
370
            if ($conditions[0] != '/') {
371
                $conditions = '/'.rawurlencode('('.($conditions).')');
372
            }
373
        } else {
374 13
            $conditions = '';
375
        }
376 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...
377
            $transactions = $this->performRequest($this->agenda.$conditions.'.'.$this->format.'?'.$suffix,
378
                'GET');
379
        } else {
380 13
            $transactions = $this->performRequest($this->agenda.$conditions.'.'.$this->format,
381 13
                'GET');
382
        }
383 13
        if (isset($transactions[$this->agenda])) {
384
            $result = $transactions[$this->agenda];
385
        } else {
386 13
            $result = $transactions;
387
        }
388
389 13
        return $result;
390
    }
391
392
    /**
393
     * Načte záznam z FlexiBee.
394
     *
395
     * @param int $id ID záznamu
396
     *
397
     * @return int počet načtených položek
398
     */
399
    public function loadFromFlexiBee($id = null)
400
    {
401
        if (is_null($id)) {
402
            $id = $this->getId();
0 ignored issues
show
Bug introduced by
The method getId() does not seem to exist on object<FlexiPeeHP\FlexiBee>.

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...
403
        }
404
405
        return $this->takeData($this->getFlexiData('/'.$id));
406
    }
407
408
    /**
409
     * Uloží data do FlexiBee.
410
     *
411
     * @param array $data
412
     *
413
     * @return array výsledek
414
     */
415 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...
416
    {
417
        if (is_null($data)) {
418
            $data = $this->getData();
419
        }
420
421
        $jsonizedData = $this->jsonizeData($data);
422
423
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $jsonizedData);
424
425
        return $this->performRequest($this->agenda.'.'.$this->format, 'PUT');
426
    }
427
428
    /**
429
     * Převede data do Json formátu pro FlexiBee.
430
     *
431
     * @param array $data
432
     *
433
     * @return string
434
     */
435 13
    public function jsonizeData($data)
436
    {
437
        $jsonize = [
438 13
            $this->nameSpace => [
439 13
                '@version' => $this->protoVersion,
440 13
                $this->agenda => $data,
441 13
            ],
442 13
        ];
443
444 13
        return json_encode($jsonize);
445
    }
446
447
    /**
448
     * Uloží záznam.
449
     *
450
     * @param array $data
451
     *
452
     * @return array odpověď
453
     */
454 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...
455
    {
456
        if (is_null($data)) {
457
            $data = $this->getData();
458
        }
459
        $jsonizedData = $this->jsonizeData($data);
460
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $jsonizedData);
461
462
        return $this->performRequest($this->agenda.'.'.$this->format, 'PUT');
463
    }
464
465
    /**
466
     * Test if given record ID exists in FlexiBee.
467
     *
468
     * @param string|int $identifer
469
     */
470
    public function idExists($identifer = null)
471
    {
472
        if (is_null($identifer)) {
473
            $identifer = $this->getMyKey();
474
        }
475
        $flexiData = $this->getFlexiData(
476
            'detail=custom:'.$this->getmyKeyColumn(), $identifer);
477
478
        return $flexiData;
479
    }
480
481
    /**
482
     * Test if given record exists in FlexiBee.
483
     *
484
     * @param array $data
485
     */
486
    public function recordExists($data = null)
487
    {
488
        if (is_null($data)) {
489
            $data = $this->getData();
490
        }
491
492
        $res = $this->getColumnsFromFlexibee([$this->myKeyColumn],
493
            self::flexiUrl($data));
494
495
        return $res;
496
    }
497
498
    /**
499
     * Vrací z FlexiBee sloupečky podle podmínek.
500
     *
501
     * @param array|int|string $conditions pole podmínek nebo ID záznamu
502
     * @param array|string     $orderBy    třídit dle
503
     * @param string           $indexBy    klice vysledku naplnit hodnotou ze
504
     *                                     sloupečku
505
     * @param int              $limit      maximální počet vrácených záznamů
506
     *
507
     * @return array
508
     */
509
    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...
510
                                       $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...
511
    {
512
        if (is_int($conditions)) {
513
            $conditions = [$this->getmyKeyColumn() => $conditions];
514
        }
515
516
        $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...
517
518 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...
519
            $flexiData2 = [];
520
            foreach ($flexiData as $dataID => $data) {
521
                $flexiData2[$data[$indexBy]] = $data;
522
            }
523
            $flexiData = $flexiData2;
524
        }
525
526
        return $flexiData;
527
    }
528
529
    /**
530
     * Vrací z FlexiBee sloupečky podle podmínek.
531
     *
532
     * @param string[]         $columnsList seznam položek
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 getColumnsFromFlexibee($columnsList, $conditions = null,
542
                                           $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...
543
                                           $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...
544
    {
545
        if (($columnsList != '*') && !count($columnsList)) {
546
            $this->error('getColumnsFromFlexiBee: Missing ColumnList');
547
548
            return;
549
        }
550
551
        if (is_int($conditions)) {
552
            $conditions = [$this->getmyKeyColumn() => $conditions];
553
        }
554
555
        if (is_array($columnsList)) {
556
            $columns = implode(',', array_unique($columnsList));
557
        } else {
558
            $columns = $columnsList;
559
        }
560
561
        $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...
562
563 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...
564
            $flexiData2 = [];
565
            foreach ($flexiData as $dataID => $data) {
566
                $flexiData2[$data[$indexBy]] = $data;
567
            }
568
            $flexiData = $flexiData2;
569
        }
570
571
        return $flexiData;
572
    }
573
574
    /**
575
     * Vrací kód záznamu.
576
     *
577
     * @param array $data
578
     *
579
     * @todo papat i string
580
     *
581
     * @return string
582
     */
583
    public function getKod($data = null, $unique = true)
584
    {
585
        $kod = null;
586
587
        if (is_null($data)) {
588
            $data = $this->getData();
589
        }
590
591
        if (isset($data['kod'])) {
592
            $kod = $data['kod'];
593
        } else {
594
            if (isset($data[$this->nameColumn])) {
595
                $kod = preg_replace('/[^a-zA-Z0-9]/', '',
596
                    \Ease\Sand::rip($data[$this->nameColumn]));
597
            } else {
598
                if (isset($data[$this->myKeyColumn])) {
599
                    $kod = \Ease\Sand::rip($data[$this->myKeyColumn]);
600
                }
601
            }
602
        }
603
604
        if (strlen($kod) > 18) {
605
            $kodfinal = substr($kod, 0, 18);
606
        } else {
607
            $kodfinal = $kod;
608
        }
609
610
        if ($unique) {
611
            $counter = 0;
612
            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...
613
                foreach ($this->codes as $codesearch) {
614
                    if (!strlen($codesearch)) {
615
                        echo 'Error';
616
                    }
617
                    if (strstr($codesearch, $kodfinal)) {
618
                        ++$counter;
619
                    }
620
                }
621
            }
622
            if ($counter) {
623
                $kodfinal = $kodfinal.$counter;
624
            }
625
626
            $this->codes[$kodfinal] = $kod;
627
        }
628
629
        return strtoupper($kodfinal);
630
    }
631
632
    /**
633
     * Vyhledavani v záznamech objektu FlexiBee.
634
     *
635
     * @param string $what hledaný výraz
636
     *
637
     * @return array pole výsledků
638
     */
639
    public function searchString($what)
640
    {
641
        $results = [];
642
        $conds = [];
643
        $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...
644
        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...
645
            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...
646
                == true)) {
647
                if ($keyword == $this->nameColumn) {
648
                    $this->nameColumn = $this->myKeyColumn;
649
                }
650
                continue;
651
            }
652
            switch ($keywordInfo) {
653
                case 'INT':
654 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...
655
                    if (is_numeric($what)) {
656
                        $conds[] = "($keyword = ".$what.')';
657
                        $columns[] = "$keyword";
658
                    }
659
                    break;
660
                case 'TEXT':
661 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...
662
                    if (is_string($what)) {
663
                        $conds[] = "( $keyword like '".$what."')";
664
                        $columns[] = "$keyword";
665
                    }
666
                    break;
667
                default:
668
                    break;
669
            }
670
        }
671
672
//        $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...
673
674
        $res = $this->getColumnsFromFlexibee($columns, implode(' or ', $conds));
675
676
        foreach ($res as $result) {
677
            $occurences = '';
678
            foreach ($result as $key => $value) {
679
                if (is_array($value)) {
680
                    continue;
681
                }
682
                if (mb_stristr($value, $what)) {
683
                    $occurences .= '('.$key.': '.$value.')';
684
                }
685
            }
686
            $results[$result[$this->myKeyColumn]] = [$this->nameColumn => $result[$this->nameColumn],
687
                'what' => $occurences, ];
688
        }
689
690
        return $results;
691
    }
692
693
    /**
694
     * Write Operation Result.
695
     * 
696
     * @param array  $resultData
697
     * @param string $url        URL
698
     */
699
    public function logResult($resultData, $url = null)
700
    {
701
        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...
702
            $this->logger->addStatusMessage($url);
703
        }
704
705
        if (isset($resultData['results'])) {
706
            $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...
707
            if ($resultData['success'] == 'false') {
708
                $status = 'error';
709
            } else {
710
                $status = 'success';
711
            }
712
            foreach ($resultData['results'] as $result) {
713
                if (isset($result['request-id'])) {
714
                    $rid = $result['request-id'];
715
                } else {
716
                    $rid = '';
717
                }
718
                if (isset($result['errors'])) {
719
                    foreach ($result['errors'] as $error) {
720
                        $this->logger->addStatusMessage($rid.': '.$error['message'],
721
                            $status);
722
                    }
723
                }
724
            }
725
        }
726
        if (is_object($this->logger)) {
727
            $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...
728
        }
729
    }
730
731
    /**
732
     * Generuje fragment url pro filtrování.
733
     *
734
     * @see https://www.flexibee.eu/api/dokumentace/ref/filters
735
     *
736
     * @param array  $data
737
     * @param string $operator and/or
738
     *
739
     * @return string
740
     */
741 13
    public static function flexiUrl($data, $operator = 'and')
742
    {
743 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...
744 13
        $parts = [];
745
746 13
        foreach ($data as $column => $value) {
747 13
            if (is_numeric($data[$column])) {
748 13
                $parts[$column] = $column.' = '.$data[$column];
749 13
            } else {
750 13
                $parts[$column] = $column." = '".$data[$column]."'";
751
            }
752 13
        }
753
754 13
        $flexiUrl = implode(' '.$operator.' ', $parts);
755
756 13
        return $flexiUrl;
757
    }
758
}
759