Test Failed
Push — master ( c6d711...9cdcc0 )
by Vítězslav
03:31
created

FlexiBeeRO::flexiDateToDateTime()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
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
     * Availble Formats.
27
     *
28
     * @see https://www.flexibee.eu/api/dokumentace/ref/format-types/
29
     * @var array formats known to flexibee
30
     */
31
    static public $formats = [
32
        'JS' => ['desc' => 'JavaScropt',
33
            'suffix' => 'js', 'content-type' => 'application/javascript', 'import' => false],
34
        'CSS' => ['desc' => 'Kaskádový styl',
35
            'suffix' => 'css', 'content-type' => 'text/css', 'import' => false],
36
        'HTML' => ['desc' => 'HTML stránka pro zobrazení informací na webové stránce.',
37
            'suffix' => 'html', 'content-type' => 'text/html', 'import' => false],
38
        'XML' => ['desc' => 'Strojově čitelná struktura ve formátu XML.', 'suffix' => 'xml',
39
            'content-type' => 'application/xml', 'import' => true],
40
        'JSON' => ['desc' => 'Strojově čitelná struktura ve formátu JSON. ', 'suffix' => 'json',
41
            'content-type' => 'application/json', 'import' => true],
42
        'CSV' => ['desc' => 'Tabulkový výstup do formátu CSV (Column Separated Values).',
43
            'suffix' => 'csv', 'content-type' => 'text/csv', 'import' => true],
44
        'DBF' => ['desc' => 'Databázový výstup ve formátu DBF (dBase).', 'suffix' => 'dbf',
45
            'content-type' => 'application/dbf', 'import' => true],
46
        'XLS' => ['desc' => 'Tabulkový výstup ve formátu Excel.', 'suffix' => 'xls',
47
            'content-type' => 'application/ms-excel', 'import' => true],
48
        'ISDOC' => ['desc' => 'e-faktura ISDOC.', 'suffix' => 'isdoc', 'content-type' => 'application/x-isdoc',
49
            'import' => false],
50
        'ISDOCx' => ['desc' => 'e-faktura ISDOC s PDF přílohou', 'suffix' => 'isdocx',
51
            'content-type' => 'application/x-isdocx',
52
            'import' => false],
53
        'EDI' => ['desc' => 'Elektronická výměna data (EDI) ve formátu INHOUSE.',
54
            'suffix' => 'edi', 'content-type' => 'application/x-edi-inhouse', 'import' => 'objednavka-prijata'],
55
        'PDF' => ['desc' => 'Generování tiskového reportu. Jedná se o stejnou funkci která je dostupná v aplikaci. Export do PDF',
56
            'suffix' => 'pdf', 'content-type' => 'application/pdf', 'import' => false],
57
        'vCard' => ['desc' => 'Výstup adresáře do formátu elektronické vizitky vCard.',
58
            'suffix' => 'vcf', 'content-type' => 'text/vcard', 'import' => false],
59
        'iCalendar' => ['desc' => 'Výstup do kalendáře ve formátu iCalendar. Lze takto exportovat události, ale také třeba splatnosti u přijatých či vydaných faktur.',
60
            'suffix' => 'ical', 'content-type' => 'text/calendar', 'import' => false]
61
    ];
62
63
    /**
64
     * Základní namespace pro komunikaci s FlexiBee.
65
     * Basic namespace for communication with FlexiBee
66
     *
67
     * @var string Jmený prostor datového bloku odpovědi
68
     */
69
    public $nameSpace = 'winstrom';
70
71
    /**
72
     * URL of object data in FlexiBee
73
     * @var string url
74
     */
75
    public $apiURL = null;
76
77
    /**
78
     * Datový blok v poli odpovědi.
79
     * Data block in response field.
80
     *
81
     * @var string
82
     */
83
    public $resultField = 'results';
84
85
    /**
86
     * Verze protokolu použitého pro komunikaci.
87
     * Communication protocol version used.
88
     *
89
     * @var string Verze použitého API
90
     */
91
    public $protoVersion = '1.0';
92
93
    /**
94
     * Evidence užitá objektem.
95
     * Evidence used by object
96
     *
97
     * @link https://demo.flexibee.eu/c/demo/evidence-list Přehled evidencí
98
     * @var string
99
     */
100
    public $evidence = null;
101
102
    /**
103
     * Výchozí formát pro komunikaci.
104
     * Default communication format.
105
     *
106
     * @link https://www.flexibee.eu/api/dokumentace/ref/format-types Přehled možných formátů
107
     *
108
     * @var string json|xml|...
109
     */
110
    public $format = 'json';
111
112
    /**
113
     * Curl Handle.
114
     *
115
     * @var resource
116
     */
117
    public $curl = null;
118
119
    /**
120
     * @link https://demo.flexibee.eu/devdoc/company-identifier Identifikátor firmy
121
     * @var string
122
     */
123
    public $company = null;
124
125
    /**
126
     * Server[:port]
127
     * @var string
128
     */
129
    public $url = null;
130
131
    /**
132
     * REST API Username
133
     * @var string
134
     */
135
    public $user = null;
136
137
    /**
138
     * REST API Password
139
     * @var string
140
     */
141
    public $password = null;
142
143
    /**
144
     * @var array Pole HTTP hlaviček odesílaných s každým požadavkem
145
     */
146
    public $defaultHttpHeaders = ['User-Agent' => 'FlexiPeeHP'];
147
148
    /**
149
     * Default additional request url parameters after question mark
150
     *
151
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls   Common params
152
     * @link https://www.flexibee.eu/api/dokumentace/ref/paging Paging params
153
     * @var array
154
     */
155
    public $defaultUrlParams = ['limit' => 0];
156
157
    /**
158
     * Identifikační řetězec.
159
     *
160
     * @var string
161
     */
162
    public $init = null;
163
164
    /**
165
     * Sloupeček s názvem.
166
     *
167
     * @var string
168
     */
169
    public $nameColumn = 'nazev';
170
171
    /**
172
     * Sloupeček obsahující datum vložení záznamu do shopu.
173
     *
174
     * @var string
175
     */
176
    public $myCreateColumn = 'false';
177
178
    /**
179
     * Slopecek obsahujici datum poslení modifikace záznamu do shopu.
180
     *
181
     * @var string
182
     */
183
    public $myLastModifiedColumn = 'lastUpdate';
184
185
    /**
186
     * Klíčový idendifikátor záznamu.
187
     *
188
     * @var string
189
     */
190
    public $fbKeyColumn = 'id';
191
192
    /**
193
     * Informace o posledním HTTP requestu.
194
     *
195
     * @var *
196
     */
197
    public $info;
198
199
    /**
200
     * Informace o poslední HTTP chybě.
201
     *
202
     * @var string
203
     */
204
    public $lastCurlError = null;
205
206
    /**
207
     * Used codes storage.
208
     *
209
     * @var array
210
     */
211
    public $codes = null;
212
213
    /**
214
     * Last Inserted ID.
215
     *
216
     * @var int
217
     */
218
    public $lastInsertedID = null;
219
220
    /**
221
     * Default Line Prefix.
222
     *
223
     * @var string
224
     */
225
    public $prefix = '/c/';
226
227
    /**
228
     * Raw Content of last curl response
229
     *
230
     * @var string
231
     */
232
    public $lastCurlResponse;
233
234
    /**
235
     * HTTP Response code of last request
236
     *
237
     * @var int
238
     */
239
    public $lastResponseCode = null;
240
241
    /**
242
     * Body data  for next curl POST operation
243
     *
244
     * @var string
245
     */
246
    protected $postFields = null;
247
248
    /**
249
     * Last operation result data or message(s)
250
     *
251
     * @var array
252
     */
253
    public $lastResult = null;
254
255
    /**
256
     * Nuber from  @rowCount
257
     * @var int
258
     */
259
    public $rowCount = null;
260
261
    /**
262
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
263
     * @var string
264
     */
265
    protected $action;
266
267
    /**
268
     * Pole akcí které podporuje ta která evidence
269
     * @link https://demo.flexibee.eu/c/demo/faktura-vydana/actions.json Např. Akce faktury
270
     * @var array
271
     */
272
    public $actionsAvailable = null;
273
274
    /**
275
     * Parmetry pro URL
276
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Všechny podporované parametry
277
     * @var array
278
     */
279
    public $urlParams = [
280
        'idUcetniObdobi',
281
        'dry-run',
282
        'fail-on-warning',
283
        'report-name',
284
        'report-lang',
285
        'report-sign',
286
        'detail', //See: https://www.flexibee.eu/api/dokumentace/ref/detail-levels
287
        'mode',
288
        'limit',
289
        'start',
290
        'order',
291
        'sort',
292
        'add-row-count',
293
        'relations',
294
        'includes',
295
        'use-ext-id',
296
        'use-internal-id',
297
        'stitky-as-ids',
298
        'only-ext-ids',
299
        'no-ext-ids',
300
        'no-ids',
301
        'code-as-id',
302
        'no-http-errors',
303
        'export-settings',
304
        'as-gui',
305
        'code-in-response',
306
        'add-global-version',
307
        'encoding',
308
        'delimeter',
309
        'format',
310
        'auth',
311
        'skupina-stitku',
312
        'dir',
313
        'relations',
314
        'relations',
315
        'xpath', // See: https://www.flexibee.eu/api/dokumentace/ref/xpath/
316
        'dry-run', // See: https://www.flexibee.eu/api/dokumentace/ref/dry-run/
317
        'inDesktopApp' // Note: Undocumented function (html only)
318
    ];
319
320
    /**
321
     * Save 404 results to log ?
322
     * @var boolean
323
     */
324
    protected $ignoreNotFound = false;
325
326
    /**
327
     * Class for read only interaction with FlexiBee.
328
     *
329
     * @param mixed $init default record id or initial data
330
     * @param array $options Connection settings override
331
     */
332
    public function __construct($init = null, $options = [])
333
    {
334
        $this->init = $init;
335
336
        parent::__construct();
337
        $this->setUp($options);
338
        $this->curlInit();
339
        if (!is_null($init)) {
340
            $this->processInit($init);
341
        }
342
    }
343
344
    /**
345
     * SetUp Object to be ready for connect
346
     *
347
     * @param array $options Object Options (company,url,user,password,evidence,
348
     *                                       prefix,debug)
349
     */
350
    public function setUp($options = [])
351
    {
352
        if (isset($options['company'])) {
353
            $this->company = $options['company'];
354
        } else {
355
            if (is_null($this->company) && defined('FLEXIBEE_COMPANY')) {
356
                $this->company = constant('FLEXIBEE_COMPANY');
357
            }
358
        }
359
        if (isset($options['url'])) {
360
            $this->url = $options['url'];
361
        } else {
362
            if (is_null($this->url) && defined('FLEXIBEE_URL')) {
363
                $this->url = constant('FLEXIBEE_URL');
364
            }
365
        }
366
        if (isset($options['user'])) {
367
            $this->user = $options['user'];
368
        } else {
369
            if (is_null($this->user) && defined('FLEXIBEE_LOGIN')) {
370
                $this->user = constant('FLEXIBEE_LOGIN');
371
            }
372
        }
373
        if (isset($options['password'])) {
374
            $this->password = $options['password'];
375
        } else {
376
            if (is_null($this->password) && defined('FLEXIBEE_PASSWORD')) {
377
                $this->password = constant('FLEXIBEE_PASSWORD');
378
            }
379
        }
380
        if (isset($options['evidence'])) {
381
            $this->setEvidence($options['evidence']);
382
        }
383
        if (isset($options['prefix'])) {
384
            $this->setPrefix($options['prefix']);
385
        }
386
        if (isset($options['debug'])) {
387
            $this->debug = $options['debug'];
388
        }
389
    }
390
391
    /**
392
     * Inicializace CURL
393
     */
394
    public function curlInit()
395
    {
396
        $this->curl = \curl_init(); // create curl resource
397
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); // return content as a string from curl_exec
398
        curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); // follow redirects (compatibility for future changes in FlexiBee)
399
        curl_setopt($this->curl, CURLOPT_HTTPAUTH, true);       // HTTP authentication
400
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); // FlexiBee by default uses Self-Signed certificates
401
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
402
        curl_setopt($this->curl, CURLOPT_VERBOSE, ($this->debug === true)); // For debugging
403
        curl_setopt($this->curl, CURLOPT_USERPWD,
404
            $this->user.':'.$this->password); // set username and password
405
    }
406
407
    /**
408
     * Zinicializuje objekt dle daných dat
409
     *
410
     * @param mixed $init
411
     */
412
    public function processInit($init)
413
    {
414
        if (is_integer($init)) {
415
            $this->loadFromFlexiBee($init);
416
        } elseif (is_array($init)) {
417
            $this->takeData($init);
418
        } elseif (strstr($init, 'code:')) {
419
            $this->loadFromFlexiBee($init);
420
        }
421
    }
422
423
    /**
424
     * Set URL prefix
425
     *
426
     * @param string $prefix
427
     */
428
    public function setPrefix($prefix)
429
    {
430
        switch ($prefix) {
431
            case 'a': //Access
432
            case 'c': //Company
433
            case 'u': //User
434
            case 'g': //License Groups
435
            case 'admin':
436
            case 'status':
437
            case 'login-logout':
438
                $this->prefix = '/'.$prefix.'/';
439
                break;
440
            case null:
441
            case '':
442
            case '/':
443
                $this->prefix = '';
444
                break;
445
            default:
446
                throw new \Exception(sprintf('Unknown prefix %s', $prefix));
447
                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...
448
        }
449
    }
450
451
    /**
452
     * Set communication format.
453
     * One of html|xml|json|csv|dbf|xls|isdoc|isdocx|edi|pdf|pdf|vcf|ical
454
     *
455
     * @param string $format
456
     */
457
    public function setFormat($format)
458
    {
459
        $this->format = $format;
460
    }
461
462
    /**
463
     * Nastaví Evidenci pro Komunikaci.
464
     * Set evidence for communication
465
     *
466
     * @param string $evidence evidence pathName to use
467
     * @return boolean evidence switching status
468
     */
469
    public function setEvidence($evidence)
470
    {
471
        $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...
472
        switch ($this->prefix) {
473
            case '/c/':
474
                if (array_key_exists($evidence, EvidenceList::$name)) {
475
                    $this->evidence = $evidence;
476
                    $result         = true;
477
                } else {
478
                    throw new \Exception(sprintf('Try to set unsupported evidence %s',
479
                        $evidence));
480
                }
481
                break;
482
            default:
483
                $this->evidence = $evidence;
484
                $result         = true;
485
                break;
486
        }
487
        $this->updateApiURL();
488
        return $result;
489
    }
490
491
    /**
492
     * Vrací právě používanou evidenci pro komunikaci
493
     * Obtain current used evidence
494
     *
495
     * @return string
496
     */
497
    public function getEvidence()
498
    {
499
        return $this->evidence;
500
    }
501
502
    /**
503
     * Set used company.
504
     * Nastaví Firmu.
505
     *
506
     * @param string $company
507
     */
508
    public function setCompany($company)
509
    {
510
        $this->company = $company;
511
    }
512
513
    /**
514
     * Obtain company now used
515
     * Vrací právě používanou firmu
516
     *
517
     * @return string
518
     */
519
    public function getCompany()
520
    {
521
        return $this->company;
522
    }
523
524
    /**
525
     * Vrací název evidence použité v odpovědích z FlexiBee
526
     *
527
     * @return string
528
     */
529
    public function getResponseEvidence()
530
    {
531
        switch ($this->evidence) {
532
            case 'c':
533
                $evidence = 'company';
534
                break;
535
            case 'evidence-list':
536
                $evidence = 'evidences';
537
                break;
538
            default:
539
                $evidence = $this->getEvidence();
540
                break;
541
        }
542
        return $evidence;
543
    }
544
545
    /**
546
     * Převede rekurzivně Objekt na pole.
547
     *
548
     * @param object|array $object
549
     *
550
     * @return array
551
     */
552
    public static function object2array($object)
553
    {
554
        $result = null;
555
        if (is_object($object)) {
556
            $objectData = get_object_vars($object);
557
            if (is_array($objectData) && count($objectData)) {
558
                $result = array_map('self::object2array', $objectData);
559
            }
560 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...
561
            if (is_array($object)) {
562
                foreach ($object as $item => $value) {
563
                    $result[$item] = self::object2array($value);
564
                }
565
            } else {
566
                $result = $object;
567
            }
568
        }
569
570
        return $result;
571
    }
572
573
    /**
574
     * Převede rekurzivně v poli všechny objekty na jejich identifikátory.
575
     *
576
     * @param object|array $object
577
     *
578
     * @return array
579
     */
580
    public static function objectToID($object)
581
    {
582
        $result = null;
583
        if (is_object($object)) {
584
            $result = $object->__toString();
585 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...
586
            if (is_array($object)) {
587
                foreach ($object as $item => $value) {
588
                    $result[$item] = self::objectToID($value);
589
                }
590
            } else { //String
591
                $result = $object;
592
            }
593
        }
594
595
        return $result;
596
    }
597
598
    /**
599
     * Return basic URL for used Evidence
600
     *
601
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
602
     * @param string $urlSuffix
603
     */
604
    public function getEvidenceURL($urlSuffix = null)
605
    {
606
        if (is_null($urlSuffix)) {
607
            $urlSuffix = $this->getEvidence();
608
        } elseif ($urlSuffix[0] == ';') {
609
            $urlSuffix = $this->getEvidence().$urlSuffix;
610
        }
611
        return $this->url.$this->prefix.$this->company.'/'.$urlSuffix;
612
    }
613
614
    /**
615
     * Update $this->apiURL
616
     */
617
    public function updateApiURL()
618
    {
619
        $this->apiURL = $this->getEvidenceURL();
620
        $id           = $this->__toString();
621
        if (!is_null($id)) {
622
            $this->apiURL .= '/'.urlencode($id);
623
        }
624
    }
625
626
    /**
627
     * Funkce, která provede I/O operaci a vyhodnotí výsledek.
628
     *
629
     * @param string $urlSuffix část URL za identifikátorem firmy.
630
     * @param string $method    HTTP/REST metoda
631
     * @param string $format    Requested format
632
     * @return array|boolean Výsledek operace
633
     */
634
    public function performRequest($urlSuffix = null, $method = 'GET',
635
                                   $format = null)
636
    {
637
        $response       = null;
638
        $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...
639
        $this->rowCount = null;
640
641
        if (preg_match('/^http/', $urlSuffix)) {
642
            $url = $urlSuffix;
643
        } else {
644
            $url = $this->getEvidenceURL($urlSuffix);
645
        }
646
647
        $responseCode = $this->doCurlRequest($url, $method, $format);
648
649
        if (is_null($format)) {
650
            $format = $this->format;
651
        }
652
653
        switch ($responseCode) {
654
            case 200:
655
            case 201:
656
                // Parse response
657
                $responseDecoded = [];
0 ignored issues
show
Unused Code introduced by
$responseDecoded 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...
658
659
                switch ($format) {
660
                    case 'json':
661
                        $responseDecoded = json_decode($this->lastCurlResponse,
662
                            true, 10);
663
                        if (($method == 'PUT') && isset($responseDecoded[$this->nameSpace][$this->resultField][0]['id'])) {
664
                            $this->lastInsertedID = $responseDecoded[$this->nameSpace][$this->resultField][0]['id'];
665
                            $this->setMyKey($this->lastInsertedID);
666
                            $this->apiURL         = $this->getEvidenceURL().'/'.$this->lastInsertedID;
667
                        } else {
668
                            $this->lastInsertedID = null;
669
                            if (isset($responseDecoded[$this->nameSpace]['@rowCount'])) {
670
                                $this->rowCount = (int) $responseDecoded[$this->nameSpace]['@rowCount'];
671
                            }
672
                        }
673
                        $decodeError = json_last_error_msg();
674
                        if ($decodeError != 'No error') {
675
                            $this->addStatusMessage($decodeError, 'error');
676
                        }
677
                        break;
678
                    case 'xml':
679
                        if (strlen($this->lastCurlResponse)) {
680
                            $responseDecoded = self::xml2array($this->lastCurlResponse);
681
                        } else {
682
                            $responseDecoded = null;
683
                        }
684
                        break;
685
                    case 'txt':
686
                    default:
687
                        $responseDecoded = $this->lastCurlResponse;
688
                        break;
689
                }
690
691
692
                $response         = $this->lastResult = $this->unifyResponseFormat($responseDecoded);
693
694
                break;
695
696
            default: //Some goes wrong
697
                $this->lastCurlError = curl_error($this->curl);
698
                switch ($format) {
699
                    case 'json':
700
                        $response = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/',
701
                            function ($match) {
702
                            return mb_convert_encoding(pack('H*', $match[1]),
703
                                'UTF-8', 'UCS-2BE');
704
                        }, $this->lastCurlResponse);
705
                        $response = (json_encode(json_decode($response, true, 10),
706
                                JSON_PRETTY_PRINT));
707
                        break;
708
                    case 'xml':
709
                        if (strlen($this->lastCurlResponse)) {
710
                            $response = self::xml2array($this->lastCurlResponse);
711
                        }
712
                        break;
713
                    case 'txt':
714
                    default:
715
                        $response = $this->lastCurlResponse;
716
                        break;
717
                }
718
719
                if (is_array($response)) {
720
                    $result = urldecode(http_build_query($response));
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...
721
                } elseif (strlen($response) && ($response != 'null')) {
722
                    $decoded = json_decode($response);
723
                    if (is_array($decoded)) {
724
                        $result = urldecode(http_build_query(self::object2array(current($decoded))));
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...
725
                    }
726
                } else {
727
                    $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...
728
                }
729
730
                if ($response == 'null') {
731
                    if ($this->lastResponseCode == 200) {
732
                        $response = true;
733
                    } else {
734
                        $response = null;
735
                    }
736
                } else {
737
                    if (is_string($response)) {
738
                        $decoded = json_decode($response);
739
                        if (is_array($decoded)) {
740
                            $response = self::object2array(current($decoded));
741
                        }
742
                    }
743
                }
744
745
                if (is_array($response) && ($this->lastResponseCode == 400)) {
746
                    $this->logResult($response, $url);
747
                } else {
748
                    $responseDecoded = json_decode($this->lastCurlResponse,
749
                        true, 10);
750
751
                    if (is_array($responseDecoded) && array_key_exists('results',
752
                            $responseDecoded[$this->nameSpace])) {
753
                        $errors = $responseDecoded[$this->nameSpace]['results'][0]['errors'];
754
                    } else {
755
                        $errors = null;
756
                    }
757
758
                    if (!is_array($errors)) {
759
                        $errors[]['message'] = '';
760
                    }
761
762
                    if (( $responseCode == 404 ) && ($this->ignoreNotFound === true)) {
763
                        break;
764
                    }
765
                    foreach ($errors as $error) {
766
                        $this->addStatusMessage(sprintf('Error (HTTP %d): %s %s',
767
                                $responseCode,
768
                                implode('; ', $error)
769
                                , $this->lastCurlError), 'error');
770
                    }
771
772
                    $this->addStatusMessage($url, 'info');
773
                    if (!empty($this->postFields) && $this->debug === true) {
774
                        if (is_array($this->postFields)) {
775
                            $this->addStatusMessage(urldecode(http_build_query($this->postFields)),
776
                                'debug');
777
                        } else {
778
                            $this->addStatusMessage(urldecode($this->postFields),
779
                                'debug');
780
                        }
781
                    }
782
                }
783
784
                break;
785
        }
786
787
        if ($this->debug === true) {
788
            $this->saveDebugFiles();
789
        }
790
791
        return $response;
792
    }
793
794
    /**
795
     * Vykonej HTTP požadavek
796
     *
797
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
798
     * @param string $url    URL požadavku
799
     * @param string $method HTTP Method GET|POST|PUT|OPTIONS|DELETE
800
     * @param string $format požadovaný formát komunikace
801
     * @return int HTTP Response CODE
802
     */
803
    public function doCurlRequest($url, $method, $format = null)
804
    {
805
        if (is_null($format)) {
806
            $format = $this->format;
807
        }
808
        curl_setopt($this->curl, CURLOPT_URL, $url);
809
// Nastavení samotné operace
810
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, strtoupper($method));
811
//Vždy nastavíme byť i prázná postdata jako ochranu před chybou 411
812
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->postFields);
813
814
        $httpHeaders = $this->defaultHttpHeaders;
815
816
        $formats = $this->reindexArrayBy(self::$formats, 'suffix');
817
818
        if (!isset($httpHeaders['Accept'])) {
819
            $httpHeaders['Accept'] = $formats[$format]['content-type'];
820
        }
821
        if (!isset($httpHeaders['Content-Type'])) {
822
            $httpHeaders['Content-Type'] = $formats[$format]['content-type'];
823
        }
824
        $httpHeadersFinal = [];
825
        foreach ($httpHeaders as $key => $value) {
826
            if (($key == 'User-Agent') && ($value == 'FlexiPeeHP')) {
827
                $value .= ' v'.self::$libVersion;
828
            }
829
            $httpHeadersFinal[] = $key.': '.$value;
830
        }
831
832
        curl_setopt($this->curl, CURLOPT_HTTPHEADER, $httpHeadersFinal);
833
834
// Proveď samotnou operaci
835
        $this->lastCurlResponse = curl_exec($this->curl);
836
837
        $this->info = curl_getinfo($this->curl);
838
839
        $this->lastResponseCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
840
        return $this->lastResponseCode;
841
    }
842
843
    /**
844
     * Nastaví druh prováděné akce.
845
     *
846
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
847
     * @param string $action
848
     * @return boolean
849
     */
850
    public function setAction($action)
851
    {
852
        $result           = false;
853
        $actionsAvailable = $this->getActionsInfo();
854
        if (array_key_exists($action, $actionsAvailable)) {
855
            $this->action = $action;
856
            $result       = true;
857
        }
858
        return $result;
859
    }
860
861
    /**
862
     * Convert XML to array.
863
     *
864
     * @param string $xml
865
     *
866
     * @return array
867
     */
868
    public static function xml2array($xml)
869
    {
870
        $arr = [];
871
872
        if (is_string($xml)) {
873
            $xml = simplexml_load_string($xml);
874
        }
875
876
        foreach ($xml->children() as $r) {
877
            if (count($r->children()) == 0) {
878
                $arr[$r->getName()] = strval($r);
879
            } else {
880
                $arr[$r->getName()][] = self::xml2array($r);
881
            }
882
        }
883
884
        return $arr;
885
    }
886
887
    /**
888
     * Odpojení od FlexiBee.
889
     */
890
    public function disconnect()
891
    {
892
        if (is_resource($this->curl)) {
893
            curl_close($this->curl);
894
        }
895
        $this->curl = null;
896
    }
897
898
    /**
899
     * Disconnect CURL befere pass away
900
     */
901
    public function __destruct()
902
    {
903
        $this->disconnect();
904
    }
905
906
    /**
907
     * Načte řádek dat z FlexiBee.
908
     *
909
     * @param int $recordID id požadovaného záznamu
910
     *
911
     * @return array
912
     */
913
    public function getFlexiRow($recordID)
914
    {
915
        $record   = null;
916
        $response = $this->performRequest($this->evidence.'/'.$recordID.'.json');
917
        if (isset($response[$this->evidence])) {
918
            $record = $response[$this->evidence][0];
919
        }
920
921
        return $record;
922
    }
923
924
    /**
925
     * Oddělí z pole podmínek ty jenž patří za ? v URL požadavku
926
     *
927
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
928
     * @param array $conditions pole podmínek   - rendrují se do ()
929
     * @param array $urlParams  pole parametrů  - rendrují za ?
930
     */
931
    public function extractUrlParams(&$conditions, &$urlParams)
932
    {
933
        foreach ($this->urlParams as $urlParam) {
934
            if (isset($conditions[$urlParam])) {
935
                \Ease\Sand::divDataArray($conditions, $urlParams, $urlParam);
936
            }
937
        }
938
    }
939
940
    /**
941
     * Načte data z FlexiBee.
942
     *
943
     * @param string $suffix     dotaz
944
     * @param string|array $conditions Volitelný filtrovací výraz
945
     */
946
    public function getFlexiData($suffix = null, $conditions = null)
947
    {
948
        $urlParams = $this->defaultUrlParams;
949
        if (!is_null($conditions)) {
950
            if (is_array($conditions)) {
951
                $this->extractUrlParams($conditions, $urlParams);
952
                $conditions = $this->flexiUrl($conditions);
953
            }
954
955
            if (strlen($conditions) && ($conditions[0] != '/')) {
956
                $conditions = '/'.rawurlencode('('.($conditions).')');
957
            }
958
        } else {
959
            $conditions = '';
960
        }
961
962
        if (preg_match('/^http/', $suffix)) {
963
            $transactions = $this->performRequest($suffix, 'GET');
964
        } else {
965
            if (strlen($suffix)) {
966
                $transactions = $this->performRequest($this->evidence.$conditions.'.'.$this->format.'?'.$suffix.'&'.http_build_query($urlParams),
967
                    'GET');
968
            } else {
969
                $transactions = $this->performRequest($this->evidence.$conditions.'.'.$this->format.'?'.http_build_query($urlParams),
970
                    'GET');
971
            }
972
        }
973
        if (isset($transactions[$this->evidence])) {
974
            $result = $transactions[$this->evidence];
975
            if ((count($result) == 1) && (count(current($result)) == 0 )) {
976
                $result = null; // Response is empty Array
977
            }
978
        } else {
979
            $result = $transactions;
980
        }
981
982
        return $result;
983
    }
984
985
    /**
986
     * Načte záznam z FlexiBee.
987
     *
988
     * @param int $id ID záznamu
989
     *
990
     * @return int počet načtených položek
991
     */
992
    public function loadFromFlexiBee($id = null)
993
    {
994
        $data = [];
995
        if (is_null($id)) {
996
            $id = $this->getMyKey();
997
        }
998
999
        $flexidata    = $this->getFlexiData(null, '/'.$id);
1000
        $this->apiURL = $this->info['url'];
1001
        if (is_array($flexidata) && (count($flexidata) == 1)) {
1002
            $data = current($flexidata);
1003
        }
1004
        return $this->takeData($data);
1005
    }
1006
1007
    /**
1008
     * Převede data do Json formátu pro FlexiBee.
1009
     * Convert data to FlexiBee like Json format
1010
     *
1011
     * @param array $data
1012
     *
1013
     * @return string
1014
     */
1015
    public function jsonizeData($data)
1016
    {
1017
        $jsonize = [
1018
            $this->nameSpace => [
1019
                '@version' => $this->protoVersion,
1020
                $this->evidence => $this->objectToID($data),
1021
            ],
1022
        ];
1023
1024
        if (!is_null($this->action)) {
1025
            $jsonize[$this->nameSpace][$this->evidence.'@action'] = $this->action;
1026
            $this->action                                         = null;
1027
        }
1028
1029
        return json_encode($jsonize);
1030
    }
1031
1032
    /**
1033
     * Test if given record ID exists in FlexiBee.
1034
     *
1035
     * @param string|int $identifer
1036
     */
1037
    public function idExists($identifer = null)
1038
    {
1039
        if (is_null($identifer)) {
1040
            $identifer = $this->getMyKey();
1041
        }
1042
        $flexiData = $this->getFlexiData(
1043
            'detail=custom:'.$this->getmyKeyColumn(), $identifer);
1044
1045
        return $flexiData;
1046
    }
1047
1048
    /**
1049
     * Test if given record exists in FlexiBee.
1050
     *
1051
     * @param array $data
1052
     * @return boolean Record presence status
1053
     */
1054
    public function recordExists($data = null)
1055
    {
1056
1057
        if (is_null($data)) {
1058
            $data = $this->getData();
1059
        }
1060
1061
        $res = $this->getColumnsFromFlexibee([$this->myKeyColumn],
1062
            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...
1063
1064
        if (!count($res) || (isset($res['success']) && ($res['success'] == 'false'))
1065
            || !count($res[0])) {
1066
            $found = false;
1067
        } else {
1068
            $found = true;
1069
        }
1070
        return $found;
1071
    }
1072
1073
    /**
1074
     * Vrací z FlexiBee sloupečky podle podmínek.
1075
     *
1076
     * @param array|int|string $conditions pole podmínek nebo ID záznamu
1077
     * @param string           $indexBy    klice vysledku naplnit hodnotou ze
1078
     *                                     sloupečku
1079
     * @return array
1080
     */
1081
    public function getAllFromFlexibee($conditions = null, $indexBy = null)
1082
    {
1083
        if (is_int($conditions)) {
1084
            $conditions = [$this->getmyKeyColumn() => $conditions];
1085
        }
1086
1087
        $flexiData = $this->getFlexiData('', $conditions);
1088
1089
        if (!is_null($indexBy)) {
1090
            $flexiData = $this->reindexArrayBy($flexiData);
1091
        }
1092
1093
        return $flexiData;
1094
    }
1095
1096
    /**
1097
     * Vrací z FlexiBee sloupečky podle podmínek.
1098
     *
1099
     * @param string[] $columnsList seznam položek
1100
     * @param array    $conditions  pole podmínek nebo ID záznamu
1101
     * @param string   $indexBy     Sloupeček podle kterého indexovat záznamy
1102
     *
1103
     * @return array
1104
     */
1105
    public function getColumnsFromFlexibee($columnsList, $conditions = null,
1106
                                           $indexBy = null)
1107
    {
1108
        if (is_int($conditions)) {
1109
            $conditions = [$this->getmyKeyColumn() => $conditions];
1110
        }
1111
1112
        if ($columnsList != '*') {
1113
            if (is_array($columnsList)) {
1114
                if (!is_null($indexBy) && !array_key_exists($indexBy,
1115
                        $columnsList)) {
1116
                    $columnsList[] = $indexBy;
1117
                }
1118
                $columns = implode(',', array_unique($columnsList));
1119
            } else {
1120
                $columns = $columnsList;
1121
            }
1122
            $detail = 'custom:'.$columns;
0 ignored issues
show
Unused Code introduced by
$detail 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...
1123
        }
1124
        switch ($columnsList) {
1125
            case 'id':
1126
                $detail = 'id';
1127
                break;
1128
            case 'summary':
1129
                $detail = 'summary';
1130
                break;
1131
            case 'full':
1132
            default:
1133
                $detail = 'full';
1134
                break;
1135
        }
1136
1137
        $flexiData = $this->getFlexiData('detail='.$detail, $conditions);
1138
1139
        if (!is_null($indexBy) && count($flexiData) && count(current($flexiData))) {
1140
            $flexiData = $this->reindexArrayBy($flexiData, $indexBy);
1141
        }
1142
1143
        return $flexiData;
1144
    }
1145
1146
    /**
1147
     * Vrací kód záznamu.
1148
     *
1149
     * @param mixed $data
1150
     *
1151
     * @return string
1152
     */
1153
    public function getKod($data = null, $unique = true)
1154
    {
1155
        $kod = null;
1156
1157
        if (is_null($data)) {
1158
            $data = $this->getData();
1159
        }
1160
1161
        if (is_string($data)) {
1162
            $data = [$this->nameColumn => $data];
1163
        }
1164
1165
        if (isset($data['kod'])) {
1166
            $kod = $data['kod'];
1167
        } else {
1168
            if (isset($data[$this->nameColumn])) {
1169
                $kod = preg_replace('/[^a-zA-Z0-9]/', '',
1170
                    \Ease\Sand::rip($data[$this->nameColumn]));
1171
            } else {
1172
                if (isset($data[$this->myKeyColumn])) {
1173
                    $kod = \Ease\Sand::rip($data[$this->myKeyColumn]);
1174
                }
1175
            }
1176
        }
1177
1178
        if (!strlen($kod)) {
1179
            $kod = 'NOTSET';
1180
        }
1181
1182
        if (strlen($kod) > 18) {
1183
            $kodfinal = strtoupper(substr($kod, 0, 18));
1184
        } else {
1185
            $kodfinal = strtoupper($kod);
1186
        }
1187
1188
        if ($unique) {
1189
            $counter = 0;
1190
            if (count($this->codes)) {
1191
                foreach ($this->codes as $codesearch => $keystring) {
1192
                    if (strstr($codesearch, $kodfinal)) {
1193
                        ++$counter;
1194
                    }
1195
                }
1196
            }
1197
            if ($counter) {
1198
                $kodfinal = $kodfinal.$counter;
1199
            }
1200
1201
            $this->codes[$kodfinal] = $kod;
1202
        }
1203
1204
        return $kodfinal;
1205
    }
1206
1207
    /**
1208
     * Write Operation Result.
1209
     *
1210
     * @param array  $resultData
1211
     * @param string $url        URL
1212
     * @return boolean Log save success
1213
     */
1214
    public function logResult($resultData = null, $url = null)
1215
    {
1216
        $logResult = false;
1217
        if (isset($resultData['success']) && ($resultData['success'] == 'false')) {
1218
            if (isset($resultData['message'])) {
1219
                $this->addStatusMessage($resultData['message'], 'warning');
1220
            }
1221
            $this->addStatusMessage('Error '.$this->lastResponseCode.': '.urldecode($url),
1222
                'warning');
1223
            unset($url);
1224
        }
1225
        if (is_null($resultData)) {
1226
            $resultData = $this->lastResult;
1227
        }
1228
        if (isset($url)) {
1229
            $this->logger->addStatusMessage(urldecode($url));
1230
        }
1231
1232
        if (isset($resultData['results'])) {
1233
            $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...
1234
            if ($resultData['success'] == 'false') {
1235
                $status = 'error';
1236
            } else {
1237
                $status = 'success';
1238
            }
1239
            foreach ($resultData['results'] as $result) {
1240
                if (isset($result['request-id'])) {
1241
                    $rid = $result['request-id'];
1242
                } else {
1243
                    $rid = '';
1244
                }
1245
                if (isset($result['errors'])) {
1246
                    foreach ($result['errors'] as $error) {
1247
                        $message = $error['message'];
1248
                        if (isset($error['for'])) {
1249
                            $message .= ' for: '.$error['for'];
1250
                        }
1251
                        if (isset($error['value'])) {
1252
                            $message .= ' value:'.$error['value'];
1253
                        }
1254
                        if (isset($error['code'])) {
1255
                            $message .= ' code:'.$error['code'];
1256
                        }
1257
                        $this->addStatusMessage($rid.': '.$message, $status);
1258
                    }
1259
                }
1260
            }
1261
        }
1262
        return $logResult;
1263
    }
1264
1265
    /**
1266
     * Save RAW Curl Request & Response to files in Temp directory
1267
     */
1268
    public function saveDebugFiles()
1269
    {
1270
        $tmpdir = sys_get_temp_dir();
1271
        file_put_contents($tmpdir.'/request-'.$this->evidence.'-'.microtime().'.'.$this->format,
1272
            $this->postFields);
1273
        file_put_contents($tmpdir.'/response-'.$this->evidence.'-'.microtime().'.'.$this->format,
1274
            $this->lastCurlResponse);
1275
    }
1276
1277
    /**
1278
     * Připraví data pro odeslání do FlexiBee
1279
     *
1280
     * @param string $data
1281
     */
1282
    public function setPostFields($data)
1283
    {
1284
        $this->postFields = $data;
1285
    }
1286
1287
    /**
1288
     * Generuje fragment url pro filtrování.
1289
     *
1290
     * @see https://www.flexibee.eu/api/dokumentace/ref/filters
1291
     *
1292
     * @param array  $data
1293
     * @param string $joiner default and/or
1294
     * @param string $defop  default operator
1295
     *
1296
     * @return string
1297
     */
1298
    public static function flexiUrl(array $data, $joiner = 'and', $defop = 'eq')
1299
    {
1300
        $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...
1301
        $parts    = [];
1302
1303
        foreach ($data as $column => $value) {
1304
            if (is_integer($data[$column]) || is_float($data[$column])) {
1305
                $parts[$column] = $column.' eq \''.$data[$column].'\'';
1306
            } elseif (is_bool($data[$column])) {
1307
                $parts[$column] = $data[$column] ? $column.' eq true' : $column.' eq false';
1308
            } elseif (is_null($data[$column])) {
1309
                $parts[$column] = $column." is null";
1310
            } else {
1311
                switch ($value) {
1312
                    case '!null':
1313
                        $parts[$column] = $column." is not null";
1314
                        break;
1315
                    case 'is empty':
1316
                    case 'is not empty':
1317
                        $parts[$column] = $column.' '.$value;
1318
                        break;
1319
                    default:
1320
                        $parts[$column] = $column." $defop '".$data[$column]."'";
1321
                        break;
1322
                }
1323
            }
1324
        }
1325
1326
        $flexiUrl = implode(' '.$joiner.' ', $parts);
1327
1328
        return $flexiUrl;
1329
    }
1330
1331
    /**
1332
     * Obtain record/object identificator code: or id:
1333
     * Vrací identifikátor objektu code: nebo id:
1334
     *
1335
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1336
     * @return string|int indentifikátor záznamu reprezentovaného objektem
1337
     */
1338
    public function getRecordID()
1339
    {
1340
        $myCode = $this->getDataValue('kod');
1341
        if ($myCode) {
1342
            $id = 'code:'.$myCode;
1343
        } else {
1344
            $id = $this->getDataValue('id');
1345
            if (($this->debug === true) && is_null($id)) {
1346
                $this->addToLog('Object Data does not contain code: or id: cannot match with statement!',
1347
                    'warning');
1348
            }
1349
        }
1350
        return is_numeric($id) ? intval($id) : strval($id);
1351
    }
1352
1353
    /**
1354
     * Obtain record/object identificator code: or id:
1355
     * Vrací identifikátor objektu code: nebo id:
1356
     *
1357
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1358
     * @return string indentifikátor záznamu reprezentovaného objektem
1359
     */
1360
    public function __toString()
1361
    {
1362
        return strval($this->getRecordID());
1363
    }
1364
1365
    /**
1366
     * Gives you FlexiPeeHP class name for Given Evidence
1367
     *
1368
     * @param string $evidence
1369
     * @return string Class name
1370
     */
1371
    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...
1372
    {
1373
        return str_replace(' ', '', ucwords(str_replace('-', ' ', $evidence)));
1374
    }
1375
1376
    /**
1377
     * Vrací hodnotu daného externího ID
1378
     *
1379
     * @param string $want Which ? If empty,you obtain the first one.
1380
     * @return string
1381
     */
1382
    public function getExternalID($want = null)
1383
    {
1384
        $extid = null;
1385
        $ids   = $this->getDataValue('external-ids');
1386
        if (is_null($want)) {
1387
            if (count($ids)) {
1388
                $extid = current($ids);
1389
            }
1390
        } else {
1391
            if (!is_null($ids) && is_array($ids)) {
1392
                foreach ($ids as $id) {
1393
                    if (strstr($id, 'ext:'.$want)) {
1394
                        $extid = str_replace('ext:'.$want.':', '', $id);
1395
                    }
1396
                }
1397
            }
1398
        }
1399
        return $extid;
1400
    }
1401
1402
    /**
1403
     * Obtain actual GlobalVersion
1404
     * Vrací aktuální globální verzi změn
1405
     *
1406
     * @link https://www.flexibee.eu/api/dokumentace/ref/changes-api#globalVersion Globální Verze
1407
     * @return type
1408
     */
1409
    public function getGlobalVersion()
1410
    {
1411
        $globalVersion = null;
1412
        if (!count($this->lastResult) || !isset($this->lastResult['@globalVersion'])) {
1413
            $this->getFlexiData(null,
1414
                ['add-global-version' => 'true', 'limit' => 1]);
1415
        }
1416
1417
        if (isset($this->lastResult['@globalVersion'])) {
1418
            $globalVersion = intval($this->lastResult['@globalVersion']);
1419
        }
1420
1421
        return $globalVersion;
1422
    }
1423
1424
    /**
1425
     * Obtain content type of last response
1426
     *
1427
     * @return string
1428
     */
1429
    public function getResponseFormat()
1430
    {
1431
        if (isset($this->info['content_type'])) {
1432
            $responseFormat = $this->info['content_type'];
1433
        } else {
1434
            $responseFormat = null;
1435
        }
1436
        return $responseFormat;
1437
    }
1438
1439
    /**
1440
     * Return the same response format for one and multiplete results
1441
     *
1442
     * @param array $responseRaw
1443
     * @return array
1444
     */
1445
    public function unifyResponseFormat($responseRaw)
1446
    {
1447
        $response = $responseRaw;
1448
        $evidence = $this->getResponseEvidence();
1449
        if (is_array($responseRaw)) {
1450
            // Get response body root automatically
1451
            if (array_key_exists($this->nameSpace, $responseRaw)) { //Unifi response format
1452
                $responseBody = $responseRaw[$this->nameSpace];
1453
                if (array_key_exists($evidence, $responseBody)) {
1454
                    $evidenceContent = $responseBody[$evidence];
1455
                    if (array_key_exists(0, $evidenceContent)) {
1456
                        $response[$evidence] = $evidenceContent; //Multiplete Results
1457
                    } else {
1458
                        $response[$evidence][0] = $evidenceContent; //One result
1459
                    }
1460
                } else {
1461
                    if (isset($responseBody['priloha'])) {
1462
                        $response = $responseBody['priloha'];
1463
                    } else {
1464
                        $response = $responseBody;
1465
                    }
1466
                }
1467
            } else {
1468
                $response = $responseRaw;
1469
            }
1470
        }
1471
        return $response;
1472
    }
1473
1474
    /**
1475
     * Obtain structure for current (or given) evidence
1476
     *
1477
     * @param string $evidence
1478
     * @return array Evidence structure
1479
     */
1480 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...
1481
    {
1482
        $columnsInfo = null;
1483
        if (is_null($evidence)) {
1484
            $evidence = $this->getEvidence();
1485
        }
1486
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
1487
        if (isset(\FlexiPeeHP\Properties::$$propsName)) {
1488
            $columnsInfo = Properties::$$propsName;
1489
        }
1490
        return $columnsInfo;
1491
    }
1492
1493
    /**
1494
     * Obtain actions for current (or given) evidence
1495
     *
1496
     * @param string $evidence
1497
     * @return array Evidence structure
1498
     */
1499 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...
1500
    {
1501
        $actionsInfo = null;
1502
        if (is_null($evidence)) {
1503
            $evidence = $this->getEvidence();
1504
        }
1505
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
1506
        if (isset(\FlexiPeeHP\Actions::$$propsName)) {
1507
            $actionsInfo = Actions::$$propsName;
1508
        }
1509
        return $actionsInfo;
1510
    }
1511
1512
    /**
1513
     * Obtain relations for current (or given) evidence
1514
     *
1515
     * @param string $evidence
1516
     * @return array Evidence structure
1517
     */
1518
    public function getRelationsInfo($evidence = null)
1519
    {
1520
        $relationsInfo = null;
1521
        if (is_null($evidence)) {
1522
            $evidence = $this->getEvidence();
1523
        }
1524
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
1525
        if (isset(\FlexiPeeHP\Relations::$$propsName)) {
1526
            $relationsInfo = Relations::$$propsName;
1527
        }
1528
        return $relationsInfo;
1529
    }
1530
1531
    /**
1532
     * Obtain info for current (or given) evidence
1533
     *
1534
     * @param string $evidence
1535
     * @return array Evidence info
1536
     */
1537 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...
1538
    {
1539
        $evidencesInfo = null;
1540
        if (is_null($evidence)) {
1541
            $evidence = $this->getEvidence();
1542
        }
1543
        if (isset(EvidenceList::$evidences[$evidence])) {
1544
            $evidencesInfo = EvidenceList::$evidences[$evidence];
1545
        }
1546
        return $evidencesInfo;
1547
    }
1548
1549
    /**
1550
     * Obtain name for current (or given) evidence path
1551
     *
1552
     * @param string $evidence Evidence Path
1553
     * @return array Evidence info
1554
     */
1555 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...
1556
    {
1557
        $evidenceName = null;
1558
        if (is_null($evidence)) {
1559
            $evidence = $this->getEvidence();
1560
        }
1561
        if (isset(EvidenceList::$name[$evidence])) {
1562
            $evidenceName = EvidenceList::$name[$evidence];
1563
        }
1564
        return $evidenceName;
1565
    }
1566
1567
    /**
1568
     * Perform given action (if availble) on current evidence/record
1569
     * @url https://demo.flexibee.eu/devdoc/actions
1570
     *
1571
     * @param string $action one of evidence actions
1572
     * @param string $method ext|int External method call operation in URL.
1573
     *                               Internal add the @action element to request body
1574
     */
1575
    public function performAction($action, $method = 'ext')
1576
    {
1577
        $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...
1578
1579
        $actionsAvailble = $this->getActionsInfo();
1580
1581
        if (is_array($actionsAvailble) && array_key_exists($action,
1582
                $actionsAvailble)) {
1583
            switch ($actionsAvailble[$action]['actionMakesSense']) {
1584
                case 'ONLY_WITH_INSTANCE_AND_NOT_IN_EDIT':
1585
                case 'ONLY_WITH_INSTANCE': //Add instance
1586
                    $urlSuffix = '/'.$this->__toString().'/'.$action.'.'.$this->format;
1587
                    break;
1588
1589
                default:
1590
                    $urlSuffix = '/'.$action;
1591
                    break;
1592
            }
1593
1594
            switch ($method) {
1595
                case 'int':
1596
                    $this->setAction($action);
1597
                    $this->setPostFields($this->jsonizeData($this->getData()));
1598
                    $result = $this->performRequest(null, 'POST');
1599
                    break;
1600
1601
                default:
1602
                    $result = $this->performRequest($urlSuffix, 'GET');
1603
                    break;
1604
            }
1605
        } else {
1606
            throw new \Exception(sprintf(_('Unsupported action %s for evidence %s'),
1607
                $action, $this->getEvidence()));
1608
        }
1609
1610
        return $result;
1611
    }
1612
1613
    /**
1614
     * Save current object to file
1615
     *
1616
     * @param string $destfile path to file
1617
     */
1618
    public function saveResponseToFile($destfile)
1619
    {
1620
        if (strlen($this->lastCurlResponse)) {
1621
            $this->doCurlRequest($this->apiURL, 'GET', $this->format);
1622
        }
1623
        file_put_contents($destfile, $this->lastCurlResponse);
1624
    }
1625
1626
    /**
1627
     * Obtain established relations listing
1628
     *
1629
     * @return array Null or Relations
1630
     */
1631
    public function getVazby()
1632
    {
1633
        $vazby = $this->getDataValue('vazby');
1634
        if (is_null($vazby)) {
1635
            $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...
1636
                ['relations' => 'vazby', 'id' => $this->getRecordID()]);
1637
            $vazby = $vazby[0]['vazby'];
1638
        }
1639
        return $vazby;
1640
    }
1641
1642
    /**
1643
     * Gives You URL for Current Record in FlexiBee web interface
1644
     *
1645
     * @return string url
1646
     */
1647
    public function getFlexiBeeURL()
1648
    {
1649
        $parsed_url = parse_url(str_replace('.'.$this->format, '', $this->apiURL));
1650
        $scheme     = isset($parsed_url['scheme']) ? $parsed_url['scheme'].'://'
1651
                : '';
1652
        $host       = isset($parsed_url['host']) ? $parsed_url['host'] : '';
1653
        $port       = isset($parsed_url['port']) ? ':'.$parsed_url['port'] : '';
1654
        $user       = isset($parsed_url['user']) ? $parsed_url['user'] : '';
1655
        $pass       = isset($parsed_url['pass']) ? ':'.$parsed_url['pass'] : '';
1656
        $pass       = ($user || $pass) ? "$pass@" : '';
1657
        $path       = isset($parsed_url['path']) ? $parsed_url['path'] : '';
1658
        return $scheme.$user.$pass.$host.$port.$path;
1659
    }
1660
1661
    /**
1662
     * Set Record Key
1663
     *
1664
     * @param int|string $myKeyValue
1665
     * @return boolean
1666
     */
1667
    public function setMyKey($myKeyValue)
1668
    {
1669
        $res = parent::setMyKey($myKeyValue);
1670
        $this->updateApiURL();
1671
        return $res;
1672
    }
1673
1674
    /**
1675
     * Set or get ignore not found pages flag
1676
     *
1677
     * @param boolean $ignore set flag to
1678
     *
1679
     * @return boolean get flag state
1680
     */
1681
    public function ignore404($ignore = null)
1682
    {
1683
        if (!is_null($ignore)) {
1684
            $this->ignoreNotFound;
1685
        }
1686
        return $this->ignoreNotFound;
1687
    }
1688
1689
    /**
1690
     * Send Invoice by mail
1691
     *
1692
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
1693
     *
1694
     * @param string $to
1695
     * @param string $subject
1696
     * @param string $body Email Text
1697
     *
1698
     * @return int http response code
1699
     */
1700
    public function sendByMail($to, $subject, $body, $cc = null)
1701
    {
1702
        $this->setPostFields($body);
1703
        $result = $this->doCurlRequest($this->getEvidenceURL().'/'.
1704
                urlencode($this->getRecordID()).'/odeslani-dokladu?to='.$to.'&subject='.urlencode($subject).'&cc='.$cc
1705
            , 'PUT', 'xml');
1706
        return $result == 200;
1707
    }
1708
1709
    /**
1710
     * Send all unsent Invoices by mail
1711
     *
1712
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
1713
     * @return int http response code
1714
     */
1715
    public function sendUnsent()
1716
    {
1717
        return $this->doCurlRequest($this->getEvidenceURL().'/automaticky-odeslat-neodeslane',
1718
                'PUT', 'xml');
1719
    }
1720
1721
    /**
1722
     * FlexiBee date to PHP DateTime
1723
     *
1724
     * @param string $flexidate
1725
     * @return \DateTime
1726
     */
1727
    public static function flexiDateToDateTime($flexidate)
1728
    {
1729
        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 1729 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...
1730
    }
1731
}
1732