Completed
Push — master ( 09fdd7...b21fd5 )
by Vítězslav
05:29
created

FlexiBeeRO::getGlobalVersion()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 8
c 1
b 0
f 0
nc 4
nop 0
dl 0
loc 14
rs 9.2
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 = null;
63
64
    /**
65
     * Server[:port]
66
     * @var string
67
     */
68
    public $url = null;
69
70
    /**
71
     * REST API Username
72
     * @var string
73
     */
74
    public $user = null;
75
76
    /**
77
     * REST API Password
78
     * @var string
79
     */
80
    public $password = null;
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
     * Raw Content of last curl response
168
     * 
169
     * @var string
170
     */
171
    public $lastCurlResponse;
172
173
    /**
174
     * HTTP Response code of last request
175
     *
176
     * @var int
177
     */
178
    public $lastResponseCode = null;
179
180
    /**
181
     * Array of fields for next curl POST operation
182
     *
183
     * @var array
184
     */
185
    protected $postFields = [];
186
187
    /**
188
     * Last operation result data or message(s)
189
     *
190
     * @var array
191
     */
192
    public $lastResult = null;
193
194
    /**
195
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
196
     * @var string
197
     */
198
    protected $action;
199
200
    /**
201
     * Pole akcí které podporuje ta která evidence
202
     * @link https://demo.flexibee.eu/c/demo/faktura-vydana/actions.json Např. Akce faktury
203
     * @var array
204
     */
205
    public $actionsAvailable = null;
206
207
    /**
208
     * Parmetry pro URL
209
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Všechny podporované parametry
210
     * @var array
211
     */
212
    public $urlParams = [
213
        'dry-run',
214
        'fail-on-warning',
215
        'report-name',
216
        'report-lang',
217
        'report-sign',
218
        'detail',
219
        'mode',
220
        'limit',
221
        'start',
222
        'order',
223
        'sort',
224
        'add-row-count',
225
        'relations',
226
        'includes',
227
        'use-ext-id',
228
        'use-internal-id',
229
        'stitky-as-ids',
230
        'only-ext-ids',
231
        'no-ext-ids',
232
        'no-ids',
233
        'code-as-id',
234
        'no-http-errors',
235
        'export-settings',
236
        'as-gui',
237
        'code-in-response',
238
        'add-global-version',
239
        'encoding',
240
        'delimeter',
241
        'format',
242
        'auth',
243
        'skupina-stitku',
244
        'dir'
245
    ];
246
247
    /**
248
     * Třída pro práci s FlexiBee.
249
     *
250
     * @param mixed $init výchozí selektor dat
251
     */
252
    public function __construct($init = null)
253
    {
254
        $this->init = $init;
255
256
        parent::__construct();
257
        $this->setUp();
258
        $this->curlInit();
259
        if (!is_null($init)) {
260
            $this->processInit($init);
261
        }
262
    }
263
264
    /**
265
     * SetUp Object to be ready for connect
266
     */
267
    public function setUp()
268
    {
269
        if (is_null($this->company) && defined('FLEXIBEE_COMPANY')) {
270
            $this->company = constant('FLEXIBEE_COMPANY');
271
        }
272
        if (is_null($this->url) && defined('FLEXIBEE_URL')) {
273
            $this->url = constant('FLEXIBEE_URL');
274
        }
275
276
        if (is_null($this->user) && defined('FLEXIBEE_LOGIN')) {
277
            $this->user = constant('FLEXIBEE_LOGIN');
278
        }
279
280
        if (is_null($this->password) && defined('FLEXIBEE_PASSWORD')) {
281
            $this->password = constant('FLEXIBEE_PASSWORD');
282
        }
283
    }
284
285
    /**
286
     * Inicializace CURL
287
     */
288
    public function curlInit()
289
    {
290
        $this->curl = \curl_init(); // create curl resource
291
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); // return content as a string from curl_exec
292
        curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); // follow redirects (compatibility for future changes in FlexiBee)
293
        curl_setopt($this->curl, CURLOPT_HTTPAUTH, true);       // HTTP authentication
294
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); // FlexiBee by default uses Self-Signed certificates
295
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
296
        curl_setopt($this->curl, CURLOPT_VERBOSE, true); // For debugging
297
        curl_setopt($this->curl, CURLOPT_USERPWD,
298
            $this->user.':'.$this->password); // set username and password
299
    }
300
301
    /**
302
     * Zinicializuje objekt dle daných dat
303
     * 
304
     * @param mixed $init
305
     */
306
    public function processInit($init)
307
    {
308
        if (is_integer($init)) {
309
            $this->loadFromFlexiBee($init);
310
        } elseif (is_array($init)) {
311
            $this->takeData($init);
312
        } elseif (strstr($init, 'code:')) {
313
            $this->loadFromFlexiBee($init);
314
        }
315
    }
316
317
    /**
318
     * Nastaví Evidenci pro Komunikaci.
319
     *
320
     * @param string $evidence
321
     */
322
    public function setEvidence($evidence)
323
    {
324
        $this->evidence = $evidence;
325
    }
326
327
    /**
328
     * Vrací právě používanou evidenci pro komunikaci
329
     * 
330
     * @return string
331
     */
332
    public function getEvidence()
333
    {
334
        return $this->evidence;
335
    }
336
337
    /**
338
     * Převede rekurzivně Objekt na pole.
339
     *
340
     * @param object|array $object
341
     *
342
     * @return array
343
     */
344
    public static function object2array($object)
345
    {
346
        $result = null;
347
        if (is_object($object)) {
348
            $objectData = get_object_vars($object);
349
            if (is_array($objectData) && count($objectData)) {
350
                $result = array_map('self::object2array', $objectData);
351
            }
352 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...
353
            if (is_array($object)) {
354
                foreach ($object as $item => $value) {
355
                    $result[$item] = self::object2array($value);
356
                }
357
            } else {
358
                $result = $object;
359
            }
360
        }
361
362
        return $result;
363
    }
364
365
    /**
366
     * Převede rekurzivně v poli všechny objekty na jejich identifikátory.
367
     *
368
     * @param object|array $object
369
     *
370
     * @return array
371
     */
372
    public static function objectToID($object)
373
    {
374
        $result = null;
375
        if (is_object($object)) {
376
            $result = $object->__toString();
377 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...
378
            if (is_array($object)) {
379
                foreach ($object as $item => $value) {
380
                    $result[$item] = self::objectToID($value);
381
                }
382
            } else { //String
383
                $result = $object;
384
            }
385
        }
386
387
        return $result;
388
    }
389
390
    /**
391
     * Vrací základní URL pro užitou evidenci
392
     *
393
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
394
     * @param string $urlSuffix
395
     */
396
    public function getEvidenceURL($urlSuffix = null)
397
    {
398
        if (is_null($urlSuffix)) {
399
            $urlSuffix = $this->evidence;
400
        }
401
        return $this->url.$this->prefix.$this->company.'/'.$urlSuffix;
402
    }
403
404
    /**
405
     * Funkce, která provede I/O operaci a vyhodnotí výsledek.
406
     *
407
     * @param string $urlSuffix část URL za identifikátorem firmy.
408
     * @param string $method    HTTP/REST metoda
409
     * @param string $format    Requested format
410
     * @return array|boolean Výsledek operace
411
     */
412
    public function performRequest($urlSuffix = null, $method = 'GET',
413
                                   $format = null)
414
    {
415
416
        $url = $this->getEvidenceURL($urlSuffix);
417
418
        $responseCode = $this->doCurlRequest($url, $method, $format);
0 ignored issues
show
Documentation introduced by
$method is of type string, but the function expects a object<FlexiPeeHP\strinf>.

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...
419
420
        if (is_null($format)) {
421
            $format = $this->format;
422
        }
423
424
        switch ($responseCode) {
425
            case 200:
426
            case 201:
427
                // Parse response
428
                $responseDecoded = [];
429
430
                switch ($format) {
431
                    case 'json':
432
                        $responseDecoded = json_decode($this->lastCurlResponse,
433
                            true, 10);
434
                        if (($method == 'PUT') && isset($responseDecoded[$this->nameSpace][$this->resultField][0]['id'])) {
435
                            $this->lastInsertedID = $responseDecoded[$this->nameSpace][$this->resultField][0]['id'];
436
                        } else {
437
                            $this->lastInsertedID = null;
438
                        }
439
                        $decodeError = json_last_error_msg();
440
                        if ($decodeError != 'No error') {
441
                            $this->addStatusMessage($decodeError, 'error');
442
                        }
443
                        break;
444
                    case 'xml':
445
                        if (strlen($this->lastCurlResponse)) {
446
                            $responseDecoded = self::xml2array($this->lastCurlResponse);
447
                        } else {
448
                            $responseDecoded = null;
449
                        }
450
                        break;
451
                }
452
453
                // Get response body root automatically
454
                if (isset($responseDecoded[$this->nameSpace])) {
455
                    $responseDecoded = $responseDecoded[$this->nameSpace];
456
                }
457
458
                $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...
459
                $response         = $responseDecoded;
460
461
                break;
462
463
            default: //Some goes wrong
464
                $this->lastCurlError = curl_error($this->curl);
465
                switch ($format) {
466
                    case 'json':
467
                        $response = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/',
468
                            function ($match) {
469
                            return mb_convert_encoding(pack('H*', $match[1]),
470
                                'UTF-8', 'UCS-2BE');
471
                        }, $this->lastCurlResponse);
472
                        $response = (json_encode(json_decode($response, true, 10),
473
                                JSON_PRETTY_PRINT));
474
                        break;
475
                    case 'xml':
476
                        if (strlen($this->lastCurlResponse)) {
477
                            $response = self::xml2array($this->lastCurlResponse);
478
                        }
479
                        break;
480
                }
481
482
                if (is_array($response)) {
483
                    $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...
484
                } elseif (strlen($response) && ($response != 'null')) {
485
                    $result = urldecode(http_build_query(self::object2array(current(json_decode($response)))));
486
                } else {
487
                    $result = null;
488
                }
489
490
                if ($response == 'null') {
491
                    if ($this->lastResponseCode == 200) {
492
                        $response = true;
493
                    } else {
494
                        $response = null;
495
                    }
496
                } else {
497
                    if (is_string($response)) {
498
                        $response = self::object2array(current(json_decode($response)));
499
                    }
500
                }
501
502
                if (is_array($response) && ($this->lastResponseCode == 400)) {
503
                    $this->logResult($response);
504
                } else {
505
                    $this->addStatusMessage(sprintf('Error (HTTP %d): <pre>%s</pre> %s',
506
                            curl_getinfo($this->curl, CURLINFO_HTTP_CODE),
507
                            $result, $this->lastCurlError), 'error');
508
                    $this->addStatusMessage($url, 'info');
509
                    if (count($this->postFields)) {
510
                        $this->addStatusMessage(urldecode(http_build_query($this->postFields)),
511
                            'debug');
512
                    }
513
                }
514
515
516
                break;
517
        }
518
        return $response;
519
    }
520
521
    /**
522
     * Vykonej HTTP požadavek
523
     *
524
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
525
     * @param string $url    URL požadavku
526
     * @param strinf $method HTTP Method GET|POST|PUT|OPTIONS|DELETE
527
     * @param string $format požadovaný formát komunikace
528
     * @return int HTTP Response CODE
529
     */
530
    public function doCurlRequest($url, $method, $format = null)
531
    {
532
        if (is_null($format)) {
533
            $format = $this->format;
534
        }
535
        curl_setopt($this->curl, CURLOPT_URL, $url);
536
// Nastavení samotné operace
537
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, strtoupper($method));
538
//Vždy nastavíme byť i prázná postdata jako ochranu před chybou 411
539
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->postFields);
540
541
        $httpHeaders = $this->defaultHttpHeaders;
542
        switch ($format) {
543
            case 'json':
544
                $httpHeaders['Accept']       = 'application/json';
545
                $httpHeaders['Content-Type'] = 'application/json';
546
547
                break;
548
            case 'xml':
549
                $httpHeaders['Accept']       = 'application/xml';
550
                $httpHeaders['Content-Type'] = 'application/xml';
551
                break;
552
        }
553
554
        $httpHeadersFinal = [];
555
        foreach ($httpHeaders as $key => $value) {
556
            $httpHeadersFinal[] = $key.': '.$value;
557
        }
558
559
        curl_setopt($this->curl, CURLOPT_HTTPHEADER, $httpHeadersFinal);
560
561
// Proveď samotnou operaci
562
        $this->lastCurlResponse = curl_exec($this->curl);
563
564
        $this->info = curl_getinfo($this->curl);
565
566
        $this->lastResponseCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
567
        return $this->lastResponseCode;
568
    }
569
570
    /**
571
     * Nastaví druh prováděné akce.
572
     *
573
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
574
     * @param string $action
575
     * @return boolean
576
     */
577
    public function setAction($action)
578
    {
579
        $result = false;
580
        if (is_null($this->actionsAvailable)) {
581
            $this->action = $action;
582
            $result       = true;
583
        } else {
584
            if (array_search($action, $this->actionsAvailable)) {
585
                $this->action = $action;
586
                $result       = true;
587
            }
588
        }
589
        return $result;
590
    }
591
592
    /**
593
     * Convert XML to array.
594
     *
595
     * @param string $xml
596
     *
597
     * @return array
598
     */
599
    public static function xml2array($xml)
600
    {
601
        $arr = [];
602
603
        if (is_string($xml)) {
604
            $xml = simplexml_load_string($xml);
605
        }
606
607
        foreach ($xml->children() as $r) {
608
            if (count($r->children()) == 0) {
609
                $arr[$r->getName()] = strval($r);
610
            } else {
611
                $arr[$r->getName()][] = self::xml2array($r);
612
            }
613
        }
614
615
        return $arr;
616
    }
617
618
    /**
619
     * Odpojení od FlexiBee.
620
     */
621
    public function disconnect()
622
    {
623
        if (is_resource($this->curl)) {
624
            curl_close($this->curl);
625
        }
626
        $this->curl = null;
627
    }
628
629
    public function __destruct()
630
    {
631
        $this->disconnect();
632
    }
633
634
    /**
635
     * Načte data z FlexiBee.
636
     *
637
     * @param string $suffix dotaz
638
     */
639
    public function loadFlexiData($suffix = null)
640
    {
641
        return $this->takeData($this->getFlexiData($suffix));
642
    }
643
644
    /**
645
     * Načte řádek dat z FlexiBee.
646
     *
647
     * @param int $recordID id požadovaného záznamu
648
     *
649
     * @return array
650
     */
651
    public function getFlexiRow($recordID)
652
    {
653
        $record   = null;
654
        $response = $this->performRequest($this->evidence.'/'.$recordID.'.json');
655
        if (isset($response[$this->evidence])) {
656
            $record = $response[$this->evidence][0];
657
        }
658
659
        return $record;
660
    }
661
662
    /**
663
     * Oddělí z pole podmínek ty jenž patří za ? v URL požadavku
664
     *
665
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
666
     * @param array $conditions pole podmínek   - rendrují se do ()
667
     * @param array $urlParams  pole parametrů  - rendrují za ?
668
     */
669
    public function extractUrlParams(&$conditions, &$urlParams)
670
    {
671
        foreach ($this->urlParams as $urlParam) {
672
            if (isset($conditions[$urlParam])) {
673
                \Ease\Sand::divDataArray($conditions, $urlParams, $urlParam);
674
            }
675
        }
676
    }
677
678
    /**
679
     * Načte data z FlexiBee.
680
     *
681
     * @param string $suffix     dotaz
682
     * @param string|array $conditions Volitelný filtrovací výraz
683
     */
684
    public function getFlexiData($suffix = null, $conditions = null)
685
    {
686
        $urlParams = $this->defaultUrlParams;
687
        if (!is_null($conditions)) {
688
            if (is_array($conditions)) {
689
                $this->extractUrlParams($conditions, $urlParams);
690
                $conditions = $this->flexiUrl($conditions);
691
            }
692
693
            if (strlen($conditions) && ($conditions[0] != '/')) {
694
                $conditions = '/'.rawurlencode('('.($conditions).')');
695
            }
696
        } else {
697
            $conditions = '';
698
        }
699
        if (strlen($suffix)) {
700
            $transactions = $this->performRequest($this->evidence.$conditions.'.'.$this->format.'?'.$suffix.'&'.http_build_query($urlParams),
701
                'GET');
702
        } else {
703
            $transactions = $this->performRequest($this->evidence.$conditions.'.'.$this->format.'?'.http_build_query($urlParams),
704
                'GET');
705
        }
706
        if (isset($transactions[$this->evidence])) {
707
            $result = $transactions[$this->evidence];
708
        } else {
709
            $result = $transactions;
710
        }
711
712
        return $result;
713
    }
714
715
    /**
716
     * Načte záznam z FlexiBee.
717
     *
718
     * @param int $id ID záznamu
719
     *
720
     * @return int počet načtených položek
721
     */
722 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...
723
    {
724
        $data = [];
725
        if (is_null($id)) {
726
            $id = $this->getMyKey();
727
        }
728
729
        $flexidata = $this->getFlexiData(null, '/'.$id);
730
        if (count($flexidata) == 1) {
731
            $data = current($flexidata);
732
        }
733
        return $this->takeData($data);
734
    }
735
736
    /**
737
     * Převede data do Json formátu pro FlexiBee.
738
     *
739
     * @param array $data
740
     *
741
     * @return string
742
     */
743
    public function jsonizeData($data)
744
    {
745
        $jsonize = [
746
            $this->nameSpace => [
747
                '@version' => $this->protoVersion,
748
                $this->evidence => $this->objectToID($data),
749
            ],
750
        ];
751
752
        if (!is_null($this->action)) {
753
            $jsonize[$this->nameSpace][$this->evidence.'@action'] = $this->action;
754
            $this->action                                         = null;
755
        }
756
757
        return json_encode($jsonize);
758
    }
759
760
    /**
761
     * Test if given record ID exists in FlexiBee.
762
     *
763
     * @param string|int $identifer
764
     */
765
    public function idExists($identifer = null)
766
    {
767
        if (is_null($identifer)) {
768
            $identifer = $this->getMyKey();
769
        }
770
        $flexiData = $this->getFlexiData(
771
            'detail=custom:'.$this->getmyKeyColumn(), $identifer);
772
773
        return $flexiData;
774
    }
775
776
    /**
777
     * Test if given record exists in FlexiBee.
778
     *
779
     * @param array $data
780
     */
781
    public function recordExists($data = null)
782
    {
783
        if (is_null($data)) {
784
            $data = $this->getData();
785
        }
786
787
        $res = $this->getColumnsFromFlexibee([$this->myKeyColumn],
788
            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...
789
790
        return $res;
791
    }
792
793
    /**
794
     * Vrací z FlexiBee sloupečky podle podmínek.
795
     *
796
     * @param array|int|string $conditions pole podmínek nebo ID záznamu
797
     * @param string           $indexBy    klice vysledku naplnit hodnotou ze
798
     *                                     sloupečku
799
     * @return array
800
     */
801 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...
802
    {
803
        if (is_int($conditions)) {
804
            $conditions = [$this->getmyKeyColumn() => $conditions];
805
        }
806
807
        $flexiData = $this->getFlexiData('', $conditions);
808
809
        if (!is_null($indexBy)) {
810
            $flexiData = $this->reindexArrayBy($flexiData);
811
        }
812
813
        return $flexiData;
814
    }
815
816
    /**
817
     * Vrací z FlexiBee sloupečky podle podmínek.
818
     *
819
     * @param string[] $columnsList seznam položek
820
     * @param array    $conditions  pole podmínek nebo ID záznamu
821
     * @param string   $indexBy     Sloupeček podle kterého indexovat záznamy
822
     *
823
     * @return array
824
     */
825
    public function getColumnsFromFlexibee($columnsList, $conditions = null,
826
                                           $indexBy = null)
827
    {
828
        if (($columnsList != '*') && !count($columnsList)) {
829
            $this->error('getColumnsFromFlexiBee: Missing ColumnList');
830
831
            return;
832
        }
833
834
        if (is_int($conditions)) {
835
            $conditions = [$this->getmyKeyColumn() => $conditions];
836
        }
837
838
        if (is_array($columnsList)) {
839
            $columns = implode(',', array_unique($columnsList));
840
        } else {
841
            $columns = $columnsList;
842
        }
843
844
        $flexiData = $this->getFlexiData('detail=custom:'.$columns, $conditions);
845
846
        if (!is_null($indexBy)) {
847
            $flexiData = $this->reindexArrayBy($flexiData, $indexBy);
848
        }
849
850
        return $flexiData;
851
    }
852
853
    /**
854
     * Vrací kód záznamu.
855
     *
856
     * @param mixed $data
857
     *
858
     * @todo papat i string
859
     *
860
     * @return string
861
     */
862
    public function getKod($data = null, $unique = true)
863
    {
864
        $kod = null;
865
866
        if (is_null($data)) {
867
            $data = $this->getData();
868
        }
869
870
        if (is_string($data)) {
871
            $data = [$this->nameColumn => $data];
872
        }
873
874
        if (isset($data['kod'])) {
875
            $kod = $data['kod'];
876
        } else {
877
            if (isset($data[$this->nameColumn])) {
878
                $kod = preg_replace('/[^a-zA-Z0-9]/', '',
879
                    \Ease\Sand::rip($data[$this->nameColumn]));
880
            } else {
881
                if (isset($data[$this->myKeyColumn])) {
882
                    $kod = \Ease\Sand::rip($data[$this->myKeyColumn]);
883
                }
884
            }
885
        }
886
887
        if (!strlen($kod)) {
888
            $kod = 'NOTSET';
889
        }
890
891
        if (strlen($kod) > 18) {
892
            $kodfinal = strtoupper(substr($kod, 0, 18));
893
        } else {
894
            $kodfinal = strtoupper($kod);
895
        }
896
897
        if ($unique) {
898
            $counter = 0;
899
            if (count($this->codes)) {
900
                foreach ($this->codes as $codesearch => $keystring) {
901
                    if (strstr($codesearch, $kodfinal)) {
902
                        ++$counter;
903
                    }
904
                }
905
            }
906
            if ($counter) {
907
                $kodfinal = $kodfinal.$counter;
908
            }
909
910
            $this->codes[$kodfinal] = $kod;
911
        }
912
913
        return $kodfinal;
914
    }
915
916
    /**
917
     * Write Operation Result.
918
     *
919
     * @param array  $resultData
920
     * @param string $url        URL
921
     */
922
    public function logResult($resultData = null, $url = null)
923
    {
924
        if (is_null($resultData)) {
925
            $resultData = $this->lastResult;
926
        }
927
        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...
928
            $this->logger->addStatusMessage($url);
929
        }
930
931
        if (isset($resultData['results'])) {
932
            $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...
933
            if ($resultData['success'] == 'false') {
934
                $status = 'error';
935
            } else {
936
                $status = 'success';
937
            }
938
            foreach ($resultData['results'] as $result) {
939
                if (isset($result['request-id'])) {
940
                    $rid = $result['request-id'];
941
                } else {
942
                    $rid = '';
943
                }
944
                if (isset($result['errors'])) {
945
                    foreach ($result['errors'] as $error) {
946
                        $message = $error['message'];
947
                        if (isset($error['for'])) {
948
                            $message .= ' for: '.$error['for'];
949
                        }
950
                        if (isset($error['value'])) {
951
                            $message .= ' value:'.$error['value'];
952
                        }
953
                        if (isset($error['code'])) {
954
                            $message .= ' code:'.$error['code'];
955
                        }
956
                        $this->logger->addStatusMessage($rid.': '.$message,
957
                            $status);
958
                    }
959
                }
960
            }
961
        }
962
        if (is_object($this->logger)) {
963
            $this->logger->flush(get_class($this));
964
        }
965
    }
966
967
    /**
968
     * Save RAW Curl Request & Response to files in Temp directory
969
     */
970
    public function saveDebugFiles()
971
    {
972
        $tmpdir = sys_get_temp_dir();
973
        file_put_contents($tmpdir.'/request-'.$this->evidence.'-'.microtime().'.'.$this->format,
974
            $this->postFields);
975
        file_put_contents($tmpdir.'/response-'.$this->evidence.'-'.microtime().'.'.$this->format,
976
            $this->lastCurlResponse);
977
    }
978
979
    /**
980
     * Připraví data pro odeslání do FlexiBee
981
     * 
982
     * @param string $data
983
     */
984
    public function setPostFields($data)
985
    {
986
        $this->postFields = $data;
0 ignored issues
show
Documentation Bug introduced by
It seems like $data of type string is incompatible with the declared type array of property $postFields.

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...
987
    }
988
989
    /**
990
     * Generuje fragment url pro filtrování.
991
     *
992
     * @see https://www.flexibee.eu/api/dokumentace/ref/filters
993
     *
994
     * @param array  $data
995
     * @param string $operator default and/or
996
     *
997
     * @return string
998
     */
999
    public static function flexiUrl(array $data, $operator = 'and')
1000
    {
1001
        $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...
1002
        $parts    = [];
1003
1004
        foreach ($data as $column => $value) {
1005
            if (is_integer($data[$column]) || is_float($data[$column])) {
1006
                $parts[$column] = $column.' eq '.$data[$column];
1007
            } elseif (is_bool($data[$column])) {
1008
                $parts[$column] = $data[$column] ? $column.' eq true' : $column.' eq false';
1009
            } elseif (is_null($data[$column])) {
1010
                $parts[$column] = $column." is null";
1011
            } elseif ($value == '!null') {
1012
                $parts[$column] = $column." is not null";
1013
            } else {
1014
                $parts[$column] = $column." eq '".$data[$column]."'";
1015
            }
1016
        }
1017
1018
        $flexiUrl = implode(' '.$operator.' ', $parts);
1019
1020
        return $flexiUrl;
1021
    }
1022
1023
    /**
1024
     * Vrací identifikátor objektu code: nebo id:
1025
     *
1026
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1027
     * @return string indentifikátor záznamu reprezentovaného objektem
1028
     * @throws Exception data objektu neobsahují kód nebo id
1029
     */
1030
    public function __toString()
1031
    {
1032
        $myCode = $this->getDataValue('kod');
1033
        if ($myCode) {
1034
            $id = 'code:'.$myCode;
1035
        } else {
1036
            $id = $this->getDataValue('id');
1037
            if (!$id) {
1038
                throw new \Exception(_('invoice without loaded code: or id: cannot match with statement!'));
1039
            }
1040
        }
1041
        return $id;
1042
    }
1043
1044
    /**
1045
     * Gives you FlexiPeeHP class name for Given Evidence
1046
     *
1047
     * @param string $evidence
1048
     * @return string Class name
1049
     */
1050
    static public function evidenceToClassName($evidence)
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
1051
    {
1052
        return str_replace(' ', '', ucwords(str_replace('-', ' ', $evidence)));
1053
    }
1054
1055
    /**
1056
     * Vrací hodnotu daného externího ID
1057
     *
1058
     * @param string $want
1059
     * @return string
1060
     */
1061
    public function getExternalID($want)
1062
    {
1063
        $extid = null;
1064
        $ids   = $this->getDataValue('external-ids');
1065
        if (!is_null($ids)) {
1066
            foreach ($ids as $id) {
0 ignored issues
show
Bug introduced by
The expression $ids of type object|integer|double|string|array|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
1067
                if (strstr($id, 'ext:'.$want)) {
1068
                    $extid = str_replace('ext:'.$want.':', '', $id);
1069
                }
1070
            }
1071
        }
1072
        return $extid;
1073
    }
1074
1075
    /**
1076
     * Vrací aktuální globální verzi změn
1077
     *
1078
     * @link https://www.flexibee.eu/api/dokumentace/ref/changes-api#globalVersion Globální Verze
1079
     * @return type
1080
     */
1081
    public function getGlobalVersion()
1082
    {
1083
        $globalVersion = null;
1084
        if (!count($this->lastResult) || !isset($this->lastResult['@globalVersion'])) {
1085
            $this->getFlexiData(null,
1086
                ['add-global-version' => 'true', 'limit' => 1]);
1087
        }
1088
1089
        if (isset($this->lastResult['@globalVersion'])) {
1090
            $globalVersion = intval($this->lastResult['@globalVersion']);
1091
        }
1092
1093
        return $globalVersion;
1094
    }
1095
}