Test Failed
Push — master ( e1e8a5...f6f865 )
by Vítězslav
03:08
created

FlexiBeeRO::dateToFlexiDateTime()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 4
cts 4
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * FlexiPeeHP - Read Only Access to FlexiBee class.
4
 *
5
 * @author     Vítězslav Dvořák <[email protected]>
6
 * @copyright  (C) 2015-2018 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.9.2.1';
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',
281
        'dry-run', // See: https://www.flexibee.eu/api/dokumentace/ref/dry-run/
282
        'encoding',
283
        'export-settings',
284
        'fail-on-warning',
285
        'filter',
286
        'format',
287
        'idUcetniObdobi',
288
        'includes',
289
        'inDesktopApp', // Note: Undocumented function (html only)
290
        'limit',
291
        'mode',
292
        'no-ext-ids',
293
        'no-http-errors',
294
        'no-ids',
295
        'only-ext-ids',
296
        'order',
297
        'relations',
298
        'report-lang',
299
        'report-name',
300
        'report-sign',
301
        'skupina-stitku',
302
        'sort',
303
        'start',
304
        'stitky-as-ids',
305
        'use-ext-id',
306
        'use-internal-id',
307
        'xpath', // See: https://www.flexibee.eu/api/dokumentace/ref/xpath/
308
    ];
309
310
    /**
311
     * Session ID
312
     * @var string
313
     */
314
    public $authSessionId = null;
315
316
    /**
317
     * Save 404 results to log ?
318
     * @var boolean
319
     */
320
    protected $ignoreNotFound = false;
321
322
    /**
323
     * Array of errors caused by last request
324
     * @var array
325
     */
326
    private $errors = [];
327
328
    /**
329
     * List of Error500 reports sent
330
     * @var array
331
     */
332
    private $reports = [];
333
334
    /**
335
     * Send Error500 Report to
336
     * @var string email address
337
     */
338
    public $reportRecipient = '[email protected]';
339
340 70
    /**
341
     * Formating string for \DateTime::format() for datetime columns
342 70
     * @var string
343
     */
344 70
    static public $DateTimeFormat = 'Y-m-d\TH:i:s.u+P';
345 70
346 70
    /**
347 70
     * Formating string for \DateTime::format() for date columns
348 22
     * @var string
349 22
     */
350 70
    static public $DateFormat = 'Y-m-d';
351
352
    /**
353
     * Last Request response stats
354
     * @var array 
355
     */
356
    private $responseStats = null;
357
358 71
    /**
359
     * Chained Objects
360 71
     * @var array
361 71
     */
362 71
    public $chained = [];
363 71
364 71
    /**
365 23
     * We Connect to server by default
366 23
     * @var boolean
367 71
     */
368 71
    public $offline = false;
369 23
370 23
    /**
371 71
     * Class for read only interaction with FlexiBee.
372
     *
373
     * @param mixed $init default record id or initial data
374 71
     * @param array $options Connection settings and other options override
375 71
     */
376 71
    public function __construct($init = null, $options = [])
377
    {
378
        $this->init = $init;
379
380
        parent::__construct();
381
        $this->setUp($options);
382
        $this->curlInit();
383
        if (!empty($init)) {
384
            $this->processInit($init);
385 48
        }
386
    }
387 48
388
    /**
389
     * SetUp Object to be ready for work
390 48
     *
391 48
     * @param array $options Object Options ( user,password,authSessionId
392 48
     *                                        company,url,evidence,
393
     *                                        prefix,defaultUrlParams,debug,
394 48
     *                                        detail,offline,filter,ignore404
395
     */
396
    public function setUp($options = [])
397
    {
398
        $this->setupProperty($options, 'company', 'FLEXIBEE_COMPANY');
399 94
        $this->setupProperty($options, 'url', 'FLEXIBEE_URL');
400
        $this->setupProperty($options, 'user', 'FLEXIBEE_LOGIN');
401 94
        $this->setupProperty($options, 'password', 'FLEXIBEE_PASSWORD');
402 94
        $this->setupProperty($options, 'authSessionId', 'FLEXIBEE_AUTHSESSID');
403 94
        if (!empty($this->authSessionId)) {
404 94
            $this->defaultHttpHeaders['X-authSessionId'] = $this->authSessionId;
405 94
        }
406 94
        if (isset($options['evidence'])) {
407 94
            $this->setEvidence($options['evidence']);
408 94
        }
409 94
        $this->setupProperty($options, 'defaultUrlParams');
410 94
        if (isset($options['prefix'])) {
411
            $this->setPrefix($options['prefix']);
412
        }
413
        if (array_key_exists('detail', $options)) {
414
            $this->defaultUrlParams['detail'] = $options['detail'];
415
        }
416
        $this->setupProperty($options, 'filter');
417
        if (array_key_exists('offline', $options)) {
418
            $this->offline = (boolean) $options['offline'];
419
        }
420
421
        if (array_key_exists('ignore404', $options)) {
422
            $this->ignore404($options['ignore404']);
423 13
        }
424
425 13
        $this->setupProperty($options, 'debug');
426 10
        $this->updateApiURL();
427 13
    }
428 13
429 13
    /**
430 10
     * Set up one of properties
431 10
     *
432 10
     * @param array  $options  array of given properties
433 8
     * @param string $name     name of property to process
434
     * @param string $constant load default property value from constant
435 13
     */
436
    public function setupProperty($options, $name, $constant = null)
437
    {
438
        if (array_key_exists($name, $options)) {
439
            $this->$name = $options[$name];
440
        } else {
441
            if (property_exists($this, $name) && !empty($constant) && defined($constant)) {
442 23
                $this->$name = constant($constant);
443
            }
444
        }
445 23
    }
446 23
447 23
    /**
448 23
     * Get Current connection options for use in another object
449 23
     *
450 23
     * @return array usable as second constructor parameter
451 23
     */
452 23
    public function getConnectionOptions()
453 23
    {
454 23
        $conOpts = ['url' => $this->url];
455 23
        if (empty($this->authSessionId)) {
456 23
            $conOpts ['user']    = $this->user;
457 23
            $conOpts['password'] = $this->password;
458 23
        } else {
459 23
            $conOpts['authSessionId'] = $this->authSessionId;
460 23
        }
461 23
        $company = $this->getCompany();
462 23
        if (!empty($company)) {
463
            $conOpts['company'] = $company;
464
        }
465
        return $conOpts;
466
    }
467
468
    /**
469
     * Inicializace CURL
470
     *
471 23
     * @return boolean Online Status
472
     */
473 23
    public function curlInit()
474 23
    {
475
        if ($this->offline === false) {
476
            $this->curl = \curl_init(); // create curl resource
477
            curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); // return content as a string from curl_exec
478
            curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); // follow redirects (compatibility for future changes in FlexiBee)
479
            curl_setopt($this->curl, CURLOPT_HTTPAUTH, true);       // HTTP authentication
480 23
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); // FlexiBee by default uses Self-Signed certificates
481 23
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
482 23
            curl_setopt($this->curl, CURLOPT_VERBOSE, ($this->debug === true)); // For debugging
483 23
            if (empty($this->authSessionId)) {
484 23
                curl_setopt($this->curl, CURLOPT_USERPWD,
485
                    $this->user.':'.$this->password); // set username and password
486
            }
487
        }
488
        return !$this->offline;
489
    }
490
491
    /**
492
     * Zinicializuje objekt dle daných dat. Možné hodnoty:
493
     *
494 23
     *  * 234                              - interní číslo záznamu k načtení
495
     *  * code:LOPATA                      - kód záznamu
496 23
     *  * BAGR                             - kód záznamu k načtení
497 23
     *  * ['id'=>24,'nazev'=>'hoblík']     - pole hodnot k předvyplnění
498 23
     *  * 743.json?relations=adresa,vazby  - část url s parametry k načtení
499 23
     *
500
     * @param mixed $init číslo/"(code:)kód"/(část)URI záznamu k načtení | pole hodnot k předvyplnění
501
     */
502
    public function processInit($init)
503 23
    {
504 23
        if (is_integer($init)) {
505
            $this->loadFromFlexiBee($init);
506
        } elseif (is_array($init)) {
507 20
            $this->takeData($init);
508 20
        } elseif (preg_match('/\.(json|xml|csv)/', $init)) {
509
            $this->takeData($this->getFlexiData((($init[0] != '/') ? $this->getEvidenceURL($init)
0 ignored issues
show
Unused Code introduced by
The call to FlexiBeeRO::getEvidenceURL() has too many arguments starting with $init.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
510 20
                            : $init)));
511 3
        } else {
512 3
            $this->loadFromFlexiBee($init);
513 3
        }
514 3
    }
515 23
516 23
    /**
517 23
     * Set Data Field value
518
     *
519
     * @param string $columnName field name
520
     * @param mixed  $value      field data value
521
     *
522
     * @return bool Success
523
     */
524
    public function setDataValue($columnName, $value)
525
    {
526 69
        switch ($columnName) {
527
            case 'kod':
528 69
                $value = self::uncode($value); //Alwyas uncode "kod" column
529
                break;
530
            default:
531
                break;
532
        }
533
        if (is_object($value)) {
534
            switch (get_class($value)) {
535
                case 'DateTime':
536
                    $columnInfo = $this->getColumnInfo($columnName);
537 23
                    switch ($columnInfo['type']) {
538
                        case 'date':
539 23
                            $value = self::dateToFlexiDate($value);
540 23
                            break;
541
                        case 'datetime':
542
                            $value = self::dateToFlexiDateTime($value);
543
                            break;
544
                    }
545
                    break;
546
            }
547
        }
548 23
        return parent::setDataValue($columnName, $value);
549
    }
550 23
551
    /**
552
     * PHP Date object to FlexiBee date format
553
     * 
554
     * @param \DateTime $date
555
     */
556
    public static function dateToFlexiDate($date)
557
    {
558 25
        return $date->format(self::$DateFormat);
559
    }
560 25
561 25
    /**
562
     * PHP Date object to FlexiBee date format
563
     * 
564 25
     * @param \DateTime $dateTime
565 1
     */
566 1
    public static function dateToFlexiDateTime($dateTime)
567 24
    {
568 24
        return $dateTime->format(self::$DateTimeFormat);
569 24
    }
570 25
571 25
    /**
572
     * Set URL prefix
573
     *
574
     * @param string $prefix
575
     */
576
    public function setPrefix($prefix)
577
    {
578
        switch ($prefix) {
579
            case 'a': //Access
580
            case 'c': //Company
581 23
            case 'u': //User
582
            case 'g': //License Groups
583 23
            case 'admin':
584 23
            case 'status':
585 23
            case 'login-logout':
586 23
                $this->prefix = '/'.$prefix.'/';
587 23
                break;
588 23
            case null:
589 23
            case '':
590 23
            case '/':
591 23
                $this->prefix = '';
592 23
                break;
593 23
            default:
594 23
                throw new \Exception(sprintf('Unknown prefix %s', $prefix));
595 23
        }
596
    }
597
598
    /**
599 23
     * Set communication format.
600
     * One of html|xml|json|csv|dbf|xls|isdoc|isdocx|edi|pdf|pdf|vcf|ical
601
     *
602
     * @param string $format
603
     * @return boolen format is availble
604
     */
605
    public function setFormat($format)
606
    {
607
        $result = true;
608
        if (($this->debug === true) && !empty($this->evidence) && isset(Formats::$$this->evidence)) {
609 23
            if (array_key_exists($format, array_flip(Formats::$$this->evidence))
610
                === false) {
611 23
                $result = false;
612 23
            }
613 22
        }
614 22
        if ($result === true) {
615 23
            $this->format = $format;
616 17
            $this->updateApiURL();
617 17
        }
618 17
        return $result;
619 17
    }
620 23
621
    /**
622
     * Nastaví Evidenci pro Komunikaci.
623
     * Set evidence for communication
624 23
     *
625
     * @param string $evidence evidence pathName to use
626
     * @return boolean evidence switching status
627
     */
628
    public function setEvidence($evidence)
629
    {
630
        switch ($this->prefix) {
631
            case '/c/':
632
                if ($this->debug === true) {
633
                    if (array_key_exists($evidence, EvidenceList::$name)) {
634 68
                        $this->evidence = $evidence;
635
                        $result         = true;
636 68
                    } else {
637 68
                        throw new \Exception(sprintf('Try to set unsupported evidence %s',
638 68
                                $evidence));
639 62
                    }
640 62
                } else {
641 68
                    $this->evidence = $evidence;
642
                    $result         = true;
643
                }
644
                break;
645
            default:
646
                $this->evidence = $evidence;
647
                $result         = true;
648
                break;
649
        }
650
        $this->updateApiURL();
651 23
        return $result;
652
    }
653 23
654 23
    /**
655 23
     * Vrací právě používanou evidenci pro komunikaci
656 23
     * Obtain current used evidence
657 23
     *
658 23
     * @return string
659 23
     */
660 23
    public function getEvidence()
661 23
    {
662
        return $this->evidence;
663
    }
664
665
    /**
666
     * Set used company.
667 48
     * Nastaví Firmu.
668
     *
669 48
     * @param string $company
670 48
     */
671 48
    public function setCompany($company)
672
    {
673
        $this->company = $company;
674 48
    }
675 48
676
    /**
677
     * Obtain company now used
678
     * Vrací právě používanou firmu
679
     *
680
     * @return string
681
     */
682
    public function getCompany()
683
    {
684
        return $this->company;
685
    }
686 23
687
    /**
688 23
     * Vrací název evidence použité v odpovědích z FlexiBee
689 23
     *
690 23
     * @return string
691 23
     */
692 23
    public function getResponseEvidence()
693 23
    {
694 23
        switch ($this->evidence) {
695 23
            case 'c':
696 23
                $evidence = 'company';
697 23
                break;
698 23
            case 'evidence-list':
699 23
                $evidence = 'evidence';
700 23
                break;
701
            default:
702
                $evidence = $this->getEvidence();
703 23
                break;
704 23
        }
705 23
        return $evidence;
706
    }
707
708 23
    /**
709
     * Převede rekurzivně Objekt na pole.
710
     *
711
     * @param object|array $object
712
     *
713
     * @return array
714
     */
715
    public static function object2array($object)
716
    {
717
        $result = null;
718 23
        if (is_object($object)) {
719
            $objectData = get_object_vars($object);
720 23
            if (is_array($objectData) && count($objectData)) {
721
                $result = array_map('self::object2array', $objectData);
722
            }
723
        } else {
724
            if (is_array($object)) {
725
                foreach ($object as $item => $value) {
726
                    $result[$item] = self::object2array($value);
727
                }
728
            } else {
729
                $result = $object;
730
            }
731 25
        }
732
733
        return $result;
734 25
    }
735
736 25
    /**
737
     * Převede rekurzivně v poli všechny objekty na jejich identifikátory.
738 25
     *
739 4
     * @param object|array $object
740 4
     *
741 22
     * @return array
742
     */
743
    public static function objectToID($object)
744 25
    {
745
        $resultID = null;
746 25
        if (is_object($object) && method_exists($object, '__toString')
747 25
        ) {
748
            $resultID = $object->__toString();
749
        } else {
750
            if (is_array($object)) {
751
                foreach ($object as $item => $value) {
752
                    $resultID[$item] = self::objectToID($value);
753
                }
754
            } else { //String
755
                $resultID = $object;
756
            }
757
        }
758 3
759
        return $resultID;
760 3
    }
761
762 3
    /**
763 3
     * Return basic URL for used Evidence
764 3
     *
765
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
766
     *
767
     * @return string Evidence URL
768
     */
769
    public function getEvidenceURL()
770
    {
771
        $evidenceUrl = $this->url.$this->prefix.$this->company;
772
        $evidence    = $this->getEvidence();
773 3
        if (!empty($evidence)) {
774
            $evidenceUrl .= '/'.$evidence;
775 3
        }
776
        return $evidenceUrl;
777
    }
778
779
    /**
780
     * Add suffix to Evidence URL
781
     *
782
     * @param string $urlSuffix
783
     *
784
     * @return string
785 3
     */
786
    public function evidenceUrlWithSuffix($urlSuffix)
787 3
    {
788 3
        $evidenceUrl = $this->getEvidenceUrl();
789 3
        if (!empty($urlSuffix)) {
790 3
            if (($urlSuffix[0] != '/') && ($urlSuffix[0] != ';') && ($urlSuffix[0]
791
                != '?')) {
792
                $evidenceUrl .= '/';
793 3
            }
794
            $evidenceUrl .= $urlSuffix;
795
        }
796
        return $evidenceUrl;
797 3
    }
798
799
    /**
800
     * Update $this->apiURL
801
     */
802
    public function updateApiURL()
803
    {
804
        $this->apiURL = $this->getEvidenceURL();
805
        $id           = $this->__toString();
806
        if (!empty($id)) {
807
            $this->apiURL .= '/'.self::urlEncode($id);
808
        }
809
        $this->apiURL .= '.'.$this->format;
810
    }
811
812
    /**
813
     * Add params to url
814
     *
815
     * @param string  $url      originall url
816
     * @param array   $params   value to add
817
     * @param boolean $override replace already existing values ?
818
     *
819
     * @return string url with parameters added
820 3
     */
821
    public function addUrlParams($url, $params, $override = false)
822 3
    {
823
        $urlParts = parse_url($url);
824 3
        $urlFinal = '';
825
        if (array_key_exists('scheme', $urlParts)) {
826
            $urlFinal .= $urlParts['scheme'].'://'.$urlParts['host'];
827
        }
828
        if (array_key_exists('port', $urlParts)) {
829
            $urlFinal .= ':'.$urlParts['port'];
830
        }
831
        if (array_key_exists('path', $urlParts)) {
832 3
            $urlFinal .= $urlParts['path'];
833 3
        }
834 3
        if (array_key_exists('query', $urlParts)) {
835
            parse_str($urlParts['query'], $queryUrlParams);
836
            $urlParams = $override ? array_merge($params, $queryUrlParams) : array_merge($queryUrlParams,
837 3
                    $params);
838
        } else {
839
            $urlParams = $params;
840 3
        }
841
842
        if (!empty($urlParams)) {
843
            $urlFinal .= '?';
844
            if (is_array($urlParams)) {
845
                $urlFinal .= http_build_query($urlParams);
846
            } else {
847
                $urlFinal .= $urlParams;
848
            }
849
        }
850
        return $urlFinal;
851
    }
852
853
    /**
854
     * Add Default Url params to given url if not overrided
855
     *
856
     * @param string $urlRaw
857
     *
858
     * @return string url with default params added
859
     */
860 3
    public function addDefaultUrlParams($urlRaw)
861
    {
862
        return $this->addUrlParams($urlRaw, $this->defaultUrlParams, false);
863
    }
864
865
    /**
866
     * Funkce, která provede I/O operaci a vyhodnotí výsledek.
867
     *
868
     * @param string $urlSuffix část URL za identifikátorem firmy.
869
     * @param string $method    HTTP/REST metoda
870
     * @param string $format    Requested format
871
     * @return array|boolean Výsledek operace
872
     */
873
    public function performRequest($urlSuffix = null, $method = 'GET',
874
                                   $format = null)
875
    {
876
        $this->rowCount      = null;
877
        $this->responseStats = [];
878
879
        if (preg_match('/^http/', $urlSuffix)) {
880
            $url = $urlSuffix;
881
        } elseif (strlen($urlSuffix) && ($urlSuffix[0] == '/')) {
882
            $url = $this->url.$urlSuffix;
883
        } else {
884
            $url = $this->evidenceUrlWithSuffix($urlSuffix);
885
        }
886
887
        $responseCode = $this->doCurlRequest($this->addDefaultUrlParams($url),
888
            $method, $format);
889
890 3
        return $this->parseResponse($this->rawResponseToArray($this->lastCurlResponse,
0 ignored issues
show
Bug introduced by
It seems like $this->rawResponseToArra... $this->responseFormat) targeting FlexiPeeHP\FlexiBeeRO::rawResponseToArray() can also be of type string; however, FlexiPeeHP\FlexiBeeRO::parseResponse() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
891
                    $this->responseFormat), $responseCode);
892 3
    }
893 3
894 3
    /**
895 3
     * Parse Raw FlexiBee response in several formats
896
     *
897 3
     * @param string $responseRaw raw response body
898
     * @param string $format      Raw Response format json|xml|etc
899 3
     *
900
     * @return array
901 3
     */
902
    public function rawResponseToArray($responseRaw, $format)
903 3
    {
904
        $responseDecoded = [];
905 3
        if (!empty(trim($responseRaw))) {
906 3
            switch ($format) {
907 3
                case 'json':
908 3
                    $responseDecoded = $this->rawJsonToArray($responseRaw);
909 3
                    break;
910 3
                case 'xml':
911 3
                    $responseDecoded = $this->rawXmlToArray($this->lastCurlResponse);
912 3
                    break;
913 3
                case 'txt':
914 3
                default:
915 3
                    $responseDecoded = $this->lastCurlResponse;
916 3
                    break;
917 3
            }
918
        }
919 3
        return $responseDecoded;
920
    }
921
922 3
    /**
923 3
     * Convert FlexiBee Response JSON to Array
924 3
     *
925 3
     * @param string $rawJson
926 3
     *
927 3
     * @return array
928 3
     */
929 3
    public function rawJsonToArray($rawJson)
930 3
    {
931
        $responseDecoded = json_decode($rawJson, true, 10);
932
        $decodeError     = json_last_error_msg();
933
        if ($decodeError == 'No error') {
934
            if (array_key_exists($this->nameSpace, $responseDecoded)) {
935 3
                $responseDecoded = $responseDecoded[$this->nameSpace];
936
            }
937
        } else {
938
            $this->addStatusMessage('JSON Decoder: '.$decodeError, 'error');
939 3
            $this->addStatusMessage($rawJson, 'debug');
940
        }
941
        return $responseDecoded;
942
    }
943
944
    /**
945
     * Convert FlexiBee Response XML to Array
946
     *
947
     * @param string $rawXML
948
     *
949 23
     * @return array
950
     */
951 23
    public function rawXmlToArray($rawXML)
952 23
    {
953 23
        return self::xml2array($rawXML);
954 23
    }
955 15
956 15
    /**
957 15
     * Parse Response array
958 23
     *
959
     * @param array $responseDecoded
960
     * @param int $responseCode Request Response Code
961
     *
962
     * @return array main data part of response
963
     */
964
    public function parseResponse($responseDecoded, $responseCode)
965
    {
966
        if (is_array($responseDecoded)) {
967
            $mainResult          = $this->unifyResponseFormat($responseDecoded);
968 23
            $this->responseStats = array_key_exists('stats', $responseDecoded) ? (isset($responseDecoded['stats'][0])
969
                    ? $responseDecoded['stats'][0] : $responseDecoded['stats']) : null;
970 23
        } else {
971 23
            $mainResult = $responseDecoded;
972 23
        }
973 23
        switch ($responseCode) {
974 23
            case 201: //Success Write
975
            case 200: //Success Read
976 23
                if (is_array($responseDecoded)) {
977 23
                    $this->lastResult = $mainResult;
978 23
                    if (isset($responseDecoded['@rowCount'])) {
979 23
                        $this->rowCount = (int) $responseDecoded['@rowCount'];
980 23
                    }
981
                    if (isset($responseDecoded['@globalVersion'])) {
982 23
                        $this->globalVersion = (int) $responseDecoded['@globalVersion'];
983 23
                    }
984 23
                }
985
                break;
986
987
            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...
988
                if ($this->debug === true) {
989
                    $this->error500Reporter($responseDecoded);
990 1
                }
991
            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...
992 1
                if ($this->ignoreNotFound === true) {
993 1
                    break;
994 1
                }
995 1
            case 400: //Bad Request parameters
996 1
            default: //Something goes wrong
997
                $this->addStatusMessage($this->lastResponseCode.': '.$this->curlInfo['url'],
998
                    'warning');
999
                if (is_array($responseDecoded)) {
1000
                    $this->parseError($responseDecoded);
1001 1
                }
1002
                $this->logResult($responseDecoded, $this->curlInfo['url']);
1003 1
                break;
1004 1
        }
1005
        return $mainResult;
1006
    }
1007
1008
    /**
1009
     * Parse error message response
1010
     *
1011
     * @param array $responseDecoded
1012
     * @return int number of errors processed
1013 23
     */
1014
    public function parseError(array $responseDecoded)
1015 23
    {
1016 23
        if (array_key_exists('results', $responseDecoded)) {
1017 22
            $this->errors = $responseDecoded['results'][0]['errors'];
1018
        } else {
1019
            if (array_key_exists('message', $responseDecoded)) {
1020
                $this->errors = [['message' => $responseDecoded['message']]];
1021 22
            }
1022
        }
1023
        return count($this->errors);
1024
    }
1025
1026
    /**
1027
     * Vykonej HTTP požadavek
1028
     *
1029
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
1030
     * @param string $url    URL požadavku
1031
     * @param string $method HTTP Method GET|POST|PUT|OPTIONS|DELETE
1032
     * @param string $format požadovaný formát komunikace
1033
     * @return int HTTP Response CODE
1034
     */
1035
    public function doCurlRequest($url, $method, $format = null)
1036
    {
1037
        if (is_null($format)) {
1038
            $format = $this->format;
1039
        }
1040
        curl_setopt($this->curl, CURLOPT_URL, $url);
1041
// Nastavení samotné operace
1042
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, strtoupper($method));
1043
//Vždy nastavíme byť i prázná postdata jako ochranu před chybou 411
1044
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->postFields);
1045
1046
        $httpHeaders = $this->defaultHttpHeaders;
1047
1048
        $formats = Formats::bySuffix();
1049
1050
        if (!isset($httpHeaders['Accept'])) {
1051
            $httpHeaders['Accept'] = $formats[$format]['content-type'];
1052
        }
1053
        if (!isset($httpHeaders['Content-Type'])) {
1054
            $httpHeaders['Content-Type'] = $formats[$format]['content-type'];
1055
        }
1056
        $httpHeadersFinal = [];
1057
        foreach ($httpHeaders as $key => $value) {
1058
            if (($key == 'User-Agent') && ($value == 'FlexiPeeHP')) {
1059 15
                $value .= ' v'.self::$libVersion;
1060
            }
1061 15
            $httpHeadersFinal[] = $key.': '.$value;
1062 15
        }
1063
1064 15
        curl_setopt($this->curl, CURLOPT_HTTPHEADER, $httpHeadersFinal);
1065 8
1066 7
// Proveď samotnou operaci
1067 7
        $this->lastCurlResponse            = curl_exec($this->curl);
1068 7
        $this->curlInfo                    = curl_getinfo($this->curl);
1069
        $this->curlInfo['when']            = microtime();
1070 8
        $this->curlInfo['request_headers'] = $httpHeadersFinal;
1071 1
        $this->responseFormat              = isset($this->curlInfo['content_type'])
1072 1
                ? Formats::contentTypeToSuffix($this->curlInfo['content_type']) : 'txt';
1073 8
        $this->lastResponseCode            = $this->curlInfo['http_code'];
1074
        $this->lastCurlError               = curl_error($this->curl);
1075 15
        if (strlen($this->lastCurlError)) {
1076 4
            $this->addStatusMessage(sprintf('Curl Error (HTTP %d): %s',
1077 4
                    $this->lastResponseCode, $this->lastCurlError), 'error');
1078 4
        }
1079
1080
        if ($this->debug === true) {
1081
            $this->saveDebugFiles();
1082
        }
1083 4
1084
        return $this->lastResponseCode;
1085 15
    }
1086
1087 15
    /**
1088 15
     * Nastaví druh prováděné akce.
1089
     *
1090
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
1091 15
     * @param string $action
1092
     * @return boolean
1093 15
     */
1094 15
    public function setAction($action)
1095 15
    {
1096
        $result           = false;
1097 15
        $actionsAvailable = $this->getActionsInfo();
1098
        if (is_array($actionsAvailable) && array_key_exists($action,
1099 15
                $actionsAvailable)) {
1100 15
            $this->action = $action;
1101 15
            $result       = true;
1102 9
        }
1103 9
        return $result;
1104 6
    }
1105 6
1106 9
    /**
1107 6
     * Convert XML to array.
1108
     *
1109
     * @param string $xml
1110 15
     *
1111
     * @return array
1112
     */
1113
    public static function xml2array($xml)
1114
    {
1115
        $arr = [];
1116
        if (!empty($xml)) {
1117
            if (is_string($xml)) {
1118
                $xml = simplexml_load_string($xml);
1119
            }
1120
1121 23
            foreach ($xml->children() as $r) {
1122
                if (count($r->children()) == 0) {
1123 23
                    $arr[$r->getName()] = strval($r);
1124 23
                } else {
1125 23
                    $arr[$r->getName()][] = self::xml2array($r);
1126 23
                }
1127 23
            }
1128
        }
1129
        return $arr;
1130
    }
1131 23
1132
    /**
1133
     * Odpojení od FlexiBee.
1134
     */
1135 23
    public function disconnect()
1136 22
    {
1137 22
        if (is_resource($this->curl)) {
1138 9
            curl_close($this->curl);
1139 9
        }
1140 22
        $this->curl = null;
1141
    }
1142
1143
    /**
1144
     * Disconnect CURL befere pass away
1145
     */
1146
    public function __destruct()
1147
    {
1148
        $this->disconnect();
1149
    }
1150
1151 6
    /**
1152
     * Načte řádek dat z FlexiBee.
1153
     *
1154 6
     * @param int $recordID id požadovaného záznamu
1155 6
     *
1156 6
     * @return array
1157 6
     */
1158 6
    public function getFlexiRow($recordID)
1159
    {
1160 6
        $record   = null;
1161
        $response = $this->performRequest($this->evidence.'/'.$recordID.'.json');
1162
        if (isset($response[$this->evidence])) {
1163
            $record = $response[$this->evidence][0];
1164
        }
1165 6
1166
        return $record;
1167
    }
1168
1169 6
    /**
1170
     * Oddělí z pole podmínek ty jenž patří za ? v URL požadavku
1171
     *
1172
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
1173
     * @param array $conditions pole podmínek   - rendrují se do ()
1174
     * @param array $urlParams  pole parametrů  - rendrují za ?
1175
     */
1176
    public function extractUrlParams(&$conditions, &$urlParams)
1177 16
    {
1178
        foreach ($this->urlParams as $urlParam) {
1179 16
            if (isset($conditions[$urlParam])) {
1180 9
                \Ease\Sand::divDataArray($conditions, $urlParams, $urlParam);
1181 9
            }
1182 16
        }
1183 16
    }
1184 16
1185
    /**
1186 16
     * convert unicode to entities for use with FlexiBee queries
1187 16
     *
1188 16
     * @param string $urlRaw
1189 15
     * 
1190 15
     * @return string
1191
     */
1192
    public static function urlEncode($urlRaw)
1193
    {
1194
        return str_replace(['%27', '%3A'], ["'", ':'], rawurlencode($urlRaw));
1195
    }
1196
1197
    /**
1198
     * Načte data z FlexiBee.
1199 15
     *
1200
     * @param string $suffix     dotaz
1201
     * @param string|array $conditions Volitelný filtrovací výraz
1202 15
     *
1203 10
     * @return array Data obtained
1204 10
     */
1205 15
    public function getFlexiData($suffix = null, $conditions = null)
1206 15
    {
1207 15
        $finalUrl  = '';
1208 15
        $urlParams = $this->defaultUrlParams;
1209
1210 14
        if (!empty($conditions)) {
1211 14
            if (is_array($conditions)) {
1212 14
                $this->extractUrlParams($conditions, $urlParams);
1213 14
                $conditions = $this->flexiUrl($conditions);
1214 10
            }
1215
1216 14
            if (strlen($conditions) && ($conditions[0] != '/')) {
1217 14
                $conditions = '('.self::urlEncode($conditions).')';
1218
            }
1219
        }
1220
1221
        if (strlen($suffix)) {
1222
            if (preg_match('/^http/', $suffix) || ($suffix[0] == '/') || is_numeric($suffix)) {
1223
                $finalUrl = $suffix;
1224
            } else {
1225
                if (preg_match('/^(code|ext):(.*)/', $suffix, $matches)) {
1226
                    $finalUrl = $matches[1].':'.rawurlencode($matches[2]);
1227
                }
1228
            }
1229
        }
1230
1231
        $finalUrl .= $conditions;
1232
1233
        if (count($urlParams)) {
1234
            if (strstr($finalUrl, '?')) {
1235
                $finalUrl .= '&';
1236
            } else {
1237
                $finalUrl .= '?';
1238
            }
1239
            $finalUrl .= http_build_query($urlParams, null, '&',
1240
                PHP_QUERY_RFC3986);
1241
        }
1242
1243
        $transactions = $this->performRequest($finalUrl, 'GET');
1244
1245
        $responseEvidence = $this->getResponseEvidence();
1246
        if (is_array($transactions) && array_key_exists($responseEvidence,
1247
                $transactions)) {
1248
            $result = $transactions[$responseEvidence];
1249
            if ((count($result) == 1) && (count(current($result)) == 0 )) {
1250
                $result = null; // Response is empty Array
1251
            }
1252 15
        } else {
1253
            $result = $transactions;
1254
        }
1255 15
1256 15
        return $result;
1257 15
    }
1258
1259 15
    /**
1260 15
     * Načte záznam z FlexiBee a uloží v sobě jeho data
1261 15
     * Read FlexiBee record and store it inside od object
1262 15
     *
1263 15
     * @param int $id ID or conditions
1264 15
     *
1265 15
     * @return int počet načtených položek
1266 15
     */
1267
    public function loadFromFlexiBee($id = null)
1268 15
    {
1269
        $data = [];
1270
        if (is_null($id)) {
1271 15
            $id = $this->getMyKey();
1272
        }
1273
        if (is_array($id)) {
1274 15
            $id = rawurlencode('('.self::flexiUrl($id).')');
1275 15
        } else if (preg_match('/^ext:/', $id)) {
1276 15
            $id = self::urlEncode($id);
1277 15
        } else if (preg_match('/^code:/', $id)) {
1278 15
            $id = self::code(rawurlencode(self::uncode($id)));
1279
        }
1280 15
1281
        $flexidata    = $this->getFlexiData($this->getEvidenceUrl().'/'.$id);
1282 15
        $this->apiURL = $this->curlInfo['url'];
1283
        if (is_array($flexidata) && (count($flexidata) == 1)) {
1284 15
            $data = current($flexidata);
1285 9
        }
1286 9
        return $this->takeData($data);
1287
    }
1288 15
1289
    /**
1290
     * Set Filter code for requests
1291
     *
1292
     * @link https://www.flexibee.eu/api/dokumentace/ref/zamykani-odemykani/
1293
     *
1294
     * @param array|string $filter filter formula or ['key'=>'value']
1295
     *
1296
     * @return string Filter code
1297
     */
1298
    public function setFilter($filter)
1299 23
    {
1300
        return $this->filter = is_array($filter) ? self::flexiUrl($filter) : $filter;
1301 23
    }
1302
1303 23
    /**
1304 23
     * Převede data do Json formátu pro FlexiBee.
1305 23
     * Convert data to FlexiBee like Json format
1306
     *
1307 23
     * @url https://www.flexibee.eu/api/dokumentace/ref/actions/
1308 23
     * @url https://www.flexibee.eu/api/dokumentace/ref/zamykani-odemykani/
1309 23
     *
1310
     * @param array $data    object data
1311 23
     * @param int   $options json_encode options like JSON_PRETTY_PRINT etc
1312 23
     *
1313 23
     * @return string
1314 23
     */
1315 23
    public function getJsonizedData($data = null, $options = 0)
1316 23
    {
1317 23
        if (is_null($data)) {
1318 23
            $data = $this->getData();
1319 23
        }
1320 23
1321
        $dataToJsonize = array_merge(['@version' => $this->protoVersion],
1322
            $this->getDataForJSON($data));
1323
        $jsonRaw       = json_encode([$this->nameSpace => $dataToJsonize],
1324 23
            $options);
1325 23
1326 23
        return $jsonRaw;
1327
    }
1328 23
1329 23
    /**
1330 23
     * Get Data Fragment specific for current object
1331 23
     *
1332
     * @param array $data
1333
     *
1334 23
     * @return array
1335 23
     */
1336 23
    public function getDataForJSON($data = null)
1337 23
    {
1338 23
        if (is_null($data)) {
1339 23
            $data = $this->getData();
1340 23
        }
1341 23
1342 23
        $dataForJson = [$this->getEvidence() => $this->objectToID($data)];
1343 23
1344 23
        if (!is_null($this->action)) {
1345 23
            $dataForJson[$this->evidence.'@action'] = $this->action;
1346
            $this->action                           = null;
1347 23
        }
1348 23
1349
        if (!is_null($this->filter)) {
1350 23
            $dataForJson[$this->evidence.'@filter'] = $this->filter;
1351
        }
1352
1353
1354
        foreach ($this->chained as $chained) {
1355
            $chainedData = $chained->getDataForJSON();
1356
            foreach ($chainedData as $chainedItemEvidence => $chainedItemData) {
1357
                if (array_key_exists($chainedItemEvidence, $dataForJson)) {
1358
                    if (is_string(key($dataForJson[$chainedItemEvidence]))) {
1359
                        $dataBackup                          = $dataForJson[$chainedItemEvidence];
1360 23
                        $dataForJson[$chainedItemEvidence]   = [];
1361
                        $dataForJson[$chainedItemEvidence][] = $dataBackup;
1362 23
                    }
1363 23
                    if (array_key_exists(0, $chainedItemData)) {
1364 23
                        foreach ($chainedItemData as $chainedItem) {
1365
                            $dataForJson[$chainedItemEvidence][] = $chainedItem;
1366
                        }
1367 23
                    } else {
1368 23
                        $dataForJson[$chainedItemEvidence][] = $chainedItemData;
1369 23
                    }
1370 23
                } else {
1371 23
                    $dataForJson[$chainedItemEvidence] = $chainedItemData;
1372
                }
1373
            }
1374 23
        }
1375 23
1376 23
1377
        return $dataForJson;
1378 23
    }
1379 23
1380 23
    /**
1381 23
     * Join another FlexiPeeHP Object
1382 23
     *
1383
     * @param FlexiBeeRO $object
1384 23
     *
1385 23
     * @return boolean adding to stack success
1386 23
     */
1387 23
    public function join(&$object)
1388 23
    {
1389
        $result = true;
1390 23
        if (method_exists($object, 'getDataForJSON')) {
1391 23
            $this->chained[] = $object;
1392 23
        } else {
1393 23
            throw new \Ease\Exception('$object->getDataForJSON() does not exist');
1394
        }
1395
1396 23
        return $result;
1397
    }
1398
1399 23
    /**
1400
     * Test if given record ID exists in FlexiBee.
1401
     *
1402 23
     * @param mixed $identifer presence state
1403 23
     *
1404 23
     * @return boolean
1405 23
     */
1406 23
    public function idExists($identifer = null)
1407 23
    {
1408
        if (is_null($identifer)) {
1409
            $identifer = $this->getMyKey();
1410
        }
1411
        $ignorestate = $this->ignore404();
1412
        $this->ignore404(true);
1413
        $this->getFlexiData(null,
1414
            [
1415
                'detail' => 'custom:'.$this->getKeyColumn(),
1416
                $this->getKeyColumn() => $identifer
1417
        ]);
1418
        $this->ignore404($ignorestate);
1419
        return $this->lastResponseCode == 200;
1420
    }
1421
1422
    /**
1423
     * Test if given record exists in FlexiBee.
1424
     *
1425
     * @param array|string|int $data ext:id:23|code:ITEM|['id'=>23]|23
1426
     * @return boolean Record presence status
1427
     */
1428
    public function recordExists($data = [])
1429
    {
1430
1431
        if (empty($data)) {
1432
            $data = $this->getData();
1433
        }
1434
        $ignorestate = $this->ignore404();
1435
        $this->ignore404(true);
1436
        $keyColumn   = $this->getKeyColumn();
1437
        $res         = $this->getColumnsFromFlexibee([$keyColumn],
1438
            is_array($data) ? $data : [$keyColumn => $data]);
1439
1440
        if (!count($res) || (isset($res['success']) && ($res['success'] == 'false'))
1441
            || ((isset($res) && is_array($res)) && !isset($res[0]) )) {
1442
            $found = false;
1443
        } else {
1444 23
            $found = true;
1445
        }
1446 23
        $this->ignore404($ignorestate);
1447
        return $found;
1448 23
    }
1449 23
1450 23
    /**
1451 23
     * Vrací z FlexiBee sloupečky podle podmínek.
1452 23
     *
1453 23
     * @param array|int|string $conditions pole podmínek nebo ID záznamu
1454 23
     * @param string           $indexBy    klice vysledku naplnit hodnotou ze
1455 23
     *                                     sloupečku
1456 23
     * @return array
1457
     */
1458 23
    public function getAllFromFlexibee($conditions = null, $indexBy = null)
1459 23
    {
1460 23
        if (is_int($conditions)) {
1461 23
            $conditions = [$this->getmyKeyColumn() => $conditions];
0 ignored issues
show
Bug introduced by
The method getmyKeyColumn() does not exist on FlexiPeeHP\FlexiBeeRO. Did you maybe mean getMyKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1462 23
        }
1463
1464
        $flexiData = $this->getFlexiData('', $conditions);
1465 23
1466 23
        if (!is_null($indexBy)) {
1467
            $flexiData = $this->reindexArrayBy($flexiData);
1468
        }
1469 23
1470
        return $flexiData;
1471 23
    }
1472 23
1473
    /**
1474 23
     * Vrací z FlexiBee sloupečky podle podmínek.
1475
     *
1476
     * @param string[] $columnsList seznam položek
1477 23
     * @param array    $conditions  pole podmínek nebo ID záznamu
1478 23
     * @param string   $indexBy     Sloupeček podle kterého indexovat záznamy
1479
     *
1480
     * @return array
1481
     */
1482
    public function getColumnsFromFlexibee($columnsList, $conditions = [],
1483
                                           $indexBy = null)
1484
    {
1485
        $detail = 'full';
1486
        switch (gettype($columnsList)) {
1487
            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...
1488
                $conditions = [$this->getmyKeyColumn() => $conditions];
0 ignored issues
show
Bug introduced by
The method getmyKeyColumn() does not exist on FlexiPeeHP\FlexiBeeRO. Did you maybe mean getMyKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1489 65
            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...
1490
                if (!is_null($indexBy) && !array_key_exists($indexBy,
1491 65
                        $columnsList)) {
1492 65
                    $columnsList[] = $indexBy;
1493
                }
1494
                $columns = implode(',', array_unique($columnsList));
1495 65
                $detail  = 'custom:'.$columns;
1496 65
            default:
1497
                switch ($columnsList) {
1498
                    case 'id':
1499
                        $detail = 'id';
1500
                        break;
1501 65
                    case 'summary':
1502
                        $detail = 'summary';
1503
                        break;
1504
                    default:
1505
                        break;
1506
                }
1507
                break;
1508
        }
1509
1510
        $conditions['detail'] = $detail;
1511 71
1512
        $flexiData = $this->getFlexiData(null, $conditions);
1513 71
1514
        if (is_array($indexBy) && count($flexiData) && count(current($flexiData))) {
1515
            $flexiData = $this->reindexArrayBy($flexiData, $indexBy);
0 ignored issues
show
Documentation introduced by
$indexBy is of type array, but the function expects a string|null.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1516
        }
1517
1518
        return $flexiData;
1519
    }
1520
1521
    /**
1522 23
     * Vrací kód záznamu.
1523
     * Obtain record CODE
1524 23
     *
1525
     * @param mixed $data
1526
     *
1527
     * @return string
1528
     */
1529
    public function getKod($data = null, $unique = true)
1530
    {
1531
        $kod = null;
1532 15
1533
        if (is_null($data)) {
1534 15
            $data = $this->getData();
1535 15
        }
1536 15
1537 15
        if (is_string($data)) {
1538 15
            $data = [$this->nameColumn => $data];
1539 9
        }
1540 9
1541 15
        if (isset($data['kod'])) {
1542
            $kod = $data['kod'];
1543
        } else {
1544
            if (isset($data[$this->nameColumn])) {
1545
                $kod = preg_replace('/[^a-zA-Z0-9]/', '',
1546
                    \Ease\Sand::rip($data[$this->nameColumn]));
1547
            } else {
1548
                if (isset($data[$this->keyColumn])) {
1549
                    $kod = \Ease\Sand::rip($data[$this->keyColumn]);
1550 23
                }
1551
            }
1552 23
            $kod = substr($kod, 0, 20);
1553 23
        }
1554 23
1555 23
        if (!strlen($kod)) {
1556 23
            $kod = 'NOTSET';
1557 23
        }
1558 23
1559 23
        if (strlen($kod) > 18) {
1560 23
            $kodfinal = strtoupper(substr($kod, 0, 18));
1561 23
        } else {
1562 23
            $kodfinal = strtoupper($kod);
1563 23
        }
1564 23
1565 23
        if ($unique) {
1566
            $counter = 0;
1567 23
            if (count($this->codes)) {
1568
                foreach ($this->codes as $codesearch => $keystring) {
1569
                    if (strstr($codesearch, $kodfinal)) {
1570
                        ++$counter;
1571
                    }
1572
                }
1573
            }
1574
            if ($counter) {
1575
                $kodfinal = $kodfinal.$counter;
1576
            }
1577 22
1578
            $this->codes[$kodfinal] = $kod;
1579 22
        }
1580
1581 21
        return self::code($kodfinal);
1582
    }
1583
1584
    /**
1585
     * Write Operation Result.
1586
     *
1587
     * @param array  $resultData
1588
     * @param string $url        URL
1589 22
     * @return boolean Log save success
1590
     */
1591 22
    public function logResult($resultData = null, $url = null)
1592 22
    {
1593 22
        $logResult = false;
1594
        if (isset($resultData['success']) && ($resultData['success'] == 'false')) {
1595
            if (isset($resultData['message'])) {
1596 22
                $this->addStatusMessage($resultData['message'], 'warning');
1597
            }
1598
            $this->addStatusMessage('Error '.$this->lastResponseCode.': '.urldecode($url),
1599
                'warning');
1600
            unset($url);
1601
        }
1602
        if (is_null($resultData)) {
1603
            $resultData = $this->lastResult;
1604
        }
1605 22
        if (isset($url)) {
1606
            $this->logger->addStatusMessage($this->lastResponseCode.':'.urldecode($url));
1607 22
        }
1608 22
1609 22
        if (isset($resultData['results'])) {
1610 22
            if ($resultData['success'] == 'false') {
1611 22
                $status = 'error';
1612 22
            } else {
1613 22
                $status = 'success';
1614 22
            }
1615 22
            foreach ($resultData['results'] as $result) {
1616 22
                if (isset($result['request-id'])) {
1617 22
                    $rid = $result['request-id'];
1618 22
                } else {
1619
                    $rid = '';
1620 22
                }
1621
                if (isset($result['errors'])) {
1622
                    foreach ($result['errors'] as $error) {
1623
                        $message = $error['message'];
1624
                        if (isset($error['for'])) {
1625
                            $message .= ' for: '.$error['for'];
1626
                        }
1627
                        if (isset($error['value'])) {
1628
                            $message .= ' value:'.$error['value'];
1629
                        }
1630
                        if (isset($error['code'])) {
1631
                            $message .= ' code:'.$error['code'];
1632 22
                        }
1633
                        $this->addStatusMessage($rid.': '.$message, $status);
1634
                    }
1635
                }
1636
            }
1637
        }
1638
        return $logResult;
1639
    }
1640
1641 23
    /**
1642
     * Save RAW Curl Request & Response to files in Temp directory
1643 23
     */
1644 23
    public function saveDebugFiles()
1645 23
    {
1646 23
        $tmpdir   = sys_get_temp_dir();
1647 16
        $fname    = $this->evidence.'-'.$this->curlInfo['when'].'.'.$this->format;
1648 16
        $reqname  = $tmpdir.'/request-'.$fname;
1649 23
        $respname = $tmpdir.'/response-'.$fname;
1650
        file_put_contents($reqname, $this->postFields);
1651
        file_put_contents($respname, $this->lastCurlResponse);
1652
    }
1653
1654
    /**
1655
     * Připraví data pro odeslání do FlexiBee
1656
     *
1657
     * @param string $data
1658 23
     */
1659
    public function setPostFields($data)
1660 23
    {
1661 23
        $this->postFields = $data;
1662 23
    }
1663 23
1664 23
    /**
1665 23
     * Generuje fragment url pro filtrování.
1666 23
     *
1667 23
     * @see https://www.flexibee.eu/api/dokumentace/ref/filters
1668 23
     *
1669
     * @param array  $data
1670
     * @param string $joiner default and/or
1671
     * @param string $defop  default operator
1672
     *
1673
     * @return string
1674
     */
1675
    public static function flexiUrl(array $data, $joiner = 'and', $defop = 'eq')
1676
    {
1677 23
        $parts = [];
1678
1679 23
        foreach ($data as $column => $value) {
1680 23
            if (!is_numeric($column)) {
1681 23
                if (is_integer($data[$column]) || is_float($data[$column])) {
1682 23
                    $parts[$column] = $column.' eq \''.$data[$column].'\'';
1683 23
                } elseif (is_bool($data[$column])) {
1684 23
                    $parts[$column] = $data[$column] ? $column.' eq true' : $column.' eq false';
1685 13
                } elseif (is_null($data[$column])) {
1686 13
                    $parts[$column] = $column." is null";
1687 23
                } else {
1688
                    switch ($value) {
1689
                        case '!null':
1690
                            $parts[$column] = $column." is not null";
1691
                            break;
1692
                        case 'is empty':
1693
                        case 'is not empty':
1694
                            $parts[$column] = $column.' '.$value;
1695
                            break;
1696 23
                        default:
1697
                            if ($column == 'stitky') {
1698 23
                                $parts[$column] = $column."='".self::code($data[$column])."'";
1699 23
                            } else {
1700 23
                                $parts[$column] = $column." $defop '".$data[$column]."'";
1701 23
                            }
1702 23
                            break;
1703 16
                    }
1704 16
                }
1705 23
            } else {
1706
                $parts[] = $value;
1707
            }
1708
        }
1709
        return implode(' '.$joiner.' ', $parts);
1710
    }
1711
1712
    /**
1713
     * Obtain record/object numeric identificator id:
1714 23
     * Vrací číselný identifikátor objektu id:
1715
     *
1716 23
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1717 23
     *
1718 23
     * @return null|int indentifikátor záznamu reprezentovaného objektem
1719 23
     */
1720 23
    public function getRecordID()
1721 16
    {
1722 16
        $id = $this->getDataValue('id');
1723 23
        return is_null($id) ? null : is_numeric($id) ? intval($id) : $id;
1724
    }
1725
1726
    /**
1727
     * Obtain record/object identificator code:
1728
     * Vrací identifikátor objektu code:
1729
     *
1730
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1731 23
     *
1732
     * @return string record code identifier
1733 23
     */
1734 1
    public function getRecordCode()
1735 1
    {
1736 23
        return empty($this->getDataValue('kod')) ? null : self::code($this->getDataValue('kod'));
1737 23
    }
1738
1739
    /**
1740
     * Obtain record/object identificator extId: code: or id:
1741
     * Vrací identifikátor objektu extId: code: nebo id:
1742
     *
1743
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1744 20
     *
1745
     * @return string|int|null record code identifier
1746 20
     */
1747 20
    public function getRecordIdent()
1748 20
    {
1749 20
        $ident = $this->getExternalID();
1750
        if (empty($ident)) {
1751
            $ident = $this->getRecordCode();
1752
        }
1753
        if (empty($ident)) {
1754
            $ident = $this->getRecordID();
1755 20
        }
1756
        return $ident;
1757
    }
1758
1759
    /**
1760
     * Obtain record/object identificator code: or id:
1761
     * Vrací identifikátor objektu code: nebo id:
1762
     *
1763
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1764
     * @return string indentifikátor záznamu reprezentovaného objektem
1765
     */
1766
    public function __toString()
1767
    {
1768
        return strval($this->getRecordIdent());
1769
    }
1770
1771
    /**
1772
     * Gives you FlexiPeeHP class name for Given Evidence
1773
     *
1774
     * @param string $evidence
1775
     * @return string Class name
1776
     */
1777
    public static function evidenceToClassName($evidence)
1778
    {
1779
        return str_replace(' ', '', ucwords(str_replace('-', ' ', $evidence)));
1780
    }
1781
1782
    /**
1783
     * Obtain ID of first record in evidence
1784
     *
1785
     * @return string|null id or null if no records
1786
     */
1787
    public function getFirstRecordID()
1788
    {
1789
        $firstID    = null;
1790
        $keyColumn  = $this->getKeyColumn();
1791
        $firstIdRaw = $this->getColumnsFromFlexibee([$keyColumn],
1792
            ['limit' => 1, 'order' => $keyColumn], $keyColumn);
1793
        if (!empty($firstIdRaw) && isset(current($firstIdRaw)[$keyColumn])) {
1794
            $firstID = current($firstIdRaw)[$keyColumn];
1795
        }
1796
        return is_numeric($firstID) ? intval($firstID) : $firstID;
1797
    }
1798
1799
    /**
1800
     * Vrací hodnotu daného externího ID
1801
     *
1802
     * @param string $want Which ? If empty,you obtain the first one.
1803
     * @return string
1804
     */
1805
    public function getExternalID($want = null)
1806
    {
1807
        $extid = null;
1808
        $ids   = $this->getDataValue('external-ids');
1809
        if (is_null($want)) {
1810
            if (!empty($ids)) {
1811
                $extid = current($ids);
1812
            }
1813
        } else {
1814
            if (!is_null($ids) && is_array($ids)) {
1815
                foreach ($ids as $id) {
1816
                    if (strstr($id, 'ext:'.$want)) {
1817
                        $extid = str_replace('ext:'.$want.':', '', $id);
1818
                    }
1819
                }
1820
            }
1821
        }
1822
        return $extid;
1823
    }
1824
1825
    /**
1826
     * Obtain actual GlobalVersion
1827
     * Vrací aktuální globální verzi změn
1828
     *
1829
     * @link https://www.flexibee.eu/api/dokumentace/ref/changes-api#globalVersion Globální Verze
1830
     * @return type
1831
     */
1832
    public function getGlobalVersion()
1833
    {
1834
        $this->getFlexiData(null, ['add-global-version' => 'true', 'limit' => 1]);
1835
1836
        return $this->globalVersion;
1837
    }
1838
1839
    /**
1840
     * Gives you current ApiURL with given format suffix
1841
     * 
1842
     * @param string $format json|html|xml|...
1843
     * 
1844
     * @return string API URL for current record or object/evidence
1845 23
     */
1846
    public function getApiURL($format = null)
1847 23
    {
1848
        $apiUrl = str_replace(['.'.$this->format, '?limit=0'], '', $this->apiURL);
1849
        return $apiUrl.(empty($format) ? '' : '.'.$format );
1850
    }
1851
1852
    /**
1853
     * Obtain content type of last response
1854
     *
1855
     * @return string
1856
     */
1857 23
    public function getResponseFormat()
1858
    {
1859 23
        if (isset($this->curlInfo['content_type'])) {
1860
            $responseFormat = $this->curlInfo['content_type'];
1861
        } else {
1862
            $responseFormat = null;
1863
        }
1864
        return $responseFormat;
1865
    }
1866
1867
    /**
1868
     * Return the same response format for one and multiplete results
1869
     *
1870
     * @param array $responseBody
1871
     * @return array
1872
     */
1873
    public function unifyResponseFormat($responseBody)
1874
    {
1875
        if (!is_array($responseBody) || array_key_exists('message',
1876
                $responseBody)) { //Unifi response format
1877
            $response = $responseBody;
1878
        } else {
1879
            $evidence = $this->getResponseEvidence();
1880
            if (array_key_exists($evidence, $responseBody)) {
1881
                $response        = [];
1882
                $evidenceContent = $responseBody[$evidence];
1883
                if (array_key_exists(0, $evidenceContent)) {
1884
                    $response[$evidence] = $evidenceContent; //Multiplete Results
1885
                } else {
1886
                    $response[$evidence][0] = $evidenceContent; //One result
1887
                }
1888
            } else {
1889
                if (isset($responseBody['priloha'])) {
1890
                    $response = $responseBody['priloha'];
1891
                } else {
1892
                    if (array_key_exists('results', $responseBody)) {
1893
                        $response = $responseBody['results'];
1894
                    } else {
1895
                        $response = $responseBody;
1896
                    }
1897
                }
1898
            }
1899
        }
1900
        return $response;
1901
    }
1902
1903
    /**
1904
     * Obtain structure for current (or given) evidence
1905
     *
1906
     * @param string $evidence
1907
     * @return array Evidence structure
1908
     */
1909
    public function getColumnsInfo($evidence = null)
1910
    {
1911
        $columnsInfo = null;
1912
        $infoSource  = self::$infoDir.'/Properties.'.(empty($evidence) ? $this->getEvidence()
1913
                : $evidence).'.json';
1914
        if (file_exists($infoSource)) {
1915
            $columnsInfo = json_decode(file_get_contents($infoSource), true);
1916
        }
1917
        return $columnsInfo;
1918
    }
1919
1920
    /**
1921
     * Gives you properties for (current) evidence column
1922
     *
1923
     * @param string $column    name of column
1924
     * @param string $evidence  evidence name if different
1925
     *
1926
     * @return array column properties or null if column not exits
1927
     */
1928
    public function getColumnInfo($column, $evidence = null)
1929
    {
1930
        $columnsInfo = $this->getColumnsInfo(empty($evidence) ? $this->getEvidence()
1931
                : $evidence);
1932
        return array_key_exists($column, $columnsInfo) ? $columnsInfo[$column] : null;
1933
    }
1934
1935
    /**
1936
     * Obtain actions for current (or given) evidence
1937
     *
1938
     * @param string $evidence
1939
     * @return array Evidence structure
1940
     */
1941
    public function getActionsInfo($evidence = null)
1942
    {
1943
        $actionsInfo = null;
1944
        if (is_null($evidence)) {
1945
            $evidence = $this->getEvidence();
1946
        }
1947
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
1948
        if (isset(\FlexiPeeHP\Actions::$$propsName)) {
1949
            $actionsInfo = Actions::$$propsName;
1950
        }
1951
        return $actionsInfo;
1952
    }
1953
1954
    /**
1955
     * Obtain relations for current (or given) evidence
1956
     *
1957
     * @param string $evidence
1958
     * @return array Evidence structure
1959
     */
1960
    public function getRelationsInfo($evidence = null)
1961
    {
1962
        $relationsInfo = null;
1963
        if (is_null($evidence)) {
1964
            $evidence = $this->getEvidence();
1965
        }
1966
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
1967
        if (isset(\FlexiPeeHP\Relations::$$propsName)) {
1968
            $relationsInfo = Relations::$$propsName;
1969
        }
1970
        return $relationsInfo;
1971
    }
1972
1973
    /**
1974
     * Obtain info for current (or given) evidence
1975
     *
1976
     * @param string $evidence
1977
     * @return array Evidence info
1978
     */
1979
    public function getEvidenceInfo($evidence = null)
1980
    {
1981
        $evidencesInfo = null;
1982
        if (is_null($evidence)) {
1983
            $evidence = $this->getEvidence();
1984
        }
1985
        if (isset(EvidenceList::$evidences[$evidence])) {
1986
            $evidencesInfo = EvidenceList::$evidences[$evidence];
1987
        }
1988
        return $evidencesInfo;
1989
    }
1990
1991
    /**
1992
     * Obtain name for current (or given) evidence path
1993
     *
1994
     * @param string $evidence Evidence Path
1995
     * @return array Evidence info
1996
     */
1997
    public function getEvidenceName($evidence = null)
1998
    {
1999
        $evidenceName = null;
2000
        if (is_null($evidence)) {
2001
            $evidence = $this->getEvidence();
2002
        }
2003
        if (isset(EvidenceList::$name[$evidence])) {
2004
            $evidenceName = EvidenceList::$name[$evidence];
2005
        }
2006
        return $evidenceName;
2007
    }
2008
2009
    /**
2010
     * Save current object to file
2011
     *
2012
     * @param string $destfile path to file
2013
     */
2014
    public function saveResponseToFile($destfile)
2015
    {
2016
        if (strlen($this->lastCurlResponse)) {
2017
            $this->doCurlRequest($this->apiURL, 'GET', $this->format);
2018
        }
2019
        file_put_contents($destfile, $this->lastCurlResponse);
2020
    }
2021
2022
    /**
2023
     * Obtain established relations listing
2024
     *
2025
     * @return array Null or Relations
2026
     */
2027
    public function getVazby($id = null)
2028
    {
2029
        if (is_null($id)) {
2030
            $id = $this->getRecordID();
2031
        }
2032
        if (!empty($id)) {
2033
            $vazbyRaw = $this->getColumnsFromFlexibee(['vazby'],
2034
                ['relations' => 'vazby', 'id' => $id]);
2035 23
            $vazby    = array_key_exists('vazby', $vazbyRaw[0]) ? $vazbyRaw[0]['vazby']
2036
                    : null;
2037 23
        } else {
2038 23
            throw new \Exception(_('ID requied to get record relations '));
2039 23
        }
2040 23
        return $vazby;
2041
    }
2042
2043
    /**
2044
     * Gives You URL for Current Record in FlexiBee web interface
2045
     *
2046
     * @return string url
2047
     */
2048
    public function getFlexiBeeURL()
2049
    {
2050
        $parsed_url = parse_url(str_replace('.'.$this->format, '', $this->apiURL));
2051
        $scheme     = isset($parsed_url['scheme']) ? $parsed_url['scheme'].'://'
2052
                : '';
2053
        $host       = isset($parsed_url['host']) ? $parsed_url['host'] : '';
2054
        $port       = isset($parsed_url['port']) ? ':'.$parsed_url['port'] : '';
2055
        $user       = isset($parsed_url['user']) ? $parsed_url['user'] : '';
2056
        $pass       = isset($parsed_url['pass']) ? ':'.$parsed_url['pass'] : '';
2057
        $pass       = ($user || $pass) ? "$pass@" : '';
2058
        $path       = isset($parsed_url['path']) ? $parsed_url['path'] : '';
2059
        return $scheme.$user.$pass.$host.$port.$path;
2060
    }
2061
2062
    /**
2063
     * Set Record Key
2064
     *
2065
     * @param int|string $myKeyValue
2066
     * @return boolean
2067
     */
2068
    public function setMyKey($myKeyValue)
2069
    {
2070
        if (substr($myKeyValue, 0, 4) == 'ext:') {
2071
            $extIds = $this->getDataValue('external-ids');
2072
            if (count($extIds)) {
2073
                $extIds = array_combine($extIds, $extIds);
2074
            }
2075
            $extIds[$myKeyValue] = $myKeyValue;
2076
            $res                 = $this->setDataValue('external-ids', $extIds);
2077
        } else {
2078
            $res = parent::setMyKey($myKeyValue);
2079
        }
2080
        $this->updateApiURL();
2081
        return $res;
2082
    }
2083
2084
    /**
2085
     * Set or get ignore not found pages flag
2086
     *
2087
     * @param boolean $ignore set flag to
2088
     *
2089
     * @return boolean get flag state
2090
     */
2091
    public function ignore404($ignore = null)
2092
    {
2093
        if (!is_null($ignore)) {
2094
            $this->ignoreNotFound = $ignore;
2095
        }
2096
        return $this->ignoreNotFound;
2097
    }
2098
2099
    /**
2100
     * Send Document by mail
2101
     *
2102
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
2103
     *
2104
     * @param string $to         Email ecipient
2105
     * @param string $subject    Email Subject
2106
     * @param string $body       Email Text
2107
     *
2108
     * @return int http response code
2109
     */
2110
    public function sendByMail($to, $subject, $body, $cc = null)
2111
    {
2112
        $this->setPostFields($body);
2113
2114
        $this->performRequest(rawurlencode($this->getRecordID()).'/odeslani-dokladu?to='.$to.'&subject='.urlencode($subject).'&cc='.$cc
2115
            , 'PUT', 'xml');
2116
2117
        return $this->lastResponseCode == 200;
2118
    }
2119
2120
    /**
2121
     * Send all unsent Invoices by mail
2122
     *
2123
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
2124
     * @return int http response code
2125
     */
2126
    public function sendUnsent()
2127
    {
2128
        return $this->doCurlRequest('automaticky-odeslat-neodeslane', 'PUT',
2129
                'xml');
2130
    }
2131
2132
    /**
2133
     * FlexiBee date to PHP DateTime conversion
2134
     *
2135
     * @param string $flexidate 2017-05-26+02:00
2136
     *
2137
     * @return \DateTime | false
2138
     */
2139
    public static function flexiDateToDateTime($flexidate)
2140
    {
2141
        return \DateTime::createFromFormat(self::$DateFormat.'O', $flexidate)->setTime(0,
2142
                0);
2143
    }
2144
2145
    /**
2146
     * FlexiBee dateTime to PHP DateTime conversion
2147
     *
2148
     * @param string $flexidatetime 2017-09-26T10:00:53.755+02:00 or older 2017-05-19T00:00:00+02:00
2149
     *
2150
     * @return \DateTime | false
2151
     */
2152
    public static function flexiDateTimeToDateTime($flexidatetime)
2153
    {
2154
        if (strchr($flexidatetime, '.')) { //NewFormat
2155
            $format = self::$DateTimeFormat;
2156
        } else { // Old format
2157
            $format = 'Y-m-d\TH:i:s+P';
2158
        }
2159
        return \DateTime::createFromFormat($format, $flexidatetime);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression \DateTime::createFromFor...ormat, $flexidatetime); of type DateTime|false adds false to the return on line 2159 which is incompatible with the return type documented by FlexiPeeHP\FlexiBeeRO::flexiDateTimeToDateTime of type DateTime. It seems like you forgot to handle an error condition.
Loading history...
2160
    }
2161
2162
    /**
2163
     * Získá dokument v daném formátu
2164
     * Obtain document in given format
2165
     *
2166
     * @param string $format  pdf/csv/xml/json/ ...
2167
     * @param string $reportName Template used to generate PDF
2168
     *
2169
     * @return string|null filename downloaded or none
2170
     */
2171
    public function getInFormat($format, $reportName = null)
2172
    {
2173
        $response = null;
2174
        if ($this->setFormat($format)) {
2175
            $urlParams = [];
2176
            if (!empty($reportName)) {
2177
                $urlParams['report-name'] = $reportName;
2178
            }
2179
            if ($format == 'html') {
2180
                $urlParams['inDesktopApp'] = 'true';
2181
            }
2182
            if (($this->doCurlRequest($this->addUrlParams($this->apiURL,
2183
                        $urlParams), 'GET') == 200)) {
2184
                $response = $this->lastCurlResponse;
2185
            }
2186
        }
2187
        return $response;
2188
    }
2189
2190
    /**
2191
     * Uloží dokument v daném formátu do složky v systému souborů
2192
     * Save document in given format to directory in filesystem
2193
     *
2194
     * @param string $format  pdf/csv/xml/json/ ...
2195
     * @param string $destDir where to put file (prefix)
2196
     * @param string $reportName Template used to generate PDF
2197
     *
2198
     * @return string|null filename downloaded or none
2199
     */
2200
    public function downloadInFormat($format, $destDir = './',
2201
                                     $reportName = null)
2202
    {
2203
        $fileOnDisk   = null;
2204
        $formatBackup = $this->format;
2205
        if ($this->setFormat($format)) {
2206
            $downloadTo = $destDir.$this->getEvidence().'_'.$this->getMyKey().'.'.$format;
2207
            if (($this->doCurlRequest(empty($reportName) ? $this->apiURL : $this->addUrlParams($this->apiURL,
2208
                            ['report-name' => $reportName]), 'GET') == 200) && (file_put_contents($downloadTo,
2209
                    $this->lastCurlResponse) !== false)) {
2210
                $fileOnDisk = $downloadTo;
2211
            }
2212
            $this->setFormat($formatBackup);
2213
        }
2214
        return $fileOnDisk;
2215
    }
2216
2217
    /**
2218
     * Compile and send Report about Error500 to FlexiBee developers
2219
     * If FlexiBee is running on localost try also include java backtrace
2220
     *
2221
     * @param array $errorResponse result of parseError();
2222
     */
2223
    public function error500Reporter($errorResponse)
2224
    {
2225
        $ur = str_replace('/c/'.$this->company, '',
2226
            str_replace($this->url, '', $this->curlInfo['url']));
2227
        if (!array_key_exists($ur, $this->reports)) {
2228
            $tmpdir   = sys_get_temp_dir();
2229
            $myTime   = $this->curlInfo['when'];
2230
            $curlname = $tmpdir.'/curl-'.$this->evidence.'-'.$myTime.'.json';
2231
            file_put_contents($curlname,
2232
                json_encode($this->curlInfo, JSON_PRETTY_PRINT));
2233
2234
            $report = new \Ease\Mailer($this->reportRecipient,
2235
                'Error report 500 - '.$ur);
2236
2237
            $d     = dir($tmpdir);
2238
            while (false !== ($entry = $d->read())) {
2239
                if (strstr($entry, $myTime)) {
2240
                    $ext  = pathinfo($tmpdir.'/'.$entry, PATHINFO_EXTENSION);
2241
                    $mime = Formats::suffixToContentType($ext);
2242
                    $report->addFile($tmpdir.'/'.$entry,
2243
                        empty($mime) ? 'text/plain' : $mime);
2244
                }
2245
            }
2246
            $d->close();
2247
2248
            if ((strstr($this->url, '://localhost') || strstr($this->url,
2249
                    '://127.')) && file_exists('/var/log/flexibee.log')) {
2250
2251
                $fl = fopen('/var/log/'.'flexibee.log', 'r');
2252
                if ($fl) {
2253
                    $tracelog = [];
2254
                    for ($x_pos = 0, $ln = 0, $output = array(); fseek($fl,
2255
                            $x_pos, SEEK_END) !== -1; $x_pos--) {
2256
                        $char = fgetc($fl);
2257
                        if ($char === "\n") {
2258
                            $tracelog[] = $output[$ln];
2259
                            if (strstr($output[$ln], $errorResponse['message'])) {
2260
                                break;
2261
                            }
2262
                            $ln++;
2263
                            continue;
2264
                        }
2265
                        $output[$ln] = $char.((array_key_exists($ln, $output)) ? $output[$ln]
2266
                                : '');
2267
                    }
2268
2269
                    $trace     = implode("\n", array_reverse($tracelog));
2270
                    $tracefile = $tmpdir.'/trace-'.$this->evidence.'-'.$myTime.'.log';
2271
                    file_put_contents($tracefile, $trace);
2272
                    $report->addItem("\n\n".$trace);
2273
                    fclose($fl);
2274
                }
2275
            } else {
2276
                $report->addItem($errorResponse['message']);
2277
            }
2278
2279
            $licenseInfo = $this->performRequest($this->url.'/default-license.json');
2280
2281
            $report->addItem("\n\n".json_encode($licenseInfo['license'],
2282
                    JSON_PRETTY_PRINT));
2283
2284
            if ($report->send()) {
2285
                $this->reports[$ur] = $myTime;
2286
            }
2287
        }
2288
    }
2289
2290
    /**
2291
     * Returns code:CODE
2292
     *
2293
     * @param string $code
2294
     *
2295
     * @return string
2296
     */
2297
    public static function code($code)
2298
    {
2299
        return 'code:'.strtoupper(self::uncode($code));
2300
    }
2301
2302
    /**
2303
     * Returns CODE without code: prefix
2304
     *
2305
     * @param string $code
2306
     *
2307
     * @return string
2308
     */
2309
    public static function uncode($code)
2310
    {
2311
        return str_replace(['code:', 'code%3A'], '', $code);
2312
    }
2313
2314
    /**
2315
     * Remove all @ items from array
2316
     *
2317
     * @param array $data original data
2318
     *
2319
     * @return array data without @ columns
2320
     */
2321
    public static function arrayCleanUP($data)
2322
    {
2323
        return array_filter(
2324
            $data,
2325
            function ($key) {
2326
            return !strchr($key, '@');
2327
        }, ARRAY_FILTER_USE_KEY);
2328
    }
2329
2330
    /**
2331
     * Add Info about used user, server and libraries
2332
     *
2333
     * @param string $additions Additional note text
2334
     */
2335
    public function logBanner($additions = null)
2336
    {
2337
        $this->addStatusMessage('FlexiBee '.str_replace('://',
2338
                '://'.$this->user.'@', str_replace('.json', '', $this->apiURL)).' FlexiPeeHP v'.self::$libVersion.' (FlexiBee '.EvidenceList::$version.') EasePHP Framework v'.\Ease\Atom::$frameworkVersion.' '.$additions,
2339
            'debug');
2340
    }
2341
2342
    /**
2343
     * Reconnect After unserialization
2344
     */
2345
    public function __wakeup()
2346
    {
2347
        parent::__wakeup();
2348
        $this->curlInit();
2349
    }
2350
}
2351