Test Failed
Push — master ( 85e235...5ad4a7 )
by Vítězslav
02:46
created

FlexiBeeRO::setFormat()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 10
nc 6
nop 1
dl 0
loc 15
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * FlexiPeeHP - Read Only Access to FlexiBee class.
4
 *
5
 * @author     Vítězslav Dvořák <[email protected]>
6
 * @copyright  (C) 2015-2017 Spoje.Net
7
 */
8
9
namespace FlexiPeeHP;
10
11
/**
12
 * Základní třída pro čtení z FlexiBee
13
 *
14
 * @url https://demo.flexibee.eu/devdoc/
15
 */
16
class FlexiBeeRO extends \Ease\Brick
17
{
18
    /**
19
     * Version of FlexiPeeHP library
20
     *
21
     * @var string
22
     */
23
    static public $libVersion = '1.6.4.2';
24
25
    /**
26
     * Základní namespace pro komunikaci s FlexiBee.
27
     * Basic namespace for communication with FlexiBee
28
     *
29
     * @var string Jmený prostor datového bloku odpovědi
30
     */
31
    public $nameSpace = 'winstrom';
32
33
    /**
34
     * URL of object data in FlexiBee
35
     * @var string url
36
     */
37
    public $apiURL = null;
38
39
    /**
40
     * Datový blok v poli odpovědi.
41
     * Data block in response field.
42
     *
43
     * @var string
44
     */
45
    public $resultField = 'results';
46
47
    /**
48
     * Verze protokolu použitého pro komunikaci.
49
     * Communication protocol version used.
50
     *
51
     * @var string Verze použitého API
52
     */
53
    public $protoVersion = '1.0';
54
55
    /**
56
     * Evidence užitá objektem.
57
     * Evidence used by object
58
     *
59
     * @link https://demo.flexibee.eu/c/demo/evidence-list Přehled evidencí
60
     * @var string
61
     */
62
    public $evidence = null;
63
64
    /**
65
     * Výchozí formát pro komunikaci.
66
     * Default communication format.
67
     *
68
     * @link https://www.flexibee.eu/api/dokumentace/ref/format-types Přehled možných formátů
69
     *
70
     * @var string json|xml|...
71
     */
72
    public $format = 'json';
73
74
    /**
75
     * formát příchozí odpovědi
76
     * response format
77
     *
78
     * @link https://www.flexibee.eu/api/dokumentace/ref/format-types Přehled možných formátů
79
     *
80
     * @var string json|xml|...
81
     */
82
    public $responseFormat = 'json';
83
84
    /**
85
     * Curl Handle.
86
     *
87
     * @var resource
88
     */
89
    public $curl = null;
90
91
    /**
92
     * @link https://demo.flexibee.eu/devdoc/company-identifier Identifikátor firmy
93
     * @var string
94
     */
95
    public $company = null;
96
97
    /**
98
     * Server[:port]
99
     * @var string
100
     */
101
    public $url = null;
102
103
    /**
104
     * REST API Username
105
     * @var string
106
     */
107
    public $user = null;
108
109
    /**
110
     * REST API Password
111
     * @var string
112
     */
113
    public $password = null;
114
115
    /**
116
     * @var array Pole HTTP hlaviček odesílaných s každým požadavkem
117
     */
118
    public $defaultHttpHeaders = ['User-Agent' => 'FlexiPeeHP'];
119
120
    /**
121
     * Default additional request url parameters after question mark
122
     *
123
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls   Common params
124
     * @link https://www.flexibee.eu/api/dokumentace/ref/paging Paging params
125
     * @var array
126
     */
127
    public $defaultUrlParams = ['limit' => 0];
128
129
    /**
130
     * Identifikační řetězec.
131
     *
132
     * @var string
133
     */
134
    public $init = null;
135
136
    /**
137
     * Sloupeček s názvem.
138
     *
139
     * @var string
140
     */
141
    public $nameColumn = 'nazev';
142
143
    /**
144
     * Sloupeček obsahující datum vložení záznamu do shopu.
145
     *
146
     * @var string
147
     */
148
    public $myCreateColumn = 'false';
149
150
    /**
151
     * Slopecek obsahujici datum poslení modifikace záznamu do shopu.
152
     *
153
     * @var string
154
     */
155
    public $myLastModifiedColumn = 'lastUpdate';
156
157
    /**
158
     * Klíčový idendifikátor záznamu.
159
     *
160
     * @var string
161
     */
162
    public $fbKeyColumn = 'id';
163
164
    /**
165
     * Informace o posledním HTTP requestu.
166
     *
167
     * @var *
168
     */
169
    public $curlInfo;
170
171
    /**
172
     * Informace o poslední HTTP chybě.
173
     *
174
     * @var string
175
     */
176
    public $lastCurlError = null;
177
178
    /**
179
     * Used codes storage.
180
     *
181
     * @var array
182
     */
183
    public $codes = null;
184
185
    /**
186
     * Last Inserted ID.
187
     *
188
     * @var int
189
     */
190
    public $lastInsertedID = null;
191
192
    /**
193
     * Default Line Prefix.
194
     *
195
     * @var string
196
     */
197
    public $prefix = '/c/';
198
199
    /**
200
     * Raw Content of last curl response
201
     *
202
     * @var string
203
     */
204
    public $lastCurlResponse;
205
206
    /**
207
     * HTTP Response code of last request
208
     *
209
     * @var int
210
     */
211
    public $lastResponseCode = null;
212
213
    /**
214
     * Body data  for next curl POST operation
215
     *
216
     * @var string
217
     */
218
    protected $postFields = null;
219
220
    /**
221
     * Last operation result data or message(s)
222
     *
223
     * @var array
224
     */
225
    public $lastResult = null;
226
227
    /**
228
     * Nuber from  @rowCount
229
     * @var int
230
     */
231
    public $rowCount = null;
232
233
    /**
234
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
235
     * @var string
236
     */
237
    protected $action;
238
239
    /**
240
     * Pole akcí které podporuje ta která evidence
241
     * @link https://demo.flexibee.eu/c/demo/faktura-vydana/actions.json Např. Akce faktury
242
     * @var array
243
     */
244
    public $actionsAvailable = null;
245
246
    /**
247
     * Parmetry pro URL
248
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Všechny podporované parametry
249
     * @var array
250
     */
251
    public $urlParams = [
252
        'idUcetniObdobi',
253
        'dry-run',
254
        'fail-on-warning',
255
        'report-name',
256
        'report-lang',
257
        'report-sign',
258
        'detail', //See: https://www.flexibee.eu/api/dokumentace/ref/detail-levels
259
        'mode',
260
        'limit',
261
        'start',
262
        'order',
263
        'sort',
264
        'add-row-count',
265
        'relations',
266
        'includes',
267
        'use-ext-id',
268
        'use-internal-id',
269
        'stitky-as-ids',
270
        'only-ext-ids',
271
        'no-ext-ids',
272
        'no-ids',
273
        'code-as-id',
274
        'no-http-errors',
275
        'export-settings',
276
        'as-gui',
277
        'code-in-response',
278
        'add-global-version',
279
        'encoding',
280
        'delimeter',
281
        'format',
282
        'auth',
283
        'skupina-stitku',
284
        'dir',
285
        'relations',
286
        'relations',
287
        'xpath', // See: https://www.flexibee.eu/api/dokumentace/ref/xpath/
288
        'dry-run', // See: https://www.flexibee.eu/api/dokumentace/ref/dry-run/
289
        'inDesktopApp' // Note: Undocumented function (html only)
290
    ];
291
292
    /**
293
     * Save 404 results to log ?
294
     * @var boolean
295
     */
296
    protected $ignoreNotFound = false;
297
298
    /**
299
     * Array of errors caused by last request
300
     * @var array
301
     */
302
    private $errors = [];
303
304
    /**
305
     * Class for read only interaction with FlexiBee.
306
     *
307
     * @param mixed $init default record id or initial data
308
     * @param array $options Connection settings override
309
     */
310
    public function __construct($init = null, $options = [])
311
    {
312
        $this->init = $init;
313
314
        parent::__construct();
315
        $this->setUp($options);
316
        $this->curlInit();
317
        if (!is_null($init)) {
318
            $this->processInit($init);
319
        }
320
    }
321
322
    /**
323
     * SetUp Object to be ready for connect
324
     *
325
     * @param array $options Object Options (company,url,user,password,evidence,
326
     *                                       prefix,debug)
327
     */
328
    public function setUp($options = [])
329
    {
330
        if (isset($options['company'])) {
331
            $this->company = $options['company'];
332
        } else {
333
            if (is_null($this->company) && defined('FLEXIBEE_COMPANY')) {
334
                $this->company = constant('FLEXIBEE_COMPANY');
335
            }
336
        }
337
        if (isset($options['url'])) {
338
            $this->url = $options['url'];
339
        } else {
340
            if (is_null($this->url) && defined('FLEXIBEE_URL')) {
341
                $this->url = constant('FLEXIBEE_URL');
342
            }
343
        }
344
        if (isset($options['user'])) {
345
            $this->user = $options['user'];
346
        } else {
347
            if (is_null($this->user) && defined('FLEXIBEE_LOGIN')) {
348
                $this->user = constant('FLEXIBEE_LOGIN');
349
            }
350
        }
351
        if (isset($options['password'])) {
352
            $this->password = $options['password'];
353
        } else {
354
            if (is_null($this->password) && defined('FLEXIBEE_PASSWORD')) {
355
                $this->password = constant('FLEXIBEE_PASSWORD');
356
            }
357
        }
358
        if (isset($options['evidence'])) {
359
            $this->setEvidence($options['evidence']);
360
        }
361
        if (isset($options['prefix'])) {
362
            $this->setPrefix($options['prefix']);
363
        }
364
        if (isset($options['debug'])) {
365
            $this->debug = $options['debug'];
366
        }
367
    }
368
369
    /**
370
     * Inicializace CURL
371
     */
372
    public function curlInit()
373
    {
374
        $this->curl = \curl_init(); // create curl resource
375
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); // return content as a string from curl_exec
376
        curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); // follow redirects (compatibility for future changes in FlexiBee)
377
        curl_setopt($this->curl, CURLOPT_HTTPAUTH, true);       // HTTP authentication
378
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); // FlexiBee by default uses Self-Signed certificates
379
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
380
        curl_setopt($this->curl, CURLOPT_VERBOSE, ($this->debug === true)); // For debugging
381
        curl_setopt($this->curl, CURLOPT_USERPWD,
382
            $this->user.':'.$this->password); // set username and password
383
    }
384
385
    /**
386
     * Zinicializuje objekt dle daných dat
387
     *
388
     * @param mixed $init
389
     */
390
    public function processInit($init)
391
    {
392
        if (is_integer($init)) {
393
            $this->loadFromFlexiBee($init);
394
        } elseif (is_array($init)) {
395
            $this->takeData($init);
396
        } elseif (strstr($init, 'code:')) {
397
            $this->loadFromFlexiBee($init);
398
        }
399
    }
400
401
    /**
402
     * Set URL prefix
403
     *
404
     * @param string $prefix
405
     */
406
    public function setPrefix($prefix)
407
    {
408
        switch ($prefix) {
409
            case 'a': //Access
410
            case 'c': //Company
411
            case 'u': //User
412
            case 'g': //License Groups
413
            case 'admin':
414
            case 'status':
415
            case 'login-logout':
416
                $this->prefix = '/'.$prefix.'/';
417
                break;
418
            case null:
419
            case '':
420
            case '/':
421
                $this->prefix = '';
422
                break;
423
            default:
424
                throw new \Exception(sprintf('Unknown prefix %s', $prefix));
425
                break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
426
        }
427
    }
428
429
    /**
430
     * Set communication format.
431
     * One of html|xml|json|csv|dbf|xls|isdoc|isdocx|edi|pdf|pdf|vcf|ical
432
     *
433
     * @param string $format
434
     * @return boolen format is availble
435
     */
436
    public function setFormat($format)
437
    {
438
        $result = true;
439
        if (($this->debug === true) && isset(Formats::$$evidence)) {
0 ignored issues
show
Bug introduced by
The variable $evidence seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
440
            $evidence = lcfirst(FlexiBeeRO::evidenceToClassName($this->getEvidence()));
441
            if (array_key_exists($format, array_flip(Formats::$$evidence)) === false) {
442
                $result = false;
443
            }
444
        }
445
        if ($result === true) {
446
            $this->format = $format;
447
            $this->updateApiURL();
448
        }
449
        return $result;
450
    }
451
452
    /**
453
     * Nastaví Evidenci pro Komunikaci.
454
     * Set evidence for communication
455
     *
456
     * @param string $evidence evidence pathName to use
457
     * @return boolean evidence switching status
458
     */
459
    public function setEvidence($evidence)
460
    {
461
        $result = null;
0 ignored issues
show
Unused Code introduced by
$result 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...
462
        switch ($this->prefix) {
463
            case '/c/':
464
                if (array_key_exists($evidence, EvidenceList::$name)) {
465
                    $this->evidence = $evidence;
466
                    $result         = true;
467
                } else {
468
                    throw new \Exception(sprintf('Try to set unsupported evidence %s',
469
                        $evidence));
470
                }
471
                break;
472
            default:
473
                $this->evidence = $evidence;
474
                $result         = true;
475
                break;
476
        }
477
        $this->updateApiURL();
478
        return $result;
479
    }
480
481
    /**
482
     * Vrací právě používanou evidenci pro komunikaci
483
     * Obtain current used evidence
484
     *
485
     * @return string
486
     */
487
    public function getEvidence()
488
    {
489
        return $this->evidence;
490
    }
491
492
    /**
493
     * Set used company.
494
     * Nastaví Firmu.
495
     *
496
     * @param string $company
497
     */
498
    public function setCompany($company)
499
    {
500
        $this->company = $company;
501
    }
502
503
    /**
504
     * Obtain company now used
505
     * Vrací právě používanou firmu
506
     *
507
     * @return string
508
     */
509
    public function getCompany()
510
    {
511
        return $this->company;
512
    }
513
514
    /**
515
     * Vrací název evidence použité v odpovědích z FlexiBee
516
     *
517
     * @return string
518
     */
519
    public function getResponseEvidence()
520
    {
521
        switch ($this->evidence) {
522
            case 'c':
523
                $evidence = 'company';
524
                break;
525
            case 'evidence-list':
526
                $evidence = 'evidences';
527
                break;
528
            default:
529
                $evidence = $this->getEvidence();
530
                break;
531
        }
532
        return $evidence;
533
    }
534
535
    /**
536
     * Převede rekurzivně Objekt na pole.
537
     *
538
     * @param object|array $object
539
     *
540
     * @return array
541
     */
542
    public static function object2array($object)
543
    {
544
        $result = null;
545
        if (is_object($object)) {
546
            $objectData = get_object_vars($object);
547
            if (is_array($objectData) && count($objectData)) {
548
                $result = array_map('self::object2array', $objectData);
549
            }
550 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...
551
            if (is_array($object)) {
552
                foreach ($object as $item => $value) {
553
                    $result[$item] = self::object2array($value);
554
                }
555
            } else {
556
                $result = $object;
557
            }
558
        }
559
560
        return $result;
561
    }
562
563
    /**
564
     * Převede rekurzivně v poli všechny objekty na jejich identifikátory.
565
     *
566
     * @param object|array $object
567
     *
568
     * @return array
569
     */
570
    public static function objectToID($object)
571
    {
572
        $result = null;
573
        if (is_object($object)) {
574
            $result = $object->__toString();
575 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...
576
            if (is_array($object)) {
577
                foreach ($object as $item => $value) {
578
                    $result[$item] = self::objectToID($value);
579
                }
580
            } else { //String
581
                $result = $object;
582
            }
583
        }
584
585
        return $result;
586
    }
587
588
    /**
589
     * Return basic URL for used Evidence
590
     *
591
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
592
     * @param string $urlSuffix
593
     */
594
    public function getEvidenceURL($urlSuffix = null)
595
    {
596
        if (is_null($urlSuffix)) {
597
            $urlSuffix = $this->getEvidence();
598
        } elseif ($urlSuffix[0] == ';') {
599
            $urlSuffix = $this->getEvidence().$urlSuffix;
600
        }
601
        return $this->url.$this->prefix.$this->company.'/'.$urlSuffix;
602
    }
603
604
    /**
605
     * Update $this->apiURL
606
     */
607
    public function updateApiURL()
608
    {
609
        $this->apiURL = $this->getEvidenceURL();
610
        $id           = $this->__toString();
611
        if (!is_null($id)) {
612
            $this->apiURL .= '/'.urlencode($id);
613
        }
614
        $this->apiURL .= '.'.$this->format;
615
    }
616
617
    /**
618
     * Funkce, která provede I/O operaci a vyhodnotí výsledek.
619
     *
620
     * @param string $urlSuffix část URL za identifikátorem firmy.
621
     * @param string $method    HTTP/REST metoda
622
     * @param string $format    Requested format
623
     * @return array|boolean Výsledek operace
624
     */
625
    public function performRequest($urlSuffix = null, $method = 'GET',
626
                                   $format = null)
627
    {
628
        $response       = null;
0 ignored issues
show
Unused Code introduced by
$response 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...
629
        $result         = null;
0 ignored issues
show
Unused Code introduced by
$result 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...
630
        $this->rowCount = null;
631
632
        if (preg_match('/^http/', $urlSuffix)) {
633
            $url = $urlSuffix;
634
        } else {
635
            $url = $this->getEvidenceURL($urlSuffix);
636
        }
637
638
        $responseCode = $this->doCurlRequest($url, $method, $format);
639
640
        return strlen($this->lastCurlResponse) ? $this->parseResponse($this->rawResponseToArray($this->lastCurlResponse,
641
                    $this->responseFormat, $method), $responseCode) : null;
642
    }
643
644
    /**
645
     * Parse Raw FlexiBee response in several formats
646
     *
647
     * @param string $responseRaw raw response body
648
     * @param string $format      Raw Response format json|xml|etc
649
     * @param string $method      Http method GET|POST|etc
650
     *
651
     * @return array
652
     */
653
    public function rawResponseToArray($responseRaw, $format, $method)
0 ignored issues
show
Unused Code introduced by
The parameter $method 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...
654
    {
655
        switch ($format) {
656
            case 'json':
657
                $responseDecoded = json_decode($responseRaw, true, 10);
658
                $decodeError     = json_last_error_msg();
659
                if ($decodeError != 'No error') {
660
                    $this->addStatusMessage($decodeError, 'error');
661
                }
662
                if (array_key_exists($this->nameSpace, $responseDecoded)) {
663
                    $responseDecoded = $responseDecoded[$this->nameSpace];
664
                }
665
                break;
666
            case 'xml':
667
                $responseDecoded = self::xml2array($this->lastCurlResponse);
668
                break;
669
            case 'txt':
670
            default:
671
                $responseDecoded = $this->lastCurlResponse;
672
                break;
673
        }
674
        return $responseDecoded;
675
    }
676
677
    /**
678
     * Parse Response array
679
     * 
680
     * @param array $responseDecoded
681
     * @param int $responseCode Request Response Code
682
     *
683
     * @return array main data part of response
684
     */
685
    public function parseResponse($responseDecoded, $responseCode)
686
    {
687
        switch ($responseCode) {
688
            case 201:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
689
                if (isset($responseDecoded[$this->resultField][0]['id'])) {
690
                    $this->lastInsertedID = $responseDecoded[$this->nameSpace][$this->resultField][0]['id'];
691
                    $this->setMyKey($this->lastInsertedID);
692
                    $this->apiURL         = $this->getEvidenceURL().'/'.$this->lastInsertedID;
693
                } else {
694
                    $this->lastInsertedID = null;
695
                    if (isset($responseDecoded[$this->nameSpace]['@rowCount'])) {
696
                        $this->rowCount = (int) $responseDecoded[$this->nameSpace]['@rowCount'];
697
                    }
698
                }
699
            case 200:
700
                $response         = $this->lastResult = $this->unifyResponseFormat($responseDecoded);
701
                break;
702
703
            case 404:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
704
                if ($this->ignoreNotFound === true) {
705
                    break;
706
                }
707
            case 400:
708
            default: //Something goes wrong
709
                $this->addStatusMessage($this->curlInfo['url'], 'warning');
710
                $this->parseError($responseDecoded);
711
712
                $this->logResult($response, $url);
0 ignored issues
show
Bug introduced by
The variable $response seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
Bug introduced by
The variable $url does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
713
                break;
714
        }
715
        return $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...
716
    }
717
718
    public function parseError($responseDecoded)
719
    {
720
        $errorInfo = $responseDecoded[$this->nameSpace];
721
722
        if (is_array($responseDecoded) && array_key_exists('results',
723
                $responseDecoded[$this->nameSpace])) {
724
            $this->errors = $responseDecoded[$this->nameSpace]['results'][0]['errors'];
725
        } else {
726
            $this->errors = [['message' => $errorInfo['message']]];
727
        }
728
        foreach ($this->errors as $error) {
729
            $this->addStatusMessage($error['message'], 'error');
730
        }
731
        return count($this->errors);
732
    }
733
734
    /**
735
     * Vykonej HTTP požadavek
736
     *
737
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
738
     * @param string $url    URL požadavku
739
     * @param string $method HTTP Method GET|POST|PUT|OPTIONS|DELETE
740
     * @param string $format požadovaný formát komunikace
741
     * @return int HTTP Response CODE
742
     */
743
    public function doCurlRequest($url, $method, $format = null)
744
    {
745
        if (is_null($format)) {
746
            $format = $this->format;
747
        }
748
        curl_setopt($this->curl, CURLOPT_URL, $url);
749
// Nastavení samotné operace
750
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, strtoupper($method));
751
//Vždy nastavíme byť i prázná postdata jako ochranu před chybou 411
752
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->postFields);
753
754
        $httpHeaders = $this->defaultHttpHeaders;
755
756
        $formats = $this->reindexArrayBy(Formats::$formats, 'suffix');
757
758
        if (!isset($httpHeaders['Accept'])) {
759
            $httpHeaders['Accept'] = $formats[$format]['content-type'];
760
        }
761
        if (!isset($httpHeaders['Content-Type'])) {
762
            $httpHeaders['Content-Type'] = $formats[$format]['content-type'];
763
        }
764
        $httpHeadersFinal = [];
765
        foreach ($httpHeaders as $key => $value) {
766
            if (($key == 'User-Agent') && ($value == 'FlexiPeeHP')) {
767
                $value .= ' v'.self::$libVersion;
768
            }
769
            $httpHeadersFinal[] = $key.': '.$value;
770
        }
771
772
        curl_setopt($this->curl, CURLOPT_HTTPHEADER, $httpHeadersFinal);
773
774
// Proveď samotnou operaci
775
        $this->lastCurlResponse = curl_exec($this->curl);
776
        $this->curlInfo         = curl_getinfo($this->curl);
777
        $this->responseFormat   = Formats::contentTypeToSuffix($this->curlInfo['content_type']);
778
        $this->lastResponseCode = $this->curlInfo['http_code'];
779
        $this->lastCurlError    = curl_error($this->curl);
780
        if (strlen($this->lastCurlError)) {
781
            $this->addStatusMessage(sprintf('Curl Error (HTTP %d): %s',
782
                    $this->lastResponseCode, $this->lastCurlError), 'error');
783
        }
784
785
        if ($this->debug === true) {
786
            $this->saveDebugFiles();
787
        }
788
789
        return $this->lastResponseCode;
790
    }
791
792
    /**
793
     * Nastaví druh prováděné akce.
794
     *
795
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
796
     * @param string $action
797
     * @return boolean
798
     */
799
    public function setAction($action)
800
    {
801
        $result           = false;
802
        $actionsAvailable = $this->getActionsInfo();
803
        if (array_key_exists($action, $actionsAvailable)) {
804
            $this->action = $action;
805
            $result       = true;
806
        }
807
        return $result;
808
    }
809
810
    /**
811
     * Convert XML to array.
812
     *
813
     * @param string $xml
814
     *
815
     * @return array
816
     */
817
    public static function xml2array($xml)
818
    {
819
        $arr = [];
820
821
        if (is_string($xml)) {
822
            $xml = simplexml_load_string($xml);
823
        }
824
825
        foreach ($xml->children() as $r) {
826
            if (count($r->children()) == 0) {
827
                $arr[$r->getName()] = strval($r);
828
            } else {
829
                $arr[$r->getName()][] = self::xml2array($r);
830
            }
831
        }
832
833
        return $arr;
834
    }
835
836
    /**
837
     * Odpojení od FlexiBee.
838
     */
839
    public function disconnect()
840
    {
841
        if (is_resource($this->curl)) {
842
            curl_close($this->curl);
843
        }
844
        $this->curl = null;
845
    }
846
847
    /**
848
     * Disconnect CURL befere pass away
849
     */
850
    public function __destruct()
851
    {
852
        $this->disconnect();
853
    }
854
855
    /**
856
     * Načte řádek dat z FlexiBee.
857
     *
858
     * @param int $recordID id požadovaného záznamu
859
     *
860
     * @return array
861
     */
862
    public function getFlexiRow($recordID)
863
    {
864
        $record   = null;
865
        $response = $this->performRequest($this->evidence.'/'.$recordID.'.json');
866
        if (isset($response[$this->evidence])) {
867
            $record = $response[$this->evidence][0];
868
        }
869
870
        return $record;
871
    }
872
873
    /**
874
     * Oddělí z pole podmínek ty jenž patří za ? v URL požadavku
875
     *
876
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
877
     * @param array $conditions pole podmínek   - rendrují se do ()
878
     * @param array $urlParams  pole parametrů  - rendrují za ?
879
     */
880
    public function extractUrlParams(&$conditions, &$urlParams)
881
    {
882
        foreach ($this->urlParams as $urlParam) {
883
            if (isset($conditions[$urlParam])) {
884
                \Ease\Sand::divDataArray($conditions, $urlParams, $urlParam);
885
            }
886
        }
887
    }
888
889
    /**
890
     * Načte data z FlexiBee.
891
     *
892
     * @param string $suffix     dotaz
893
     * @param string|array $conditions Volitelný filtrovací výraz
894
     */
895
    public function getFlexiData($suffix = null, $conditions = null)
896
    {
897
        $urlParams = $this->defaultUrlParams;
898
        if (!is_null($conditions)) {
899
            if (is_array($conditions)) {
900
                $this->extractUrlParams($conditions, $urlParams);
901
                $conditions = $this->flexiUrl($conditions);
902
            }
903
904
            if (strlen($conditions) && ($conditions[0] != '/')) {
905
                $conditions = '/'.rawurlencode('('.($conditions).')');
906
            }
907
        } else {
908
            $conditions = '';
909
        }
910
911
        if (preg_match('/^http/', $suffix)) {
912
            $transactions = $this->performRequest($suffix, 'GET');
913
        } else {
914
            if (strlen($suffix)) {
915
                $transactions = $this->performRequest($this->evidence.$conditions.'.'.$this->format.'?'.$suffix.'&'.http_build_query($urlParams),
916
                    'GET');
917
            } else {
918
                $transactions = $this->performRequest($this->evidence.$conditions.'.'.$this->format.'?'.http_build_query($urlParams),
919
                    'GET');
920
            }
921
        }
922
        if (isset($transactions[$this->evidence])) {
923
            $result = $transactions[$this->evidence];
924
            if ((count($result) == 1) && (count(current($result)) == 0 )) {
925
                $result = null; // Response is empty Array
926
            }
927
        } else {
928
            $result = $transactions;
929
        }
930
931
        return $result;
932
    }
933
934
    /**
935
     * Načte záznam z FlexiBee.
936
     *
937
     * @param int $id ID záznamu
938
     *
939
     * @return int počet načtených položek
940
     */
941
    public function loadFromFlexiBee($id = null)
942
    {
943
        $data = [];
944
        if (is_null($id)) {
945
            $id = $this->getMyKey();
946
        }
947
948
        $flexidata    = $this->getFlexiData(null, '/'.$id);
949
        $this->apiURL = $this->curlInfo['url'];
950
        if (is_array($flexidata) && (count($flexidata) == 1)) {
951
            $data = current($flexidata);
952
        }
953
        return $this->takeData($data);
954
    }
955
956
    /**
957
     * Převede data do Json formátu pro FlexiBee.
958
     * Convert data to FlexiBee like Json format
959
     *
960
     * @param array $data
961
     *
962
     * @return string
963
     */
964
    public function jsonizeData($data)
965
    {
966
        $jsonize = [
967
            $this->nameSpace => [
968
                '@version' => $this->protoVersion,
969
                $this->evidence => $this->objectToID($data),
970
            ],
971
        ];
972
973
        if (!is_null($this->action)) {
974
            $jsonize[$this->nameSpace][$this->evidence.'@action'] = $this->action;
975
            $this->action                                         = null;
976
        }
977
978
        return json_encode($jsonize);
979
    }
980
981
    /**
982
     * Test if given record ID exists in FlexiBee.
983
     *
984
     * @param string|int $identifer
985
     */
986
    public function idExists($identifer = null)
987
    {
988
        if (is_null($identifer)) {
989
            $identifer = $this->getMyKey();
990
        }
991
        $flexiData = $this->getFlexiData(
992
            'detail=custom:'.$this->getmyKeyColumn(), $identifer);
993
994
        return $flexiData;
995
    }
996
997
    /**
998
     * Test if given record exists in FlexiBee.
999
     *
1000
     * @param array $data
1001
     * @return boolean Record presence status
1002
     */
1003
    public function recordExists($data = null)
1004
    {
1005
1006
        if (is_null($data)) {
1007
            $data = $this->getData();
1008
        }
1009
1010
        $res = $this->getColumnsFromFlexibee([$this->myKeyColumn],
1011
            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...
1012
1013
        if (!count($res) || (isset($res['success']) && ($res['success'] == 'false'))
1014
            || !count($res[0])) {
1015
            $found = false;
1016
        } else {
1017
            $found = true;
1018
        }
1019
        return $found;
1020
    }
1021
1022
    /**
1023
     * Vrací z FlexiBee sloupečky podle podmínek.
1024
     *
1025
     * @param array|int|string $conditions pole podmínek nebo ID záznamu
1026
     * @param string           $indexBy    klice vysledku naplnit hodnotou ze
1027
     *                                     sloupečku
1028
     * @return array
1029
     */
1030
    public function getAllFromFlexibee($conditions = null, $indexBy = null)
1031
    {
1032
        if (is_int($conditions)) {
1033
            $conditions = [$this->getmyKeyColumn() => $conditions];
1034
        }
1035
1036
        $flexiData = $this->getFlexiData('', $conditions);
1037
1038
        if (!is_null($indexBy)) {
1039
            $flexiData = $this->reindexArrayBy($flexiData);
1040
        }
1041
1042
        return $flexiData;
1043
    }
1044
1045
    /**
1046
     * Vrací z FlexiBee sloupečky podle podmínek.
1047
     *
1048
     * @param string[] $columnsList seznam položek
1049
     * @param array    $conditions  pole podmínek nebo ID záznamu
1050
     * @param string   $indexBy     Sloupeček podle kterého indexovat záznamy
1051
     *
1052
     * @return array
1053
     */
1054
    public function getColumnsFromFlexibee($columnsList, $conditions = null,
1055
                                           $indexBy = null)
1056
    {
1057
        $detail = 'full';
1058
        switch (gettype($columnsList)) {
1059
            case 'integer':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1060
                $conditions = [$this->getmyKeyColumn() => $conditions];
1061
            case 'array':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1062
                if (!is_null($indexBy) && !array_key_exists($indexBy,
1063
                        $columnsList)) {
1064
                    $columnsList[] = $indexBy;
1065
                }
1066
                $columns = implode(',', array_unique($columnsList));
1067
                $detail  = 'custom:'.$columns;
1068
            default:
1069
                switch ($columnsList) {
1070
                    case 'id':
1071
                        $detail = 'id';
1072
                        break;
1073
                    case 'summary':
1074
                        $detail = 'summary';
1075
                        break;
1076
                    default:
1077
                        break;
1078
                }
1079
                break;
1080
        }
1081
1082
        $flexiData = $this->getFlexiData('detail='.$detail, $conditions);
1083
1084
        if (!is_null($indexBy) && count($flexiData) && count(current($flexiData))) {
1085
            $flexiData = $this->reindexArrayBy($flexiData, $indexBy);
1086
        }
1087
1088
        return $flexiData;
1089
    }
1090
1091
    /**
1092
     * Vrací kód záznamu.
1093
     *
1094
     * @param mixed $data
1095
     *
1096
     * @return string
1097
     */
1098
    public function getKod($data = null, $unique = true)
1099
    {
1100
        $kod = null;
1101
1102
        if (is_null($data)) {
1103
            $data = $this->getData();
1104
        }
1105
1106
        if (is_string($data)) {
1107
            $data = [$this->nameColumn => $data];
1108
        }
1109
1110
        if (isset($data['kod'])) {
1111
            $kod = $data['kod'];
1112
        } else {
1113
            if (isset($data[$this->nameColumn])) {
1114
                $kod = preg_replace('/[^a-zA-Z0-9]/', '',
1115
                    \Ease\Sand::rip($data[$this->nameColumn]));
1116
            } else {
1117
                if (isset($data[$this->myKeyColumn])) {
1118
                    $kod = \Ease\Sand::rip($data[$this->myKeyColumn]);
1119
                }
1120
            }
1121
        }
1122
1123
        if (!strlen($kod)) {
1124
            $kod = 'NOTSET';
1125
        }
1126
1127
        if (strlen($kod) > 18) {
1128
            $kodfinal = strtoupper(substr($kod, 0, 18));
1129
        } else {
1130
            $kodfinal = strtoupper($kod);
1131
        }
1132
1133
        if ($unique) {
1134
            $counter = 0;
1135
            if (count($this->codes)) {
1136
                foreach ($this->codes as $codesearch => $keystring) {
1137
                    if (strstr($codesearch, $kodfinal)) {
1138
                        ++$counter;
1139
                    }
1140
                }
1141
            }
1142
            if ($counter) {
1143
                $kodfinal = $kodfinal.$counter;
1144
            }
1145
1146
            $this->codes[$kodfinal] = $kod;
1147
        }
1148
1149
        return $kodfinal;
1150
    }
1151
1152
    /**
1153
     * Write Operation Result.
1154
     *
1155
     * @param array  $resultData
1156
     * @param string $url        URL
1157
     * @return boolean Log save success
1158
     */
1159
    public function logResult($resultData = null, $url = null)
1160
    {
1161
        $logResult = false;
1162
        if (isset($resultData['success']) && ($resultData['success'] == 'false')) {
1163
            if (isset($resultData['message'])) {
1164
                $this->addStatusMessage($resultData['message'], 'warning');
1165
            }
1166
            $this->addStatusMessage('Error '.$this->lastResponseCode.': '.urldecode($url),
1167
                'warning');
1168
            unset($url);
1169
        }
1170
        if (is_null($resultData)) {
1171
            $resultData = $this->lastResult;
1172
        }
1173
        if (isset($url)) {
1174
            $this->logger->addStatusMessage(urldecode($url));
1175
        }
1176
1177
        if (isset($resultData['results'])) {
1178
            $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...
1179
            if ($resultData['success'] == 'false') {
1180
                $status = 'error';
1181
            } else {
1182
                $status = 'success';
1183
            }
1184
            foreach ($resultData['results'] as $result) {
1185
                if (isset($result['request-id'])) {
1186
                    $rid = $result['request-id'];
1187
                } else {
1188
                    $rid = '';
1189
                }
1190
                if (isset($result['errors'])) {
1191
                    foreach ($result['errors'] as $error) {
1192
                        $message = $error['message'];
1193
                        if (isset($error['for'])) {
1194
                            $message .= ' for: '.$error['for'];
1195
                        }
1196
                        if (isset($error['value'])) {
1197
                            $message .= ' value:'.$error['value'];
1198
                        }
1199
                        if (isset($error['code'])) {
1200
                            $message .= ' code:'.$error['code'];
1201
                        }
1202
                        $this->addStatusMessage($rid.': '.$message, $status);
1203
                    }
1204
                }
1205
            }
1206
        }
1207
        return $logResult;
1208
    }
1209
1210
    /**
1211
     * Save RAW Curl Request & Response to files in Temp directory
1212
     */
1213
    public function saveDebugFiles()
1214
    {
1215
        $tmpdir = sys_get_temp_dir();
1216
        file_put_contents($tmpdir.'/request-'.$this->evidence.'-'.microtime().'.'.$this->format,
1217
            $this->postFields);
1218
        file_put_contents($tmpdir.'/response-'.$this->evidence.'-'.microtime().'.'.$this->format,
1219
            $this->lastCurlResponse);
1220
    }
1221
1222
    /**
1223
     * Připraví data pro odeslání do FlexiBee
1224
     *
1225
     * @param string $data
1226
     */
1227
    public function setPostFields($data)
1228
    {
1229
        $this->postFields = $data;
1230
    }
1231
1232
    /**
1233
     * Generuje fragment url pro filtrování.
1234
     *
1235
     * @see https://www.flexibee.eu/api/dokumentace/ref/filters
1236
     *
1237
     * @param array  $data
1238
     * @param string $joiner default and/or
1239
     * @param string $defop  default operator
1240
     *
1241
     * @return string
1242
     */
1243
    public static function flexiUrl(array $data, $joiner = 'and', $defop = 'eq')
1244
    {
1245
        $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...
1246
        $parts    = [];
1247
1248
        foreach ($data as $column => $value) {
1249
            if (is_integer($data[$column]) || is_float($data[$column])) {
1250
                $parts[$column] = $column.' eq \''.$data[$column].'\'';
1251
            } elseif (is_bool($data[$column])) {
1252
                $parts[$column] = $data[$column] ? $column.' eq true' : $column.' eq false';
1253
            } elseif (is_null($data[$column])) {
1254
                $parts[$column] = $column." is null";
1255
            } else {
1256
                switch ($value) {
1257
                    case '!null':
1258
                        $parts[$column] = $column." is not null";
1259
                        break;
1260
                    case 'is empty':
1261
                    case 'is not empty':
1262
                        $parts[$column] = $column.' '.$value;
1263
                        break;
1264
                    default:
1265
                        $parts[$column] = $column." $defop '".$data[$column]."'";
1266
                        break;
1267
                }
1268
            }
1269
        }
1270
1271
        $flexiUrl = implode(' '.$joiner.' ', $parts);
1272
1273
        return $flexiUrl;
1274
    }
1275
1276
    /**
1277
     * Obtain record/object identificator code: or id:
1278
     * Vrací identifikátor objektu code: nebo id:
1279
     *
1280
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1281
     * @return string|int indentifikátor záznamu reprezentovaného objektem
1282
     */
1283
    public function getRecordID()
1284
    {
1285
        $myCode = $this->getDataValue('kod');
1286
        if ($myCode) {
1287
            $id = 'code:'.$myCode;
1288
        } else {
1289
            $id = $this->getDataValue('id');
1290
            if (($this->debug === true) && is_null($id)) {
1291
                $this->addToLog('Object Data does not contain code: or id: cannot match with statement!',
1292
                    'warning');
1293
            }
1294
        }
1295
        return is_numeric($id) ? intval($id) : strval($id);
1296
    }
1297
1298
    /**
1299
     * Obtain record/object identificator code: or id:
1300
     * Vrací identifikátor objektu code: nebo id:
1301
     *
1302
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1303
     * @return string indentifikátor záznamu reprezentovaného objektem
1304
     */
1305
    public function __toString()
1306
    {
1307
        return strval($this->getRecordID());
1308
    }
1309
1310
    /**
1311
     * Gives you FlexiPeeHP class name for Given Evidence
1312
     *
1313
     * @param string $evidence
1314
     * @return string Class name
1315
     */
1316
    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...
1317
    {
1318
        return str_replace(' ', '', ucwords(str_replace('-', ' ', $evidence)));
1319
    }
1320
1321
    /**
1322
     * Vrací hodnotu daného externího ID
1323
     *
1324
     * @param string $want Which ? If empty,you obtain the first one.
1325
     * @return string
1326
     */
1327
    public function getExternalID($want = null)
1328
    {
1329
        $extid = null;
1330
        $ids   = $this->getDataValue('external-ids');
1331
        if (is_null($want)) {
1332
            if (count($ids)) {
1333
                $extid = current($ids);
1334
            }
1335
        } else {
1336
            if (!is_null($ids) && is_array($ids)) {
1337
                foreach ($ids as $id) {
1338
                    if (strstr($id, 'ext:'.$want)) {
1339
                        $extid = str_replace('ext:'.$want.':', '', $id);
1340
                    }
1341
                }
1342
            }
1343
        }
1344
        return $extid;
1345
    }
1346
1347
    /**
1348
     * Obtain actual GlobalVersion
1349
     * Vrací aktuální globální verzi změn
1350
     *
1351
     * @link https://www.flexibee.eu/api/dokumentace/ref/changes-api#globalVersion Globální Verze
1352
     * @return type
1353
     */
1354
    public function getGlobalVersion()
1355
    {
1356
        $globalVersion = null;
1357
        if (!count($this->lastResult) || !isset($this->lastResult['@globalVersion'])) {
1358
            $this->getFlexiData(null,
1359
                ['add-global-version' => 'true', 'limit' => 1]);
1360
        }
1361
1362
        if (isset($this->lastResult['@globalVersion'])) {
1363
            $globalVersion = intval($this->lastResult['@globalVersion']);
1364
        }
1365
1366
        return $globalVersion;
1367
    }
1368
1369
    /**
1370
     * Obtain content type of last response
1371
     *
1372
     * @return string
1373
     */
1374
    public function getResponseFormat()
1375
    {
1376
        if (isset($this->curlInfo['content_type'])) {
1377
            $responseFormat = $this->curlInfo['content_type'];
1378
        } else {
1379
            $responseFormat = null;
1380
        }
1381
        return $responseFormat;
1382
    }
1383
1384
    /**
1385
     * Return the same response format for one and multiplete results
1386
     *
1387
     * @param array $responseBody
1388
     * @return array
1389
     */
1390
    public function unifyResponseFormat($responseBody)
1391
    {
1392
        $evidence = $this->getResponseEvidence();
1393
        if (array_key_exists('message', $responseBody)) { //Unifi response format
1394
            $response = $responseBody;
1395
        } else {
1396
            if (array_key_exists($evidence, $responseBody)) {
1397
                $evidenceContent = $responseBody[$evidence];
1398
                if (array_key_exists(0, $evidenceContent)) {
1399
                    $response[$evidence] = $evidenceContent; //Multiplete Results
0 ignored issues
show
Coding Style Comprehensibility introduced by
$response was never initialized. Although not strictly required by PHP, it is generally a good practice to add $response = 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...
1400
                } else {
1401
                    $response[$evidence][0] = $evidenceContent; //One result
0 ignored issues
show
Coding Style Comprehensibility introduced by
$response was never initialized. Although not strictly required by PHP, it is generally a good practice to add $response = 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...
1402
                }
1403
            } else {
1404
                if (isset($responseBody['priloha'])) {
1405
                    $response = $responseBody['priloha'];
1406
                } else {
1407
                    $response = $responseBody;
1408
                }
1409
            }
1410
        }
1411
        return $response;
1412
    }
1413
1414
    /**
1415
     * Obtain structure for current (or given) evidence
1416
     *
1417
     * @param string $evidence
1418
     * @return array Evidence structure
1419
     */
1420 View Code Duplication
    public function getColumnsInfo($evidence = 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...
1421
    {
1422
        $columnsInfo = null;
1423
        if (is_null($evidence)) {
1424
            $evidence = $this->getEvidence();
1425
        }
1426
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
1427
        if (isset(\FlexiPeeHP\Properties::$$propsName)) {
1428
            $columnsInfo = Properties::$$propsName;
1429
        }
1430
        return $columnsInfo;
1431
    }
1432
1433
    /**
1434
     * Obtain actions for current (or given) evidence
1435
     *
1436
     * @param string $evidence
1437
     * @return array Evidence structure
1438
     */
1439 View Code Duplication
    public function getActionsInfo($evidence = 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...
1440
    {
1441
        $actionsInfo = null;
1442
        if (is_null($evidence)) {
1443
            $evidence = $this->getEvidence();
1444
        }
1445
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
1446
        if (isset(\FlexiPeeHP\Actions::$$propsName)) {
1447
            $actionsInfo = Actions::$$propsName;
1448
        }
1449
        return $actionsInfo;
1450
    }
1451
1452
    /**
1453
     * Obtain relations for current (or given) evidence
1454
     *
1455
     * @param string $evidence
1456
     * @return array Evidence structure
1457
     */
1458
    public function getRelationsInfo($evidence = null)
1459
    {
1460
        $relationsInfo = null;
1461
        if (is_null($evidence)) {
1462
            $evidence = $this->getEvidence();
1463
        }
1464
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
1465
        if (isset(\FlexiPeeHP\Relations::$$propsName)) {
1466
            $relationsInfo = Relations::$$propsName;
1467
        }
1468
        return $relationsInfo;
1469
    }
1470
1471
    /**
1472
     * Obtain info for current (or given) evidence
1473
     *
1474
     * @param string $evidence
1475
     * @return array Evidence info
1476
     */
1477 View Code Duplication
    public function getEvidenceInfo($evidence = 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...
1478
    {
1479
        $evidencesInfo = null;
1480
        if (is_null($evidence)) {
1481
            $evidence = $this->getEvidence();
1482
        }
1483
        if (isset(EvidenceList::$evidences[$evidence])) {
1484
            $evidencesInfo = EvidenceList::$evidences[$evidence];
1485
        }
1486
        return $evidencesInfo;
1487
    }
1488
1489
    /**
1490
     * Obtain name for current (or given) evidence path
1491
     *
1492
     * @param string $evidence Evidence Path
1493
     * @return array Evidence info
1494
     */
1495 View Code Duplication
    public function getEvidenceName($evidence = 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...
1496
    {
1497
        $evidenceName = null;
1498
        if (is_null($evidence)) {
1499
            $evidence = $this->getEvidence();
1500
        }
1501
        if (isset(EvidenceList::$name[$evidence])) {
1502
            $evidenceName = EvidenceList::$name[$evidence];
1503
        }
1504
        return $evidenceName;
1505
    }
1506
1507
    /**
1508
     * Perform given action (if availble) on current evidence/record
1509
     * @url https://demo.flexibee.eu/devdoc/actions
1510
     *
1511
     * @param string $action one of evidence actions
1512
     * @param string $method ext|int External method call operation in URL.
1513
     *                               Internal add the @action element to request body
1514
     */
1515
    public function performAction($action, $method = 'ext')
1516
    {
1517
        $result = null;
0 ignored issues
show
Unused Code introduced by
$result 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...
1518
1519
        $actionsAvailble = $this->getActionsInfo();
1520
1521
        if (is_array($actionsAvailble) && array_key_exists($action,
1522
                $actionsAvailble)) {
1523
            switch ($actionsAvailble[$action]['actionMakesSense']) {
1524
                case 'ONLY_WITH_INSTANCE_AND_NOT_IN_EDIT':
1525
                case 'ONLY_WITH_INSTANCE': //Add instance
1526
                    $urlSuffix = '/'.$this->__toString().'/'.$action.'.'.$this->format;
1527
                    break;
1528
1529
                default:
1530
                    $urlSuffix = '/'.$action;
1531
                    break;
1532
            }
1533
1534
            switch ($method) {
1535
                case 'int':
1536
                    $this->setAction($action);
1537
                    $this->setPostFields($this->jsonizeData($this->getData()));
1538
                    $result = $this->performRequest(null, 'POST');
1539
                    break;
1540
1541
                default:
1542
                    $result = $this->performRequest($urlSuffix, 'GET');
1543
                    break;
1544
            }
1545
        } else {
1546
            throw new \Exception(sprintf(_('Unsupported action %s for evidence %s'),
1547
                $action, $this->getEvidence()));
1548
        }
1549
1550
        return $result;
1551
    }
1552
1553
    /**
1554
     * Save current object to file
1555
     *
1556
     * @param string $destfile path to file
1557
     */
1558
    public function saveResponseToFile($destfile)
1559
    {
1560
        if (strlen($this->lastCurlResponse)) {
1561
            $this->doCurlRequest($this->apiURL, 'GET', $this->format);
1562
        }
1563
        file_put_contents($destfile, $this->lastCurlResponse);
1564
    }
1565
1566
    /**
1567
     * Obtain established relations listing
1568
     *
1569
     * @return array Null or Relations
1570
     */
1571
    public function getVazby()
1572
    {
1573
        $vazby = $this->getDataValue('vazby');
1574
        if (is_null($vazby)) {
1575
            $vazby = $this->getColumnsFromFlexibee('*',
0 ignored issues
show
Documentation introduced by
'*' is of type string, but the function expects a array<integer,string>.

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...
1576
                ['relations' => 'vazby', 'id' => $this->getRecordID()]);
1577
            $vazby = $vazby[0]['vazby'];
1578
        }
1579
        return $vazby;
1580
    }
1581
1582
    /**
1583
     * Gives You URL for Current Record in FlexiBee web interface
1584
     *
1585
     * @return string url
1586
     */
1587
    public function getFlexiBeeURL()
1588
    {
1589
        $parsed_url = parse_url(str_replace('.'.$this->format, '', $this->apiURL));
1590
        $scheme     = isset($parsed_url['scheme']) ? $parsed_url['scheme'].'://'
1591
                : '';
1592
        $host       = isset($parsed_url['host']) ? $parsed_url['host'] : '';
1593
        $port       = isset($parsed_url['port']) ? ':'.$parsed_url['port'] : '';
1594
        $user       = isset($parsed_url['user']) ? $parsed_url['user'] : '';
1595
        $pass       = isset($parsed_url['pass']) ? ':'.$parsed_url['pass'] : '';
1596
        $pass       = ($user || $pass) ? "$pass@" : '';
1597
        $path       = isset($parsed_url['path']) ? $parsed_url['path'] : '';
1598
        return $scheme.$user.$pass.$host.$port.$path;
1599
    }
1600
1601
    /**
1602
     * Set Record Key
1603
     *
1604
     * @param int|string $myKeyValue
1605
     * @return boolean
1606
     */
1607
    public function setMyKey($myKeyValue)
1608
    {
1609
        $res = parent::setMyKey($myKeyValue);
1610
        $this->updateApiURL();
1611
        return $res;
1612
    }
1613
1614
    /**
1615
     * Set or get ignore not found pages flag
1616
     *
1617
     * @param boolean $ignore set flag to
1618
     *
1619
     * @return boolean get flag state
1620
     */
1621
    public function ignore404($ignore = null)
1622
    {
1623
        if (!is_null($ignore)) {
1624
            $this->ignoreNotFound = $ignore;
1625
        }
1626
        return $this->ignoreNotFound;
1627
    }
1628
1629
    /**
1630
     * Send Document by mail
1631
     *
1632
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
1633
     *
1634
     * @param string $to
1635
     * @param string $subject
1636
     * @param string $body Email Text
1637
     *
1638
     * @return int http response code
1639
     */
1640
    public function sendByMail($to, $subject, $body, $cc = null)
1641
    {
1642
        $this->setPostFields($body);
1643
        $result = $this->doCurlRequest($this->getEvidenceURL().'/'.
1644
            urlencode($this->getRecordID()).'/odeslani-dokladu?to='.$to.'&subject='.urlencode($subject).'&cc='.$cc
1645
            , 'PUT', 'xml');
1646
        return $result == 200;
1647
    }
1648
1649
    /**
1650
     * Send all unsent Invoices by mail
1651
     *
1652
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
1653
     * @return int http response code
1654
     */
1655
    public function sendUnsent()
1656
    {
1657
        return $this->doCurlRequest($this->getEvidenceURL().'/automaticky-odeslat-neodeslane',
1658
                'PUT', 'xml');
1659
    }
1660
1661
    /**
1662
     * FlexiBee date to PHP DateTime
1663
     *
1664
     * @param string $flexidate
1665
     * @return \DateTime
1666
     */
1667
    public static function flexiDateToDateTime($flexidate)
1668
    {
1669
        return \DateTime::createFromFormat('Y-m-jO', $flexidate);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression \DateTime::createFromFor...('Y-m-jO', $flexidate); of type DateTime|false adds false to the return on line 1669 which is incompatible with the return type documented by FlexiPeeHP\FlexiBeeRO::flexiDateToDateTime of type DateTime. It seems like you forgot to handle an error condition.
Loading history...
1670
    }
1671
1672
    /**
1673
     * Uloží dokument v daném formátu do složky v systému souborů
1674
     * Save document in given format to directory in filesystem
1675
     *
1676
     * @param string $format  pdf/csv/xml/json/ ...
1677
     * @param string $destDir where to put file (prefix)
1678
     * 
1679
     * @return string|null filename downloaded or none
1680
     */
1681
    public function downloadInFormat($format, $destDir = './')
1682
    {
1683
        $fileOnDisk = null;
1684
        if ($this->setFormat($format)) {
1685
            $downloadTo = $destDir.$this->getEvidence().'_'.$this->getMyKey().'.'.$format;
1686
            if (($this->doCurlRequest($this->apiURL, 'GET') == 200) && (file_put_contents($downloadTo,
1687
                    $this->lastCurlResponse) !== false)) {
1688
                $fileOnDisk = $downloadTo;
1689
            }
1690
        }
1691
        return $fileOnDisk;
1692
    }
1693
}
1694