Completed
Push — master ( 923447...d5d70a )
by Vítězslav
03:36
created

FlexiBeeRO::searchString()   C

Complexity

Conditions 15
Paths 60

Size

Total Lines 52
Code Lines 36

Duplication

Lines 12
Ratio 23.08 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 15
eloc 36
c 2
b 0
f 1
nc 60
nop 1
dl 12
loc 52
rs 5.9385

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/**
3
 * FlexiPeeHP - Třída pro č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
     * @link https://demo.flexibee.eu/devdoc/company-identifier Identifikátor firmy
60
     * @var string
61
     */
62
    public $company = FLEXIBEE_COMPANY;
63
64
    /**
65
     * Server[:port]
66
     * @var string
67
     */
68
    public $url = FLEXIBEE_URL;
69
70
    /**
71
     * REST API Username
72
     * @var string
73
     */
74
    public $user = FLEXIBEE_LOGIN;
75
76
    /**
77
     * REST API Password
78
     * @var string
79
     */
80
    public $password = FLEXIBEE_PASSWORD;
81
82
    /**
83
     * @var array Pole HTTP hlaviček odesílaných s každým požadavkem
84
     */
85
    public $defaultHttpHeaders = ['User-Agent' => 'FlexiPeeHP'];
86
87
    /**
88
     * Default additional request url parameters after question mark
89
     * 
90
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls   Common params
91
     * @link https://www.flexibee.eu/api/dokumentace/ref/paging Paging params
92
     * @var array
93
     */
94
    public $defaultUrlParams = ['limit' => 0];
95
96
    /**
97
     * Identifikační řetězec.
98
     *
99
     * @var string
100
     */
101
    public $init = null;
102
103
    /**
104
     * Sloupeček s názvem.
105
     *
106
     * @var string
107
     */
108
    public $nameColumn = 'nazev';
109
110
    /**
111
     * Sloupeček obsahující datum vložení záznamu do shopu.
112
     *
113
     * @var string
114
     */
115
    public $myCreateColumn = 'false';
116
117
    /**
118
     * Slopecek obsahujici datum poslení modifikace záznamu do shopu.
119
     *
120
     * @var string
121
     */
122
    public $myLastModifiedColumn = 'lastUpdate';
123
124
    /**
125
     * Klíčový idendifikátor záznamu.
126
     *
127
     * @var string
128
     */
129
    public $fbKeyColumn = 'id';
130
131
    /**
132
     * Informace o posledním HTTP requestu.
133
     *
134
     * @var *
135
     */
136
    public $info;
137
138
    /**
139
     * Informace o poslední HTTP chybě.
140
     *
141
     * @var string
142
     */
143
    public $lastCurlError = null;
144
145
    /**
146
     * Used codes storage.
147
     *
148
     * @var array
149
     */
150
    public $codes = null;
151
152
    /**
153
     * Last Inserted ID.
154
     *
155
     * @var int
156
     */
157
    public $lastInsertedID = null;
158
159
    /**
160
     * Default Line Prefix.
161
     *
162
     * @var string
163
     */
164
    public $prefix = '/c/';
165
166
    /**
167
     * HTTP Response code of last request
168
     *
169
     * @var int
170
     */
171
    public $lastResponseCode = null;
172
173
    /**
174
     * Array of fields for next curl POST operation
175
     *
176
     * @var array
177
     */
178
    protected $postFields = [];
179
180
    /**
181
     * Last operation result data or message(s)
182
     *
183
     * @var array
184
     */
185
    public $lastResult = null;
186
187
    /**
188
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
189
     * @var string
190
     */
191
    protected $action;
192
193
    /**
194
     * Pole akcí které podporuje ta která evidence
195
     * @link https://demo.flexibee.eu/c/demo/faktura-vydana/actions.json Např. Akce faktury
196
     * @var array
197
     */
198
    private $actionsAvailable = null;
199
200
    /**
201
     * Třída pro práci s FlexiBee.
202
     *
203
     * @param mixed $init výchozí selektor dat
204
     */
205
    public function __construct($init = null)
206
    {
207
        $this->init = $init;
208
209
        parent::__construct();
210
        $this->curlInit();
211
        if ($init) {
212
            $this->processInit($init);
213
        }
214
    }
215
216
    /**
217
     * Inicializace CURL
218
     */
219
    public function curlInit()
220
    {
221
        $this->curl = \curl_init(); // create curl resource
222
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); // return content as a string from curl_exec
223
        curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); // follow redirects (compatibility for future changes in FlexiBee)
224
        curl_setopt($this->curl, CURLOPT_HTTPAUTH, true);       // HTTP authentication
225
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); // FlexiBee by default uses Self-Signed certificates
226
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
227
        curl_setopt($this->curl, CURLOPT_VERBOSE, true); // For debugging
228
        curl_setopt($this->curl, CURLOPT_USERPWD,
229
            $this->user.':'.$this->password); // set username and password
230
    }
231
232
    /**
233
     * Zinicializuje objekt dle daných dat
234
     * 
235
     * @param mixed $init
236
     */
237
    public function processInit($init)
238
    {
239
        if (is_integer($init)) {
240
            $this->loadFromFlexiBee($init);
241
        } elseif (is_array($init)) {
242
            $this->takeData($init);
243
        }
244
    }
245
246
    /**
247
     * Nastaví Agendu pro Komunikaci.
248
     *
249
     * @param string $evidence
250
     */
251
    public function setEvidence($evidence)
252
    {
253
        $this->evidence = $evidence;
254
    }
255
256
    /**
257
     * Převede rekurzivně Objekt na pole.
258
     *
259
     * @param object|array $object
260
     *
261
     * @return array
262
     */
263
    public static function object2array($object)
264
    {
265
        $result = null;
266
        if (is_object($object)) {
267
            $objectData = get_object_vars($object);
268
            if (is_array($objectData) && count($objectData)) {
269
                $result = array_map('self::object2array', $objectData);
270
            }
271 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...
272
            if (is_array($object)) {
273
                foreach ($object as $item => $value) {
274
                    $result[$item] = self::object2array($value);
275
                }
276
            } else {
277
                $result = $object;
278
            }
279
        }
280
281
        return $result;
282
    }
283
284
    /**
285
     * Převede rekurzivně v poli všechny objekty na jejich identifikátory.
286
     *
287
     * @param object|array $object
288
     *
289
     * @return array
290
     */
291
    public static function objectToID($object)
292
    {
293
        $result = null;
294
        if (is_object($object)) {
295
            $result = $object->__toString();
296 View Code Duplication
        } else {
1 ignored issue
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...
297
            if (is_array($object)) {
298
                foreach ($object as $item => $value) {
299
                    $result[$item] = self::objectToID($value);
300
                }
301
            } else { //String
302
                $result = $object;
303
            }
304
        }
305
306
        return $result;
307
    }
308
309
    /**
310
     * Funkce, která provede I/O operaci a vyhodnotí výsledek.
311
     *
312
     * @param string $urlSuffix část URL za identifikátorem firmy.
313
     * @param string $method    HTTP/REST metoda
314
     * @param string $format    Requested format
315
     * @return array|boolean Výsledek operace
316
     */
317
    public function performRequest($urlSuffix = null, $method = 'GET',
318
                                   $format = null)
319
    {
320
        if (is_null($format)) {
321
            $format = $this->format;
322
        }
323
        if (is_null($urlSuffix)) {
324
            $urlSuffix = $this->evidence.'.'.$format;
325
        }
326
        $url = $this->url.$this->prefix.$this->company.'/'.$urlSuffix;
327
        curl_setopt($this->curl, CURLOPT_URL, $url);
328
// Nastavení samotné operace
329
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $method);
330
//Vždy nastavíme byť i prázná postdata jako ochranu před chybou 411
331
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->postFields);
332
333
        $httpHeaders = $this->defaultHttpHeaders;
334
        switch ($format) {
335
            case 'json':
336
                $httpHeaders['Accept']       = 'application/json';
337
                $httpHeaders['Content-Type'] = 'application/json';
338
339
                break;
340
            case 'xml':
341
                $httpHeaders['Accept']       = 'application/xml';
342
                $httpHeaders['Content-Type'] = 'application/xml';
343
                break;
344
        }
345
346
        foreach ($httpHeaders as $key => $value) {
347
            $httpHeadersFinal[] = $key.': '.$value;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$httpHeadersFinal was never initialized. Although not strictly required by PHP, it is generally a good practice to add $httpHeadersFinal = 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...
348
        }
349
350
        curl_setopt($this->curl, CURLOPT_HTTPHEADER, $httpHeadersFinal);
0 ignored issues
show
Bug introduced by
The variable $httpHeadersFinal 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...
351
352
// Proveď samotnou operaci
353
        $curlResponse = curl_exec($this->curl);
354
355
        $this->info = curl_getinfo($this->curl);
356
357
        $this->lastResponseCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
358
359
        if ($this->lastResponseCode != 200 && $this->lastResponseCode != 201) {
360
            $this->lastCurlError = curl_error($this->curl);
361
            switch ($format) {
362
                case 'json':
363
                    $response = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/',
364
                        function ($match) {
365
                        return mb_convert_encoding(pack('H*', $match[1]),
366
                            'UTF-8', 'UCS-2BE');
367
                    }, $curlResponse);
368
                    $response = (json_encode(json_decode($response, true, 10),
369
                            JSON_PRETTY_PRINT));
370
                    break;
371
                case 'xml':
372
                    if (strlen($curlResponse)) {
373
                        $response = self::xml2array($curlResponse);
374
                    }
375
                    break;
376
            }
377
378
            if (is_array($response)) {
379
                $result = urldecode(http_build_query($response));
0 ignored issues
show
Bug introduced by
The variable $response 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...
380
            } elseif (strlen($response) && ($response != 'null')) {
381
                $result = urldecode(http_build_query(self::object2array(current(json_decode($response)))));
382
            } else {
383
                $result = null;
384
            }
385
386
            if ($response == 'null') {
387
                if ($this->lastResponseCode == 200) {
388
                    $response = true;
389
                } else {
390
                    $response = null;
391
                }
392
            } else {
393
                if (is_string($response)) {
394
                    $response = self::object2array(current(json_decode($response)));
395
                }
396
            }
397
398
            if (is_array($response) && ($this->lastResponseCode == 400)) {
399
                $this->logResult($response);
400
            } else {
401
                $this->addStatusMessage(sprintf('Error (HTTP %d): <pre>%s</pre> %s',
402
                        curl_getinfo($this->curl, CURLINFO_HTTP_CODE), $result,
403
                        $this->lastCurlError), 'error');
404
                $this->addStatusMessage($url, 'info');
405
                if (count($this->postFields)) {
406
                    $this->addStatusMessage(urldecode(http_build_query($this->postFields)),
407
                        'debug');
408
                }
409
            }
410
            return $response;
411
        }
412
        // Parse response
413
        $responseDecoded = [];
414
        switch ($format) {
415
            case 'json':
416
                $responseDecoded = json_decode($curlResponse, true, 10);
417
                if (($method == 'PUT') && isset($responseDecoded[$this->nameSpace][$this->resultField][0]['id'])) {
418
                    $this->lastInsertedID = $responseDecoded[$this->nameSpace][$this->resultField][0]['id'];
419
                } else {
420
                    $this->lastInsertedID = null;
421
                }
422
                $decodeError = json_last_error_msg();
423
                if ($decodeError != 'No error') {
424
                    $this->addStatusMessage($decodeError, 'error');
425
                }
426
                break;
427
            case 'xml':
428
                if (strlen($curlResponse)) {
429
                    $responseDecoded = self::xml2array($curlResponse);
430
                } else {
431
                    $responseDecoded = null;
432
                }
433
                break;
434
        }
435
436
        // Get response body root automatically
437
        if (isset($responseDecoded[$this->nameSpace])) {
438
            $responseDecoded = $responseDecoded[$this->nameSpace];
439
        }
440
441
        $this->lastResult = $responseDecoded;
0 ignored issues
show
Documentation Bug introduced by
It seems like $responseDecoded 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...
442
        return $responseDecoded;
443
    }
444
445
    /**
446
     * Todo: Sem vyčlenit zpracování výsledku requestu
447
     */
448
    public function processRequest()
449
    {
450
451
    }
452
453
    /**
454
     * Nastaví druh prováděné akce.
455
     *
456
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
457
     * @param string $action
458
     * @return boolean
459
     */
460
    public function setAction($action)
461
    {
462
        $result = false;
463
        if (is_null($this->actionsAvailable)) {
464
            $this->action = $action;
465
            $result       = true;
466
        } else {
467
            if (array_search($action, $this->actionsAvailable)) {
468
                $this->action = $action;
469
                $result       = true;
470
            }
471
        }
472
        return $result;
473
    }
474
475
    /**
476
     * Convert XML to array.
477
     *
478
     * @param string $xml
479
     *
480
     * @return array
481
     */
482
    public static function xml2array($xml)
483
    {
484
        $arr = [];
485
486
        if (is_string($xml)) {
487
            $xml = simplexml_load_string($xml);
488
        }
489
490
        foreach ($xml->children() as $r) {
491
            if (count($r->children()) == 0) {
492
                $arr[$r->getName()] = strval($r);
493
            } else {
494
                $arr[$r->getName()][] = self::xml2array($r);
495
            }
496
        }
497
498
        return $arr;
499
    }
500
501
    /**
502
     * Odpojení od FlexiBee.
503
     */
504
    public function disconnect()
505
    {
506
        if (is_resource($this->curl)) {
507
            curl_close($this->curl);
508
        }
509
        $this->curl = null;
510
    }
511
512
    public function __destruct()
513
    {
514
        $this->disconnect();
515
    }
516
517
    /**
518
     * Načte data z FlexiBee.
519
     *
520
     * @param string $suffix dotaz
521
     */
522
    public function loadFlexiData($suffix = null)
523
    {
524
        return $this->takeData($this->getFlexiData($suffix));
525
    }
526
527
    /**
528
     * Načte řádek dat z FlexiBee.
529
     *
530
     * @param int $recordID id požadovaného záznamu
531
     *
532
     * @return array
533
     */
534
    public function getFlexiRow($recordID)
535
    {
536
        $record   = null;
537
        $response = $this->performRequest($this->evidence.'/'.$recordID.'.json');
538
        if (isset($response[$this->evidence])) {
539
            $record = $response[$this->evidence][0];
540
        }
541
542
        return $record;
543
    }
544
545
    /**
546
     * Načte data z FlexiBee.
547
     *
548
     * @param string $suffix     dotaz
549
     * @param string|array $conditions Volitelný filtrovací výraz
550
     */
551
    public function getFlexiData($suffix = null, $conditions = null)
552
    {
553
        $urlParams = $this->defaultUrlParams;
554
        if (!is_null($conditions)) {
555
            if (is_array($conditions)) {
556
557
                if (isset($conditions['sort'])) {
558
                    \Ease\Sand::divDataArray($conditions, $urlParams, 'sort');
559
                }
560
                if (isset($conditions['order'])) {
561
                    \Ease\Sand::divDataArray($conditions, $urlParams, 'order');
562
                }
563
                if (isset($conditions['limit'])) {
564
                    \Ease\Sand::divDataArray($conditions, $urlParams, 'limit');
565
                }
566
                if (isset($conditions['start'])) {
567
                    \Ease\Sand::divDataArray($conditions, $urlParams, 'start');
568
                }
569
                if (isset($conditions['add-row-count'])) {
570
                    \Ease\Sand::divDataArray($conditions, $urlParams,
571
                        'add-row-count');
572
                }
573
574
                $conditions = $this->flexiUrl($conditions);
575
            }
576
577
            if (strlen($conditions) && ($conditions[0] != '/')) {
578
                $conditions = '/'.rawurlencode('('.($conditions).')');
579
            }
580
        } else {
581
            $conditions = '';
582
        }
583
        if (strlen($suffix)) {
584
            $transactions = $this->performRequest($this->evidence.$conditions.'.'.$this->format.'?'.$suffix.'&'.http_build_query($urlParams),
585
                'GET');
586
        } else {
587
            $transactions = $this->performRequest($this->evidence.$conditions.'.'.$this->format.'?'.http_build_query($urlParams),
588
                'GET');
589
        }
590
        if (isset($transactions[$this->evidence])) {
591
            $result = $transactions[$this->evidence];
592
        } else {
593
            $result = $transactions;
594
        }
595
596
        return $result;
597
    }
598
599
    /**
600
     * Načte záznam z FlexiBee.
601
     *
602
     * @param int $id ID záznamu
603
     *
604
     * @return int počet načtených položek
605
     */
606 View Code Duplication
    public function loadFromFlexiBee($id = 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...
607
    {
608
        $data = [];
609
        if (is_null($id)) {
610
            $id = $this->getMyKey();
611
        }
612
613
        $flexidata = $this->getFlexiData(null, '/'.$id);
614
        if (count($flexidata) == 1) {
615
            $data = current($flexidata);
616
        }
617
        return $this->takeData($data);
618
    }
619
620
    /**
621
     * Převede data do Json formátu pro FlexiBee.
622
     *
623
     * @param array $data
624
     *
625
     * @return string
626
     */
627
    public function jsonizeData($data)
628
    {
629
        $jsonize = [
630
            $this->nameSpace => [
631
                '@version' => $this->protoVersion,
632
                $this->evidence => $this->objectToID($data),
633
            ],
634
        ];
635
636
        if (!is_null($this->action)) {
637
            $jsonize[$this->nameSpace.'@action'] = $this->action;
638
            $this->action                        = null;
639
        }
640
641
        return json_encode($jsonize);
642
    }
643
644
    /**
645
     * Test if given record ID exists in FlexiBee.
646
     *
647
     * @param string|int $identifer
648
     */
649
    public function idExists($identifer = null)
650
    {
651
        if (is_null($identifer)) {
652
            $identifer = $this->getMyKey();
653
        }
654
        $flexiData = $this->getFlexiData(
655
            'detail=custom:'.$this->getmyKeyColumn(), $identifer);
656
657
        return $flexiData;
658
    }
659
660
    /**
661
     * Test if given record exists in FlexiBee.
662
     *
663
     * @param array $data
664
     */
665
    public function recordExists($data = null)
666
    {
667
        if (is_null($data)) {
668
            $data = $this->getData();
669
        }
670
671
        $res = $this->getColumnsFromFlexibee([$this->myKeyColumn],
672
            self::flexiUrl($data));
0 ignored issues
show
Documentation introduced by
self::flexiUrl($data) is of type string, but the function expects a array|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
673
674
        return $res;
675
    }
676
677
    /**
678
     * Vrací z FlexiBee sloupečky podle podmínek.
679
     *
680
     * @param array|int|string $conditions pole podmínek nebo ID záznamu
681
     * @param string           $indexBy    klice vysledku naplnit hodnotou ze
682
     *                                     sloupečku
683
     * @return array
684
     */
685 View Code Duplication
    public function getAllFromFlexibee($conditions = null, $indexBy = 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...
686
    {
687
        if (is_int($conditions)) {
688
            $conditions = [$this->getmyKeyColumn() => $conditions];
689
        }
690
691
        $flexiData = $this->getFlexiData('', $conditions);
692
693
        if (!is_null($indexBy)) {
694
            $flexiData = $this->reindexArrayBy($flexiData);
0 ignored issues
show
Bug introduced by
The method reindexArrayBy() does not seem to exist on object<FlexiPeeHP\FlexiBeeRO>.

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...
695
        }
696
697
        return $flexiData;
698
    }
699
700
    /**
701
     * Vrací z FlexiBee sloupečky podle podmínek.
702
     *
703
     * @param string[] $columnsList seznam položek
704
     * @param array    $conditions  pole podmínek nebo ID záznamu
705
     * @param string   $indexBy     Sloupeček podle kterého indexovat záznamy
706
     *
707
     * @return array
708
     */
709
    public function getColumnsFromFlexibee($columnsList, $conditions = null,
710
                                           $indexBy = null)
711
    {
712
        if (($columnsList != '*') && !count($columnsList)) {
713
            $this->error('getColumnsFromFlexiBee: Missing ColumnList');
714
715
            return;
716
        }
717
718
        if (is_int($conditions)) {
719
            $conditions = [$this->getmyKeyColumn() => $conditions];
720
        }
721
722
        if (is_array($columnsList)) {
723
            $columns = implode(',', array_unique($columnsList));
724
        } else {
725
            $columns = $columnsList;
726
        }
727
728
        $flexiData = $this->getFlexiData('detail=custom:'.$columns, $conditions);
729
730
        if (!is_null($indexBy)) {
731
            $flexiData = $this->reindexArrayBy($flexiData, $indexBy);
0 ignored issues
show
Bug introduced by
The method reindexArrayBy() does not seem to exist on object<FlexiPeeHP\FlexiBeeRO>.

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...
732
        }
733
734
        return $flexiData;
735
    }
736
737
    /**
738
     * Vrací kód záznamu.
739
     *
740
     * @param mixed $data
741
     *
742
     * @todo papat i string
743
     *
744
     * @return string
745
     */
746
    public function getKod($data = null, $unique = true)
747
    {
748
        $kod = null;
749
750
        if (is_null($data)) {
751
            $data = $this->getData();
752
        }
753
754
        if (is_string($data)) {
755
            $data = [$this->nameColumn => $data];
756
        }
757
758
        if (isset($data['kod'])) {
759
            $kod = $data['kod'];
760
        } else {
761
            if (isset($data[$this->nameColumn])) {
762
                $kod = preg_replace('/[^a-zA-Z0-9]/', '',
763
                    \Ease\Sand::rip($data[$this->nameColumn]));
764
            } else {
765
                if (isset($data[$this->myKeyColumn])) {
766
                    $kod = \Ease\Sand::rip($data[$this->myKeyColumn]);
767
                }
768
            }
769
        }
770
771
        if (!strlen($kod)) {
772
            $kod = 'NOTSET';
773
        }
774
775
        if (strlen($kod) > 18) {
776
            $kodfinal = strtoupper(substr($kod, 0, 18));
777
        } else {
778
            $kodfinal = strtoupper($kod);
779
        }
780
781
        if ($unique) {
782
            $counter = 0;
783
            if (count($this->codes)) {
784
                foreach ($this->codes as $codesearch => $keystring) {
785
                    if (strstr($codesearch, $kodfinal)) {
786
                        ++$counter;
787
                    }
788
                }
789
            }
790
            if ($counter) {
791
                $kodfinal = $kodfinal.$counter;
792
            }
793
794
            $this->codes[$kodfinal] = $kod;
795
        }
796
797
        return $kodfinal;
798
    }
799
800
    /**
801
     * Write Operation Result.
802
     *
803
     * @param array  $resultData
804
     * @param string $url        URL
805
     */
806
    public function logResult($resultData = null, $url = null)
807
    {
808
        if (is_null($resultData)) {
809
            $resultData = $this->lastResult;
810
        }
811
        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...
812
            $this->logger->addStatusMessage($url);
813
        }
814
815
        if (isset($resultData['results'])) {
816
            $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...
817
            if ($resultData['success'] == 'false') {
818
                $status = 'error';
819
            } else {
820
                $status = 'success';
821
            }
822
            foreach ($resultData['results'] as $result) {
823
                if (isset($result['request-id'])) {
824
                    $rid = $result['request-id'];
825
                } else {
826
                    $rid = '';
827
                }
828
                if (isset($result['errors'])) {
829
                    foreach ($result['errors'] as $error) {
830
                        $message = $error['message'];
831
                        if (isset($error['for'])) {
832
                            $message .= ' for: '.$error['for'];
833
                        }
834
                        if (isset($error['value'])) {
835
                            $message .= ' value:'.$error['value'];
836
                        }
837
                        if (isset($error['code'])) {
838
                            $message .= ' code:'.$error['code'];
839
                        }
840
                        $this->logger->addStatusMessage($rid.': '.$message,
841
                            $status);
842
                    }
843
                }
844
            }
845
        }
846
        if (is_object($this->logger)) {
847
            $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...
848
        }
849
    }
850
851
    /**
852
     * Generuje fragment url pro filtrování.
853
     *
854
     * @see https://www.flexibee.eu/api/dokumentace/ref/filters
855
     *
856
     * @param array  $data
857
     * @param string $operator default and/or
858
     *
859
     * @return string
860
     */
861
    public static function flexiUrl(array $data, $operator = 'and')
862
    {
863
        $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...
864
        $parts    = [];
865
866
        foreach ($data as $column => $value) {
867
            if (is_integer($data[$column]) || is_float($data[$column])) {
868
                $parts[$column] = $column.' eq '.$data[$column];
869
            } elseif (is_bool($data[$column])) {
870
                $parts[$column] = $data[$column] ? $column.' eq true' : $column.' eq false';
871
            } elseif (is_null($data[$column])) {
872
                $parts[$column] = $column." is null";
873
            } elseif ($value == '!null') {
874
                $parts[$column] = $column." is not null";
875
            } else {
876
                $parts[$column] = $column." eq '".$data[$column]."'";
877
            }
878
        }
879
880
        $flexiUrl = implode(' '.$operator.' ', $parts);
881
882
        return $flexiUrl;
883
    }
884
885
    /**
886
     * Vrací identifikátor objektu code: nebo id:
887
     *
888
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
889
     * @return string indentifikátor záznamu reprezentovaného objektem
890
     * @throws Exception data objektu neobsahují kód nebo id
891
     */
892
    public function __toString()
893
    {
894
        $myCode = $this->getDataValue('kod');
895
        if ($myCode) {
896
            $id = 'code:'.$myCode;
897
        } else {
898
            $id = $this->getDataValue('id');
899
            if (!$id) {
900
                throw new \Exception(_('invoice without loaded code: or id: cannot match with statement!'));
901
            }
902
        }
903
        return $id;
904
    }
905
}