FlexiBeeRO::dateToFlexiDateTime()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
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-2019 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\Sand
17
{
18
    /**
19
     * Where to get JSON files with evidence stricture etc.
20
     * @var string
21
     */
22
    public static $infoDir = __DIR__.'/../../static';
23
24
    /**
25
     * Version of FlexiPeeHP library
26
     *
27
     * @var string
28
     */
29
    public static $libVersion = '1.20.2';
30
31
    /**
32
     * Základní namespace pro komunikaci s FlexiBee.
33
     * Basic namespace for communication with FlexiBee
34
     *
35
     * @var string Jmený prostor datového bloku odpovědi
36
     */
37
    public $nameSpace = 'winstrom';
38
39
    /**
40
     * URL of object data in FlexiBee
41
     * @var string url
42
     */
43
    public $apiURL = null;
44
45
    /**
46
     * Datový blok v poli odpovědi.
47
     * Data block in response field.
48
     *
49
     * @var string
50
     */
51
    public $resultField = 'results';
52
53
    /**
54
     * Verze protokolu použitého pro komunikaci.
55
     * Communication protocol version used.
56
     *
57
     * @var string Verze použitého API
58
     */
59
    public $protoVersion = '1.0';
60
61
    /**
62
     * Evidence užitá objektem.
63
     * Evidence used by object
64
     *
65
     * @link https://demo.flexibee.eu/c/demo/evidence-list Přehled evidencí
66
     * @var string
67
     */
68
    public $evidence = null;
69
70
    /**
71
     * Výchozí formát pro komunikaci.
72
     * Default communication format.
73
     *
74
     * @link https://www.flexibee.eu/api/dokumentace/ref/format-types Přehled možných formátů
75
     *
76
     * @var string json|xml|...
77
     */
78
    public $format = 'json';
79
80
    /**
81
     * formát příchozí odpovědi
82
     * response format
83
     *
84
     * @link https://www.flexibee.eu/api/dokumentace/ref/format-types Přehled možných formátů
85
     *
86
     * @var string json|xml|...
87
     */
88
    public $responseFormat = 'json';
89
90
    /**
91
     * Curl Handle.
92
     *
93
     * @var resource
94
     */
95
    public $curl = null;
96
97
    /**
98
     * @link https://demo.flexibee.eu/devdoc/company-identifier Identifikátor firmy
99
     * @var string
100
     */
101
    public $company = null;
102
103
    /**
104
     * Server[:port]
105
     * @var string
106
     */
107
    public $url = null;
108
109
    /**
110
     * REST API Username
111
     * @var string
112
     */
113
    public $user = null;
114
115
    /**
116
     * REST API Password
117
     * @var string
118
     */
119
    public $password = null;
120
121
    /**
122
     * @var array Pole HTTP hlaviček odesílaných s každým požadavkem
123
     */
124
    public $defaultHttpHeaders = ['User-Agent' => 'FlexiPeeHP'];
125
126
    /**
127
     * Default additional request url parameters after question mark
128
     *
129
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls   Common params
130
     * @link https://www.flexibee.eu/api/dokumentace/ref/paging Paging params
131
     * @var array
132
     */
133
    public $defaultUrlParams = ['limit' => 0];
134
135
    /**
136
     * Identifikační řetězec.
137
     *
138
     * @var string
139
     */
140
    public $init = null;
141
142
    /**
143
     * Sloupeček s názvem.
144
     *
145
     * @var string
146
     */
147
    public $nameColumn = 'nazev';
148
149
    /**
150
     * Sloupeček obsahující datum vložení záznamu do shopu.
151
     *
152
     * @var string
153
     */
154
    public $myCreateColumn = 'false';
155
156
    /**
157
     * Slopecek obsahujici datum poslení modifikace záznamu do shopu.
158
     *
159
     * @var string
160
     */
161
    public $myLastModifiedColumn = 'lastUpdate';
162
163
    /**
164
     * Klíčový idendifikátor záznamu.
165
     *
166
     * @var string
167
     */
168
    public $fbKeyColumn = 'id';
169
170
    /**
171
     * Informace o posledním HTTP requestu.
172
     *
173
     * @var *
174
     */
175
    public $curlInfo;
176
177
    /**
178
     * Informace o poslední HTTP chybě.
179
     *
180
     * @var string
181
     */
182
    public $lastCurlError = null;
183
184
    /**
185
     * Used codes storage.
186
     *
187
     * @var array
188
     */
189
    public $codes = null;
190
191
    /**
192
     * Last Inserted ID.
193
     *
194
     * @var int
195
     */
196
    public $lastInsertedID = null;
197
198
    /**
199
     * Default Line Prefix.
200
     *
201
     * @var string
202
     */
203
    public $prefix = '/c/';
204
205
    /**
206
     * Raw Content of last curl response
207
     *
208
     * @var string
209
     */
210
    public $lastCurlResponse;
211
212
    /**
213
     * HTTP Response code of last request
214
     *
215
     * @var int
216
     */
217
    public $lastResponseCode = null;
218
219
    /**
220
     * Body data  for next curl POST operation
221
     *
222
     * @var string
223
     */
224
    protected $postFields = null;
225
226
    /**
227
     * Last operation result data or message(s)
228
     *
229
     * @var array
230
     */
231
    public $lastResult = null;
232
233
    /**
234
     * Number from  @rowCount in response
235
     * @var int
236
     */
237
    public $rowCount = null;
238
239
    /**
240
     * Number from  @globalVersion
241
     * @var int
242
     */
243
    public $globalVersion = null;
244
245
    /**
246
     * @link https://www.flexibee.eu/api/dokumentace/ref/zamykani-odemykani/
247
     * @var string filter query
248
     */
249
    public $filter;
250
251
    /**
252
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
253
     * @var string
254
     */
255
    protected $action;
256
257
    /**
258
     * Pole akcí které podporuje ta která evidence
259
     * @link https://demo.flexibee.eu/c/demo/faktura-vydana/actions.json Např. Akce faktury
260
     * @var array
261
     */
262
    public $actionsAvailable = null;
263
264
    /**
265
     * Parmetry pro URL
266
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Všechny podporované parametry
267
     * @var array
268
     */
269
    public $urlParams = [
270
        'add-global-version',
271
        'add-row-count',
272
        'as-gui',
273
        'auth',
274
        'authSessionId',
275
        'code-as-id',
276
        'code-in-response',
277
        'delimeter',
278
        'detail', //See: https://www.flexibee.eu/api/dokumentace/ref/detail-levels
279
        'dir',
280
        'dry-run', // See: https://www.flexibee.eu/api/dokumentace/ref/dry-run/
281
        'encoding',
282
        'export-settings',
283
        'fail-on-warning',
284
        'filter',
285
        'format',
286
        'idUcetniObdobi',
287
        'includes',
288
        'inDesktopApp', // Note: Undocumented function (html only)
289
        'limit',
290
        'mode',
291
        'no-ext-ids',
292
        'no-http-errors',
293
        'no-ids',
294
        'only-ext-ids',
295
        'order',
296
        'relations',
297
        'report-lang',
298
        'report-name',
299
        'report-sign',
300
        'skupina-stitku',
301
        'sort',
302
        'start',
303
        'stitky-as-ids',
304
        'use-ext-id',
305
        'use-internal-id',
306
        'xpath', // See: https://www.flexibee.eu/api/dokumentace/ref/xpath/
307
    ];
308
309
    /**
310
     * Session ID
311
     * @var string
312
     */
313
    public $authSessionId = null;
314
315
    /**
316
     * Token obtained during login procedure
317
     * @var string 
318
     */
319
    public $refreshToken = null;
320
321
    /**
322
     * Save 404 results to log ?
323
     * @var boolean
324
     */
325
    protected $ignoreNotFound = false;
326
327
    /**
328
     * Array of errors caused by last request
329
     * @var array
330
     */
331
    private $errors = [];
332
333
    /**
334
     * List of Error500 reports sent
335
     * @var array
336
     */
337
    private $reports = [];
338
339
    /**
340 70
     * Send Error500 Report to
341
     * @var string email address
342 70
     */
343
    public $reportRecipient = '[email protected]';
344 70
345 70
    /**
346 70
     * Formating string for \DateTime::format() for datetime columns
347 70
     * @var string
348 22
     */
349 22
    static public $DateTimeFormat = 'Y-m-d\TH:i:s.u+P';
350 70
351
    /**
352
     * Formating string for \DateTime::format() for date columns
353
     * @var string
354
     */
355
    static public $DateFormat = 'Y-m-d';
356
357
    /**
358 71
     * Last Request response stats
359
     * @var array 
360 71
     */
361 71
    private $responseStats = null;
362 71
363 71
    /**
364 71
     * Chained Objects
365 23
     * @var array
366 23
     */
367 71
    public $chained = [];
368 71
369 23
    /**
370 23
     * We Connect to server by default
371 71
     * @var boolean
372
     */
373
    public $offline = false;
374 71
375 71
    /**
376 71
     * Override cURL timeout
377
     * @var int seconds
378
     */
379
    public $timeout = null;
380
381
    /**
382
     * Columns Info for serveral evidencies
383
     * @var array 
384
     */
385 48
    private $columnsInfo = [];
386
387 48
    /**
388
     * Class for read only interaction with FlexiBee.
389
     *
390 48
     * @param mixed $init default record id or initial data
391 48
     * @param array $options Connection settings and other options override
392 48
     */
393
    public function __construct($init = null, $options = [])
394 48
    {
395
        $this->init = $init;
396
397
        parent::__construct();
398
        $this->setUp($options);
399 94
        $this->curlInit();
400
        if (!empty($init)) {
401 94
            $this->processInit($init);
402 94
        }
403 94
    }
404 94
405 94
    /**
406 94
     * Set internal Object name
407 94
     *
408 94
     * @param string $objectName
409 94
     *
410 94
     * @return string Jméno objektu
411
     */
412
    public function setObjectName($objectName = null)
413
    {
414
        return parent::setObjectName(is_null($objectName) ? ( empty($this->getRecordIdent())
415
                    ? $this->getObjectName() : $this->getRecordIdent().'@'.$this->getObjectName() )
416
                    : $objectName);
417
    }
418
419
    /**
420
     * SetUp Object to be ready for work
421
     *
422
     * @param array $options Object Options ( user,password,authSessionId
423 13
     *                                        company,url,evidence,
424
     *                                        prefix,defaultUrlParams,debug,
425 13
     *                                        detail,offline,filter,ignore404
426 10
     *                                        timeout
427 13
     */
428 13
    public function setUp($options = [])
429 13
    {
430 10
        $this->setupProperty($options, 'company', 'FLEXIBEE_COMPANY');
431 10
        $this->setupProperty($options, 'url', 'FLEXIBEE_URL');
432 10
        $this->setupProperty($options, 'user', 'FLEXIBEE_LOGIN');
433 8
        $this->setupProperty($options, 'password', 'FLEXIBEE_PASSWORD');
434
        $this->setupProperty($options, 'authSessionId', 'FLEXIBEE_AUTHSESSID');
435 13
        $this->setupProperty($options, 'timeout', 'FLEXIBEE_TIMEOUT');
436
        if (!empty($this->authSessionId)) {
437
            $this->defaultHttpHeaders['X-authSessionId'] = $this->authSessionId;
438
        }
439
        if (isset($options['evidence'])) {
440
            $this->setEvidence($options['evidence']);
441
        }
442 23
        $this->setupProperty($options, 'defaultUrlParams');
443
        if (isset($options['prefix'])) {
444
            $this->setPrefix($options['prefix']);
445 23
        }
446 23
        if (array_key_exists('detail', $options)) {
447 23
            $this->defaultUrlParams['detail'] = $options['detail'];
448 23
        }
449 23
        $this->setupProperty($options, 'filter');
450 23
        if (array_key_exists('offline', $options)) {
451 23
            $this->offline = (boolean) $options['offline'];
452 23
        }
453 23
454 23
        if (array_key_exists('ignore404', $options)) {
455 23
            $this->ignore404($options['ignore404']);
456 23
        }
457 23
458 23
        $this->setupProperty($options, 'debug');
459 23
        $this->updateApiURL();
460 23
    }
461 23
462 23
    /**
463
     * Set up one of properties
464
     *
465
     * @param array  $options  array of given properties
466
     * @param string $name     name of property to process
467
     * @param string $constant load default property value from constant
468
     */
469
    public function setupProperty($options, $name, $constant = null)
470
    {
471 23
        if (array_key_exists($name, $options)) {
472
            $this->$name = $options[$name];
473 23
        } else {
474 23
            if (property_exists($this, $name) && !empty($constant) && defined($constant)) {
475
                $this->$name = constant($constant);
476
            }
477
        }
478
    }
479
480 23
    /**
481 23
     * Get Current connection options for use in another object
482 23
     *
483 23
     * @return array usable as second constructor parameter
484 23
     */
485
    public function getConnectionOptions()
486
    {
487
        $conOpts = ['url' => $this->url];
488
        if (empty($this->authSessionId)) {
489
            $conOpts ['user']    = $this->user;
490
            $conOpts['password'] = $this->password;
491
        } else {
492
            $conOpts['authSessionId'] = $this->authSessionId;
493
        }
494 23
        $company = $this->getCompany();
495
        if (!empty($company)) {
496 23
            $conOpts['company'] = $company;
497 23
        }
498 23
        if (!is_null($this->timeout)) {
0 ignored issues
show
introduced by
The condition is_null($this->timeout) is always false.
Loading history...
499 23
            $conOpts['timeout'] = $this->timeout;
500
        }
501
        return $conOpts;
502
    }
503 23
504 23
    /**
505
     * Inicializace CURL
506
     *
507 20
     * @return boolean Online Status
508 20
     */
509
    public function curlInit()
510 20
    {
511 3
        if ($this->offline === false) {
512 3
            $this->curl = \curl_init(); // create curl resource
513 3
            curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); // return content as a string from curl_exec
514 3
            curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); // follow redirects (compatibility for future changes in FlexiBee)
515 23
            curl_setopt($this->curl, CURLOPT_HTTPAUTH, true);       // HTTP authentication
516 23
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); // FlexiBee by default uses Self-Signed certificates
517 23
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
518
            curl_setopt($this->curl, CURLOPT_VERBOSE, ($this->debug === true)); // For debugging
519
            if (empty($this->authSessionId)) {
520
                curl_setopt($this->curl, CURLOPT_USERPWD,
521
                    $this->user.':'.$this->password); // set username and password
522
            }
523
            if (!is_null($this->timeout)) {
0 ignored issues
show
introduced by
The condition is_null($this->timeout) is always false.
Loading history...
524
                curl_setopt($this->curl, CURLOPT_TIMEOUT, $this->timeout);
525
            }
526 69
        }
527
        return !$this->offline;
528 69
    }
529
530
    /**
531
     * Zinicializuje objekt dle daných dat. Možné hodnoty:
532
     *
533
     *  * 234                              - interní číslo záznamu k načtení
534
     *  * code:LOPATA                      - kód záznamu
535
     *  * BAGR                             - kód záznamu k načtení
536
     *  * ['id'=>24,'nazev'=>'hoblík']     - pole hodnot k předvyplnění
537 23
     *  * 743.json?relations=adresa,vazby  - část url s parametry k načtení
538
     *
539 23
     * @param mixed $init číslo/"(code:)kód"/(část)URI záznamu k načtení | pole hodnot k předvyplnění
540 23
     */
541
    public function processInit($init)
542
    {
543
        if (is_integer($init)) {
544
            $this->loadFromFlexiBee($init);
545
        } elseif (is_array($init)) {
546
            $this->takeData($init);
547
        } elseif (preg_match('/\.(json|xml|csv)/', $init)) {
548 23
            $this->takeData($this->getFlexiData((($init[0] != '/') ? $this->evidenceUrlWithSuffix($init)
549
                            : $init)));
550 23
        } else {
551
            $this->loadFromFlexiBee($init);
552
        }
553
    }
554
555
    /**
556
     * Set Data Field value
557
     *
558 25
     * @param string $columnName field name
559
     * @param mixed  $value      field data value
560 25
     *
561 25
     * @return bool Success
562
     */
563
    public function setDataValue($columnName, $value)
564 25
    {
565 1
        switch ($columnName) {
566 1
            case 'kod':
567 24
                $value = self::uncode($value); //Alwyas uncode "kod" column
568 24
                break;
569 24
            default:
570 25
                break;
571 25
        }
572
        if (is_object($value)) {
573
            switch (get_class($value)) {
574
                case 'DateTime':
575
                    $columnInfo = $this->getColumnInfo($columnName);
576
                    switch ($columnInfo['type']) {
577
                        case 'date':
578
                            $value = self::dateToFlexiDate($value);
579
                            break;
580
                        case 'datetime':
581 23
                            $value = self::dateToFlexiDateTime($value);
582
                            break;
583 23
                    }
584 23
                    break;
585 23
            }
586 23
        }
587 23
        return parent::setDataValue($columnName, $value);
588 23
    }
589 23
590 23
    /**
591 23
     * PHP Date object to FlexiBee date format
592 23
     * 
593 23
     * @param \DateTime $date
594 23
     */
595 23
    public static function dateToFlexiDate($date)
596
    {
597
        return $date->format(self::$DateFormat);
598
    }
599 23
600
    /**
601
     * PHP Date object to FlexiBee date format
602
     * 
603
     * @param \DateTime $dateTime
604
     */
605
    public static function dateToFlexiDateTime($dateTime)
606
    {
607
        return $dateTime->format(self::$DateTimeFormat);
608
    }
609 23
610
    /**
611 23
     * Set URL prefix
612 23
     *
613 22
     * @param string $prefix
614 22
     */
615 23
    public function setPrefix($prefix)
616 17
    {
617 17
        switch ($prefix) {
618 17
            case 'a': //Access
619 17
            case 'c': //Company
620 23
            case 'u': //User
621
            case 'g': //License Groups
622
            case 'admin':
623
            case 'status':
624 23
            case 'login-logout':
625
                $this->prefix = '/'.$prefix.'/';
626
                break;
627
            case null:
628
            case '':
629
            case '/':
630
                $this->prefix = '';
631
                break;
632
            default:
633
                throw new \Exception(sprintf('Unknown prefix %s', $prefix));
634 68
        }
635
    }
636 68
637 68
    /**
638 68
     * Set communication format.
639 62
     * One of html|xml|json|csv|dbf|xls|isdoc|isdocx|edi|pdf|pdf|vcf|ical
640 62
     *
641 68
     * @param string $format
642
     * 
643
     * @return boolen format is availble
0 ignored issues
show
Bug introduced by
The type FlexiPeeHP\boolen was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
644
     */
645
    public function setFormat($format)
646
    {
647
        $result = true;
648
        if (($this->debug === true) && !empty($this->evidence) && isset(Formats::$$this->evidence)) {
649
            if (array_key_exists($format, array_flip(Formats::$$this->evidence))
650
                === false) {
651 23
                $result = false;
652
            }
653 23
        }
654 23
        if ($result === true) {
655 23
            $this->format = $format;
656 23
            $this->updateApiURL();
657 23
        }
658 23
        return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result returns the type boolean which is incompatible with the documented return type FlexiPeeHP\boolen.
Loading history...
659 23
    }
660 23
661 23
    /**
662
     * Nastaví Evidenci pro Komunikaci.
663
     * Set evidence for communication
664
     *
665
     * @param string $evidence evidence pathName to use
666
     * 
667 48
     * @return boolean evidence switching status
668
     */
669 48
    public function setEvidence($evidence)
670 48
    {
671 48
        switch ($this->prefix) {
672
            case '/c/':
673
                if ($this->debug === true) {
674 48
                    if (array_key_exists($evidence, EvidenceList::$name)) {
675 48
                        $this->evidence = $evidence;
676
                        $result         = true;
677
                    } else {
678
                        throw new \Exception(sprintf('Try to set unsupported evidence %s',
679
                                $evidence));
680
                    }
681
                } else {
682
                    $this->evidence = $evidence;
683
                    $result         = true;
684
                }
685
                break;
686 23
            default:
687
                $this->evidence = $evidence;
688 23
                $result         = true;
689 23
                break;
690 23
        }
691 23
        $this->updateApiURL();
692 23
        return $result;
693 23
    }
694 23
695 23
    /**
696 23
     * Vrací právě používanou evidenci pro komunikaci
697 23
     * Obtain current used evidence
698 23
     *
699 23
     * @return string
700 23
     */
701
    public function getEvidence()
702
    {
703 23
        return $this->evidence;
704 23
    }
705 23
706
    /**
707
     * Set used company.
708 23
     * Nastaví Firmu.
709
     *
710
     * @param string $company
711
     */
712
    public function setCompany($company)
713
    {
714
        $this->company = $company;
715
    }
716
717
    /**
718 23
     * Obtain company now used
719
     * Vrací právě používanou firmu
720 23
     *
721
     * @return string
722
     */
723
    public function getCompany()
724
    {
725
        return $this->company;
726
    }
727
728
    /**
729
     * Vrací název evidence použité v odpovědích z FlexiBee
730
     *
731 25
     * @return string
732
     */
733
    public function getResponseEvidence()
734 25
    {
735
        switch ($this->evidence) {
736 25
            case 'c':
737
                $evidence = 'company';
738 25
                break;
739 4
            case 'evidence-list':
740 4
                $evidence = 'evidence';
741 22
                break;
742
            default:
743
                $evidence = $this->getEvidence();
744 25
                break;
745
        }
746 25
        return $evidence;
747 25
    }
748
749
    /**
750
     * Převede rekurzivně Objekt na pole.
751
     *
752
     * @param object|array $object
753
     *
754
     * @return array
755
     */
756
    public static function object2array($object)
757
    {
758 3
        $result = null;
759
        if (is_object($object)) {
760 3
            $objectData = get_object_vars($object);
761
            if (is_array($objectData) && count($objectData)) {
762 3
                $result = array_map('self::object2array', $objectData);
763 3
            }
764 3
        } else {
765
            if (is_array($object)) {
0 ignored issues
show
introduced by
The condition is_array($object) is always true.
Loading history...
766
                foreach ($object as $item => $value) {
767
                    $result[$item] = self::object2array($value);
768
                }
769
            } else {
770
                $result = $object;
771
            }
772
        }
773 3
774
        return $result;
775 3
    }
776
777
    /**
778
     * Převede rekurzivně v poli všechny objekty na jejich identifikátory.
779
     *
780
     * @param object|array $object
781
     *
782
     * @return array
783
     */
784
    public static function objectToID($object)
785 3
    {
786
        $resultID = null;
787 3
        if (is_object($object) && method_exists($object, '__toString')
788 3
        ) {
789 3
            $resultID = $object->__toString();
790 3
        } else {
791
            if (is_array($object)) {
792
                foreach ($object as $item => $value) {
793 3
                    $resultID[$item] = self::objectToID($value);
794
                }
795
            } else { //String
796
                $resultID = $object;
797 3
            }
798
        }
799
800
        return $resultID;
801
    }
802
803
    /**
804
     * Return basic URL for used Evidence
805
     *
806
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
807
     *
808
     * @return string Evidence URL
809
     */
810
    public function getEvidenceURL()
811
    {
812
        $evidenceUrl = $this->url.$this->prefix.$this->company;
813
        $evidence    = $this->getEvidence();
814
        if (!empty($evidence)) {
815
            $evidenceUrl .= '/'.$evidence;
816
        }
817
        return $evidenceUrl;
818
    }
819
820 3
    /**
821
     * Add suffix to Evidence URL
822 3
     *
823
     * @param string $urlSuffix
824 3
     *
825
     * @return string
826
     */
827
    public function evidenceUrlWithSuffix($urlSuffix)
828
    {
829
        $evidenceUrl = $this->getEvidenceUrl();
830
        if (!empty($urlSuffix)) {
831
            if (($urlSuffix[0] != '/') && ($urlSuffix[0] != ';') && ($urlSuffix[0]
832 3
                != '?')) {
833 3
                $evidenceUrl .= '/';
834 3
            }
835
            $evidenceUrl .= $urlSuffix;
836
        }
837 3
        return $evidenceUrl;
838
    }
839
840 3
    /**
841
     * Update $this->apiURL
842
     */
843
    public function updateApiURL()
844
    {
845
        $this->apiURL  = $this->getEvidenceURL();
846
        $rowIdentifier = $this->getRecordID();
847
        if (empty($rowIdentifier)) {
848
            $rowIdentifier = $this->getRecordCode();
849
            if (empty($rowIdentifier)) {
850
                $rowIdentifier = $this->getExternalID();
851
            }
852
        }
853
        if (!empty($rowIdentifier)) {
854
            $this->apiURL .= '/'.self::urlEncode($rowIdentifier);
0 ignored issues
show
Bug introduced by
It seems like $rowIdentifier can also be of type array; however, parameter $urlRaw of FlexiPeeHP\FlexiBeeRO::urlEncode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

854
            $this->apiURL .= '/'.self::urlEncode(/** @scrutinizer ignore-type */ $rowIdentifier);
Loading history...
855
        }
856
        $this->apiURL .= '.'.$this->format;
857
    }
858
    /*
859
     * Add Default Url params to given url if not overrided
860 3
     *
861
     * @param string $urlRaw
862
     *
863
     * @return string url with default params added
864
     */
865
866
    public function addDefaultUrlParams($urlRaw)
867
    {
868
        return \Ease\Shared::addUrlParams($urlRaw, $this->defaultUrlParams,
869
                false);
870
    }
871
872
    /**
873
     * Funkce, která provede I/O operaci a vyhodnotí výsledek.
874
     *
875
     * @param string $urlSuffix část URL za identifikátorem firmy.
876
     * @param string $method    HTTP/REST metoda
877
     * @param string $format    Requested format
878
     * 
879
     * @return array|boolean Výsledek operace
880
     */
881
    public function performRequest($urlSuffix = null, $method = 'GET',
882
                                   $format = null)
883
    {
884
        $this->rowCount      = null;
885
        $this->responseStats = [];
886
887
        if (preg_match('/^http/', $urlSuffix)) {
888
            $url = $urlSuffix;
889
        } elseif (strlen($urlSuffix) && ($urlSuffix[0] == '/')) {
890 3
            $url = $this->url.$urlSuffix;
891
        } else {
892 3
            $url = $this->evidenceUrlWithSuffix($urlSuffix);
893 3
        }
894 3
895 3
        $responseCode = $this->doCurlRequest($this->addDefaultUrlParams($url),
896
            $method, $format);
897 3
898
        return $this->parseResponse($this->rawResponseToArray($this->lastCurlResponse,
899 3
                    $this->responseFormat), $responseCode);
900
    }
901 3
902
    /**
903 3
     * Parse Raw FlexiBee response in several formats
904
     *
905 3
     * @param string $responseRaw raw response body
906 3
     * @param string $format      Raw Response format json|xml|etc
907 3
     *
908 3
     * @return array
909 3
     */
910 3
    public function rawResponseToArray($responseRaw, $format)
911 3
    {
912 3
        $responseDecoded = [];
913 3
        if (!empty(trim($responseRaw))) {
914 3
            switch ($format) {
915 3
                case 'json':
916 3
                    $responseDecoded = $this->rawJsonToArray($responseRaw);
917 3
                    break;
918
                case 'xml':
919 3
                    $responseDecoded = $this->rawXmlToArray($this->lastCurlResponse);
920
                    break;
921
                case 'txt':
922 3
                default:
923 3
                    $responseDecoded = [$this->lastCurlResponse];
924 3
                    break;
925 3
            }
926 3
        }
927 3
        return $responseDecoded;
928 3
    }
929 3
930 3
    /**
931
     * Convert FlexiBee Response JSON to Array
932
     *
933
     * @param string $rawJson
934
     *
935 3
     * @return array
936
     */
937
    public function rawJsonToArray($rawJson)
938
    {
939 3
        $responseDecoded = json_decode($rawJson, true, 10);
940
        $decodeError     = json_last_error_msg();
941
        if ($decodeError == 'No error') {
942
            if (array_key_exists($this->nameSpace, $responseDecoded)) {
943
                $responseDecoded = $responseDecoded[$this->nameSpace];
944
            }
945
        } else {
946
            $this->addStatusMessage('JSON Decoder: '.$decodeError, 'error');
947
            $this->addStatusMessage($rawJson, 'debug');
948
        }
949 23
        return $responseDecoded;
950
    }
951 23
952 23
    /**
953 23
     * Convert FlexiBee Response XML to Array
954 23
     *
955 15
     * @param string $rawXML
956 15
     *
957 15
     * @return array
958 23
     */
959
    public function rawXmlToArray($rawXML)
960
    {
961
        return self::xml2array($rawXML);
962
    }
963
964
    /**
965
     * Parse Response array
966
     *
967
     * @param array $responseDecoded
968 23
     * @param int $responseCode Request Response Code
969
     *
970 23
     * @return array main data part of response
971 23
     */
972 23
    public function parseResponse($responseDecoded, $responseCode)
973 23
    {
974 23
        if (is_array($responseDecoded)) {
0 ignored issues
show
introduced by
The condition is_array($responseDecoded) is always true.
Loading history...
975
            $mainResult          = $this->unifyResponseFormat($responseDecoded);
976 23
            $this->responseStats = array_key_exists('stats', $responseDecoded) ? (isset($responseDecoded['stats'][0])
977 23
                    ? $responseDecoded['stats'][0] : $responseDecoded['stats']) : null;
978 23
        } else {
979 23
            $mainResult = $responseDecoded;
980 23
        }
981
        switch ($responseCode) {
982 23
            case 201: //Success Write
983 23
            case 200: //Success Read
984 23
                if (is_array($responseDecoded)) {
0 ignored issues
show
introduced by
The condition is_array($responseDecoded) is always true.
Loading history...
985
                    $this->lastResult = $mainResult;
986
                    if (isset($responseDecoded['@rowCount'])) {
987
                        $this->rowCount = (int) $responseDecoded['@rowCount'];
988
                    }
989
                    if (isset($responseDecoded['@globalVersion'])) {
990 1
                        $this->globalVersion = (int) $responseDecoded['@globalVersion'];
991
                    }
992 1
                }
993 1
                break;
994 1
995 1
            case 500: // Internal Server Error
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...
996 1
                if ($this->debug === true) {
997
                    $this->error500Reporter($responseDecoded);
998
                }
999
            case 404: // Page not found
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...
1000
                if ($this->ignoreNotFound === true) {
1001 1
                    break;
1002
                }
1003 1
            case 400: //Bad Request parameters
1004 1
            default: //Something goes wrong
1005
                $this->addStatusMessage($this->lastResponseCode.': '.$this->curlInfo['url'],
1006
                    'warning');
1007
                if (is_array($responseDecoded)) {
0 ignored issues
show
introduced by
The condition is_array($responseDecoded) is always true.
Loading history...
1008
                    $this->parseError($responseDecoded);
1009
                }
1010
                $this->logResult($responseDecoded, $this->curlInfo['url']);
1011
                break;
1012
        }
1013 23
        return $mainResult;
1014
    }
1015 23
1016 23
    /**
1017 22
     * Parse error message response
1018
     *
1019
     * @param array $responseDecoded
1020
     * 
1021 22
     * @return int number of errors processed
1022
     */
1023
    public function parseError(array $responseDecoded)
1024
    {
1025
        if (array_key_exists('results', $responseDecoded)) {
1026
            $this->errors = $responseDecoded['results'][0]['errors'];
1027
            foreach ($this->errors as $errorInfo) {
1028
                $this->addStatusMessage($errorInfo['message'], 'error');
1029
                if (array_key_exists('for', $errorInfo)) {
1030
                    unset($errorInfo['message']);
1031
                    $this->addStatusMessage(json_encode($errorInfo), 'debug');
1032
                }
1033
            }
1034
        } else {
1035
            if (array_key_exists('message', $responseDecoded)) {
1036
                $this->errors = [['message' => $responseDecoded['message']]];
1037
            }
1038
        }
1039
        return count($this->errors);
1040
    }
1041
1042
    /**
1043
     * Vykonej HTTP požadavek
1044
     *
1045
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
1046
     * @param string $url    URL požadavku
1047
     * @param string $method HTTP Method GET|POST|PUT|OPTIONS|DELETE
1048
     * @param string $format požadovaný formát komunikace
1049
     * 
1050
     * @return int HTTP Response CODE
1051
     */
1052
    public function doCurlRequest($url, $method, $format = null)
1053
    {
1054
        if (is_null($format)) {
1055
            $format = $this->format;
1056
        }
1057
        curl_setopt($this->curl, CURLOPT_URL, $url);
1058
// Nastavení samotné operace
1059 15
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, strtoupper($method));
1060
//Vždy nastavíme byť i prázná postdata jako ochranu před chybou 411
1061 15
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->postFields);
1062 15
1063
        $httpHeaders = $this->defaultHttpHeaders;
1064 15
1065 8
        $formats = Formats::bySuffix();
1066 7
1067 7
        if (!isset($httpHeaders['Accept'])) {
1068 7
            $httpHeaders['Accept'] = $formats[$format]['content-type'];
1069
        }
1070 8
        if (!isset($httpHeaders['Content-Type'])) {
1071 1
            $httpHeaders['Content-Type'] = $formats[$format]['content-type'];
1072 1
        }
1073 8
        $httpHeadersFinal = [];
1074
        foreach ($httpHeaders as $key => $value) {
1075 15
            if (($key == 'User-Agent') && ($value == 'FlexiPeeHP')) {
1076 4
                $value .= ' v'.self::$libVersion;
1077 4
            }
1078 4
            $httpHeadersFinal[] = $key.': '.$value;
1079
        }
1080
1081
        curl_setopt($this->curl, CURLOPT_HTTPHEADER, $httpHeadersFinal);
1082
1083 4
// Proveď samotnou operaci
1084
        $this->lastCurlResponse            = curl_exec($this->curl);
1085 15
        $this->curlInfo                    = curl_getinfo($this->curl);
1086
        $this->curlInfo['when']            = microtime();
1087 15
        $this->curlInfo['request_headers'] = $httpHeadersFinal;
1088 15
        $this->responseFormat              = $this->contentTypeToResponseFormat($this->curlInfo['content_type'],
1089
            $url);
1090
        $this->lastResponseCode            = $this->curlInfo['http_code'];
1091 15
        $this->lastCurlError               = curl_error($this->curl);
1092
        if (strlen($this->lastCurlError)) {
1093 15
            $this->addStatusMessage(sprintf('Curl Error (HTTP %d): %s',
1094 15
                    $this->lastResponseCode, $this->lastCurlError), 'error');
1095 15
        }
1096
1097 15
        if ($this->debug === true) {
1098
            $this->saveDebugFiles();
1099 15
        }
1100 15
1101 15
        return $this->lastResponseCode;
1102 9
    }
1103 9
1104 6
    /**
1105 6
     * Obtain json for application/json
1106 9
     * 
1107 6
     * @param string $contentType
1108
     * @param string $url
1109
     * 
1110 15
     * @return string response format
1111
     */
1112
    public function contentTypeToResponseFormat($contentType, $url = null)
1113
    {
1114
        if (!empty($url)) {
1115
            $url = parse_url($url, PHP_URL_PATH);
1116
        }
1117
1118
        $contentTypeClean = strstr($contentType, ';') ? substr($contentType, 0,
1119
                strpos($contentType, ';')) : $contentType;
1120
1121 23
        switch ($url) {
1122
            case '/login-logout/login';
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1123 23
                $responseFormat = 'json';
1124 23
                break;
1125 23
            default :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1126 23
                switch ($contentTypeClean) {
1127 23
                    case 'text/javascript':
1128
                        $responseFormat = 'js';
1129
                        break;
1130
1131 23
                    default:
1132
                        $responseFormat = Formats::contentTypeToSuffix($contentTypeClean);
1133
                        break;
1134
                }
1135 23
                break;
1136 22
        }
1137 22
1138 9
        return $responseFormat;
1139 9
    }
1140 22
1141
    /**
1142
     * Nastaví druh prováděné akce.
1143
     *
1144
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
1145
     * @param string $action
1146
     * 
1147
     * @return boolean
1148
     */
1149
    public function setAction($action)
1150
    {
1151 6
        $result           = false;
1152
        $actionsAvailable = $this->getActionsInfo();
1153
        if (is_array($actionsAvailable) && array_key_exists($action,
1154 6
                $actionsAvailable)) {
1155 6
            $this->action = $action;
1156 6
            $result       = true;
1157 6
        }
1158 6
        return $result;
1159
    }
1160 6
1161
    /**
1162
     * Convert XML to array.
1163
     *
1164
     * @param string $xml
1165 6
     *
1166
     * @return array
1167
     */
1168
    public static function xml2array($xml)
1169 6
    {
1170
        $arr = [];
1171
        if (!empty($xml)) {
1172
            if (is_string($xml)) {
0 ignored issues
show
introduced by
The condition is_string($xml) is always true.
Loading history...
1173
                $xml = simplexml_load_string($xml);
1174
            }
1175
            foreach ($xml->attributes() as $a) {
1176
                $arr['@'.$a->getName()] = strval($a);
1177 16
            }
1178
            foreach ($xml->children() as $r) {
1179 16
                if (count($r->children()) == 0) {
1180 9
                    $arr[$r->getName()] = strval($r);
1181 9
                } else {
1182 16
                    $arr[$r->getName()][] = self::xml2array($r);
1183 16
                }
1184 16
            }
1185
        }
1186 16
        return $arr;
1187 16
    }
1188 16
1189 15
    /**
1190 15
     * Odpojení od FlexiBee.
1191
     */
1192
    public function disconnect()
1193
    {
1194
        if (is_resource($this->curl)) {
1195
            curl_close($this->curl);
1196
        }
1197
        $this->curl = null;
1198
    }
1199 15
1200
    /**
1201
     * Disconnect CURL befere pass away
1202 15
     */
1203 10
    public function __destruct()
1204 10
    {
1205 15
        $this->disconnect();
1206 15
    }
1207 15
1208 15
    /**
1209
     * Načte řádek dat z FlexiBee.
1210 14
     *
1211 14
     * @param int $recordID id požadovaného záznamu
1212 14
     *
1213 14
     * @return array
1214 10
     */
1215
    public function getFlexiRow($recordID)
1216 14
    {
1217 14
        $record   = null;
1218
        $response = $this->performRequest($this->evidence.'/'.$recordID.'.json');
1219
        if (isset($response[$this->evidence])) {
1220
            $record = $response[$this->evidence][0];
1221
        }
1222
1223
        return $record;
1224
    }
1225
1226
    /**
1227
     * Oddělí z pole podmínek ty jenž patří za ? v URL požadavku
1228
     *
1229
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
1230
     * @param array $conditions pole podmínek   - rendrují se do ()
1231
     * @param array $urlParams  pole parametrů  - rendrují za ?
1232
     */
1233
    public function extractUrlParams(&$conditions, &$urlParams)
1234
    {
1235
        foreach ($this->urlParams as $urlParam) {
1236
            if (isset($conditions[$urlParam])) {
1237
                \Ease\Sand::divDataArray($conditions, $urlParams, $urlParam);
1238
            }
1239
        }
1240
    }
1241
1242
    /**
1243
     * convert unicode to entities for use with FlexiBee queries
1244
     *
1245
     * @param string $urlRaw
1246
     * 
1247
     * @return string
1248
     */
1249
    public static function urlEncode($urlRaw)
1250
    {
1251
        return str_replace(['%27', '%3A'], ["'", ':'], rawurlencode($urlRaw));
1252 15
    }
1253
1254
    /**
1255 15
     * Načte data z FlexiBee.
1256 15
     *
1257 15
     * @param string $suffix     dotaz
1258
     * @param string|array       $conditions Custom filters or modifiers
1259 15
     *
1260 15
     * @return array Data obtained
1261 15
     */
1262 15
    public function getFlexiData($suffix = null, $conditions = null)
1263 15
    {
1264 15
        $finalUrl          = '';
1265 15
        $evidenceToRestore = null;
1266 15
        $urlParams         = $this->defaultUrlParams;
1267
1268 15
        if (!empty($conditions)) {
1269
            if (is_array($conditions)) {
1270
                $this->extractUrlParams($conditions, $urlParams);
1271 15
                if (array_key_exists('evidence', $conditions)) {
1272
                    $evidenceToRestore = $this->getEvidence();
1273
                    $this->setEvidence($conditions['evidence']);
1274 15
                    unset($conditions['evidence']);
1275 15
                }
1276 15
                $conditions = $this->flexiUrl($conditions);
1277 15
            }
1278 15
1279
            if (strlen($conditions) && ($conditions[0] != '/')) {
1280 15
                $conditions = '('.self::urlEncode($conditions).')';
1281
            }
1282 15
        }
1283
1284 15
        if (strlen($suffix)) {
1285 9
            if (preg_match('/^http/', $suffix) || ($suffix[0] == '/') || is_numeric($suffix)) {
1286 9
                $finalUrl = $suffix;
1287
            } else {
1288 15
                if (preg_match('/^(code|ext):(.*)/', $suffix)) {
1289
                    $finalUrl = self::urlizeId($suffix);
1290
                } else {
1291
                    $finalUrl = $suffix;
1292
                }
1293
            }
1294
        }
1295
1296
        $finalUrl .= $conditions;
1297
1298
        if (count($urlParams)) {
1299 23
            if (strstr($finalUrl, '?')) {
1300
                $finalUrl .= '&';
1301 23
            } else {
1302
                $finalUrl .= '?';
1303 23
            }
1304 23
            $finalUrl .= http_build_query($urlParams, null, '&',
1305 23
                PHP_QUERY_RFC3986);
1306
        }
1307 23
1308 23
        $transactions     = $this->performRequest($finalUrl, 'GET');
1309 23
        $responseEvidence = $this->getResponseEvidence();
1310
        if (is_array($transactions) && array_key_exists($responseEvidence,
1311 23
                $transactions)) {
1312 23
            $result = $transactions[$responseEvidence];
1313 23
            if ((count($result) == 1) && (count(current($result)) == 0 )) {
1314 23
                $result = null; // Response is empty Array
1315 23
            }
1316 23
        } else {
1317 23
            $result = $transactions;
1318 23
        }
1319 23
        if (!is_null($evidenceToRestore)) {
1320 23
            $this->setEvidence($evidenceToRestore);
1321
        }
1322
        return $result;
1323
    }
1324 23
1325 23
    /**
1326 23
     * Načte záznam z FlexiBee a uloží v sobě jeho data
1327
     * Read FlexiBee record and store it inside od object
1328 23
     *
1329 23
     * @param int $id ID or conditions
1330 23
     *
1331 23
     * @return int počet načtených položek
1332
     */
1333
    public function loadFromFlexiBee($id = null)
1334 23
    {
1335 23
        $data = [];
1336 23
        if (is_null($id)) {
1337 23
            $id = $this->getMyKey();
1338 23
        }
1339 23
        $flexidata = $this->getFlexiData($this->getEvidenceUrl().'/'.self::urlizeId($id));
1340 23
        if ($this->lastResponseCode == 200) {
1341 23
            $this->apiURL = $this->curlInfo['url'];
1342 23
            if (is_array($flexidata) && (count($flexidata) == 1) && is_array(current($flexidata))) {
1343 23
                $data = current($flexidata);
1344 23
            }
1345 23
        }
1346
        return $this->takeData($data);
1347 23
    }
1348 23
1349
    /**
1350 23
     * Reload current record from FlexiBee
1351
     * 
1352
     * @return boolean 
1353
     */
1354
    public function reload()
1355
    {
1356
        $id = $this->getRecordIdent();
1357
        $this->dataReset();
1358
        $this->loadFromFlexiBee($id);
0 ignored issues
show
Bug introduced by
It seems like $id can also be of type string; however, parameter $id of FlexiPeeHP\FlexiBeeRO::loadFromFlexiBee() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1358
        $this->loadFromFlexiBee(/** @scrutinizer ignore-type */ $id);
Loading history...
1359
        return $this->lastResponseCode == 200;
1360 23
    }
1361
1362 23
    /**
1363 23
     * Set Filter code for requests
1364 23
     *
1365
     * @link https://www.flexibee.eu/api/dokumentace/ref/zamykani-odemykani/
1366
     *
1367 23
     * @param array|string $filter filter formula or ['key'=>'value']
1368 23
     *
1369 23
     * @return string Filter code
1370 23
     */
1371 23
    public function setFilter($filter)
1372
    {
1373
        return $this->filter = is_array($filter) ? self::flexiUrl($filter) : $filter;
1374 23
    }
1375 23
1376 23
    /**
1377
     * Převede data do Json formátu pro FlexiBee.
1378 23
     * Convert data to FlexiBee like Json format
1379 23
     *
1380 23
     * @url https://www.flexibee.eu/api/dokumentace/ref/actions/
1381 23
     * @url https://www.flexibee.eu/api/dokumentace/ref/zamykani-odemykani/
1382 23
     *
1383
     * @param array $data    object data
1384 23
     * @param int   $options json_encode options like JSON_PRETTY_PRINT etc
1385 23
     *
1386 23
     * @return string
1387 23
     */
1388 23
    public function getJsonizedData($data = null, $options = 0)
1389
    {
1390 23
        if (is_null($data)) {
1391 23
            $data = $this->getData();
1392 23
        }
1393 23
1394
        $dataToJsonize = array_merge(['@version' => $this->protoVersion],
1395
            $this->getDataForJSON($data));
1396 23
        $jsonRaw       = json_encode([$this->nameSpace => $dataToJsonize],
1397
            $options);
1398
1399 23
        return $jsonRaw;
1400
    }
1401
1402 23
    /**
1403 23
     * Get Data Fragment specific for current object
1404 23
     *
1405 23
     * @param array $data
1406 23
     *
1407 23
     * @return array
1408
     */
1409
    public function getDataForJSON($data = null)
1410
    {
1411
        if (is_null($data)) {
1412
            $data = $this->getData();
1413
        }
1414
1415
        $dataForJson = [$this->getEvidence() => $this->objectToID($data)];
1416
1417
        if (!is_null($this->action)) {
0 ignored issues
show
introduced by
The condition is_null($this->action) is always false.
Loading history...
1418
            $dataForJson[$this->evidence.'@action'] = $this->action;
1419
            $this->action                           = null;
1420
        }
1421
1422
        if (!is_null($this->filter)) {
0 ignored issues
show
introduced by
The condition is_null($this->filter) is always false.
Loading history...
1423
            $dataForJson[$this->evidence.'@filter'] = $this->filter;
1424
        }
1425
1426
1427
        foreach ($this->chained as $chained) {
1428
            $chainedData = $chained->getDataForJSON();
1429
            foreach ($chainedData as $chainedItemEvidence => $chainedItemData) {
1430
                if (array_key_exists($chainedItemEvidence, $dataForJson)) {
1431
                    if (is_string(key($dataForJson[$chainedItemEvidence]))) {
1432
                        $dataBackup                          = $dataForJson[$chainedItemEvidence];
1433
                        $dataForJson[$chainedItemEvidence]   = [];
1434
                        $dataForJson[$chainedItemEvidence][] = $dataBackup;
1435
                    }
1436
                    if (array_key_exists(0, $chainedItemData)) {
1437
                        foreach ($chainedItemData as $chainedItem) {
1438
                            $dataForJson[$chainedItemEvidence][] = $chainedItem;
1439
                        }
1440
                    } else {
1441
                        $dataForJson[$chainedItemEvidence][] = $chainedItemData;
1442
                    }
1443
                } else {
1444 23
                    $dataForJson[$chainedItemEvidence] = $chainedItemData;
1445
                }
1446 23
            }
1447
        }
1448 23
1449 23
1450 23
        return $dataForJson;
1451 23
    }
1452 23
1453 23
    /**
1454 23
     * Join another FlexiPeeHP Object
1455 23
     *
1456 23
     * @param FlexiBeeRO $object
1457
     *
1458 23
     * @return boolean adding to stack success
1459 23
     */
1460 23
    public function join(&$object)
1461 23
    {
1462 23
        $result = true;
1463
        if (method_exists($object, 'getDataForJSON')) {
1464
            $this->chained[] = $object;
1465 23
        } else {
1466 23
            throw new \Ease\Exception('$object->getDataForJSON() does not exist');
1467
        }
1468
1469 23
        return $result;
1470
    }
1471 23
1472 23
    /**
1473
     * Prepare record ID to use in URL
1474 23
     * 
1475
     * @param mixed $id
1476
     * 
1477 23
     * @return string id ready for use in URL
1478 23
     */
1479
    public static function urlizeId($id)
1480
    {
1481
        if (is_array($id)) {
1482
            $id = rawurlencode('('.self::flexiUrl($id).')');
1483
        } else if (preg_match('/^ext:/', $id)) {
1484
            $id = self::urlEncode($id);
1485
        } else if (preg_match('/^code:/', $id)) {
1486
            $id = self::code(self::urlEncode(self::uncode($id)));
1487
        }
1488
        return $id;
1489 65
    }
1490
1491 65
    /**
1492 65
     * Test if given record ID exists in FlexiBee.
1493
     *
1494
     * @param mixed $identifer presence state
1495 65
     *
1496 65
     * @return boolean
1497
     */
1498
    public function idExists($identifer = null)
1499
    {
1500
        if (is_null($identifer)) {
1501 65
            $identifer = $this->getMyKey();
1502
        }
1503
        $ignorestate = $this->ignore404();
1504
        $this->ignore404(true);
1505
        $this->getFlexiData(null,
1506
            [
1507
                'detail' => 'custom:'.$this->getKeyColumn(),
1508
                $this->getKeyColumn() => $identifer
1509
        ]);
1510
        $this->ignore404($ignorestate);
1511 71
        return $this->lastResponseCode == 200;
1512
    }
1513 71
1514
    /**
1515
     * Test if given record exists in FlexiBee.
1516
     *
1517
     * @param array|string|int $data ext:id:23|code:ITEM|['id'=>23]|23
1518
     * 
1519
     * @return boolean Record presence status
1520
     */
1521
    public function recordExists($data = [])
1522 23
    {
1523
1524 23
        if (empty($data)) {
1525
            $data = $this->getData();
1526
        }
1527
        $ignorestate = $this->ignore404();
1528
        $this->ignore404(true);
1529
        $keyColumn   = $this->getKeyColumn();
1530
        $res         = $this->getColumnsFromFlexibee([$keyColumn],
1531
            is_array($data) ? $data : [$keyColumn => $data]);
1532 15
1533
        if (empty($res) || (isset($res['success']) && ($res['success'] == 'false'))
1534 15
            || ((isset($res) && is_array($res)) && !isset($res[0]) )) {
1535 15
            $found = false;
1536 15
        } else {
1537 15
            $found = true;
1538 15
        }
1539 9
        $this->ignore404($ignorestate);
1540 9
        return $found;
1541 15
    }
1542
1543
    /**
1544
     * Subitems - ex. items of invoice
1545
     * 
1546
     * @return array of document items or null
1547
     */
1548
    public function getSubItems()
1549
    {
1550 23
        return array_key_exists('polozkyFaktury', $this->getData()) ? $this->getDataValue('polozkyFaktury')
1551
                : (array_key_exists('polozkyDokladu', $this->getData()) ? $this->getDataValue('polozkyDokladu')
1552 23
                : null);
1553 23
    }
1554 23
1555 23
    /**
1556 23
     * Vrací z FlexiBee sloupečky podle podmínek.
1557 23
     *
1558 23
     * @param array|int|string $conditions pole podmínek nebo ID záznamu
1559 23
     * @param string           $indexBy    klice vysledku naplnit hodnotou ze
1560 23
     *                                     sloupečku
1561 23
     * @return array
1562 23
     */
1563 23
    public function getAllFromFlexibee($conditions = null, $indexBy = null)
1564 23
    {
1565 23
        if (is_int($conditions)) {
1566
            $conditions = [$this->getmyKeyColumn() => $conditions];
0 ignored issues
show
Bug introduced by
The method getmyKeyColumn() does not exist on FlexiPeeHP\FlexiBeeRO. Did you maybe mean getKeyColumn()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1566
            $conditions = [$this->/** @scrutinizer ignore-call */ getmyKeyColumn() => $conditions];

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1567 23
        }
1568
1569
        $flexiData = $this->getFlexiData('', $conditions);
1570
1571
        if (!is_null($indexBy)) {
1572
            $flexiData = $this->reindexArrayBy($flexiData);
1573
        }
1574
1575
        return $flexiData;
1576
    }
1577 22
1578
    /**
1579 22
     * Vrací z FlexiBee sloupečky podle podmínek.
1580
     *
1581 21
     * @param string[] $columnsList seznam položek
1582
     * @param array    $conditions  pole podmínek nebo ID záznamu
1583
     * @param string   $indexBy     Sloupeček podle kterého indexovat záznamy
1584
     *
1585
     * @return array
1586
     */
1587
    public function getColumnsFromFlexibee($columnsList, $conditions = [],
1588
                                           $indexBy = null)
1589 22
    {
1590
        $detail = 'full';
1591 22
        switch (gettype($columnsList)) {
1592 22
            case 'integer': //Record ID
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...
1593 22
                $conditions = [$this->getmyKeyColumn() => $conditions];
1594
            case 'array': //Few Conditions
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...
1595
                if (!is_null($indexBy) && !array_key_exists($indexBy,
1596 22
                        $columnsList)) {
1597
                    $columnsList[] = $indexBy;
1598
                }
1599
                $columns = implode(',', array_unique($columnsList));
1600
                $detail  = 'custom:'.$columns;
1601
            default:
1602
                switch ($columnsList) {
1603
                    case 'id':
1604
                        $detail = 'id';
1605 22
                        break;
1606
                    case 'summary':
1607 22
                        $detail = 'summary';
1608 22
                        break;
1609 22
                    default:
1610 22
                        break;
1611 22
                }
1612 22
                break;
1613 22
        }
1614 22
1615 22
        $conditions['detail'] = $detail;
1616 22
1617 22
        $flexiData = $this->getFlexiData(null, $conditions);
1618 22
1619
        if (is_string($indexBy) && is_array($flexiData) && array_key_exists(0,
1620 22
                $flexiData) && array_key_exists($indexBy, $flexiData[0])) {
1621
            $flexiData = $this->reindexArrayBy($flexiData, $indexBy);
1622
        }
1623
1624
        return $flexiData;
1625
    }
1626
1627
    /**
1628
     * Vrací kód záznamu.
1629
     * Obtain record CODE
1630
     *
1631
     * @param mixed $data
1632 22
     *
1633
     * @return string
1634
     */
1635
    public function getKod($data = null, $unique = true)
1636
    {
1637
        $kod = null;
1638
1639
        if (is_null($data)) {
1640
            $data = $this->getData();
1641 23
        }
1642
1643 23
        if (is_string($data)) {
1644 23
            $data = [$this->nameColumn => $data];
1645 23
        }
1646 23
1647 16
        if (isset($data['kod'])) {
1648 16
            $kod = $data['kod'];
1649 23
        } else {
1650
            if (isset($data[$this->nameColumn])) {
1651
                $kod = preg_replace('/[^a-zA-Z0-9]/', '',
1652
                    \Ease\Sand::rip($data[$this->nameColumn]));
1653
            } else {
1654
                if (isset($data[$this->keyColumn])) {
1655
                    $kod = \Ease\Sand::rip($data[$this->keyColumn]);
1656
                }
1657
            }
1658 23
            $kod = substr($kod, 0, 20);
1659
        }
1660 23
1661 23
        if (!strlen($kod)) {
1662 23
            $kod = 'NOTSET';
1663 23
        }
1664 23
1665 23
        if (strlen($kod) > 18) {
1666 23
            $kodfinal = strtoupper(substr($kod, 0, 18));
1667 23
        } else {
1668 23
            $kodfinal = strtoupper($kod);
1669
        }
1670
1671
        if ($unique) {
1672
            $counter = 0;
1673
            if (!empty($this->codes) && count($this->codes)) {
1674
                foreach ($this->codes as $codesearch => $keystring) {
1675
                    if (strstr($codesearch, $kodfinal)) {
1676
                        ++$counter;
1677 23
                    }
1678
                }
1679 23
            }
1680 23
            if ($counter) {
1681 23
                $kodfinal = $kodfinal.$counter;
1682 23
            }
1683 23
1684 23
            $this->codes[$kodfinal] = $kod;
1685 13
        }
1686 13
1687 23
        return self::code($kodfinal);
1688
    }
1689
1690
    /**
1691
     * Write Operation Result.
1692
     *
1693
     * @param array  $resultData
1694
     * @param string $url        URL
1695
     * 
1696 23
     * @return boolean Log save success
1697
     */
1698 23
    public function logResult($resultData = null, $url = null)
1699 23
    {
1700 23
        $logResult = false;
1701 23
        if (isset($resultData['success']) && ($resultData['success'] == 'false')) {
1702 23
            if (isset($resultData['message'])) {
1703 16
                $this->addStatusMessage($resultData['message'], 'warning');
1704 16
            }
1705 23
            $this->addStatusMessage('Error '.$this->lastResponseCode.': '.urldecode($url),
1706
                'warning');
1707
            unset($url);
1708
        }
1709
        if (is_null($resultData)) {
1710
            $resultData = $this->lastResult;
1711
        }
1712
        if (isset($url)) {
1713
            $this->logger->addStatusMessage($this->lastResponseCode.':'.urldecode($url));
1714 23
        }
1715
1716 23
        if (isset($resultData['results'])) {
1717 23
            if ($resultData['success'] == 'false') {
1718 23
                $status = 'error';
1719 23
            } else {
1720 23
                $status = 'success';
1721 16
            }
1722 16
            foreach ($resultData['results'] as $result) {
1723 23
                if (isset($result['request-id'])) {
1724
                    $rid = $result['request-id'];
1725
                } else {
1726
                    $rid = '';
1727
                }
1728
                if (isset($result['errors'])) {
1729
                    foreach ($result['errors'] as $error) {
1730
                        $message = $error['message'];
1731 23
                        if (isset($error['for'])) {
1732
                            $message .= ' for: '.$error['for'];
1733 23
                        }
1734 1
                        if (isset($error['value'])) {
1735 1
                            $message .= ' value:'.$error['value'];
1736 23
                        }
1737 23
                        if (isset($error['code'])) {
1738
                            $message .= ' code:'.$error['code'];
1739
                        }
1740
                        $this->addStatusMessage($rid.': '.$message, $status);
1741
                    }
1742
                }
1743
            }
1744 20
        }
1745
        return $logResult;
1746 20
    }
1747 20
1748 20
    /**
1749 20
     * Save RAW Curl Request & Response to files in Temp directory
1750
     */
1751
    public function saveDebugFiles()
1752
    {
1753
        $tmpdir   = sys_get_temp_dir();
1754
        $fname    = $this->evidence.'-'.$this->curlInfo['when'].'.'.$this->format;
1755 20
        $reqname  = $tmpdir.'/request-'.$fname;
1756
        $respname = $tmpdir.'/response-'.$fname;
1757
        if (file_put_contents($reqname, $this->postFields)) {
1758
            $this->addStatusMessage($reqname, 'debug');
1759
        }
1760
        if (file_put_contents($respname, $this->lastCurlResponse)) {
1761
            $this->addStatusMessage($respname, 'debug');
1762
        }
1763
    }
1764
1765
    /**
1766
     * Připraví data pro odeslání do FlexiBee
1767
     *
1768
     * @param string $data
1769
     */
1770
    public function setPostFields($data)
1771
    {
1772
        $this->postFields = $data;
1773
    }
1774
1775
    /**
1776
     * Get Content ready to be send as POST body
1777
     * @return string
1778
     */
1779
    public function getPostFields()
1780
    {
1781
        return $this->postFields;
1782
    }
1783
1784
    /**
1785
     * Generuje fragment url pro filtrování.
1786
     *
1787
     * @see https://www.flexibee.eu/api/dokumentace/ref/filters
1788
     *
1789
     * @param array  $data   key=>values; value can bee class DatePeriod
1790
     * @param string $joiner default and/or
1791
     * @param string $defop  default operator
1792
     *
1793
     * @return string
1794
     */
1795
    public static function flexiUrl(array $data, $joiner = 'and', $defop = 'eq')
1796
    {
1797
        $parts = [];
1798
1799
        foreach ($data as $column => $value) {
1800
            if (!is_numeric($column)) {
1801
                if (is_integer($data[$column]) || is_float($data[$column])) {
1802
                    $parts[$column] = $column.' eq \''.$data[$column].'\'';
1803
                } elseif (is_bool($data[$column])) {
1804
                    $parts[$column] = $data[$column] ? $column.' eq true' : $column.' eq false';
1805
                } elseif (is_null($data[$column])) {
1806
                    $parts[$column] = $column." is null";
1807
                } elseif (is_object($data[$column])) {
1808
                    switch (get_class($data[$column])) {
1809
                        case 'DatePeriod':
1810
                            $parts[$column] = $column." between '".$data[$column]->getStartDate()->format(self::$DateFormat)."' '".$data[$column]->getEndDate()->format(self::$DateFormat)."'";
1811
                            break;
1812
                        case 'DateTime':
1813
                            $parts[$column] = $column." eq '".$data[$column]->format(self::$DateFormat)."'";
1814
                            break;
1815
                        default:
1816
                            $parts[$column] = $column." $defop '".$data[$column]."'";
1817
                            break;
1818
                    }
1819
                } else {
1820
                    switch ($value) {
1821
                        case '!null':
1822
                            $parts[$column] = $column." is not null";
1823
                            break;
1824
                        case 'is empty':
1825
                        case 'is not empty':
1826
                            $parts[$column] = $column.' '.$value;
1827
                            break;
1828
                        default:
1829
                            switch (explode(' ', trim($value))[0]) {
1830
                                case 'like':
1831
                                case 'begins':
1832
                                case 'ends':
1833
                                    $parts[$column] = $column         .= ' '.$value;
1834
                                    break;
1835
                                default:
1836
                                    if ($column == 'stitky') {
1837
                                        $parts[$column] = $column."='".self::code($data[$column])."'";
1838
                                    } else {
1839
                                        $parts[$column] = $column." $defop '".$data[$column]."'";
1840
                                    }
1841
                                    break;
1842
                            }
1843
1844
                            break;
1845 23
                    }
1846
                }
1847 23
            } else {
1848
                $parts[] = $value;
1849
            }
1850
        }
1851
        return implode(' '.$joiner.' ', $parts);
1852
    }
1853
1854
    /**
1855
     * Obtain record/object numeric identificator id:
1856
     * Vrací číselný identifikátor objektu id:
1857 23
     *
1858
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1859 23
     *
1860
     * @return null|int indentifikátor záznamu reprezentovaného objektem
1861
     */
1862
    public function getRecordID()
1863
    {
1864
        $id = $this->getDataValue('id');
1865
        return is_null($id) ? null : is_numeric($id) ? intval($id) : $id;
1866
    }
1867
1868
    /**
1869
     * Obtain record/object identificator code:
1870
     * Vrací identifikátor objektu code:
1871
     *
1872
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1873
     *
1874
     * @return string record code identifier
1875
     */
1876
    public function getRecordCode()
1877
    {
1878
        return empty($this->getDataValue('kod')) ? null : self::code($this->getDataValue('kod'));
1879
    }
1880
1881
    /**
1882
     * Obtain record/object identificator extId: code: or id:
1883
     * Vrací identifikátor objektu extId: code: nebo id:
1884
     *
1885
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1886
     *
1887
     * @return string|int|null record code identifier
1888
     */
1889
    public function getRecordIdent()
1890
    {
1891
        $ident = $this->getExternalID();
1892
        if (empty($ident)) {
1893
            $ident = $this->getRecordCode();
1894
        }
1895
        if (empty($ident)) {
1896
            $ident = $this->getRecordID();
1897
        }
1898
        return $ident;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ident also could return the type array which is incompatible with the documented return type integer|null|string.
Loading history...
1899
    }
1900
1901
    /**
1902
     * Obtain record/object identificator code: or id:
1903
     * Vrací identifikátor objektu code: nebo id:
1904
     *
1905
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1906
     * 
1907
     * @return string indentifikátor záznamu reprezentovaného objektem
1908
     */
1909
    public function __toString()
1910
    {
1911
        return strval($this->getRecordIdent());
1912
    }
1913
1914
    /**
1915
     * Gives you FlexiPeeHP class name for Given Evidence
1916
     *
1917
     * @param string $evidence
1918
     * 
1919
     * @return string Class name
1920
     */
1921
    public static function evidenceToClassName($evidence)
1922
    {
1923
        return str_replace(' ', '', ucwords(str_replace('-', ' ', $evidence)));
1924
    }
1925
1926
    /**
1927
     * Obtain ID of first record in evidence
1928
     *
1929
     * @return string|null id or null if no records
1930
     */
1931
    public function getFirstRecordID()
1932
    {
1933
        $firstID    = null;
1934
        $keyColumn  = $this->getKeyColumn();
1935
        $firstIdRaw = $this->getColumnsFromFlexibee([$keyColumn],
1936
            ['limit' => 1, 'order' => $keyColumn], $keyColumn);
1937
        if (!empty($firstIdRaw) && isset(current($firstIdRaw)[$keyColumn])) {
1938
            $firstID = current($firstIdRaw)[$keyColumn];
1939
        }
1940
        return is_numeric($firstID) ? intval($firstID) : $firstID;
1941
    }
1942
1943
    /**
1944
     * Get previous record ID
1945
     * 
1946
     * @param array $conditions optional
1947
     * 
1948
     * @return int|null
1949
     */
1950
    function getNextRecordID($conditions = [])
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1951
    {
1952
        $conditions['order'] = 'id@D';
1953
        $conditions['limit'] = 1;
1954
        $conditions[]        = 'id gt '.$this->getRecordID();
1955
        $next                = $this->getColumnsFromFlexibee(['id'], $conditions);
1956
        return (is_array($next) && array_key_exists(0, $next) && array_key_exists('id',
1957
                $next[0])) ? intval($next[0]['id']) : null;
1958
    }
1959
1960
    /**
1961
     * Get next record ID
1962
     * 
1963
     * @param array $conditions optional
1964
     * 
1965
     * @return int|null
1966
     */
1967
    function getPrevRecordID($conditions = [])
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1968
    {
1969
        $conditions['order'] = 'id@A';
1970
        $conditions['limit'] = 1;
1971
        $conditions[]        = 'id lt '.$this->getRecordID();
1972
        $prev                = $this->getColumnsFromFlexibee(['id'], $conditions);
1973
        return (is_array($prev) && array_key_exists(0, $prev) && array_key_exists('id',
1974
                $prev[0])) ? intval($prev[0]['id']) : null;
1975
    }
1976
1977
    /**
1978
     * Vrací hodnotu daného externího ID
1979
     *
1980
     * @param string $want Namespace Selector. If empty,you obtain the first one.
1981
     * 
1982
     * @return string|array one id or array if multiplete
1983
     */
1984
    public function getExternalID($want = null)
1985
    {
1986
        $extid = null;
1987
        $ids   = $this->getExternalIDs();
1988
        if (is_null($want)) {
1989
            if (!empty($ids)) {
1990
                $extid = current($ids);
1991
            }
1992
        } else {
1993
            if (!is_null($ids) && is_array($ids)) {
0 ignored issues
show
introduced by
The condition is_array($ids) is always true.
Loading history...
introduced by
The condition is_null($ids) is always false.
Loading history...
1994
                foreach ($ids as $id) {
1995
                    if (strstr($id, 'ext:'.$want)) {
1996
                        if (is_null($extid)) {
1997
                            $extid = str_replace('ext:'.$want.':', '', $id);
1998
                        } else {
1999
                            if (is_array($extid)) {
2000
                                $extid[] = str_replace('ext:'.$want.':', '', $id);
2001
                            } else {
2002
                                $extid = [$extid, str_replace('ext:'.$want.':',
2003
                                        '', $id)];
2004
                            }
2005
                        }
2006
                    }
2007
                }
2008
            }
2009
        }
2010
        return $extid;
2011
    }
2012
2013
    /**
2014
     * gives you currently loaded extermal IDs
2015
     * 
2016
     * @return array
2017
     */
2018
    public function getExternalIDs()
2019
    {
2020
        return $this->getDataValue('external-ids');
2021
    }
2022
2023
    /**
2024
     * Obtain actual GlobalVersion
2025
     * Vrací aktuální globální verzi změn
2026
     *
2027
     * @link https://www.flexibee.eu/api/dokumentace/ref/changes-api#globalVersion Globální Verze
2028
     * 
2029
     * @return type
0 ignored issues
show
Bug introduced by
The type FlexiPeeHP\type was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
2030
     */
2031
    public function getGlobalVersion()
2032
    {
2033
        $this->getFlexiData(null, ['add-global-version' => 'true', 'limit' => 1]);
2034
2035 23
        return $this->globalVersion;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->globalVersion returns the type integer which is incompatible with the documented return type FlexiPeeHP\type.
Loading history...
2036
    }
2037 23
2038 23
    /**
2039 23
     * Gives you current ApiURL with given format suffix
2040 23
     * 
2041
     * @param string $format json|html|xml|...
2042
     * 
2043
     * @return string API URL for current record or object/evidence
2044
     */
2045
    public function getApiURL($format = null)
2046
    {
2047
        $apiUrl = str_replace(['.'.$this->format, '?limit=0'], '', $this->apiURL);
2048
        return $apiUrl.(empty($format) ? '' : '.'.$format );
2049
    }
2050
2051
    /**
2052
     * Obtain content type of last response
2053
     *
2054
     * @return string
2055
     */
2056
    public function getResponseFormat()
2057
    {
2058
        return $this->responseFormat;
2059
    }
2060
2061
    /**
2062
     * Return the same response format for one and multiplete results
2063
     *
2064
     * @param array $responseBody
2065
     * 
2066
     * @return array
2067
     */
2068
    public function unifyResponseFormat($responseBody)
2069
    {
2070
        if (!is_array($responseBody) || array_key_exists('message',
0 ignored issues
show
introduced by
The condition is_array($responseBody) is always true.
Loading history...
2071
                $responseBody)) { //Unifi response format
2072
            $response = $responseBody;
2073
        } else {
2074
            $evidence = $this->getResponseEvidence();
2075
            if (array_key_exists($evidence, $responseBody)) {
2076
                $response        = [];
2077
                $evidenceContent = $responseBody[$evidence];
2078
                if (array_key_exists(0, $evidenceContent)) {
2079
                    $response[$evidence] = $evidenceContent; //Multiplete Results
2080
                } else {
2081
                    $response[$evidence][0] = $evidenceContent; //One result
2082
                }
2083
            } else {
2084
                if (isset($responseBody['priloha'])) {
2085
                    $response = $responseBody['priloha'];
2086
                } else {
2087
                    if (array_key_exists('results', $responseBody)) {
2088
                        $response = $responseBody['results'];
2089
                    } else {
2090
                        $response = $responseBody;
2091
                    }
2092
                }
2093
            }
2094
        }
2095
        return $response;
2096
    }
2097
2098
    /**
2099
     * Obtain structure for current (or given) evidence
2100
     *
2101
     * @param string $evidence
2102
     * 
2103
     * @return array Evidence structure
2104
     */
2105
    public function getOfflineColumnsInfo($evidence = null)
2106
    {
2107
        $columnsInfo = null;
2108
        $infoSource  = self::$infoDir.'/Properties.'.(empty($evidence) ? $this->getEvidence()
2109
                : $evidence).'.json';
2110
        if (file_exists($infoSource)) {
2111
            $columnsInfo = json_decode(file_get_contents($infoSource), true);
2112
        }
2113
        return $columnsInfo;
2114
    }
2115
2116
    /**
2117
     * Obtain Current evidence Live structure
2118
     * 
2119
     * @param string $evidence
2120
     * 
2121
     * @return array structure
2122
     */
2123
    public function getOnlineColumnsInfo($evidence = null)
2124
    {
2125
        $properties = [];
2126
        $evidence   = is_null($evidence) ? $this->getEvidence() : $evidence;
2127
        $flexinfo   = $this->performRequest('/c/'.$this->company.'/'.$evidence.'/properties.json');
2128
        if (count($flexinfo) && array_key_exists('properties', $flexinfo)) {
2129
            foreach ($flexinfo['properties']['property'] as $evidenceProperty) {
2130
                $key                      = $evidenceProperty['propertyName'];
2131
                $properties[$key]         = $evidenceProperty;
2132
                $properties[$key]['name'] = $evidenceProperty['name'];
2133
                $properties[$key]['type'] = $evidenceProperty['type'];
2134
                if (array_key_exists('url', $evidenceProperty)) {
2135
                    $properties[$key]['url'] = str_replace('?limit=0', '',
2136
                        $evidenceProperty['url']);
2137
                }
2138
            }
2139
        }
2140
        return $properties;
2141
    }
2142
2143
    /**
2144
     * Update evidence info from array or online from properties.json or offline
2145
     * 
2146
     * @param array  $columnsInfo
2147
     * @param string $evidence
2148
     */
2149
    public function updateColumnsInfo($columnsInfo = null, $evidence = null)
2150
    {
2151
        $evidence = is_null($evidence) ? $this->getEvidence() : $evidence;
2152
        if (is_null($columnsInfo)) {
2153
            $this->columnsInfo[$evidence] = $this->offline ? $this->getOfflineColumnsInfo($evidence)
2154
                    : $this->getOnlineColumnsInfo($evidence);
2155
        } else {
2156
            $this->columnsInfo[$evidence] = $columnsInfo;
2157
        }
2158
    }
2159
2160
    /**
2161
     * Gives you evidence structure. You can obtain current online by pre-calling:
2162
     * $this->updateColumnsInfo($evidence, $this->getOnlineColumnsInfo($evidence));
2163
     * 
2164
     * @param string $evidence
2165
     * 
2166
     * @return array
2167
     */
2168
    public function getColumnsInfo($evidence = null)
2169
    {
2170
        $evidence = is_null($evidence) ? $this->getEvidence() : $evidence;
2171
        if (!array_key_exists($evidence, $this->columnsInfo)) {
2172
            $this->updateColumnsInfo($this->getOfflineColumnsInfo($evidence),
2173
                $evidence);
2174
        }
2175
        return $this->columnsInfo[$evidence];
2176
    }
2177
2178
    /**
2179
     * Gives you properties for (current) evidence column
2180
     *
2181
     * @param string $column    name of column
2182
     * @param string $evidence  evidence name if different
2183
     *
2184
     * @return array column properties or null if column not exits
2185
     */
2186
    public function getColumnInfo($column, $evidence = null)
2187
    {
2188
        $columnsInfo = $this->getColumnsInfo(empty($evidence) ? $this->getEvidence()
2189
                : $evidence);
2190
        return (empty($column) || empty($columnsInfo) || !is_array($columnsInfo))
2191
                ? null : array_key_exists($column, $columnsInfo) ? $columnsInfo[$column]
2192
                : null;
2193
    }
2194
2195
    /**
2196
     * Obtain actions for current (or given) evidence
2197
     *
2198
     * @param string $evidence
2199
     * 
2200
     * @return array Evidence structure
2201
     */
2202
    public function getActionsInfo($evidence = null)
2203
    {
2204
        $actionsInfo = null;
2205
        if (is_null($evidence)) {
2206
            $evidence = $this->getEvidence();
2207
        }
2208
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
2209
        if (isset(\FlexiPeeHP\Actions::$$propsName)) {
2210
            $actionsInfo = Actions::$$propsName;
2211
        }
2212
        return $actionsInfo;
2213
    }
2214
2215
    /**
2216
     * Obtain relations for current (or given) evidence
2217
     *
2218
     * @param string $evidence
2219
     * 
2220
     * @return array Evidence structure
2221
     */
2222
    public function getRelationsInfo($evidence = null)
2223
    {
2224
        $relationsInfo = null;
2225
        if (is_null($evidence)) {
2226
            $evidence = $this->getEvidence();
2227
        }
2228
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
2229
        if (isset(\FlexiPeeHP\Relations::$$propsName)) {
2230
            $relationsInfo = Relations::$$propsName;
2231
        }
2232
        return $relationsInfo;
2233
    }
2234
2235
    /**
2236
     * Obtain info for current (or given) evidence
2237
     *
2238
     * @param string $evidence
2239
     * 
2240
     * @return array Evidence info
2241
     */
2242
    public function getEvidenceInfo($evidence = null)
2243
    {
2244
        $evidencesInfo = null;
2245
        if (is_null($evidence)) {
2246
            $evidence = $this->getEvidence();
2247
        }
2248
        if (isset(EvidenceList::$evidences[$evidence])) {
2249
            $evidencesInfo = EvidenceList::$evidences[$evidence];
2250
            $propsName     = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
2251
            if (isset(Formats::$$propsName)) {
2252
                $evidencesInfo['formats'] = Formats::$$propsName;
2253
            }
2254
        }
2255
        return $evidencesInfo;
2256
    }
2257
2258
    /**
2259
     * Obtain name for current (or given) evidence path
2260
     *
2261
     * @param string $evidence Evidence Path
2262
     * 
2263
     * @return array Evidence info
2264
     */
2265
    public function getEvidenceName($evidence = null)
2266
    {
2267
        $evidenceName = null;
2268
        if (is_null($evidence)) {
2269
            $evidence = $this->getEvidence();
2270
        }
2271
        if (isset(EvidenceList::$name[$evidence])) {
2272
            $evidenceName = EvidenceList::$name[$evidence];
2273
        }
2274
        return $evidenceName;
2275
    }
2276
2277
    /**
2278
     * Save current object to file
2279
     *
2280
     * @param string $destfile path to file
2281
     */
2282
    public function saveResponseToFile($destfile)
2283
    {
2284
        if (strlen($this->lastCurlResponse)) {
2285
            $this->doCurlRequest($this->apiURL, 'GET', $this->format);
2286
        }
2287
        file_put_contents($destfile, $this->lastCurlResponse);
2288
    }
2289
2290
    /**
2291
     * Obtain established relations listing
2292
     *
2293
     * @return array Null or Relations
2294
     */
2295
    public function getVazby($id = null)
2296
    {
2297
        if (is_null($id)) {
2298
            $id = $this->getRecordID();
2299
        }
2300
        if (!empty($id)) {
2301
            $vazbyRaw = $this->getColumnsFromFlexibee(['vazby'],
2302
                ['relations' => 'vazby', 'id' => $id]);
2303
            $vazby    = array_key_exists('vazby', $vazbyRaw[0]) ? $vazbyRaw[0]['vazby']
2304
                    : null;
2305
        } else {
2306
            throw new \Exception(_('ID requied to get record relations '));
2307
        }
2308
        return $vazby;
2309
    }
2310
2311
    /**
2312
     * Gives You URL for Current Record in FlexiBee web interface
2313
     *
2314
     * @return string url
2315
     */
2316
    public function getFlexiBeeURL()
2317
    {
2318
        $parsed_url = parse_url(str_replace('.'.$this->format, '', $this->apiURL));
2319
        $scheme     = isset($parsed_url['scheme']) ? $parsed_url['scheme'].'://'
2320
                : '';
2321
        $host       = isset($parsed_url['host']) ? $parsed_url['host'] : '';
2322
        $port       = isset($parsed_url['port']) ? ':'.$parsed_url['port'] : '';
2323
        $user       = isset($parsed_url['user']) ? $parsed_url['user'] : '';
2324
        $pass       = isset($parsed_url['pass']) ? ':'.$parsed_url['pass'] : '';
2325
        $pass       = ($user || $pass) ? "$pass@" : '';
2326
        $path       = isset($parsed_url['path']) ? $parsed_url['path'] : '';
2327
        return $scheme.$user.$pass.$host.$port.$path;
2328
    }
2329
2330
    /**
2331
     * Set Record Key
2332
     *
2333
     * @param int|string $myKeyValue
2334
     * 
2335
     * @return boolean
2336
     */
2337
    public function setMyKey($myKeyValue)
2338
    {
2339
        if (substr($myKeyValue, 0, 4) == 'ext:') {
2340
            $extIds = $this->getDataValue('external-ids');
2341
            if (!empty($extIds) && count($extIds)) {
2342
                $extIds = array_combine($extIds, $extIds);
2343
            }
2344
            $extIds[$myKeyValue] = $myKeyValue;
2345
            $res                 = $this->setDataValue('external-ids', $extIds);
2346
        } else {
2347
            $res = parent::setMyKey($myKeyValue);
2348
        }
2349
        $this->updateApiURL();
2350
        return $res;
2351
    }
2352
2353
    /**
2354
     * Set or get ignore not found pages flag
2355
     *
2356
     * @param boolean $ignore set flag to
2357
     *
2358
     * @return boolean get flag state
2359
     */
2360
    public function ignore404($ignore = null)
2361
    {
2362
        if (!is_null($ignore)) {
2363
            $this->ignoreNotFound = $ignore;
2364
        }
2365
        return $this->ignoreNotFound;
2366
    }
2367
2368
    /**
2369
     * Send Document by mail
2370
     *
2371
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
2372
     *
2373
     * @param string $to         Email ecipient
2374
     * @param string $subject    Email Subject
2375
     * @param string $body       Email Text
2376
     *
2377
     * @return int http response code
2378
     */
2379
    public function sendByMail($to, $subject, $body, $cc = null)
2380
    {
2381
        $this->setPostFields($body);
2382
2383
        $this->performRequest(rawurlencode($this->getRecordID()).'/odeslani-dokladu?to='.$to.'&subject='.urlencode($subject).'&cc='.$cc
2384
            , 'PUT', 'xml');
2385
2386
        return $this->lastResponseCode == 200;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->lastResponseCode == 200 returns the type boolean which is incompatible with the documented return type integer.
Loading history...
2387
    }
2388
2389
    /**
2390
     * Send all unsent Documents by eMail
2391
     *
2392
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
2393
     * 
2394
     * @return int http response code
2395
     */
2396
    public function sendUnsent()
2397
    {
2398
        return $this->doCurlRequest('automaticky-odeslat-neodeslane', 'PUT',
2399
                'xml');
2400
    }
2401
2402
    /**
2403
     * FlexiBee date to PHP DateTime conversion
2404
     *
2405
     * @param string $flexidate 2017-05-26 or 2017-05-26+02:00
2406
     *
2407
     * @return \DateTime | false
2408
     */
2409
    public static function flexiDateToDateTime($flexidate)
2410
    {
2411
        return \DateTime::createFromFormat(strstr($flexidate, '+') ? self::$DateFormat.'O'
2412
                    : self::$DateFormat, $flexidate)->setTime(0, 0);
2413
    }
2414
2415
    /**
2416
     * FlexiBee dateTime to PHP DateTime conversion
2417
     *
2418
     * @param string $flexidatetime 2017-09-26T10:00:53.755+02:00 or older 2017-05-19T00:00:00+02:00
2419
     *
2420
     * @return \DateTime | false
2421
     */
2422
    public static function flexiDateTimeToDateTime($flexidatetime)
2423
    {
2424
        if (strchr($flexidatetime, '.')) { //NewFormat
2425
            $format = self::$DateTimeFormat;
2426
        } else { // Old format
2427
            $format = 'Y-m-d\TH:i:s+P';
2428
        }
2429
        return \DateTime::createFromFormat($format, $flexidatetime);
2430
    }
2431
2432
    /**
2433
     * Získá dokument v daném formátu
2434
     * Obtain document in given format
2435
     *
2436
     * @link https://www.flexibee.eu/api/dokumentace/ref/pdf/ PDF Exports
2437
     *
2438
     * @param string  $format     pdf/csv/xml/json/ ...
2439
     * @param string  $reportName Template used to generate PDF
2440
     * @param string  $lang       cs|sk|en|de Template language used to generate PDF
2441
     * @param boolean $sign       sign resulting PDF by certificate ?
2442
     *
2443
     * @return string|null filename downloaded or none
2444
     */
2445
    public function getInFormat($format, $reportName = null, $lang = null,
2446
                                $sign = false)
2447
    {
2448
        $response = null;
2449
        if ($this->setFormat($format)) {
2450
            $urlParams = [];
2451
            switch ($format) {
2452
                case 'pdf':
2453
                    switch ($lang) {
2454
                        case 'cs':
2455
                        case 'sk':
2456
                        case 'en':
2457
                        case 'de':
2458
                            $urlParams['report-lang'] = $lang;
2459
                            break;
2460
                        case null:
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $lang of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
2461
                            break;
2462
                        default:
2463
                            throw new \Ease\Exception('Unknown language '.$lang.' for PDF export');
2464
                            break;
2465
                    }
2466
                    if (boolval($sign) === true) {
2467
                        $urlParams['report-sign'] = 'true';
2468
                    }
2469
                    break;
2470
                case 'html':
2471
                    $urlParams['inDesktopApp'] = 'true';
2472
                    break;
2473
            }
2474
            if (!empty($reportName)) {
2475
                $urlParams['report-name'] = $reportName;
2476
            }
2477
            if (($this->doCurlRequest(\Ease\Shared::addUrlParams($this->apiURL,
2478
                        $urlParams), 'GET') == 200)) {
2479
                $response = $this->lastCurlResponse;
2480
            }
2481
        }
2482
        return $response;
2483
    }
2484
2485
    /**
2486
     * Uloží dokument v daném formátu do složky v systému souborů
2487
     * Save document in given format to directory in filesystem
2488
     *
2489
     * @param string $format  pdf/csv/xml/json/ ...
2490
     * @param string $destDir where to put file (prefix)
2491
     * @param string $reportName Template used to generate PDF
2492
     *
2493
     * @return string|null filename downloaded or none
2494
     */
2495
    public function downloadInFormat($format, $destDir = './',
2496
                                     $reportName = null)
2497
    {
2498
        $fileOnDisk   = null;
2499
        $formatBackup = $this->format;
2500
        if ($this->setFormat($format)) {
2501
            $downloadTo = $destDir.$this->getEvidence().'_'.$this->getMyKey().'.'.$format;
2502
            if (($this->doCurlRequest(empty($reportName) ? $this->apiURL : \Ease\Shared::addUrlParams($this->apiURL,
2503
                            ['report-name' => $reportName]), 'GET') == 200) && (file_put_contents($downloadTo,
2504
                    $this->lastCurlResponse) !== false)) {
2505
                $fileOnDisk = $downloadTo;
2506
            }
2507
            $this->setFormat($formatBackup);
2508
        }
2509
        return $fileOnDisk;
2510
    }
2511
2512
    /**
2513
     * Take data for object. separate external IDs
2514
     *
2515
     * @param array $data Data to keep
2516
     * 
2517
     * @return int number of records taken
2518
     */
2519
    public function takeData($data)
2520
    {
2521
        $keyColumn = $this->getKeyColumn();
2522
        if (array_key_exists($keyColumn, $data) && is_array($data[$keyColumn])) {
2523
            foreach ($data[$keyColumn] as $recPos => $recordKey) {
2524
                if (substr($recordKey, 0, 4) == 'ext:') {
2525
                    $data['external-ids'][] = $recordKey;
2526
                    unset($data[$keyColumn][$recPos]);
2527
                }
2528
            }
2529
            if (count($data[$keyColumn]) == 1) {
2530
                $data[$keyColumn] = current($data[$keyColumn]);
2531
            }
2532
        }
2533
        $result = parent::takeData($data);
2534
2535
        if (array_key_exists($keyColumn, $data) || array_key_exists('kod', $data)) {
2536
            $this->updateApiURL();
2537
        }
2538
2539
        return $result;
2540
    }
2541
2542
    /**
2543
     * Get Current Evidence reports listing
2544
     * 
2545
     * @link https://www.flexibee.eu/api/dokumentace/casto-kladene-dotazy-pro-api/vyber-reportu-do-pdf/ Výběr reportu do PDF
2546
     * 
2547
     * @return array
2548
     */
2549
    public function getReportsInfo()
2550
    {
2551
        $reports    = [];
2552
        $reportsRaw = $this->getFlexiData($this->getEvidenceURL().'/reports');
2553
        if (!empty($reportsRaw) && array_key_exists('reports', $reportsRaw) && !empty($reportsRaw['reports'])
2554
            && array_key_exists('report', $reportsRaw['reports']) &&
2555
            !empty($reportsRaw['reports']['report'])) {
2556
            if (\Ease\jQuery\Part::isAssoc($reportsRaw['reports']['report'])) {
2557
                $reports = [$reportsRaw['reports']['report']['reportId'] => $reportsRaw['reports']['report']];
2558
            } else {
2559
                $reports = self::reindexArrayBy($reportsRaw['reports']['report'],
2560
                        'reportId');
2561
            }
2562
        }
2563
        return $reports;
2564
    }
2565
2566
    /**
2567
     * Request authSessionId from current server
2568
     * 
2569
     * @link https://www.flexibee.eu/api/dokumentace/ref/login/ description
2570
     * 
2571
     * @param string $username
2572
     * @param string $password
2573
     * @param string $otp       optional onetime password
2574
     * 
2575
     * @return string authUserId or null in case of problems
2576
     */
2577
    public function requestAuthSessionID($username, $password, $otp = null)
2578
    {
2579
        $this->postFields = http_build_query(is_null($otp) ? ['username' => $username,
2580
            'password' => $password] : ['username' => $username, 'password' => $password,
2581
            'otp' => $otp]);
2582
        $response         = $this->performRequest('/login-logout/login', 'POST',
2583
            'json');
2584
        if (array_key_exists('refreshToken', $response)) {
2585
            $this->refreshToken = $response['refreshToken'];
2586
        } else {
2587
            $this->refreshToken = null;
2588
        }
2589
        return array_key_exists('authSessionId', $response) ? $response['authSessionId']
2590
                : null;
2591
    }
2592
2593
    /**
2594
     * Try to Sign in current user to FlexiBee and keep authSessionId
2595
     * 
2596
     * @return boolen sign in success
2597
     */
2598
    public function login()
2599
    {
2600
        $this->authSessionId = $this->requestAuthSessionID($this->user,
2601
            $this->password);
2602
        return $this->lastResponseCode == 200;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->lastResponseCode == 200 returns the type boolean which is incompatible with the documented return type FlexiPeeHP\boolen.
Loading history...
2603
    }
2604
2605
    /**
2606
     * End (current's user) session
2607
     * 
2608
     * 
2609
     * @link https://www.flexibee.eu/api/dokumentace/ref/logout Logout Reference
2610
     * 
2611
     * @param string $username force username to sign off
2612
     * 
2613
     * @return array server response
2614
     */
2615
    public function logout($username = null)
2616
    {
2617
        return $this->performRequest('/status/user/'.(is_null($username) ? $this->user
2618
                    : $username).'/logout', 'POST');
2619
    }
2620
2621
    /**
2622
     * Compile and send Report about Error500 to FlexiBee developers
2623
     * If FlexiBee is running on localost try also include java backtrace
2624
     *
2625
     * @param array $errorResponse result of parseError();
2626
     */
2627
    public function error500Reporter($errorResponse)
2628
    {
2629
        $ur = str_replace('/c/'.$this->company, '',
2630
            str_replace($this->url, '', $this->curlInfo['url']));
2631
        if (!array_key_exists($ur, $this->reports)) {
2632
            $tmpdir   = sys_get_temp_dir();
2633
            $myTime   = $this->curlInfo['when'];
2634
            $curlname = $tmpdir.'/curl-'.$this->evidence.'-'.$myTime.'.json';
2635
            file_put_contents($curlname,
2636
                json_encode($this->curlInfo, JSON_PRETTY_PRINT));
2637
2638
            $report = new \Ease\Mailer($this->reportRecipient,
2639
                'Error report 500 - '.$ur);
2640
2641
            $d     = dir($tmpdir);
2642
            while (false !== ($entry = $d->read())) {
2643
                if (strstr($entry, $myTime)) {
2644
                    $ext  = pathinfo($tmpdir.'/'.$entry, PATHINFO_EXTENSION);
2645
                    $mime = Formats::suffixToContentType($ext);
2646
                    $report->addFile($tmpdir.'/'.$entry,
2647
                        empty($mime) ? 'text/plain' : $mime);
2648
                }
2649
            }
2650
            $d->close();
2651
2652
            if ((strstr($this->url, '://localhost') || strstr($this->url,
2653
                    '://127.')) && file_exists('/var/log/flexibee.log')) {
2654
2655
                $fl = fopen('/var/log/'.'flexibee.log', 'r');
2656
                if ($fl) {
0 ignored issues
show
introduced by
$fl is of type false|resource, thus it always evaluated to false.
Loading history...
2657
                    $tracelog = [];
2658
                    for ($x_pos = 0, $ln = 0, $output = array(); fseek($fl,
2659
                            $x_pos, SEEK_END) !== -1; $x_pos--) {
2660
                        $char = fgetc($fl);
2661
                        if ($char === "\n") {
2662
                            $tracelog[] = $output[$ln];
2663
                            if (strstr($output[$ln], $errorResponse['message'])) {
2664
                                break;
2665
                            }
2666
                            $ln++;
2667
                            continue;
2668
                        }
2669
                        $output[$ln] = $char.((array_key_exists($ln, $output)) ? $output[$ln]
2670
                                : '');
2671
                    }
2672
2673
                    $trace     = implode("\n", array_reverse($tracelog));
2674
                    $tracefile = $tmpdir.'/trace-'.$this->evidence.'-'.$myTime.'.log';
2675
                    file_put_contents($tracefile, $trace);
2676
                    $report->addItem("\n\n".$trace);
2677
                    fclose($fl);
2678
                }
2679
            } else {
2680
                $report->addItem($errorResponse['message']);
2681
            }
2682
2683
            $licenseInfo = $this->performRequest($this->url.'/default-license.json');
2684
2685
            $report->addItem("\n\n".json_encode($licenseInfo['license'],
2686
                    JSON_PRETTY_PRINT));
2687
2688
            if ($report->send()) {
2689
                $this->reports[$ur] = $myTime;
2690
            }
2691
        }
2692
    }
2693
2694
    /**
2695
     * Returns code:CODE
2696
     *
2697
     * @param string $code
2698
     *
2699
     * @return string
2700
     */
2701
    public static function code($code)
2702
    {
2703
        return ((substr($code, 0, 4) == 'ext:') ? $code : 'code:'.strtoupper(self::uncode($code)));
2704
    }
2705
2706
    /**
2707
     * Returns CODE without code: prefix
2708
     *
2709
     * @param string $code
2710
     *
2711
     * @return string
2712
     */
2713
    public static function uncode($code)
2714
    {
2715
        return str_replace(['code:', 'code%3A'], '', $code);
2716
    }
2717
2718
    /**
2719
     * Remove all @ items from array
2720
     *
2721
     * @param array $data original data
2722
     *
2723
     * @return array data without @ columns
2724
     */
2725
    public static function arrayCleanUP($data)
2726
    {
2727
        return array_filter(
2728
            $data,
2729
            function ($key) {
2730
            return !strchr($key, '@');
2731
        }, ARRAY_FILTER_USE_KEY);
2732
    }
2733
2734
    /**
2735
     * Add Info about used user, server and libraries
2736
     *
2737
     * @param string $additions Additional note text
2738
     */
2739
    public function logBanner($additions = null)
2740
    {
2741
        $this->addStatusMessage('FlexiBee '.str_replace('://',
2742
                '://'.$this->user.'@', $this->getApiUrl()).' FlexiPeeHP v'.self::$libVersion.' (FlexiBee '.EvidenceList::$version.') EasePHP Framework v'.\Ease\Atom::$frameworkVersion.' '.$additions,
2743
            'debug');
2744
    }
2745
2746
    /**
2747
     * Reconnect After unserialization
2748
     */
2749
    public function __wakeup()
2750
    {
2751
        parent::__wakeup();
2752
        $this->curlInit();
2753
    }
2754
}
2755