Completed
Push — master ( 19a6ea...074943 )
by Vítězslav
07:22
created

FlexiBeeRO::logResult()   C

Complexity

Conditions 13
Paths 24

Size

Total Lines 44
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
cc 13
eloc 29
c 3
b 0
f 1
nc 24
nop 2
dl 0
loc 44
rs 5.1234

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * FlexiPeeHP - Třída pro čtení z 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 FlexiBeeRO 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
     * @link https://demo.flexibee.eu/c/demo/evidence-list Přehled evidencí
38
     * @var string
39
     */
40
    public $evidence = null;
41
42
    /**
43
     * Výchozí formát pro komunikaci.
44
     *
45
     * @link https://www.flexibee.eu/api/dokumentace/ref/format-types Přehled možných formátů
46
     *
47
     * @var string json|xml|...
48
     */
49
    public $format = 'json';
50
51
    /**
52
     * Curl Handle.
53
     *
54
     * @var resource
55
     */
56
    public $curl = null;
57
58
    /**
59
     * @var type
60
     */
61
    public $company = FLEXIBEE_COMPANY;
62
63
    /**
64
     * @var string
65
     */
66
    public $url = FLEXIBEE_URL;
67
68
    /**
69
     * @var string
70
     */
71
    public $user = FLEXIBEE_LOGIN;
72
73
    /**
74
     * @var string
75
     */
76
    public $password = FLEXIBEE_PASSWORD;
77
78
    /**
79
     * @var array Pole HTTP hlaviček odesílaných s každým požadavkem
80
     */
81
    public $defaultHttpHeaders = ['User-Agent: FlexiPeeHP'];
82
83
    /**
84
     * Default additional request url parameters after question mark
85
     * 
86
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls   Common params
87
     * @link https://www.flexibee.eu/api/dokumentace/ref/paging Paging params
88
     * @var array
89
     */
90
    public $defaultUrlParams = ['limit' => 0];
91
92
    /**
93
     * Identifikační řetězec.
94
     *
95
     * @var string
96
     */
97
    public $init = null;
98
99
    /**
100
     * Sloupeček s názvem.
101
     *
102
     * @var string
103
     */
104
    public $nameColumn = 'nazev';
105
106
    /**
107
     * Sloupeček obsahující datum vložení záznamu do shopu.
108
     *
109
     * @var string
110
     */
111
    public $myCreateColumn = 'false';
112
113
    /**
114
     * Slopecek obsahujici datum poslení modifikace záznamu do shopu.
115
     *
116
     * @var string
117
     */
118
    public $myLastModifiedColumn = 'lastUpdate';
119
120
    /**
121
     * Klíčový idendifikátor záznamu.
122
     *
123
     * @var string
124
     */
125
    public $fbKeyColumn = 'id';
126
127
    /**
128
     * Informace o posledním HTTP requestu.
129
     *
130
     * @var array
131
     */
132
    public $info;
133
134
    /**
135
     * Informace o poslední HTTP chybě.
136
     *
137
     * @var array
138
     */
139
    public $error;
140
141
    /**
142
     * Used codes storage.
143
     *
144
     * @var array
145
     */
146
    public $codes = null;
147
148
    /**
149
     * Last Inserted ID.
150
     *
151
     * @var int
152
     */
153
    public $lastInsertedID = null;
154
155
    /**
156
     * Default Line Prefix.
157
     *
158
     * @var string
159
     */
160
    public $prefix = '/c/';
161
162
    /**
163
     * HTTP Response code of last request
164
     *
165
     * @var int
166
     */
167
    public $lastResponseCode = null;
168
169
    /**
170
     * Array of fields for next curl POST operation
171
     *
172
     * @var array
173
     */
174
    protected $postFields = [];
175
176
    /**
177
     * Last operation result data or message(s)
178
     *
179
     * @var array
180
     */
181
    public $lastResult = null;
182
183
    /**
184
     * Třída pro práci s FlexiBee.
185
     *
186
     * @param mixed $init výchozí selektor dat
187
     */
188
    public function __construct($init = null)
189
    {
190
        $this->init = $init;
191
192
        parent::__construct();
193
        $this->curlInit();
194
        if ($init) {
195
            $this->processInit($init);
196
        }
197
    }
198
199
    /**
200
     * Inicializace CURL
201
     */
202
    public function curlInit()
203
    {
204
        $this->curl = \curl_init(); // create curl resource
205
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); // return content as a string from curl_exec
206
        curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); // follow redirects (compatibility for future changes in FlexiBee)
207
        curl_setopt($this->curl, CURLOPT_HTTPAUTH, true);       // HTTP authentication
208
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); // FlexiBee by default uses Self-Signed certificates
209
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
210
        curl_setopt($this->curl, CURLOPT_VERBOSE, true); // For debugging
211
        curl_setopt($this->curl, CURLOPT_USERPWD,
212
            $this->user.':'.$this->password); // set username and password
213
    }
214
215
    /**
216
     * Zinicializuje objekt dle daných dat
217
     * 
218
     * @param mixed $init
219
     */
220
    public function processInit($init)
221
    {
222
        if (is_integer($init)) {
223
            $this->loadFromFlexiBee($init);
224
        } elseif (is_array($init)) {
225
            $this->takeData($init);
226
        }
227
    }
228
229
    /**
230
     * Nastaví Agendu pro Komunikaci.
231
     *
232
     * @param string $evidence
233
     */
234
    public function setEvidence($evidence)
235
    {
236
        $this->evidence = $evidence;
237
    }
238
239
    /**
240
     * Převede rekurzivně Objekt na pole.
241
     *
242
     * @param object|array $object
243
     *
244
     * @return array
245
     */
246
    public static function object2array($object)
247
    {
248
        $result = null;
249
        if (is_object($object)) {
250
            $objectData = get_object_vars($object);
251
            if (is_array($objectData) && count($objectData)) {
252
                $result = array_map('self::object2array', $objectData);
253
            }
254 View Code Duplication
        } else {
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...
255
            if (is_array($object)) {
256
                foreach ($object as $item => $value) {
257
                    $result[$item] = self::object2array($value);
258
                }
259
            } else {
260
                $result = $object;
261
            }
262
        }
263
264
        return $result;
265
    }
266
267
    /**
268
     * Převede rekurzivně Objekt na pole.
269
     *
270
     * @param object|array $object
271
     *
272
     * @return array
273
     */
274
    public static function objectToID($object)
275
    {
276
        $result = null;
277
        if (is_object($object)) {
278
            $result = $object->__toString();
279 View Code Duplication
        } else {
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...
280
            if (is_array($object)) {
281
                foreach ($object as $item => $value) {
282
                    $result[$item] = self::objectToID($value);
283
                }
284
            } else {
285
                $result = $object;
286
            }
287
        }
288
289
        return $result;
290
    }
291
292
    /**
293
     * Funkce, která provede I/O operaci a vyhodnotí výsledek.
294
     *
295
     * @param string $urlSuffix část URL za identifikátorem firmy.
296
     * @param string $method    HTTP/REST metoda
297
     * @param string $format    Requested format
298
     * @return array Výsledek operace
299
     */
300
    public function performRequest($urlSuffix = null, $method = 'GET',
301
                                   $format = null)
302
    {
303
        if (is_null($format)) {
304
            $format = $this->format;
305
        }
306
        if (is_null($urlSuffix)) {
307
            $urlSuffix = $this->evidence.'.'.$format;
308
        }
309
        $url = $this->url.$this->prefix.$this->company.'/'.$urlSuffix;
310
        curl_setopt($this->curl, CURLOPT_URL, $url);
311
// Nastavení samotné operace
312
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $method);
313
//Vždy nastavíme byť i prázná postdata jako ochranu před chybou 411
314
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->postFields);
315
316
        $httpHeaders = $this->defaultHttpHeaders;
317
        switch ($format) {
318
            case 'json':
319
                $httpHeaders[] = 'Accept: application/json';
320
                break;
321
            case 'xml':
322
                $httpHeaders[] = 'Accept: application/xml';
323
                break;
324
325
            default:
326
                break;
327
        }
328
329
        curl_setopt($this->curl, CURLOPT_HTTPHEADER, $httpHeaders);
330
331
// Proveď samotnou operaci
332
        $response = curl_exec($this->curl);
333
334
        $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...
335
336
        $this->lastResponseCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
337
338
        if ($this->lastResponseCode != 200 && $this->lastResponseCode != 201) {
339
            $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...
340
            switch ($format) {
341
                case 'json':
342
                    $response = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/',
343
                        function ($match) {
344
                        return mb_convert_encoding(pack('H*', $match[1]),
345
                            'UTF-8', 'UCS-2BE');
346
                    }, $response);
347
                    $response = (json_encode(json_decode($response, true, 10),
348
                            JSON_PRETTY_PRINT));
349
                    break;
350
                case 'xml':
351
                    if (strlen($response)) {
352
                        $response = self::xml2array($response);
353
                    }
354
                    break;
355
            }
356
357
            if (is_array($response)) {
358
                $result = urldecode(http_build_query($response));
359
            } elseif (strlen($response) && ($response != 'null')) {
360
                $result = urldecode(http_build_query(self::object2array(current(json_decode($response)))));
361
            } else {
362
                $result = null;
363
            }
364
365
            if ($response == 'null') {
366
                if ($this->lastResponseCode == 200) {
367
                    $response = true;
368
                } else {
369
                    $response = null;
370
                }
371
            } else {
372
                if (is_string($response)) {
373
                    $response = self::object2array(current(json_decode($response)));
374
                }
375
            }
376
377
            if ($this->lastResponseCode == 400) {
378
                $this->logResult($response);
379
            } else {
380
                $this->addStatusMessage(sprintf('Error (HTTP %d): <pre>%s</pre> %s',
381
                        curl_getinfo($this->curl, CURLINFO_HTTP_CODE), $result,
382
                        $this->error), 'error');
383
                $this->addStatusMessage($url, 'info');
384
                if ($this->postFields) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->postFields 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...
385
                    $this->addStatusMessage(urldecode(http_build_query($this->postFields)),
386
                        'debug');
387
                }
388
            }
389
390
391
            return $response;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $response; (boolean|null|array|object|integer|double) is incompatible with the return type documented by FlexiPeeHP\FlexiBeeRO::performRequest of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
392
        }
393
394
        // Parse response
395
        switch ($format) {
396
            case 'json':
397
                $decoded = json_decode($response, true, 10);
398
                if (($method == 'PUT') && isset($decoded[$this->nameSpace][$this->resultField][0]['id'])) {
399
                    $this->lastInsertedID = $decoded[$this->nameSpace][$this->resultField][0]['id'];
400
                } else {
401
                    $this->lastInsertedID = null;
402
                }
403
//                $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...
404
//                $this->addStatusMessage($decodeError);
405
406
                break;
407
            case 'xml':
408
                if (strlen($response)) {
409
                    $decoded = self::xml2array($response);
410
                } else {
411
                    $decoded = null;
412
                }
413
                break;
414
        }
415
416
        // Get response body root automatically
417
        if (isset($decoded[$this->nameSpace])) {
418
            $decoded = $decoded[$this->nameSpace];
419
        }
420
421
        $this->lastResult = $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...
Documentation Bug introduced by
It seems like $decoded of type * is incompatible with the declared type array of property $lastResult.

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...
422
        return $decoded;
423
    }
424
425
    /**
426
     * Todo: Sem vyčlenit zpracování výsledku requestu
427
     */
428
    public function processRequest()
429
    {
430
431
    }
432
433
    /**
434
     * Convert XML to array.
435
     *
436
     * @param string $xml
437
     *
438
     * @return array
439
     */
440
    public static function xml2array($xml)
441
    {
442
        $arr = [];
443
444
        if (is_string($xml)) {
445
            $xml = simplexml_load_string($xml);
446
        }
447
448
        foreach ($xml->children() as $r) {
449
            $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...
450
            if (count($r->children()) == 0) {
451
                $arr[$r->getName()] = strval($r);
452
            } else {
453
                $arr[$r->getName()][] = self::xml2array($r);
454
            }
455
        }
456
457
        return $arr;
458
    }
459
460
    /**
461
     * Odpojení od FlexiBee.
462
     */
463
    public function disconnect()
464
    {
465
        if (is_resource($this->curl)) {
466
            curl_close($this->curl);
467
        }
468
        $this->curl = null;
469
    }
470
471
    public function __destruct()
472
    {
473
        $this->disconnect();
474
    }
475
476
    /**
477
     * Načte data z FlexiBee.
478
     *
479
     * @param string $suffix dotaz
480
     */
481
    public function loadFlexiData($suffix = null)
482
    {
483
        return $this->takeData($this->getFlexiData($suffix));
484
    }
485
486
    /**
487
     * Načte řádek dat z FlexiBee.
488
     *
489
     * @param int $recordID id požadovaného záznamu
490
     *
491
     * @return array
492
     */
493
    public function getFlexiRow($recordID)
494
    {
495
        $record   = null;
496
        $response = $this->performRequest($this->evidence.'/'.$recordID.'.json');
497
        if (isset($response[$this->evidence])) {
498
            $record = $response[$this->evidence][0];
499
        }
500
501
        return $record;
502
    }
503
504
    /**
505
     * Načte data z FlexiBee.
506
     *
507
     * @param string $suffix     dotaz
508
     * @param string|array $conditions Volitelný filtrovací výraz
509
     */
510
    public function getFlexiData($suffix = null, $conditions = null)
511
    {
512
        $urlParams = $this->defaultUrlParams;
513
        if (!is_null($conditions)) {
514
            if (is_array($conditions)) {
515
516
                if (isset($conditions['sort'])) {
517
                    \Ease\Sand::divDataArray($conditions, $urlParams, 'sort');
518
                }
519
                if (isset($conditions['order'])) {
520
                    \Ease\Sand::divDataArray($conditions, $urlParams, 'order');
521
                }
522
                if (isset($conditions['limit'])) {
523
                    \Ease\Sand::divDataArray($conditions, $urlParams, 'limit');
524
                }
525
                if (isset($conditions['start'])) {
526
                    \Ease\Sand::divDataArray($conditions, $urlParams, 'start');
527
                }
528
                if (isset($conditions['add-row-count'])) {
529
                    \Ease\Sand::divDataArray($conditions, $urlParams,
530
                        'add-row-count');
531
                }
532
533
                $conditions = $this->flexiUrl($conditions);
534
            }
535
            if ($conditions[0] != '/') {
536
                $conditions = '/'.rawurlencode('('.($conditions).')');
537
            }
538
        } else {
539
            $conditions = '';
540
        }
541
        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...
542
            $transactions = $this->performRequest($this->evidence.$conditions.'.'.$this->format.'?'.$suffix.'&'.http_build_query($urlParams),
543
                'GET');
544
        } else {
545
            $transactions = $this->performRequest($this->evidence.$conditions.'.'.$this->format.'?'.http_build_query($urlParams),
546
                'GET');
547
        }
548
        if (isset($transactions[$this->evidence])) {
549
            $result = $transactions[$this->evidence];
550
        } else {
551
            $result = $transactions;
552
        }
553
554
        return $result;
555
    }
556
557
    /**
558
     * Načte záznam z FlexiBee.
559
     *
560
     * @param int $id ID záznamu
561
     *
562
     * @return int počet načtených položek
563
     */
564
    public function loadFromFlexiBee($id = null)
565
    {
566
        if (is_null($id)) {
567
            $id = $this->getMyKey();
568
        }
569
570
        return $this->takeData($this->getFlexiData('/'.$id));
571
    }
572
573
    /**
574
     * Převede data do Json formátu pro FlexiBee.
575
     *
576
     * @param array $data
577
     *
578
     * @return string
579
     */
580
    public function jsonizeData($data)
581
    {
582
        $jsonize = [
583
            $this->nameSpace => [
584
                '@version' => $this->protoVersion,
585
                $this->evidence => $this->objectToID($data),
586
            ],
587
        ];
588
589
        return json_encode($jsonize);
590
    }
591
592
    /**
593
     * Test if given record ID exists in FlexiBee.
594
     *
595
     * @param string|int $identifer
596
     */
597
    public function idExists($identifer = null)
598
    {
599
        if (is_null($identifer)) {
600
            $identifer = $this->getMyKey();
601
        }
602
        $flexiData = $this->getFlexiData(
603
            'detail=custom:'.$this->getmyKeyColumn(), $identifer);
604
605
        return $flexiData;
606
    }
607
608
    /**
609
     * Test if given record exists in FlexiBee.
610
     *
611
     * @param array $data
612
     */
613
    public function recordExists($data = null)
614
    {
615
        if (is_null($data)) {
616
            $data = $this->getData();
617
        }
618
619
        $res = $this->getColumnsFromFlexibee([$this->myKeyColumn],
620
            self::flexiUrl($data));
621
622
        return $res;
623
    }
624
625
    /**
626
     * Vrací z FlexiBee sloupečky podle podmínek.
627
     *
628
     * @param array|int|string $conditions pole podmínek nebo ID záznamu
629
     * @param array|string     $orderBy    třídit dle
630
     * @param string           $indexBy    klice vysledku naplnit hodnotou ze
631
     *                                     sloupečku
632
     * @return array
633
     */
634
    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...
635
                                       $indexBy = null)
636
    {
637
        if (is_int($conditions)) {
638
            $conditions = [$this->getmyKeyColumn() => $conditions];
639
        }
640
641
        $flexiData = $this->getFlexiData('', $conditions);
642
643 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...
644
            $flexiData2 = [];
645
            foreach ($flexiData as $dataID => $data) {
646
                $flexiData2[$data[$indexBy]] = $data;
647
            }
648
            $flexiData = $flexiData2;
649
        }
650
651
        return $flexiData;
652
    }
653
654
    /**
655
     * Vrací z FlexiBee sloupečky podle podmínek.
656
     *
657
     * @param string[]         $columnsList seznam položek
658
     * @param array|int|string $conditions  pole podmínek nebo ID záznamu
659
     * @param array|string     $orderBy     třídit dle
660
     * @param string           $indexBy     klice vysledku naplnit hodnotou ze
661
     *                                      sloupečku
662
     * @param int              $limit       maximální počet vrácených záznamů
663
     *
664
     * @return array
665
     */
666
    public function getColumnsFromFlexibee($columnsList, $conditions = null,
667
                                           $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...
668
                                           $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...
669
    {
670
        if (($columnsList != '*') && !count($columnsList)) {
671
            $this->error('getColumnsFromFlexiBee: Missing ColumnList');
672
673
            return;
674
        }
675
676
        if (is_int($conditions)) {
677
            $conditions = [$this->getmyKeyColumn() => $conditions];
678
        }
679
680
        if (is_array($columnsList)) {
681
            $columns = implode(',', array_unique($columnsList));
682
        } else {
683
            $columns = $columnsList;
684
        }
685
686
        $flexiData = $this->getFlexiData('detail=custom:'.$columns, $conditions);
687
688 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...
689
            $flexiData2 = [];
690
            foreach ($flexiData as $dataID => $data) {
691
                $flexiData2[$data[$indexBy]] = $data;
692
            }
693
            $flexiData = $flexiData2;
694
        }
695
696
        return $flexiData;
697
    }
698
699
    /**
700
     * Vrací kód záznamu.
701
     *
702
     * @param mixed $data
703
     *
704
     * @todo papat i string
705
     *
706
     * @return string
707
     */
708
    public function getKod($data = null, $unique = true)
709
    {
710
        $kod = null;
711
712
        if (is_null($data)) {
713
            $data = $this->getData();
714
        }
715
716
        if (is_string($data)) {
717
            $data = [$this->nameColumn => $data];
718
        }
719
720
        if (isset($data['kod'])) {
721
            $kod = $data['kod'];
722
        } else {
723
            if (isset($data[$this->nameColumn])) {
724
                $kod = preg_replace('/[^a-zA-Z0-9]/', '',
725
                    \Ease\Sand::rip($data[$this->nameColumn]));
726
            } else {
727
                if (isset($data[$this->myKeyColumn])) {
728
                    $kod = \Ease\Sand::rip($data[$this->myKeyColumn]);
729
                }
730
            }
731
        }
732
733
        if (!strlen($kod)) {
734
            $kod = 'NOTSET';
735
        }
736
737
        if (strlen($kod) > 18) {
738
            $kodfinal = strtoupper(substr($kod, 0, 18));
739
        } else {
740
            $kodfinal = strtoupper($kod);
741
        }
742
743
        if ($unique) {
744
            $counter = 0;
745
            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...
746
                foreach ($this->codes as $codesearch => $keystring) {
747
                    if (strstr($codesearch, $kodfinal)) {
748
                        ++$counter;
749
                    }
750
                }
751
            }
752
            if ($counter) {
753
                $kodfinal = $kodfinal.$counter;
754
            }
755
756
            $this->codes[$kodfinal] = $kod;
757
        }
758
759
        return $kodfinal;
760
    }
761
762
    /**
763
     * Vyhledavani v záznamech objektu FlexiBee.
764
     *
765
     * @param string $what hledaný výraz
766
     *
767
     * @return array pole výsledků
768
     */
769
    public function searchString($what)
770
    {
771
        $results   = [];
772
        $conds     = [];
773
        $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...
774
        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...
775
            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...
776
                == true)) {
777
                if ($keyword == $this->nameColumn) {
778
                    $this->nameColumn = $this->myKeyColumn;
779
                }
780
                continue;
781
            }
782
            switch ($keywordInfo) {
783
                case 'INT':
784 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...
785
                    if (is_numeric($what)) {
786
                        $conds[]   = "($keyword = ".$what.')';
787
                        $columns[] = "$keyword";
788
                    }
789
                    break;
790
                case 'TEXT':
791 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...
792
                    if (is_string($what)) {
793
                        $conds[]   = "( $keyword like '".$what."')";
794
                        $columns[] = "$keyword";
795
                    }
796
                    break;
797
                default:
798
                    break;
799
            }
800
        }
801
802
//        $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...
803
804
        $res = $this->getColumnsFromFlexibee($columns, implode(' or ', $conds));
805
806
        foreach ($res as $result) {
807
            $occurences = '';
808
            foreach ($result as $key => $value) {
809
                if (is_array($value)) {
810
                    continue;
811
                }
812
                if (mb_stristr($value, $what)) {
813
                    $occurences .= '('.$key.': '.$value.')';
814
                }
815
            }
816
            $results[$result[$this->myKeyColumn]] = [$this->nameColumn => $result[$this->nameColumn],
817
                'what' => $occurences,];
818
        }
819
        return $results;
820
    }
821
822
    /**
823
     * Write Operation Result.
824
     *
825
     * @param array  $resultData
826
     * @param string $url        URL
827
     */
828
    public function logResult($resultData = null, $url = null)
829
    {
830
        if (is_null($resultData)) {
831
            $resultData = $this->lastResult;
832
        }
833
        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...
834
            $this->logger->addStatusMessage($url);
835
        }
836
837
        if (isset($resultData['results'])) {
838
            $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...
839
            if ($resultData['success'] == 'false') {
840
                $status = 'error';
841
            } else {
842
                $status = 'success';
843
            }
844
            foreach ($resultData['results'] as $result) {
845
                if (isset($result['request-id'])) {
846
                    $rid = $result['request-id'];
847
                } else {
848
                    $rid = '';
849
                }
850
                if (isset($result['errors'])) {
851
                    foreach ($result['errors'] as $error) {
852
                        $message = $error['message'];
853
                        if (isset($error['for'])) {
854
                            $message .= ' for: '.$error['for'];
855
                        }
856
                        if (isset($error['value'])) {
857
                            $message .= ' value:'.$error['value'];
858
                        }
859
                        if (isset($error['code'])) {
860
                            $message .= ' code:'.$error['code'];
861
                        }
862
                        $this->logger->addStatusMessage($rid.': '.$message,
863
                            $status);
864
                    }
865
                }
866
            }
867
        }
868
        if (is_object($this->logger)) {
869
            $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...
870
        }
871
    }
872
873
    /**
874
     * Generuje fragment url pro filtrování.
875
     *
876
     * @see https://www.flexibee.eu/api/dokumentace/ref/filters
877
     *
878
     * @param array  $data
879
     * @param string $operator default and/or
880
     *
881
     * @return string
882
     */
883
    public static function flexiUrl(array $data, $operator = 'and')
884
    {
885
        $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...
886
        $parts    = [];
887
888
        foreach ($data as $column => $value) {
889
            if (is_integer($data[$column]) || is_float($data[$column])) {
890
                $parts[$column] = $column.' eq '.$data[$column];
891
            } elseif (is_bool($data[$column])) {
892
                $parts[$column] = $data[$column] ? $column.' eq true' : $column.' eq false';
893
            } elseif (is_null($data[$column])) {
894
                $parts[$column] = $column." is null";
895
            } elseif ($value == '!null') {
896
                $parts[$column] = $column." is not null";
897
            } else {
898
                $parts[$column] = $column." eq '".$data[$column]."'";
899
            }
900
        }
901
902
        $flexiUrl = implode(' '.$operator.' ', $parts);
903
904
        return $flexiUrl;
905
    }
906
907
    /**
908
     * Vrací identifikátor objektu code: nebo id:
909
     *
910
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
911
     * @return string indentifikátor záznamu reprezentovaného objektem
912
     * @throws Exception data objektu neobsahují kód nebo id
913
     */
914
    public function __toString()
915
    {
916
        $myCode = $this->getDataValue('kod');
917
        if ($myCode) {
918
            $id = 'code:'.$myCode;
919
        } else {
920
            $id = $this->getDataValue('id');
921
            if (!$id) {
922
                throw new \Exception(_('invoice without loaded code: or id: cannot match with statement!'));
923
            }
924
        }
925
        return $id;
926
    }
927
}