Completed
Push — master ( 8b82c3...5f2df6 )
by Vítězslav
45:19 queued 19:43
created

FlexiBeeRO::getReportsInfo()   B

Complexity

Conditions 7
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
nc 3
nop 0
dl 0
loc 14
rs 8.8333
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * FlexiPeeHP - Read Only Access to FlexiBee class.
5
 *
6
 * @author     Vítězslav Dvořák <[email protected]>
7
 * @copyright  (C) 2015-2019 Spoje.Net
8
 */
9
10
namespace FlexiPeeHP;
11
12
/**
13
 * Základní třída pro čtení z FlexiBee
14
 *
15
 * @url https://demo.flexibee.eu/devdoc/
16
 */
17
class FlexiBeeRO extends \Ease\Sand {
18
19
    use \Ease\RecordKey;
20
21
    /**
22
     * Where to get JSON files with evidence stricture etc.
23
     * @var string
24
     */
25
    public static $infoDir = __DIR__ . '/../../static';
26
27
    /**
28
     * Version of FlexiPeeHP library
29
     *
30
     * @var string
31
     */
32
    public static $libVersion = '1.34';
33
34
    /**
35
     * Základní namespace pro komunikaci s FlexiBee.
36
     * Basic namespace for communication with FlexiBee
37
     *
38
     * @var string Jmený prostor datového bloku odpovědi
39
     */
40
    public $nameSpace = 'winstrom';
41
42
    /**
43
     * URL of object data in FlexiBee
44
     * @var string url
45
     */
46
    public $apiURL = null;
47
48
    /**
49
     * Datový blok v poli odpovědi.
50
     * Data block in response field.
51
     *
52
     * @var string
53
     */
54
    public $resultField = 'results';
55
56
    /**
57
     * Verze protokolu použitého pro komunikaci.
58
     * Communication protocol version used.
59
     *
60
     * @var string Verze použitého API
61
     */
62
    public $protoVersion = '1.0';
63
64
    /**
65
     * Evidence užitá objektem.
66
     * Evidence used by object
67
     *
68
     * @link https://demo.flexibee.eu/c/demo/evidence-list Přehled evidencí
69
     * @var string
70
     */
71
    public $evidence = null;
72
73
    /**
74
     * Detaily evidence užité objektem
75
     * 
76
     * @var array 
77
     */
78
    public $evidenceInfo = [];
79
80
    /**
81
     * Výchozí formát pro komunikaci.
82
     * Default communication 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 $format = 'json';
89
90
    /**
91
     * formát příchozí odpovědi
92
     * response format
93
     *
94
     * @link https://www.flexibee.eu/api/dokumentace/ref/format-types Přehled možných formátů
95
     *
96
     * @var string json|xml|...
97
     */
98
    public $responseFormat = 'json';
99
100
    /**
101
     * Curl Handle.
102
     *
103
     * @var resource
104
     */
105
    public $curl = null;
106
107
    /**
108
     * @link https://demo.flexibee.eu/devdoc/company-identifier Identifikátor firmy
109
     * @var string
110
     */
111
    public $company = null;
112
113
    /**
114
     * [protocol://]Server[:port]
115
     * @var string
116
     */
117
    public $url = null;
118
119
    /**
120
     * REST API Username
121
     * @var string
122
     */
123
    public $user = null;
124
125
    /**
126
     * REST API Password
127
     * @var string
128
     */
129
    public $password = null;
130
131
    /**
132
     * @var array Pole HTTP hlaviček odesílaných s každým požadavkem
133
     */
134
    public $defaultHttpHeaders = ['User-Agent' => 'FlexiPeeHP'];
135
136
    /**
137
     * Default additional request url parameters after question mark
138
     *
139
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls   Common params
140
     * @link https://www.flexibee.eu/api/dokumentace/ref/paging Paging params
141
     * @var array
142
     */
143
    public $defaultUrlParams = [];
144
145
    /**
146
     * Identifikační řetězec.
147
     *
148
     * @var string
149
     */
150
    public $init = null;
151
152
    /**
153
     * Sloupeček s názvem.
154
     *
155
     * @var string
156
     */
157
    public $nameColumn = 'nazev';
158
159
    /**
160
     * Sloupeček obsahující datum vložení záznamu do shopu.
161
     *
162
     * @var string
163
     */
164
    public $myCreateColumn = 'false';
165
166
    /**
167
     * Slopecek obsahujici datum poslení modifikace záznamu do shopu.
168
     *
169
     * @var string
170
     */
171
    public $myLastModifiedColumn = 'lastUpdate';
172
173
    /**
174
     * Klíčový idendifikátor záznamu.
175
     *
176
     * @var string
177
     */
178
    public $fbKeyColumn = 'id';
179
180
    /**
181
     * Informace o posledním HTTP requestu.
182
     *
183
     * @var *
184
     */
185
    public $curlInfo;
186
187
    /**
188
     * Informace o poslední HTTP chybě.
189
     *
190
     * @var string
191
     */
192
    public $lastCurlError = null;
193
194
    /**
195
     * Used codes storage.
196
     *
197
     * @var array
198
     */
199
    public $codes = null;
200
201
    /**
202
     * Last Inserted ID.
203
     *
204
     * @var int
205
     */
206
    public $lastInsertedID = null;
207
208
    /**
209
     * Default Line Prefix.
210
     *
211
     * @var string
212
     */
213
    public $prefix = '/c/';
214
215
    /**
216
     * Raw Content of last curl response
217
     *
218
     * @var string
219
     */
220
    public $lastCurlResponse;
221
222
    /**
223
     * HTTP Response code of last request
224
     *
225
     * @var int
226
     */
227
    public $lastResponseCode = null;
228
229
    /**
230
     * Body data  for next curl POST operation
231
     *
232
     * @var string
233
     */
234
    protected $postFields = null;
235
236
    /**
237
     * Last operation result data or message(s)
238
     *
239
     * @var array
240
     */
241
    public $lastResult = null;
242
243
    /**
244
     * Number from  @rowCount in response
245
     * @var int
246
     */
247
    public $rowCount = null;
248
249
    /**
250
     * Number from  @globalVersion
251
     * @var int
252
     */
253
    public $globalVersion = null;
254
255
    /**
256
     * @link https://www.flexibee.eu/api/dokumentace/ref/zamykani-odemykani/
257
     * @var string filter query
258
     */
259
    public $filter;
260
261
    /**
262
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
263
     * @var string
264
     */
265
    protected $action;
266
267
    /**
268
     * Pole akcí které podporuje ta která evidence
269
     * @link https://demo.flexibee.eu/c/demo/faktura-vydana/actions.json Např. Akce faktury
270
     * @var array
271
     */
272
    public $actionsAvailable = null;
273
274
    /**
275
     * Parmetry pro URL
276
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Všechny podporované parametry
277
     * @var array
278
     */
279
    public $urlParams = [
280
        'add-global-version' => ['type' => 'boolean', 'description' => 'The response will contain the global version number of the current export'],
281
        'add-row-count' => ['type' => 'boolean', 'description' => 'Adding Total Records to Output (Pagination)'],
282
        'as-gui' => ['type' => 'boolean', 'description' => 'Turns on functions that complement the GUI processing outputs'],
283
        'auth' => ['type' => 'string', 'description' => 'http: Forces login using HTTP authentication, for example, to change the default WUI login method. html: Force HTML form authentication. This can be useful to suppress automatic SSO authentication.'],
284
        'authSessionId' => ['type' => 'string', 'description' => 'Authentification Session ID'],
285
        'code-as-id' => ['type' => 'boolean', 'description' => 'If an object has unique code, it is also exported (except for the <code> element) as <id> code: ... </id>'],
286
        'code-in-response' => ['type' => 'boolean', 'description' => 'The response will contain not only ID and URL for each object, but also code.'],
287
        'delimeter' => ['type' => 'string', 'description' => 'Specifies the input / output file separator in CSV format.',
288
            'example' => ';'],
289
        'detail' => ['type' => 'string', 'description' => 'Definition of the level of detail'], //See: https://www.flexibee.eu/api/dokumentace/ref/detail-levels
290
        'dir' => ['type' => 'string', 'description' => 'Sorting direction.', 'example' => 'desc'],
291
        'dry-run' => ['type' => 'boolean', 'description' => 'Test run (dry-run)'], // See: https://www.flexibee.eu/api/dokumentace/ref/dry-run/
292
        'encoding' => ['type' => 'string', 'description' => 'Specifies the encoding of the input / output file in CSV format.'],
293
        'export-settings' => ['type' => 'boolean', 'description' => 'Export one extra entry with current settings at the beginning'],
294
        'fail-on-warning' => ['type' => 'boolean', 'description' => 'If a warning occurs, do not save a record (Data Validation)'],
295
        'filter' => ['type' => 'string', 'description' => 'filter results by this param'],
296
        'format' => ['type' => 'string', 'description' => 'One of the compiled XSL transforms will be applied to the output XML.'],
297
        'idUcetniObdobi' => ['type' => 'string', 'description' => ''], //See: https://www.flexibee.eu/api/dokumentace/ref/stavy-uctu/
298
        'includes' => ['type' => 'string', 'description' => 'Include related detail level object ',
299
            'example' => 'faktura-vydana/stredisko'],
300
        'inDesktopApp' => ['type' => 'boolean', 'description' => 'Hide menu and navigation in html format'], // Note: Undocumented function (html only)
301
        'limit' => ['type' => 'integer', 'description' => 'number of requested results'],
302
        'mode' => ['type' => 'string', 'description' => 'Support for RubyOnRails',
303
            'example' => 'ruby'],
304
        'no-ext-ids' => ['type' => 'boolean', 'description' => 'The answer will not contain external identifiers (performance optimization)'],
305
        'no-http-errors' => ['type' => 'boolean', 'description' => 'If a 4xx error occurs while processing a request, the server sends 200 OK anyway'],
306
        'no-ids' => ['type' => 'boolean', 'description' => 'The response will not contain any primary identifiers (performance optimization). It only affects the main records.'],
307
        'only-ext-ids' => ['type' => 'boolean', 'description' => 'The primary key will not be exported, the <id> elements will only contain the external ID. Similar no-ids, but also affects subevidencies.'],
308
        'order' => ['type' => 'string', 'description' => 'Sorting records', 'example' => 'nazev@A'],
309
        'relations' => ['type' => 'string', 'description' => 'Adding session data (see detail levels) A session overview can be obtained for each record (/ relations).'],
310
        'report-lang' => ['type' => 'string', 'description' => 'The language in which to print the output when exporting to PDF',
311
            'example' => 'en'],
312
        'report-name' => ['type' => 'string', 'description' => 'The name of the printout when exporting to PDF',
313
            'example' => 'invoice'],
314
        'report-sign' => ['type' => 'string', 'description' => 'Whether the PDF should be exported electronically signed'],
315
        'skupina-stitku' => ['type' => 'string', 'description' => 'Enables grouping of labels when exporting by group (multiple labels)'],
316
        'sort' => ['type' => 'string', 'description' => 'Sorting records for ExtJS'],
317
        'start' => ['type' => 'integer', 'description' => 'Pagination'],
318
        'stitky-as-ids' => ['type' => 'boolean', 'description' => 'Labels will be exported and imported not as a code list but as a list of numeric IDs'],
319
        'use-ext-id' => ['type' => 'boolean', 'description' => 'If the object contains an external ESHOP or MY ID, use it as a bind.'],
320
        'use-internal-id' => ['type' => 'boolean', 'description' => 'In addition to the ref and showAs for objects, it also supplies an internalId attribute that contains the internal record ID'],
321
        'xpath' => ['type' => 'string', 'description' => 'Apply XPATH to result',
322
            'example' => '//winstrom/adresar/email/text()'] // See: https://www.flexibee.eu/api/dokumentace/ref/xpath/
323
    ];
324
325
    /**
326
     * Session ID
327
     * @var string
328
     */
329
    public $authSessionId = null;
330
331
    /**
332
     * Token obtained during login procedure
333
     * @var string 
334
     */
335
    public $refreshToken = null;
336
337
    /**
338
     * Save 404 results to log ?
339
     * @var boolean
340
     */
341
    protected $ignoreNotFound = false;
342
343
    /**
344
     * Array of errors caused by last request
345
     * @var array
346
     */
347
    private $errors = [];
348
349
    /**
350
     * List of Error500 reports sent
351
     * @var array
352
     */
353
    private $reports = [];
354
355
    /**
356
     * Send Error500 Report to
357
     * @var string email address
358
     */
359
    public $reportRecipient = '[email protected]';
360
361
    /**
362
     * Formating string for \DateTime::format() for datetime columns
363
     * @var string
364
     */
365
    static public $DateTimeFormat = 'Y-m-d\TH:i:s.u+P';
366
367
    /**
368
     * Formating string for \DateTime::format() for date columns
369
     * @var string
370
     */
371
    static public $DateFormat = 'Y-m-d';
372
373
    /**
374
     * Last Request response stats
375
     * @var array 
376
     */
377
    protected $responseStats = null;
378
379
    /**
380
     * Chained Objects
381
     * @var array
382
     */
383
    public $chained = [];
384
385
    /**
386
     * We Connect to server by default
387
     * @var boolean
388
     */
389
    public $offline = false;
390
391
    /**
392
     * Override cURL timeout
393
     * @var int seconds
394
     */
395
    public $timeout = null;
396
397
    /**
398
     * Columns Info for serveral evidencies
399
     * @var array 
400
     */
401
    private $columnsInfo = [];
402
403
    /**
404
     * Throw Exception in case of FlexiBee error
405
     * @var boolean 
406
     */
407
    public $throwException = false;
408
409
    /**
410
     * Class for read only interaction with FlexiBee.
411
     *
412
     * @param mixed $init default record id or initial data. See processInit()
413
     * @param array $options Connection settings and other options override
414
     */
415
    public function __construct($init = null, $options = []) {
416
        $this->init = $init;
417
418
        $this->setUp($options);
419
        $this->curlInit();
420
        if (!empty($init)) {
421
            $this->processInit($init);
422
        }
423
    }
424
425
    /**
426
     * Set internal Object name
427
     *
428
     * @param string $objectName
429
     *
430
     * @return string Jméno objektu
431
     */
432
    public function setObjectName($objectName = null) {
433
        return parent::setObjectName(is_null($objectName) ? ( empty($this->getRecordIdent()) ? $this->getObjectName() : $this->getRecordIdent() . '@' . $this->getObjectName() ) : $objectName);
434
    }
435
436
    /**
437
     * SetUp Object to be ready for work
438
     *
439
     * @param array $options Object Options ( user,password,authSessionId
440
     *                                        company,url,evidence,
441
     *                                        prefix,defaultUrlParams,debug,
442
     *                                        detail,offline,filter,ignore404
443
     *                                        timeout,companyUrl,ver,throwException
444
     */
445
    public function setUp($options = []) {
446
        if (array_key_exists('ver', $options)) {
447
            $this->protoVersion = $options['ver'];
448
            $this->prefix = 'v' . round($this->protoVersion) . '/c/';
449
        }
450
        if (array_key_exists('companyUrl', $options)) {
451
            $options = array_merge(self::companyUrlToOptions($options['companyUrl']),
452
                    $options);
453
        }
454
455
        $this->setupProperty($options, 'company', 'FLEXIBEE_COMPANY');
456
        $this->setupProperty($options, 'url', 'FLEXIBEE_URL');
457
        $this->setupProperty($options, 'user', 'FLEXIBEE_LOGIN');
458
        $this->setupProperty($options, 'password', 'FLEXIBEE_PASSWORD');
459
        $this->setupProperty($options, 'authSessionId', 'FLEXIBEE_AUTHSESSID');
460
        $this->setupProperty($options, 'timeout', 'FLEXIBEE_TIMEOUT');
461
        if (!empty($this->authSessionId)) {
462
            $this->defaultHttpHeaders['X-authSessionId'] = $this->authSessionId;
463
        }
464
        if (isset($options['evidence'])) {
465
            $this->setEvidence($options['evidence']);
466
        }
467
        $this->setupProperty($options, 'defaultUrlParams');
468
        if (isset($options['prefix'])) {
469
            $this->setPrefix($options['prefix']);
470
        }
471
        if (array_key_exists('detail', $options)) {
472
            $this->defaultUrlParams['detail'] = $options['detail'];
473
        }
474
        $this->setupProperty($options, 'filter');
475
        if (array_key_exists('offline', $options)) {
476
            $this->offline = (boolean) $options['offline'];
477
        }
478
479
        if (array_key_exists('ignore404', $options)) {
480
            $this->ignore404($options['ignore404']);
481
        }
482
483
        $this->setupProperty($options, 'throwException', 'FLEXIBEE_EXCEPTIONS');
484
        $this->setupProperty($options, 'debug');
485
        $this->updateApiURL();
486
    }
487
488
    /**
489
     * Convert companyUrl provided by CustomButton to options array
490
     * 
491
     * @param string $companyUrl
492
     * 
493
     * @return array Options
494
     */
495
    public static function companyUrlToOptions($companyUrl) {
496
        $urlParts = parse_url($companyUrl);
497
        $scheme = isset($urlParts['scheme']) ? $urlParts['scheme'] . '://' : '';
498
        $host = isset($urlParts['host']) ? $urlParts['host'] : '';
499
        $port = isset($urlParts['port']) ? ':' . $urlParts['port'] : '';
500
        $path = isset($urlParts['path']) ? $urlParts['path'] : '';
501
502
        $options['company'] = basename($path);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$options was never initialized. Although not strictly required by PHP, it is generally a good practice to add $options = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
503
        $options['url'] = $scheme . $host . $port;
504
        return $options;
505
    }
506
507
    /**
508
     * Get Current connection options for use in another object
509
     *
510
     * @return array usable as second constructor parameter
511
     */
512
    public function getConnectionOptions() {
513
        $conOpts = ['url' => $this->url];
514
        if (empty($this->authSessionId)) {
515
            $conOpts ['user'] = $this->user;
516
            $conOpts['password'] = $this->password;
517
        } else {
518
            $conOpts['authSessionId'] = $this->authSessionId;
519
        }
520
        $company = $this->getCompany();
521
        if (!empty($company)) {
522
            $conOpts['company'] = $company;
523
        }
524
        if (!is_null($this->timeout)) {
525
            $conOpts['timeout'] = $this->timeout;
526
        }
527
        return $conOpts;
528
    }
529
530
    /**
531
     * Inicializace CURL
532
     *
533
     * @return boolean Online Status
534
     */
535
    public function curlInit() {
536
        if ($this->offline === false) {
537
            $this->curl = \curl_init(); // create curl resource
538
            curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); // return content as a string from curl_exec
539
            curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); // follow redirects (compatibility for future changes in FlexiBee)
540
            curl_setopt($this->curl, CURLOPT_HTTPAUTH, true);       // HTTP authentication
541
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); // FlexiBee by default uses Self-Signed certificates
542
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
543
            curl_setopt($this->curl, CURLOPT_VERBOSE, ($this->debug === true)); // For debugging
544
            if (empty($this->authSessionId)) {
545
                curl_setopt($this->curl, CURLOPT_USERPWD,
546
                        $this->user . ':' . $this->password); // set username and password
547
            }
548
            if (!is_null($this->timeout)) {
549
                curl_setopt($this->curl, CURLOPT_TIMEOUT, $this->timeout);
550
            }
551
        }
552
        return !$this->offline;
553
    }
554
555
    /**
556
     * Zinicializuje objekt dle daných dat. Možné hodnoty:
557
     *
558
     *  * 234                              - interní číslo záznamu k načtení
559
     *  * code:LOPATA                      - kód záznamu
560
     *  * BAGR                             - kód záznamu k načtení
561
     *  * ['id'=>24,'nazev'=>'hoblík']     - pole hodnot k předvyplnění
562
     *  * 743.json?relations=adresa,vazby  - část url s parametry k načtení
563
     *
564
     * @param mixed $init číslo/"(code:)kód"/(část)URI záznamu k načtení | pole hodnot k předvyplnění
565
     */
566
    public function processInit($init) {
567
        if (is_integer($init)) {
568
            $this->loadFromFlexiBee($init);
569
        } elseif (is_array($init)) {
570
            $this->takeData($init);
571
        } elseif (preg_match('/\.(json|xml|csv)/', $init)) {
572
            $this->takeData($this->getFlexiData((($init[0] != '/') ? $this->evidenceUrlWithSuffix($init) : $init)));
573
        } else {
574
            $this->loadFromFlexiBee($init);
575
        }
576
    }
577
578
    /**
579
     * Set Data Field value
580
     *
581
     * @param string $columnName field name
582
     * @param mixed  $value      field data value
583
     *
584
     * @return bool Success
585
     */
586
    public function setDataValue($columnName, $value) {
587
        switch ($columnName) {
588
            case 'kod':
589
                $value = self::uncode($value); //Alwyas uncode "kod" column
590
591
            default:
592
                if (is_object($value)) {
593
                    switch (get_class($value)) {
594
                        case 'DateTime':
595
                            $columnInfo = $this->getColumnInfo($columnName);
596
                            switch ($columnInfo['type']) {
597
                                case 'date':
598
                                    $value = self::dateToFlexiDate($value);
599
                                    break;
600
                                case 'datetime':
601
                                    $value = self::dateToFlexiDateTime($value);
602
                                    break;
603
                            }
604
                            break;
605
                    }
606
                }
607
                $result = parent::setDataValue($columnName, $value);
608
                break;
609
        }
610
        return $result;
611
    }
612
613
    /**
614
     * PHP Date object to FlexiBee date format
615
     * 
616
     * @param \DateTime $date
617
     */
618
    public static function dateToFlexiDate($date) {
619
        return $date->format(self::$DateFormat);
620
    }
621
622
    /**
623
     * PHP Date object to FlexiBee date format
624
     * 
625
     * @param \DateTime $dateTime
626
     */
627
    public static function dateToFlexiDateTime($dateTime) {
628
        return $dateTime->format(self::$DateTimeFormat);
629
    }
630
631
    /**
632
     * Set URL prefix
633
     *
634
     * @param string $prefix
635
     */
636
    public function setPrefix($prefix) {
637
        switch ($prefix) {
638
            case 'a': //Access
639
            case 'c': //Company
640
            case 'u': //User
641
            case 'g': //License Groups
642
            case 'admin':
643
            case 'status':
644
            case 'login-logout':
645
                $this->prefix = '/' . $prefix . '/';
646
                break;
647
            case null:
648
            case '':
649
            case '/':
650
                $this->prefix = '';
651
                break;
652
            default:
653
                throw new \Exception(sprintf('Unknown prefix %s', $prefix));
654
        }
655
    }
656
657
    /**
658
     * Set communication format.
659
     * One of html|xml|json|csv|dbf|xls|isdoc|isdocx|edi|pdf|pdf|vcf|ical
660
     *
661
     * @param string $format
662
     * 
663
     * @return boolean format is availble
664
     */
665
    public function setFormat($format) {
666
        $result = true;
667
        if (($this->debug === true) && !empty($this->evidence) && isset(Formats::$$this->evidence)) {
668
            if (array_key_exists($format, array_flip(Formats::$$this->evidence)) === false) {
669
                $result = false;
670
            }
671
        }
672
        if ($result === true) {
673
            $this->format = $format;
674
            $this->updateApiURL();
675
        }
676
        return $result;
677
    }
678
679
    /**
680
     * Nastaví Evidenci pro Komunikaci.
681
     * Set evidence for communication
682
     *
683
     * @param string $evidence evidence pathName to use
684
     * 
685
     * @return boolean evidence switching status
686
     */
687
    public function setEvidence($evidence) {
688
        switch ($this->prefix) {
689
            case '/c/':
690
                if ($this->debug === true) {
691
                    if (array_key_exists($evidence, EvidenceList::$name)) {
692
                        $this->evidence = $evidence;
693
                        $result = true;
694
                    } else {
695
                        throw new \Exception(sprintf('Try to set unsupported evidence %s',
696
                                        $evidence));
697
                    }
698
                } else {
699
                    $this->evidence = $evidence;
700
                    $result = true;
701
                }
702
                break;
703
            default:
704
                $this->evidence = $evidence;
705
                $result = true;
706
                break;
707
        }
708
        $this->updateApiURL();
709
        $this->evidenceInfo = $this->getEvidenceInfo();
710
        return $result;
711
    }
712
713
    /**
714
     * Vrací právě používanou evidenci pro komunikaci
715
     * Obtain current used evidence
716
     *
717
     * @return string
718
     */
719
    public function getEvidence() {
720
        return $this->evidence;
721
    }
722
723
    /**
724
     * Set used company.
725
     * Nastaví Firmu.
726
     *
727
     * @param string $company
728
     */
729
    public function setCompany($company) {
730
        $this->company = $company;
731
    }
732
733
    /**
734
     * Obtain company now used
735
     * Vrací právě používanou firmu
736
     *
737
     * @return string
738
     */
739
    public function getCompany() {
740
        return $this->company;
741
    }
742
743
    /**
744
     * Vrací název evidence použité v odpovědích z FlexiBee
745
     *
746
     * @return string
747
     */
748
    public function getResponseEvidence() {
749
        switch ($this->evidence) {
750
            case 'c':
751
                $evidence = 'company';
752
                break;
753
            case 'evidence-list':
754
                $evidence = 'evidence';
755
                break;
756
            default:
757
                $evidence = $this->getEvidence();
758
                break;
759
        }
760
        return $evidence;
761
    }
762
763
    /**
764
     * Převede rekurzivně Objekt na pole.
765
     *
766
     * @param object|array $object
767
     *
768
     * @return array
769
     */
770
    public static function object2array($object) {
771
        $result = null;
772
        if (is_object($object)) {
773
            $objectData = get_object_vars($object);
774
            if (is_array($objectData) && count($objectData)) {
775
                $result = array_map('self::object2array', $objectData);
776
            }
777
        } else {
778
            if (is_array($object)) {
779
                foreach ($object as $item => $value) {
780
                    $result[$item] = self::object2array($value);
781
                }
782
            } else {
783
                $result = $object;
784
            }
785
        }
786
787
        return $result;
788
    }
789
790
    /**
791
     * Převede rekurzivně v poli všechny objekty na jejich identifikátory.
792
     *
793
     * @param object|array $object
794
     *
795
     * @return array
796
     */
797
    public static function objectToID($object) {
798
        $resultID = null;
799
        if (is_object($object) && method_exists($object, '__toString')
800
        ) {
801
            $resultID = $object->__toString();
802
        } else {
803
            if (is_array($object)) {
804
                foreach ($object as $item => $value) {
805
                    $resultID[$item] = self::objectToID($value);
806
                }
807
            } else { //String
808
                $resultID = $object;
809
            }
810
        }
811
812
        return $resultID;
813
    }
814
815
    /**
816
     * Return basic URL for used Evidence
817
     *
818
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
819
     *
820
     * @return string Evidence URL
821
     */
822
    public function getEvidenceURL() {
823
        $evidenceUrl = $this->url . $this->prefix . $this->company;
824
        $evidence = $this->getEvidence();
825
        if (!empty($evidence)) {
826
            $evidenceUrl .= '/' . $evidence;
827
        }
828
        return $evidenceUrl;
829
    }
830
831
    /**
832
     * Add suffix to Evidence URL
833
     *
834
     * @param string $urlSuffix
835
     *
836
     * @return string
837
     */
838
    public function evidenceUrlWithSuffix($urlSuffix) {
839
        $evidenceUrl = $this->getEvidenceUrl();
840
        if (!empty($urlSuffix)) {
841
            if (($urlSuffix[0] != '/') && ($urlSuffix[0] != ';') && ($urlSuffix[0] != '?')) {
842
                $evidenceUrl .= '/';
843
            }
844
            $evidenceUrl .= $urlSuffix;
845
        }
846
        return $evidenceUrl;
847
    }
848
849
    /**
850
     * Update $this->apiURL
851
     */
852
    public function updateApiURL() {
853
        $this->apiURL = $this->getEvidenceURL();
854
        $rowIdentifier = $this->getRecordIdent();
855
        if (empty($rowIdentifier)) {
856
            $rowIdentifier = $this->getRecordCode();
857
            if (empty($rowIdentifier)) {
858
                $rowIdentifier = $this->getExternalID();
859
            }
860
        }
861
        if (!empty($rowIdentifier)) {
862
            $this->apiURL .= '/' . self::urlEncode($rowIdentifier);
863
        }
864
        $this->apiURL .= '.' . $this->format;
865
    }
866
867
    /*
868
     * Add Default Url params to given url if not overrided
869
     *
870
     * @param string $urlRaw
871
     *
872
     * @return string url with default params added
873
     */
874
875
    public function addDefaultUrlParams($urlRaw) {
876
        return \Ease\Functions::addUrlParams($urlRaw, $this->defaultUrlParams,
877
                        false);
878
    }
879
880
    /**
881
     * Funkce, která provede I/O operaci a vyhodnotí výsledek.
882
     *
883
     * @param string $urlSuffix část URL za identifikátorem firmy.
884
     * @param string $method    HTTP/REST metoda
885
     * @param string $format    Requested format
886
     * 
887
     * @return array|boolean Výsledek operace
888
     */
889
    public function performRequest($urlSuffix = null, $method = 'GET',
890
            $format = null) {
891
        $this->rowCount = null;
892
        $this->responseStats = [];
893
        $this->errors = [];
894
895
        if (preg_match('/^http/', $urlSuffix)) {
896
            $url = $urlSuffix;
897
        } elseif (strlen($urlSuffix) && ($urlSuffix[0] == '/')) {
898
            $url = $this->url . $urlSuffix;
899
        } else {
900
            $url = $this->evidenceUrlWithSuffix($urlSuffix);
901
        }
902
903
        $responseCode = $this->doCurlRequest($this->addDefaultUrlParams($url),
904
                $method, $format);
905
906
        return $this->parseResponse($this->rawResponseToArray($this->lastCurlResponse,
907
                                $this->responseFormat), $responseCode);
908
    }
909
910
    /**
911
     * Parse Raw FlexiBee response in several formats
912
     *
913
     * @param string $responseRaw raw response body
914
     * @param string $format      Raw Response format json|xml|etc
915
     *
916
     * @return array
917
     */
918
    public function rawResponseToArray($responseRaw, $format) {
919
        $responseDecoded = [];
920
        if (!empty(trim($responseRaw))) {
921
            switch ($format) {
922
                case 'json':
923
                    $responseDecoded = $this->rawJsonToArray($responseRaw);
924
                    break;
925
                case 'xml':
926
                    $responseDecoded = $this->rawXmlToArray($this->lastCurlResponse);
927
                    break;
928
                case 'txt':
929
                default:
930
                    $responseDecoded = [$this->lastCurlResponse];
931
                    break;
932
            }
933
        }
934
        return $responseDecoded;
935
    }
936
937
    /**
938
     * Convert FlexiBee Response JSON to Array
939
     *
940
     * @param string $rawJson
941
     *
942
     * @return array
943
     */
944
    public function rawJsonToArray($rawJson) {
945
        $responseDecoded = json_decode($rawJson, true, 10);
946
        $decodeError = json_last_error_msg();
947
        if ($decodeError == 'No error') {
948
            if (array_key_exists($this->nameSpace, $responseDecoded)) {
949
                $responseDecoded = $responseDecoded[$this->nameSpace];
950
            }
951
        } else {
952
            if ($this->debug) {
953
                $this->addStatusMessage('JSON Decoder: ' . $decodeError, 'error');
954
                $this->addStatusMessage($rawJson, 'debug');
955
            }
956
        }
957
        return $responseDecoded;
958
    }
959
960
    /**
961
     * Convert FlexiBee Response XML to Array
962
     *
963
     * @param string $rawXML
964
     *
965
     * @return array
966
     */
967
    public function rawXmlToArray($rawXML) {
968
        return self::xml2array($rawXML);
969
    }
970
971
    /**
972
     * Parse Response array
973
     *
974
     * @param array $responseDecoded
975
     * @param int $responseCode Request Response Code
976
     *
977
     * @return array main data part of response
978
     */
979
    public function parseResponse($responseDecoded, $responseCode) {
980
        $mainResult = null;
981
        switch ($responseCode) {
982
            case 201: //We do not care about Success Write here
983
                break;
984
            case 200: //Success Read
985
986
                if (is_array($responseDecoded)) {
987
                    if (isset($responseDecoded['@rowCount'])) {
988
                        $this->rowCount = (int) $responseDecoded['@rowCount'];
989
                    }
990
                    if (isset($responseDecoded['@globalVersion'])) {
991
                        $this->globalVersion = (int) $responseDecoded['@globalVersion'];
992
                    }
993
994
                    $mainResult = $this->unifyResponseFormat($responseDecoded);
995
996
                    if (array_key_exists('stats', $responseDecoded)) {
997
                        $this->responseStats = $responseDecoded['stats'];
998
                    } elseif (!empty($mainResult)) {
999
                        if (array_key_exists('success', $mainResult) && ($mainResult['success'] == 'false')) {
1000
                            $this->responseStats = ['read' => 0];
1001
                        } elseif (array_key_exists('properties', $mainResult)) {
1002
                            $this->responseStats = ['read' => 1];
1003
                        } else {
1004
                            $responseEvidence = $this->getResponseEvidence();
1005
                            if (!empty($this->rowCount)) {
1006
                                $this->responseStats = ['read' => $this->rowCount];
1007
                            } elseif (array_key_exists($responseEvidence,
1008
                                            $mainResult)) {
1009
                                $this->responseStats = ['read' => count($mainResult[$responseEvidence])];
1010
                            } else {
1011
                                $this->responseStats = ['read' => count($mainResult)];
1012
                            }
1013
                        }
1014
                    }
1015
                } else {
1016
                    $mainResult = $responseDecoded;
1017
                }
1018
1019
                $this->lastResult = $mainResult;
1020
                break;
1021
1022
            case 500: // Internal Server Error
1023
                if ($this->debug === true) {
1024
                    $this->error500Reporter($responseDecoded);
1025
                }
1026
            case 404: // Page not found
1027
                if ($this->ignoreNotFound === true) {
1028
                    break;
1029
                }
1030
            case 400: //Bad Request parameters
1031
            default: //Something goes wrong
1032
                if (is_array($responseDecoded)) {
1033
                    $this->parseError($responseDecoded);
1034
                }
1035
1036
                if ($this->throwException === true) {
1037
                    throw new \Ease\Exception(json_encode($this->getErrors()), $this->lastResponseCode);
1038
                } else {
1039
                    $this->addStatusMessage($this->lastResponseCode . ': ' . $this->curlInfo['url'],
1040
                            'warning');
1041
                    $this->logResult($responseDecoded, $this->curlInfo['url']);
1042
                }
1043
                break;
1044
        }
1045
        return $mainResult;
1046
    }
1047
1048
    /**
1049
     * Parse error message response
1050
     *
1051
     * @param array $responseDecoded
1052
     * 
1053
     * @return int number of errors processed
1054
     */
1055
    public function parseError(array $responseDecoded) {
1056
        if (array_key_exists('results', $responseDecoded)) {
1057
            $this->errors = $responseDecoded['results'][0]['errors'];
1058
            foreach ($this->errors as $errorInfo) {
1059
                $this->addStatusMessage($errorInfo['message'], 'error');
1060
                if (array_key_exists('for', $errorInfo)) {
1061
                    unset($errorInfo['message']);
1062
                    $this->addStatusMessage(json_encode($errorInfo), 'debug');
1063
                }
1064
            }
1065
        } else {
1066
            if (array_key_exists('message', $responseDecoded)) {
1067
                $this->errors = [['message' => $responseDecoded['message']]];
1068
            }
1069
        }
1070
        return count($this->errors);
1071
    }
1072
1073
    /**
1074
     * Vykonej HTTP požadavek
1075
     *
1076
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
1077
     * @param string $url    URL požadavku
1078
     * @param string $method HTTP Method GET|POST|PUT|OPTIONS|DELETE
1079
     * @param string $format požadovaný formát komunikace
1080
     * 
1081
     * @return int HTTP Response CODE
1082
     */
1083
    public function doCurlRequest($url, $method, $format = null) {
1084
        if (is_null($format)) {
1085
            $format = $this->format;
1086
        }
1087
        curl_setopt($this->curl, CURLOPT_URL, $url);
1088
// Nastavení samotné operace
1089
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, strtoupper($method));
1090
//Vždy nastavíme byť i prázná postdata jako ochranu před chybou 411
1091
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->postFields);
1092
1093
        $httpHeaders = $this->defaultHttpHeaders;
1094
1095
        $formats = Formats::bySuffix();
1096
1097
        if (!isset($httpHeaders['Accept'])) {
1098
            $httpHeaders['Accept'] = $formats[$format]['content-type'];
1099
        }
1100
        if (!isset($httpHeaders['Content-Type'])) {
1101
            $httpHeaders['Content-Type'] = $formats[$format]['content-type'];
1102
        }
1103
        $httpHeadersFinal = [];
1104
        foreach ($httpHeaders as $key => $value) {
1105
            if (($key == 'User-Agent') && ($value == 'FlexiPeeHP')) {
1106
                $value .= ' v' . self::$libVersion;
1107
            }
1108
            $httpHeadersFinal[] = $key . ': ' . $value;
1109
        }
1110
1111
        curl_setopt($this->curl, CURLOPT_HTTPHEADER, $httpHeadersFinal);
1112
1113
// Proveď samotnou operaci
1114
        $this->lastCurlResponse = curl_exec($this->curl);
1115
        $this->curlInfo = curl_getinfo($this->curl);
1116
        $this->curlInfo['when'] = microtime();
1117
        $this->curlInfo['request_headers'] = $httpHeadersFinal;
1118
        $this->responseFormat = $this->contentTypeToResponseFormat($this->curlInfo['content_type'],
1119
                $url);
1120
        $this->lastResponseCode = $this->curlInfo['http_code'];
1121
        $this->lastCurlError = curl_error($this->curl);
1122
        if (strlen($this->lastCurlError)) {
1123
            $this->addStatusMessage(sprintf('Curl Error (HTTP %d): %s',
1124
                            $this->lastResponseCode, $this->lastCurlError), 'error');
1125
        }
1126
1127
        if ($this->debug === true) {
1128
            $this->saveDebugFiles();
1129
        }
1130
1131
        return $this->lastResponseCode;
1132
    }
1133
1134
    /**
1135
     * Obtain json for application/json
1136
     * 
1137
     * @param string $contentType
1138
     * @param string $url
1139
     * 
1140
     * @return string response format
1141
     */
1142
    public function contentTypeToResponseFormat($contentType, $url = null) {
1143
        if (!empty($url)) {
1144
            $url = parse_url($url, PHP_URL_PATH);
1145
        }
1146
1147
        $contentTypeClean = strstr($contentType, ';') ? substr($contentType, 0,
1148
                        strpos($contentType, ';')) : $contentType;
1149
1150
        switch ($url) {
1151
            case '/login-logout/login';
1152
                $responseFormat = 'json';
1153
                break;
1154
            default :
1155
                switch ($contentTypeClean) {
1156
                    case 'text/javascript':
1157
                        $responseFormat = 'js';
1158
                        break;
1159
1160
                    default:
1161
                        $responseFormat = Formats::contentTypeToSuffix($contentTypeClean);
1162
                        break;
1163
                }
1164
                break;
1165
        }
1166
1167
        return $responseFormat;
1168
    }
1169
1170
    /**
1171
     * Nastaví druh prováděné akce.
1172
     *
1173
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
1174
     * @param string $action
1175
     * 
1176
     * @return boolean
1177
     */
1178
    public function setAction($action) {
1179
        $result = false;
1180
        $actionsAvailable = $this->getActionsInfo();
1181
        if (is_array($actionsAvailable) && array_key_exists($action,
1182
                        $actionsAvailable)) {
1183
            $this->action = $action;
1184
            $result = true;
1185
        }
1186
        return $result;
1187
    }
1188
1189
    /**
1190
     * Convert XML to array.
1191
     *
1192
     * @param string $xml
1193
     *
1194
     * @return array
1195
     */
1196
    public static function xml2array($xml) {
1197
        $arr = [];
1198
        if (!empty($xml)) {
1199
            if (is_string($xml)) {
1200
                $xml = simplexml_load_string($xml);
1201
            }
1202
            foreach ($xml->attributes() as $a) {
1203
                $arr['@' . $a->getName()] = strval($a);
1204
            }
1205
            foreach ($xml->children() as $r) {
1206
                if (count($r->children()) == 0) {
1207
                    $arr[$r->getName()] = strval($r);
1208
                } else {
1209
                    $arr[$r->getName()][] = self::xml2array($r);
1210
                }
1211
            }
1212
        }
1213
        return $arr;
1214
    }
1215
1216
    /**
1217
     * Odpojení od FlexiBee.
1218
     */
1219
    public function disconnect() {
1220
        if (is_resource($this->curl)) {
1221
            curl_close($this->curl);
1222
        }
1223
        $this->curl = null;
1224
    }
1225
1226
    /**
1227
     * Disconnect CURL befere pass away
1228
     */
1229
    public function __destruct() {
1230
        $this->disconnect();
1231
    }
1232
1233
    /**
1234
     * Načte řádek dat z FlexiBee.
1235
     *
1236
     * @param int $recordID id požadovaného záznamu
1237
     *
1238
     * @return array
1239
     */
1240
    public function getFlexiRow($recordID) {
1241
        $record = null;
1242
        $response = $this->performRequest($this->evidence . '/' . $recordID . '.json');
1243
        if (isset($response[$this->evidence])) {
1244
            $record = $response[$this->evidence][0];
1245
        }
1246
1247
        return $record;
1248
    }
1249
1250
    /**
1251
     * Oddělí z pole podmínek ty jenž patří za ? v URL požadavku
1252
     *
1253
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
1254
     * @param array $conditions pole podmínek   - rendrují se do ()
1255
     * @param array $urlParams  pole parametrů  - rendrují za ?
1256
     */
1257
    public function extractUrlParams(&$conditions, &$urlParams) {
1258
        foreach (array_keys($this->urlParams) as $urlParam) {
1259
            if (isset($conditions[$urlParam])) {
1260
                \Ease\Functions::divDataArray($conditions, $urlParams, $urlParam);
1261
            }
1262
        }
1263
    }
1264
1265
    /**
1266
     * convert unicode to entities for use with FlexiBee queries
1267
     *
1268
     * @param string $urlRaw
1269
     * 
1270
     * @return string
1271
     */
1272
    public static function urlEncode($urlRaw) {
1273
        return str_replace(['%27', '%3A'], ["'", ':'], rawurlencode($urlRaw));
1274
    }
1275
1276
    /**
1277
     * Načte data z FlexiBee.
1278
     *
1279
     * @param string $suffix     dotaz
1280
     * @param string|array       $conditions Custom filters or modifiers
1281
     *
1282
     * @return array Data obtained
1283
     */
1284
    public function getFlexiData($suffix = null, $conditions = null) {
1285
        $finalUrl = '';
1286
        $evidenceToRestore = null;
1287
        $urlParams = $this->defaultUrlParams;
1288
1289
        if (!empty($conditions)) {
1290
            if (is_array($conditions)) {
1291
                $this->extractUrlParams($conditions, $urlParams);
1292
                if (array_key_exists('evidence', $conditions) && is_null($this->getColumnInfo('evidence'))) {
1293
                    $evidenceToRestore = $this->getEvidence();
1294
                    $this->setEvidence($conditions['evidence']);
1295
                    unset($conditions['evidence']);
1296
                }
1297
                $conditions = $this->flexiUrl($conditions);
1298
            }
1299
1300
            if (strlen($conditions) && ($conditions[0] != '/')) {
1301
                $conditions = '(' . self::urlEncode($conditions) . ')';
1302
            }
1303
        }
1304
1305
        if (strlen($suffix) && ($suffix != '$sum')) {
1306
            if (preg_match('/^http/', $suffix) || ($suffix[0] == '/') || is_numeric($suffix)) {
1307
                $finalUrl = $suffix;
1308
            } else {
1309
                if (preg_match('/^(code|ext):(.*)/', $suffix)) {
1310
                    $finalUrl = self::urlizeId($suffix);
1311
                } else {
1312
                    $finalUrl = $suffix;
1313
                }
1314
            }
1315
        }
1316
1317
        $finalUrl .= $conditions;
1318
1319
        if ($suffix == '$sum') {
1320
            $finalUrl .= '/$sum';
1321
        }
1322
1323
        if (!empty($urlParams)) {
1324
            if (strstr($finalUrl, '?')) {
1325
                $finalUrl .= '&';
1326
            } else {
1327
                $finalUrl .= '?';
1328
            }
1329
            $finalUrl .= http_build_query(array_map(function($a) {
1330
                        return is_bool($a) ? ($a ? 'true' : 'false' ) : $a;
1331
                    }, $urlParams), null, '&', PHP_QUERY_RFC3986);
1332
        }
1333
1334
        $transactions = $this->performRequest($finalUrl, 'GET');
1335
        $responseEvidence = $this->getResponseEvidence();
1336
        if (is_array($transactions) && array_key_exists($responseEvidence,
1337
                        $transactions)) {
1338
            $result = $transactions[$responseEvidence];
1339
            if ((count($result) == 1) && empty(current($result))) {
1340
                $result = []; // Response is empty Array
1341
            }
1342
        } else {
1343
            $result = $transactions;
1344
        }
1345
        if (!is_null($evidenceToRestore)) {
1346
            $this->setEvidence($evidenceToRestore);
1347
        }
1348
        return $result;
1349
    }
1350
1351
    /**
1352
     * Načte záznam z FlexiBee a uloží v sobě jeho data
1353
     * Read FlexiBee record and store it inside od object
1354
     *
1355
     * @param int|string $id ID or conditions
1356
     *
1357
     * @return int počet načtených položek
1358
     */
1359
    public function loadFromFlexiBee($id = null) {
1360
        $data = [];
1361
        if (is_null($id)) {
1362
            $id = $this->getMyKey();
1363
        }
1364
        $flexidata = $this->getFlexiData($this->getEvidenceUrl() . '/' . self::urlizeId($id));
1365
        if ($this->lastResponseCode == 200) {
1366
            $this->apiURL = $this->curlInfo['url'];
1367
            if (is_array($flexidata) && (count($flexidata) == 1) && is_array(current($flexidata))) {
1368
                $data = current($flexidata);
1369
            }
1370
        }
1371
        return $this->takeData($data);
1372
    }
1373
1374
    /**
1375
     * Reload current record from FlexiBee
1376
     * 
1377
     * @return boolean 
1378
     */
1379
    public function reload() {
1380
        $id = $this->getRecordIdent();
1381
        $this->dataReset();
1382
        $this->loadFromFlexiBee($id);
1383
        return $this->lastResponseCode == 200;
1384
    }
1385
1386
    /**
1387
     * Set Filter code for requests
1388
     *
1389
     * @link https://www.flexibee.eu/api/dokumentace/ref/zamykani-odemykani/
1390
     *
1391
     * @param array|string $filter filter formula or ['key'=>'value']
1392
     *
1393
     * @return string Filter code
1394
     */
1395
    public function setFilter($filter) {
1396
        return $this->filter = is_array($filter) ? self::flexiUrl($filter) : $filter;
1397
    }
1398
1399
    /**
1400
     * Převede data do Json formátu pro FlexiBee.
1401
     * Convert data to FlexiBee like Json format
1402
     *
1403
     * @url https://www.flexibee.eu/api/dokumentace/ref/actions/
1404
     * @url https://www.flexibee.eu/api/dokumentace/ref/zamykani-odemykani/
1405
     *
1406
     * @param array $data    object data
1407
     * @param int   $options json_encode options like JSON_PRETTY_PRINT etc
1408
     *
1409
     * @return string
1410
     */
1411
    public function getJsonizedData($data = null, $options = 0) {
1412
        if (is_null($data)) {
1413
            $data = $this->getData();
1414
        }
1415
1416
        $dataToJsonize = array_merge(['@version' => $this->protoVersion],
1417
                $this->getDataForJSON($data));
1418
        $jsonRaw = json_encode([$this->nameSpace => $dataToJsonize],
1419
                $options);
1420
1421
        return $jsonRaw;
1422
    }
1423
1424
    /**
1425
     * Get Data Fragment specific for current object
1426
     *
1427
     * @param array $data
1428
     *
1429
     * @return array
1430
     */
1431
    public function getDataForJSON($data = null) {
1432
        if (is_null($data)) {
1433
            $data = $this->getData();
1434
        }
1435
1436
        $dataForJson = [$this->getEvidence() => $this->objectToID($data)];
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type null; however, FlexiPeeHP\FlexiBeeRO::objectToID() does only seem to accept object|array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
1437
1438
        if (!is_null($this->action)) {
1439
            $dataForJson[$this->evidence . '@action'] = $this->action;
1440
            $this->action = null;
1441
        }
1442
1443
        if (!is_null($this->filter)) {
1444
            $dataForJson[$this->evidence . '@filter'] = $this->filter;
1445
        }
1446
1447
1448
        foreach ($this->chained as $chained) {
1449
            $chainedData = $chained->getDataForJSON();
1450
            foreach ($chainedData as $chainedItemEvidence => $chainedItemData) {
1451
                if (array_key_exists($chainedItemEvidence, $dataForJson)) {
1452
                    if (is_string(key($dataForJson[$chainedItemEvidence]))) {
1453
                        $dataBackup = $dataForJson[$chainedItemEvidence];
1454
                        $dataForJson[$chainedItemEvidence] = [];
1455
                        $dataForJson[$chainedItemEvidence][] = $dataBackup;
1456
                    }
1457
                    if (array_key_exists(0, $chainedItemData)) {
1458
                        foreach ($chainedItemData as $chainedItem) {
1459
                            $dataForJson[$chainedItemEvidence][] = $chainedItem;
1460
                        }
1461
                    } else {
1462
                        $dataForJson[$chainedItemEvidence][] = $chainedItemData;
1463
                    }
1464
                } else {
1465
                    $dataForJson[$chainedItemEvidence] = $chainedItemData;
1466
                }
1467
            }
1468
        }
1469
1470
1471
        return $dataForJson;
1472
    }
1473
1474
    /**
1475
     * Join another FlexiPeeHP Object
1476
     *
1477
     * @param FlexiBeeRO $object
1478
     *
1479
     * @return boolean adding to stack success
1480
     */
1481
    public function join(&$object) {
1482
        $result = true;
1483
        if (method_exists($object, 'getDataForJSON')) {
1484
            $this->chained[] = $object;
1485
        } else {
1486
            throw new \Ease\Exception('$object->getDataForJSON() does not exist');
1487
        }
1488
1489
        return $result;
1490
    }
1491
1492
    /**
1493
     * Prepare record ID to use in URL
1494
     * 
1495
     * @param mixed $id
1496
     * 
1497
     * @return string id ready for use in URL
1498
     */
1499
    public static function urlizeId($id) {
1500
        if (is_array($id)) {
1501
            $id = rawurlencode('(' . self::flexiUrl($id) . ')');
1502
        } else if (preg_match('/^ext:/', $id)) {
1503
            $id = self::urlEncode($id);
1504
        } else if (preg_match('/^code:/', $id)) {
1505
            $id = self::code(self::urlEncode(self::uncode($id)));
1506
        }
1507
        return $id;
1508
    }
1509
1510
    /**
1511
     * Test if given record ID exists in FlexiBee.
1512
     *
1513
     * @param mixed $identifer presence state
1514
     *
1515
     * @return boolean
1516
     */
1517
    public function idExists($identifer = null) {
1518
        if (is_null($identifer)) {
1519
            $identifer = $this->getMyKey();
1520
        }
1521
        $ignorestate = $this->ignore404();
1522
        $this->ignore404(true);
1523
        $cands = $this->getFlexiData(null,
1524
                [
1525
                    'detail' => 'custom:' . $this->getKeyColumn(),
1526
                    $this->getKeyColumn() => $identifer
1527
        ]);
1528
        $this->ignore404($ignorestate);
1529
        return ($this->lastResponseCode == 200) && !empty($cands);
1530
    }
1531
1532
    /**
1533
     * Test if given record exists in FlexiBee.
1534
     *
1535
     * @param array|string|int $data ext:id:23|code:ITEM|['id'=>23]|23
1536
     * 
1537
     * @return boolean Record presence status
1538
     */
1539
    public function recordExists($data = []) {
1540
1541
        if (empty($data)) {
1542
            $data = $this->getData();
1543
        }
1544
        $ignorestate = $this->ignore404();
1545
        $this->ignore404(true);
1546
        $keyColumn = $this->getKeyColumn();
1547
        $res = $this->getColumnsFromFlexibee([$keyColumn],
1548
                is_array($data) ? $data : [$keyColumn => $data]);
1549
1550
        if (empty($res) || (isset($res['success']) && ($res['success'] == 'false')) || ((isset($res) && is_array($res)) && !isset($res[0]) )) {
1551
            $found = false;
1552
        } else {
1553
            $found = true;
1554
        }
1555
        $this->ignore404($ignorestate);
1556
        return $found;
1557
    }
1558
1559
    /**
1560
     * Subitems - ex. items of invoice
1561
     * 
1562
     * @return array of document items or null
1563
     */
1564
    public function getSubItems() {
1565
        return array_key_exists('polozkyFaktury', $this->getData()) ? $this->getDataValue('polozkyFaktury') : (array_key_exists('polozkyDokladu', $this->getData()) ? $this->getDataValue('polozkyDokladu') : null);
1566
    }
1567
1568
    /**
1569
     * Vrací z FlexiBee sloupečky podle podmínek.
1570
     *
1571
     * @param array|int|string $conditions pole podmínek nebo ID záznamu
1572
     * @param string           $indexBy    klice vysledku naplnit hodnotou ze
1573
     *                                     sloupečku
1574
     * @return array
1575
     */
1576
    public function getAllFromFlexibee($conditions = null, $indexBy = null) {
1577
        if (is_int($conditions)) {
1578
            $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...
1579
        }
1580
1581
        $flexiData = $this->getFlexiData('', $conditions);
1582
1583
        if (!is_null($indexBy)) {
1584
            $flexiData = \Ease\Functions::reindexArrayBy($flexiData);
1585
        }
1586
1587
        return $flexiData;
1588
    }
1589
1590
    /**
1591
     * Vrací z FlexiBee sloupečky podle podmínek.
1592
     *
1593
     * @param string|string[] $columnsList seznam položek nebo úrověň detailu: id|summary|full
1594
     * @param array           $conditions  pole podmínek nebo ID záznamu
1595
     * @param string          $indexBy     Sloupeček podle kterého indexovat záznamy
1596
     *
1597
     * @return array
1598
     */
1599
    public function getColumnsFromFlexibee($columnsList, $conditions = [],
1600
            $indexBy = null) {
1601
        $detail = 'full';
1602
        switch (gettype($columnsList)) {
1603
            case 'integer': //Record ID
1604
                $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...
1605
            case 'array': //Few Conditions
1606
                if (!is_null($indexBy) && !array_key_exists($indexBy,
1607
                                $columnsList)) {
1608
                    $columnsList[] = $indexBy;
1609
                }
1610
                $columns = implode(',', array_unique($columnsList));
1611
                $detail = 'custom:' . $columns;
1612
            default:
1613
                switch ($columnsList) {
1614
                    case 'id':
1615
                        $detail = 'id';
1616
                        break;
1617
                    case 'summary':
1618
                        $detail = 'summary';
1619
                        break;
1620
                    default:
1621
                        break;
1622
                }
1623
                break;
1624
        }
1625
1626
        $conditions['detail'] = $detail;
1627
1628
        $flexiData = $this->getFlexiData(null, $conditions);
1629
1630
        if (is_string($indexBy) && is_array($flexiData) && array_key_exists(0,
1631
                        $flexiData) && array_key_exists($indexBy, $flexiData[0])) {
1632
            $flexiData = \Ease\Functions::reindexArrayBy($flexiData, $indexBy);
1633
        }
1634
1635
        return $flexiData;
1636
    }
1637
1638
    /**
1639
     * Vrací kód záznamu.
1640
     * Obtain record CODE
1641
     *
1642
     * @param mixed $data
1643
     *
1644
     * @return string
1645
     */
1646
    public function getKod($data = null, $unique = true) {
1647
        $kod = null;
1648
1649
        if (is_null($data)) {
1650
            $data = $this->getData();
1651
        }
1652
1653
        if (is_string($data)) {
1654
            $data = [$this->nameColumn => $data];
1655
        }
1656
1657
        if (isset($data['kod'])) {
1658
            $kod = $data['kod'];
1659
        } else {
1660
            if (isset($data[$this->nameColumn])) {
1661
                $kod = preg_replace('/[^a-zA-Z0-9]/', '',
1662
                        \Ease\Functions::rip($data[$this->nameColumn]));
1663
            } else {
1664
                if (isset($data[$this->keyColumn])) {
1665
                    $kod = \Ease\Functions::rip($data[$this->keyColumn]);
1666
                }
1667
            }
1668
            $kod = substr($kod, 0, 20);
1669
        }
1670
1671
        if (!strlen($kod)) {
1672
            $kod = 'NOTSET';
1673
        }
1674
1675
        if (strlen($kod) > 18) {
1676
            $kodfinal = strtoupper(substr($kod, 0, 18));
1677
        } else {
1678
            $kodfinal = strtoupper($kod);
1679
        }
1680
1681
        if ($unique) {
1682
            $counter = 0;
1683
            if (!empty($this->codes) && count($this->codes)) {
1684
                foreach ($this->codes as $codesearch => $keystring) {
1685
                    if (strstr($codesearch, $kodfinal)) {
1686
                        ++$counter;
1687
                    }
1688
                }
1689
            }
1690
            if ($counter) {
1691
                $kodfinal = $kodfinal . $counter;
1692
            }
1693
1694
            $this->codes[$kodfinal] = $kod;
1695
        }
1696
1697
        return self::code($kodfinal);
1698
    }
1699
1700
    /**
1701
     * Write Operation Result.
1702
     *
1703
     * @param array  $resultData
1704
     * @param string $url        URL
1705
     * 
1706
     * @return boolean Log save success
1707
     */
1708
    public function logResult($resultData = null, $url = null) {
1709
        $logResult = false;
1710
        if (isset($resultData['success']) && ($resultData['success'] == 'false')) {
1711
            $this->addStatusMessage('Error ' . $this->lastResponseCode . ': ' . urldecode($url) . (array_key_exists('message',
1712
                            $resultData) ? ' ' . $resultData['message'] : ''), 'warning');
1713
            unset($url);
1714
        }
1715
        if (is_null($resultData)) {
1716
            $resultData = $this->lastResult;
1717
        }
1718
        if (isset($url)) {
1719
            \Ease\Shared::logger()->addStatusMessage($this->lastResponseCode . ':' . urldecode($url));
1720
        }
1721
1722
        if (isset($resultData['results'])) {
1723
            if ($resultData['success'] == 'false') {
1724
                $status = 'error';
1725
            } else {
1726
                $status = 'success';
1727
            }
1728
            foreach ($resultData['results'] as $result) {
1729
                if (isset($result['request-id'])) {
1730
                    $rid = $result['request-id'];
1731
                } else {
1732
                    $rid = '';
1733
                }
1734
                if (isset($result['errors'])) {
1735
                    foreach ($result['errors'] as $error) {
1736
                        $message = $error['message'];
1737
                        if (isset($error['for'])) {
1738
                            $message .= ' for: ' . $error['for'];
1739
                        }
1740
                        if (isset($error['value'])) {
1741
                            $message .= ' value:' . $error['value'];
1742
                        }
1743
                        if (isset($error['code'])) {
1744
                            $message .= ' code:' . $error['code'];
1745
                        }
1746
                        $this->addStatusMessage($rid . ': ' . $message, $status);
1747
                    }
1748
                }
1749
            }
1750
        }
1751
        return $logResult;
1752
    }
1753
1754
    /**
1755
     * Save RAW Curl Request & Response to files in Temp directory
1756
     */
1757
    public function saveDebugFiles() {
1758
        $tmpdir = sys_get_temp_dir();
1759
        $fname = $this->evidence . '-' . $this->curlInfo['when'] . '.' . $this->format;
1760
        $reqname = $tmpdir . '/request-' . $fname;
1761
        $respname = $tmpdir . '/response-' . $fname;
1762
        $header = '# ' . (new \DateTime())->format('Y-m-d\TH:i:s.u') . ' ' . $this->curlInfo['url'] . ' (' . urldecode($this->curlInfo['url']) . ')';
1763
        if (file_put_contents($reqname, $header . "\n" . $this->postFields)) {
1764
            $this->addStatusMessage($reqname, 'debug');
1765
        }
1766
        if (file_put_contents($respname, $header . "\n" . $this->lastCurlResponse)) {
1767
            $this->addStatusMessage($respname, 'debug');
1768
        }
1769
    }
1770
1771
    /**
1772
     * Připraví data pro odeslání do FlexiBee
1773
     *
1774
     * @param string $data
1775
     */
1776
    public function setPostFields($data) {
1777
        $this->postFields = $data;
1778
    }
1779
1780
    /**
1781
     * Get Content ready to be send as POST body
1782
     * @return string
1783
     */
1784
    public function getPostFields() {
1785
        return $this->postFields;
1786
    }
1787
1788
    /**
1789
     * Generuje fragment url pro filtrování.
1790
     *
1791
     * @see https://www.flexibee.eu/api/dokumentace/ref/filters
1792
     *
1793
     * @param array  $data   key=>values; value can bee class DatePeriod, DateTime or Array
1794
     * @param string $joiner default and/or
1795
     * @param string $defop  default operator
1796
     *
1797
     * @return string
1798
     */
1799
    public static function flexiUrl(array $data, $joiner = 'and', $defop = 'eq') {
1800
        $parts = [];
1801
1802
        foreach ($data as $column => $value) {
1803
            if (!is_numeric($column)) {
1804
                if (is_integer($data[$column]) || is_float($data[$column])) {
1805
                    $parts[$column] = $column . ' eq \'' . $data[$column] . '\'';
1806
                } elseif (is_bool($data[$column])) {
1807
                    $parts[$column] = $data[$column] ? $column . ' eq true' : $column . ' eq false';
1808
                } elseif (is_null($data[$column])) {
1809
                    $parts[$column] = $column . " is null";
1810
                } elseif (is_array($data[$column])) {
1811
                    $parts[$column] = $column . " in (" . implode(',',
1812
                                    array_map(function($a, $column) {
1813
                                        return $column == 'stitky' ? "'" . self::code($a) . "'" : "'$a'";
1814
                                    }, $data[$column],
1815
                                            array_fill(0, count($data[$column]), $column))) . ")";
1816
                } elseif (is_object($data[$column])) {
1817
                    switch (get_class($data[$column])) {
1818
                        case 'DatePeriod':
1819
                            $parts[$column] = $column . " between '" . $data[$column]->getStartDate()->format(self::$DateFormat) . "' '" . $data[$column]->getEndDate()->format(self::$DateFormat) . "'";
1820
                            break;
1821
                        case 'DateTime':
1822
                            $parts[$column] = $column . " eq '" . $data[$column]->format(self::$DateFormat) . "'";
1823
                            break;
1824
                        default:
1825
                            $parts[$column] = $column . " $defop '" . $data[$column] . "'";
1826
                            break;
1827
                    }
1828
                } else {
1829
                    switch ($value) {
1830
                        case '!null':
1831
                            $parts[$column] = $column . " is not null";
1832
                            break;
1833
                        case 'is empty':
1834
                        case 'is not empty':
1835
                        case 'is true':
1836
                        case 'is false':
1837
                            $parts[$column] = $column . ' ' . $value;
1838
                            break;
1839
                        default:
1840
                            $condParts = explode(' ', trim($value));
1841
                            switch ($condParts[0]) {
1842
                                case '<>':
1843
                                case '!=':
1844
                                case 'ne':
1845
                                case 'neq':
1846
                                case '<':
1847
                                case 'lt':
1848
                                case '<=':
1849
                                case 'lte':
1850
                                case '>':
1851
                                case 'gt':
1852
                                case '>=':
1853
                                case 'gte':
1854
                                case 'like':
1855
                                case 'begins':
1856
                                case 'between':
1857
                                case 'ends':
1858
                                    if (count($condParts) == 1) {
1859
                                        $parts[$column] = $column .= ' ' . $value;
1860
                                    } else {
1861
                                        $parts[$column] = $column .= ' ' . $condParts[0] . " '" . $condParts[1] . "'";
1862
                                    }
1863
                                    break;
1864
                                default:
1865
                                    if ($column == 'stitky') {
1866
                                        $parts[$column] = $column . "='" . self::code($data[$column]) . "'";
1867
                                    } else {
1868
                                        $parts[$column] = $column . " $defop '" . $data[$column] . "'";
1869
                                    }
1870
                                    break;
1871
                            }
1872
1873
                            break;
1874
                    }
1875
                }
1876
            } else {
1877
                $parts[] = $value;
1878
            }
1879
        }
1880
        return implode(' ' . $joiner . ' ', $parts);
1881
    }
1882
1883
    /**
1884
     * Obtain record/object numeric identificator id:
1885
     * Vrací číselný identifikátor objektu id:
1886
     *
1887
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1888
     *
1889
     * @return null|int indentifikátor záznamu reprezentovaného objektem
1890
     */
1891
    public function getRecordID() {
1892
        $id = $this->getDataValue('id');
1893
        return is_null($id) ? null : (is_numeric($id) ? intval($id) : $id);
1894
    }
1895
1896
    /**
1897
     * Obtain record/object identificator code:
1898
     * Vrací identifikátor objektu code:
1899
     *
1900
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1901
     *
1902
     * @return string record code identifier
1903
     */
1904
    public function getRecordCode() {
1905
        return empty($this->getDataValue('kod')) ? null : self::code($this->getDataValue('kod'));
1906
    }
1907
1908
    /**
1909
     * Obtain record/object identificator extId: code: or id:
1910
     * Vrací identifikátor objektu extId: code: nebo id:
1911
     *
1912
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1913
     *
1914
     * @return string|int|null record code identifier
1915
     */
1916
    public function getRecordIdent() {
1917
        $ident = $this->getExternalID();
1918
        if (empty($ident)) {
1919
            $ident = $this->getRecordCode();
1920
        }
1921
        if (empty($ident)) {
1922
            $ident = $this->getRecordID();
1923
        }
1924
        return $ident;
1925
    }
1926
1927
    /**
1928
     * Obtain record/object identificator code: or id:
1929
     * Vrací identifikátor objektu code: nebo id:
1930
     *
1931
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1932
     * 
1933
     * @return string indentifikátor záznamu reprezentovaného objektem
1934
     */
1935
    public function __toString() {
1936
        return strval($this->getRecordIdent());
1937
    }
1938
1939
    /**
1940
     * Gives you FlexiPeeHP class name for Given Evidence
1941
     *
1942
     * @param string $evidence
1943
     * 
1944
     * @return string Class name
1945
     */
1946
    public static function evidenceToClassName($evidence) {
1947
        return str_replace(' ', '', ucwords(str_replace('-', ' ', $evidence)));
1948
    }
1949
1950
    /**
1951
     * Obtain ID of first record in evidence
1952
     *
1953
     * @return string|null id or null if no records
1954
     */
1955
    public function getFirstRecordID() {
1956
        $firstID = null;
1957
        $keyColumn = $this->getKeyColumn();
1958
        $firstIdRaw = $this->getColumnsFromFlexibee([$keyColumn],
1959
                ['limit' => 1, 'order' => $keyColumn], $keyColumn);
1960
        if (!empty($firstIdRaw) && isset(current($firstIdRaw)[$keyColumn])) {
1961
            $firstID = current($firstIdRaw)[$keyColumn];
1962
        }
1963
        return is_numeric($firstID) ? intval($firstID) : $firstID;
1964
    }
1965
1966
    /**
1967
     * Get previous record ID
1968
     * 
1969
     * @param array $conditions optional
1970
     * 
1971
     * @return int|null
1972
     */
1973
    public function getNextRecordID($conditions = []) {
1974
        $conditions['order'] = 'id@D';
1975
        $conditions['limit'] = 1;
1976
        $conditions[] = 'id gt ' . $this->getRecordID();
1977
        $next = $this->getColumnsFromFlexibee(['id'], $conditions);
1978
        return (is_array($next) && array_key_exists(0, $next) && array_key_exists('id',
1979
                        $next[0])) ? intval($next[0]['id']) : null;
1980
    }
1981
1982
    /**
1983
     * Get next record ID
1984
     * 
1985
     * @param array $conditions optional
1986
     * 
1987
     * @return int|null
1988
     */
1989
    public function getPrevRecordID($conditions = []) {
1990
        $conditions['order'] = 'id@A';
1991
        $conditions['limit'] = 1;
1992
        $conditions[] = 'id lt ' . $this->getRecordID();
1993
        $prev = $this->getColumnsFromFlexibee(['id'], $conditions);
1994
        return (is_array($prev) && array_key_exists(0, $prev) && array_key_exists('id',
1995
                        $prev[0])) ? intval($prev[0]['id']) : null;
1996
    }
1997
1998
    /**
1999
     * Vrací hodnotu daného externího ID
2000
     *
2001
     * @param string $want Namespace Selector. If empty,you obtain the first one.
2002
     * 
2003
     * @return string|array one id or array if multiplete
2004
     */
2005
    public function getExternalID($want = null) {
2006
        $extid = null;
2007
        $ids = $this->getExternalIDs();
2008
        if (is_null($want)) {
2009
            if (!empty($ids)) {
2010
                $extid = current($ids);
2011
            }
2012
        } else {
2013
            if (!is_null($ids) && is_array($ids)) {
2014
                foreach ($ids as $id) {
2015
                    if (strstr($id, 'ext:' . $want)) {
2016
                        if (is_null($extid)) {
2017
                            $extid = str_replace('ext:' . $want . ':', '', $id);
2018
                        } else {
2019
                            if (is_array($extid)) {
2020
                                $extid[] = str_replace('ext:' . $want . ':', '', $id);
2021
                            } else {
2022
                                $extid = [$extid, str_replace('ext:' . $want . ':',
2023
                                            '', $id)];
2024
                            }
2025
                        }
2026
                    }
2027
                }
2028
            }
2029
        }
2030
        return $extid;
2031
    }
2032
2033
    /**
2034
     * gives you currently loaded extermal IDs
2035
     * 
2036
     * @return array
2037
     */
2038
    public function getExternalIDs() {
2039
        return $this->getDataValue('external-ids');
2040
    }
2041
2042
    /**
2043
     * Obtain actual GlobalVersion
2044
     * Vrací aktuální globální verzi změn
2045
     *
2046
     * @link https://www.flexibee.eu/api/dokumentace/ref/changes-api#globalVersion Globální Verze
2047
     * 
2048
     * @return int
2049
     */
2050
    public function getGlobalVersion() {
2051
        $this->getFlexiData(null, ['add-global-version' => 'true', 'limit' => 1]);
2052
2053
        return $this->globalVersion;
2054
    }
2055
2056
    /**
2057
     * Gives you current ApiURL with given format suffix
2058
     * 
2059
     * @param string $format json|html|xml|...
2060
     * 
2061
     * @return string API URL for current record or object/evidence
2062
     */
2063
    public function getApiURL($format = null) {
2064
        $apiUrl = str_replace(['.' . $this->format, '?limit=0'], '', $this->apiURL);
2065
        return $apiUrl . (empty($format) ? '' : '.' . $format );
2066
    }
2067
2068
    /**
2069
     * Obtain content type of last response
2070
     *
2071
     * @return string
2072
     */
2073
    public function getResponseFormat() {
2074
        return $this->responseFormat;
2075
    }
2076
2077
    /**
2078
     * Return the same response format for one and multiplete results
2079
     *
2080
     * @param array $responseBody
2081
     * 
2082
     * @return array
2083
     */
2084
    public function unifyResponseFormat($responseBody) {
2085
        if (!is_array($responseBody) || array_key_exists('message',
2086
                        $responseBody)) { //Unifi response format
2087
            $response = $responseBody;
2088
        } else {
2089
            $evidence = $this->getResponseEvidence();
2090
            if (array_key_exists($evidence, $responseBody)) {
2091
                $response = [];
2092
                $evidenceContent = $responseBody[$evidence];
2093
                if (array_key_exists(0, $evidenceContent)) {
2094
                    $response[$evidence] = $evidenceContent; //Multiplete Results
2095
                } else {
2096
                    $response[$evidence][0] = $evidenceContent; //One result
2097
                }
2098
            } else {
2099
                if (isset($responseBody['priloha'])) {
2100
                    $response = $responseBody['priloha'];
2101
                } else {
2102
                    if (array_key_exists('results', $responseBody)) {
2103
                        $response = $responseBody['results'];
2104
                    } else {
2105
                        $response = $responseBody;
2106
                    }
2107
                }
2108
            }
2109
        }
2110
        return $response;
2111
    }
2112
2113
    /**
2114
     * Obtain structure for current (or given) evidence
2115
     *
2116
     * @param string $evidence
2117
     * 
2118
     * @return array Evidence structure
2119
     */
2120
    public function getOfflineColumnsInfo($evidence = null) {
2121
        $columnsInfo = null;
2122
        $infoSource = self::$infoDir . '/Properties.' . (empty($evidence) ? $this->getEvidence() : $evidence) . '.json';
2123
        if (file_exists($infoSource)) {
2124
            $columnsInfo = json_decode(file_get_contents($infoSource), true);
2125
        }
2126
        return $columnsInfo;
2127
    }
2128
2129
    /**
2130
     * Obtain Current evidence Live structure
2131
     * 
2132
     * @param string $evidence
2133
     * 
2134
     * @return array structure
2135
     */
2136
    public function getOnlineColumnsInfo($evidence = null) {
2137
        $properties = [];
2138
        $evidence = is_null($evidence) ? $this->getEvidence() : $evidence;
2139
        $flexinfo = $this->performRequest('/c/' . $this->company . '/' . $evidence . '/properties.json');
2140
        if (!empty($flexinfo) && array_key_exists('properties', $flexinfo)) {
2141
            foreach ($flexinfo['properties']['property'] as $evidenceProperty) {
2142
                $key = $evidenceProperty['propertyName'];
2143
                $properties[$key] = $evidenceProperty;
2144
                if (array_key_exists('name', $evidenceProperty)) {
2145
                    $proerties[$key]['name'] = $evidenceProperty['name'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$proerties was never initialized. Although not strictly required by PHP, it is generally a good practice to add $proerties = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
2146
                }
2147
                $properties[$key]['type'] = $evidenceProperty['type'];
2148
                if (array_key_exists('url', $evidenceProperty)) {
2149
                    $properties[$key]['url'] = str_replace('?limit=0', '',
2150
                            $evidenceProperty['url']);
2151
                }
2152
            }
2153
        }
2154
        return $properties;
2155
    }
2156
2157
    /**
2158
     * Update evidence info from array or online from properties.json or offline
2159
     * 
2160
     * @param array  $columnsInfo
2161
     * @param string $evidence
2162
     */
2163
    public function updateColumnsInfo($columnsInfo = null, $evidence = null) {
2164
        $evidence = is_null($evidence) ? $this->getEvidence() : $evidence;
2165
        if (is_null($columnsInfo)) {
2166
            $this->columnsInfo[$evidence] = $this->offline ? $this->getOfflineColumnsInfo($evidence) : $this->getOnlineColumnsInfo($evidence);
2167
        } else {
2168
            $this->columnsInfo[$evidence] = $columnsInfo;
2169
        }
2170
    }
2171
2172
    /**
2173
     * Gives you evidence structure. You can obtain current online by pre-calling:
2174
     * $this->updateColumnsInfo($evidence, $this->getOnlineColumnsInfo($evidence));
2175
     * 
2176
     * @param string $evidence
2177
     * 
2178
     * @return array
2179
     */
2180
    public function getColumnsInfo($evidence = null) {
2181
        $evidence = is_null($evidence) ? $this->getEvidence() : $evidence;
2182
        if (!array_key_exists($evidence, $this->columnsInfo)) {
2183
            $this->updateColumnsInfo($this->getOfflineColumnsInfo($evidence),
2184
                    $evidence);
2185
        }
2186
        return $this->columnsInfo[$evidence];
2187
    }
2188
2189
    /**
2190
     * Gives you properties for (current) evidence column
2191
     *
2192
     * @param string $column    name of column
2193
     * @param string $evidence  evidence name if different
2194
     *
2195
     * @return array column properties or null if column not exits
2196
     */
2197
    public function getColumnInfo($column, $evidence = null) {
2198
        $columnsInfo = $this->getColumnsInfo(empty($evidence) ? $this->getEvidence() : $evidence);
2199
        return (empty($column) || empty($columnsInfo) || !is_array($columnsInfo)) ? null : array_key_exists($column, $columnsInfo) ? $columnsInfo[$column] : null;
2200
    }
2201
2202
    /**
2203
     * Obtain actions for current (or given) evidence
2204
     *
2205
     * @param string $evidence
2206
     * 
2207
     * @return array Evidence structure
2208
     */
2209
    public function getActionsInfo($evidence = null) {
2210
        $actionsInfo = null;
2211
        if (is_null($evidence)) {
2212
            $evidence = $this->getEvidence();
2213
        }
2214
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
2215
        if (isset(\FlexiPeeHP\Actions::$$propsName)) {
2216
            $actionsInfo = Actions::$$propsName;
2217
        }
2218
        return $actionsInfo;
2219
    }
2220
2221
    /**
2222
     * Obtain relations for current (or given) evidence
2223
     *
2224
     * @param string $evidence
2225
     * 
2226
     * @return array Evidence structure
2227
     */
2228
    public function getRelationsInfo($evidence = null) {
2229
        $relationsInfo = null;
2230
        if (is_null($evidence)) {
2231
            $evidence = $this->getEvidence();
2232
        }
2233
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
2234
        if (isset(\FlexiPeeHP\Relations::$$propsName)) {
2235
            $relationsInfo = Relations::$$propsName;
2236
        }
2237
        return $relationsInfo;
2238
    }
2239
2240
    /**
2241
     * Obtain info for current (or given) evidence
2242
     *
2243
     * @param string $evidence
2244
     * 
2245
     * @return array Evidence info
2246
     */
2247
    public function getEvidenceInfo($evidence = null) {
2248
        $evidencesInfo = null;
2249
        if (is_null($evidence)) {
2250
            $evidence = $this->getEvidence();
2251
        }
2252
        if (isset(EvidenceList::$evidences[$evidence])) {
2253
            $evidencesInfo = EvidenceList::$evidences[$evidence];
2254
            $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
2255
            if (isset(Formats::$$propsName)) {
2256
                $evidencesInfo['formats'] = Formats::$$propsName;
2257
            }
2258
        }
2259
        return $evidencesInfo;
2260
    }
2261
2262
    /**
2263
     * Obtain name for current (or given) evidence path
2264
     *
2265
     * @param string $evidence Evidence Path
2266
     * 
2267
     * @return array Evidence info
2268
     */
2269
    public function getEvidenceName($evidence = null) {
2270
        $evidenceName = null;
2271
        if (is_null($evidence)) {
2272
            $evidence = $this->getEvidence();
2273
        }
2274
        if (isset(EvidenceList::$name[$evidence])) {
2275
            $evidenceName = EvidenceList::$name[$evidence];
2276
        }
2277
        return $evidenceName;
2278
    }
2279
2280
    /**
2281
     * Save current object to file
2282
     *
2283
     * @param string $destfile path to file
2284
     */
2285
    public function saveResponseToFile($destfile) {
2286
        if (strlen($this->lastCurlResponse)) {
2287
            $this->doCurlRequest($this->apiURL, 'GET', $this->format);
2288
        }
2289
        file_put_contents($destfile, $this->lastCurlResponse);
2290
    }
2291
2292
    /**
2293
     * Obtain established relations listing
2294
     *
2295
     * @return array Null or Relations
2296
     */
2297
    public function getVazby($id = null) {
2298
        if (is_null($id)) {
2299
            $id = $this->getRecordID();
2300
        }
2301
        if (!empty($id)) {
2302
            $vazbyRaw = $this->getColumnsFromFlexibee(['vazby'],
2303
                    ['relations' => 'vazby', 'id' => $id]);
2304
            $vazby = array_key_exists('vazby', $vazbyRaw[0]) ? $vazbyRaw[0]['vazby'] : 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
        $parsed_url = parse_url(str_replace('.' . $this->format, '', $this->apiURL));
2318
        $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
2319
        $host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
2320
        $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
2321
        $user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
2322
        $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
2323
        $pass = ($user || $pass) ? "$pass@" : '';
2324
        $path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
2325
        return $scheme . $user . $pass . $host . $port . $path;
2326
    }
2327
2328
    /**
2329
     * Set Record Key
2330
     *
2331
     * @param int|string $myKeyValue
2332
     * 
2333
     * @return boolean
2334
     */
2335
    public function setMyKey($myKeyValue) {
2336
        if (substr($myKeyValue, 0, 4) == 'ext:') {
2337
            if ($this->evidenceInfo['extIdSupported'] == 'false') {
2338
                $this->addStatusMessage(sprintf(_('Evidence %s does not support extIDs'),
2339
                                $this->getEvidence()), 'warning');
2340
                $res = false;
2341
            } else {
2342
                $extIds = $this->getDataValue('external-ids');
2343
                if (!empty($extIds) && count($extIds)) {
2344
                    $extIds = array_combine($extIds, $extIds);
2345
                }
2346
2347
                $extIds[$myKeyValue] = $myKeyValue;
2348
                $res = $this->setDataValue('external-ids',
2349
                        $extIds);
2350
            }
2351
        } else {
2352
            $res = $this->setDataValue($this->getKeyColumn(), $myKeyValue);
2353
        }
2354
        $this->updateApiURL();
2355
        return $res;
2356
    }
2357
2358
    /**
2359
     * Set or get ignore not found pages flag
2360
     *
2361
     * @param boolean $ignore set flag to
2362
     *
2363
     * @return boolean get flag state
2364
     */
2365
    public function ignore404($ignore = null) {
2366
        if (!is_null($ignore)) {
2367
            $this->ignoreNotFound = $ignore;
2368
        }
2369
        return $this->ignoreNotFound;
2370
    }
2371
2372
    /**
2373
     * Send Document by mail
2374
     *
2375
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
2376
     *
2377
     * @param string $to         Email ecipient
2378
     * @param string $subject    Email Subject
2379
     * @param string $body       Email Text
2380
     *
2381
     * @return boolean mail sent status
2382
     */
2383
    public function sendByMail($to, $subject, $body, $cc = null) {
2384
        $this->setPostFields($body);
2385
2386
        $this->performRequest(rawurlencode($this->getRecordID()) . '/odeslani-dokladu?to=' . $to . '&subject=' . urlencode($subject) . '&cc=' . $cc
2387
                , 'PUT', 'xml');
2388
2389
        return $this->lastResponseCode == 200;
2390
    }
2391
2392
    /**
2393
     * Send all unsent Documents by eMail
2394
     *
2395
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
2396
     * 
2397
     * @return int http response code
2398
     */
2399
    public function sendUnsent() {
2400
        return $this->doCurlRequest('automaticky-odeslat-neodeslane', 'PUT',
2401
                        'xml');
2402
    }
2403
2404
    /**
2405
     * FlexiBee date to PHP DateTime conversion
2406
     *
2407
     * @param string $flexidate 2017-05-26 or 2017-05-26+02:00
2408
     *
2409
     * @return \DateTime | false
2410
     */
2411
    public static function flexiDateToDateTime($flexidate) {
2412
        return \DateTime::createFromFormat(strstr($flexidate, '+') ? self::$DateFormat . 'O' : 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
        if (strchr($flexidatetime, '.')) { //NewFormat
2424
            $format = self::$DateTimeFormat;
2425
        } else { // Old format
2426
            $format = 'Y-m-d\TH:i:s+P';
2427
        }
2428
        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 2428 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...
2429
    }
2430
2431
    /**
2432
     * Získá dokument v daném formátu
2433
     * Obtain document in given format
2434
     *
2435
     * @link https://www.flexibee.eu/api/dokumentace/ref/pdf/ PDF Exports
2436
     *
2437
     * @param string  $format     pdf/csv/xml/json/ ...
2438
     * @param string  $reportName Template used to generate PDF
2439
     * @param string  $lang       cs|sk|en|de Template language used to generate PDF
2440
     * @param boolean $sign       sign resulting PDF by certificate ?
2441
     *
2442
     * @return string|null filename downloaded or none
2443
     */
2444
    public function getInFormat($format, $reportName = null, $lang = null,
2445
            $sign = false) {
2446
        $response = null;
2447
        if ($this->setFormat($format)) {
2448
            $urlParams = [];
2449
            switch ($format) {
2450
                case 'pdf':
2451
                    switch ($lang) {
2452
                        case 'cs':
2453
                        case 'sk':
2454
                        case 'en':
2455
                        case 'de':
2456
                            $urlParams['report-lang'] = $lang;
2457
                            break;
2458
                        case null:
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $lang of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
2459
                        case '':
2460
                            break;
2461
                        default:
2462
                            throw new \Ease\Exception('Unknown language ' . $lang . ' for PDF export');
2463
                            break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

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

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

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

    return false;
}

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

Loading history...
2464
                    }
2465
                    if (boolval($sign) === true) {
2466
                        $urlParams['report-sign'] = 'true';
2467
                    }
2468
                    break;
2469
                case 'html':
2470
                    $urlParams['inDesktopApp'] = 'true';
2471
                    break;
2472
            }
2473
            if (!empty($reportName)) {
2474
                $urlParams['report-name'] = $reportName;
2475
            }
2476
            if (($this->doCurlRequest(\Ease\Functions::addUrlParams($this->apiURL,
2477
                                    $urlParams), 'GET') == 200)) {
2478
                $response = $this->lastCurlResponse;
2479
            }
2480
        }
2481
        return $response;
2482
    }
2483
2484
    /**
2485
     * Uloží dokument v daném formátu do složky v systému souborů
2486
     * Save document in given format to directory in filesystem
2487
     *
2488
     * @param string $format  pdf/csv/xml/json/ ...
2489
     * @param string $destDir where to put file (prefix)
2490
     * @param string $reportName Template used to generate PDF
2491
     *
2492
     * @return string|null filename downloaded or none
2493
     */
2494
    public function downloadInFormat($format, $destDir = './',
2495
            $reportName = null) {
2496
        $fileOnDisk = null;
2497
        $formatBackup = $this->format;
2498
        if ($this->setFormat($format)) {
2499
            $downloadTo = $destDir . $this->getEvidence() . '_' . $this->getMyKey() . '.' . $format;
2500
            if (($this->doCurlRequest(empty($reportName) ? $this->apiURL : \Ease\Functions::addUrlParams($this->apiURL,
2501
                                            ['report-name' => $reportName]), 'GET') == 200) && (file_put_contents($downloadTo,
2502
                            $this->lastCurlResponse) !== false)) {
2503
                $fileOnDisk = $downloadTo;
2504
            }
2505
            $this->setFormat($formatBackup);
2506
        }
2507
        return $fileOnDisk;
2508
    }
2509
2510
    /**
2511
     * Take data for object. separate external IDs
2512
     *
2513
     * @param array $data Data to keep
2514
     * 
2515
     * @return int number of records taken
2516
     */
2517
    public function takeData($data) {
2518
        $keyColumn = $this->getKeyColumn();
2519
        if (array_key_exists($keyColumn, $data) && is_array($data[$keyColumn])) {
2520
            foreach ($data[$keyColumn] as $recPos => $recordKey) {
2521
                if (substr($recordKey, 0, 4) == 'ext:') {
2522
                    $data['external-ids'][] = $recordKey;
2523
                    unset($data[$keyColumn][$recPos]);
2524
                }
2525
            }
2526
            if (count($data[$keyColumn]) == 1) {
2527
                $data[$keyColumn] = current($data[$keyColumn]);
2528
            }
2529
        }
2530
        $result = parent::takeData($data);
2531
2532
        if (array_key_exists($keyColumn, $data) || array_key_exists('kod', $data)) {
2533
            $this->updateApiURL();
2534
        }
2535
2536
        return $result;
2537
    }
2538
2539
    /**
2540
     * Get Current Evidence reports listing
2541
     * 
2542
     * @link https://www.flexibee.eu/api/dokumentace/casto-kladene-dotazy-pro-api/vyber-reportu-do-pdf/ Výběr reportu do PDF
2543
     * 
2544
     * @return array
2545
     */
2546
    public function getReportsInfo() {
2547
        $reports = [];
2548
        $reportsRaw = $this->getFlexiData($this->getEvidenceURL() . '/reports');
2549
        if (!empty($reportsRaw) && array_key_exists('reports', $reportsRaw) && !empty($reportsRaw['reports']) && array_key_exists('report', $reportsRaw['reports']) &&
2550
                !empty($reportsRaw['reports']['report'])) {
2551
            if (\Ease\jQuery\Part::isAssoc($reportsRaw['reports']['report'])) {
2552
                $reports = [$reportsRaw['reports']['report']['reportId'] => $reportsRaw['reports']['report']];
2553
            } else {
2554
                $reports = \Ease\Functions::reindexArrayBy($reportsRaw['reports']['report'],
2555
                                'reportId');
2556
            }
2557
        }
2558
        return $reports;
2559
    }
2560
2561
    /**
2562
     * Request authSessionId from current server
2563
     * 
2564
     * @link https://www.flexibee.eu/api/dokumentace/ref/login/ description
2565
     * 
2566
     * @param string $username
2567
     * @param string $password
2568
     * @param string $otp       optional onetime password
2569
     * 
2570
     * @return string authUserId or null in case of problems
2571
     */
2572
    public function requestAuthSessionID($username, $password, $otp = null) {
2573
        $this->postFields = http_build_query(is_null($otp) ? ['username' => $username,
2574
            'password' => $password] : ['username' => $username, 'password' => $password,
2575
            'otp' => $otp]);
2576
        $response = $this->performRequest('/login-logout/login', 'POST',
2577
                'json');
2578
        if (array_key_exists('refreshToken', $response)) {
2579
            $this->refreshToken = $response['refreshToken'];
2580
        } else {
2581
            $this->refreshToken = null;
2582
        }
2583
        return array_key_exists('authSessionId', $response) ? $response['authSessionId'] : null;
2584
    }
2585
2586
    /**
2587
     * Try to Sign in current user to FlexiBee and keep authSessionId
2588
     * 
2589
     * @return boolean sign in success
2590
     */
2591
    public function login() {
2592
        $this->authSessionId = $this->requestAuthSessionID($this->user,
2593
                $this->password);
2594
        return $this->lastResponseCode == 200;
2595
    }
2596
2597
    /**
2598
     * End (current's user) session
2599
     * 
2600
     * 
2601
     * @link https://www.flexibee.eu/api/dokumentace/ref/logout Logout Reference
2602
     * 
2603
     * @param string $username force username to sign off
2604
     * 
2605
     * @return array server response
2606
     */
2607
    public function logout($username = null) {
2608
        return $this->performRequest('/status/user/' . (is_null($username) ? $this->user : $username) . '/logout', 'POST');
2609
    }
2610
2611
    /**
2612
     * Compile and send Report about Error500 to FlexiBee developers
2613
     * If FlexiBee is running on localost try also include java backtrace
2614
     *
2615
     * @param array $errorResponse result of parseError();
2616
     */
2617
    public function error500Reporter($errorResponse) {
2618
        $ur = str_replace('/c/' . $this->company, '',
2619
                str_replace($this->url, '', $this->curlInfo['url']));
2620
        if (!array_key_exists($ur, $this->reports)) {
2621
            $tmpdir = sys_get_temp_dir();
2622
            $myTime = $this->curlInfo['when'];
2623
            $curlname = $tmpdir . '/curl-' . $this->evidence . '-' . $myTime . '.json';
2624
            file_put_contents($curlname,
2625
                    json_encode($this->curlInfo, JSON_PRETTY_PRINT));
2626
2627
            $report = new \Ease\Mailer($this->reportRecipient,
2628
                    'Error report 500 - ' . $ur);
2629
2630
            $d = dir($tmpdir);
2631
            while (false !== ($entry = $d->read())) {
2632
                if (strstr($entry, $myTime)) {
2633
                    $ext = pathinfo($tmpdir . '/' . $entry, PATHINFO_EXTENSION);
2634
                    $mime = Formats::suffixToContentType($ext);
2635
                    $report->addFile($tmpdir . '/' . $entry,
2636
                            empty($mime) ? 'text/plain' : $mime);
2637
                }
2638
            }
2639
            $d->close();
2640
2641
            if ((strstr($this->url, '://localhost') || strstr($this->url,
2642
                            '://127.')) && file_exists('/var/log/flexibee.log')) {
2643
2644
                $fl = fopen('/var/log/' . 'flexibee.log', 'r');
2645
                if ($fl) {
2646
                    $tracelog = [];
2647
                    for ($x_pos = 0, $ln = 0, $output = array(); fseek($fl,
2648
                                    $x_pos, SEEK_END) !== -1; $x_pos--) {
2649
                        $char = fgetc($fl);
2650
                        if ($char === "\n") {
2651
                            $tracelog[] = $output[$ln];
2652
                            if (strstr($output[$ln], $errorResponse['message'])) {
2653
                                break;
2654
                            }
2655
                            $ln++;
2656
                            continue;
2657
                        }
2658
                        $output[$ln] = $char . ((array_key_exists($ln, $output)) ? $output[$ln] : '');
2659
                    }
2660
2661
                    $trace = implode("\n", array_reverse($tracelog));
2662
                    $tracefile = $tmpdir . '/trace-' . $this->evidence . '-' . $myTime . '.log';
2663
                    file_put_contents($tracefile, $trace);
2664
                    $report->addItem("\n\n" . $trace);
0 ignored issues
show
Bug introduced by
The method addItem() does not seem to exist on object<Ease\Mailer>.

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...
2665
                    fclose($fl);
2666
                }
2667
            } else {
2668
                $report->addItem($errorResponse['message']);
0 ignored issues
show
Bug introduced by
The method addItem() does not seem to exist on object<Ease\Mailer>.

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...
2669
            }
2670
2671
            $licenseInfo = $this->performRequest($this->url . '/default-license.json');
2672
2673
            $report->addItem("\n\n" . json_encode($licenseInfo['license'],
0 ignored issues
show
Bug introduced by
The method addItem() does not seem to exist on object<Ease\Mailer>.

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...
2674
                            JSON_PRETTY_PRINT));
2675
2676
            if ($report->send()) {
2677
                $this->reports[$ur] = $myTime;
2678
            }
2679
        }
2680
    }
2681
2682
    /**
2683
     * Returns code:CODE
2684
     *
2685
     * @param string $code
2686
     *
2687
     * @return string
2688
     */
2689
    public static function code($code) {
2690
        return ((substr($code, 0, 4) == 'ext:') ? $code : 'code:' . strtoupper(self::uncode($code)));
2691
    }
2692
2693
    /**
2694
     * Returns CODE without code: prefix
2695
     *
2696
     * @param string $code
2697
     *
2698
     * @return string
2699
     */
2700
    public static function uncode($code) {
2701
        return str_replace(['code:', 'code%3A'], '', $code);
2702
    }
2703
2704
    /**
2705
     * Remove all @ items from array
2706
     *
2707
     * @param array $data original data
2708
     *
2709
     * @return array data without @ columns
2710
     */
2711
    public static function arrayCleanUP($data) {
2712
        return array_filter(
2713
                $data,
2714
                function ($key) {
2715
            return !strchr($key, '@');
2716
        }, ARRAY_FILTER_USE_KEY);
2717
    }
2718
2719
    /**
2720
     * Add Info about used user, server and libraries
2721
     *
2722
     * @param string $prefix banner prefix text
2723
     * @param string $suffix banner suffix text
2724
     */
2725
    public function logBanner($prefix = null, $suffix = null) {
2726
        parent::logBanner($prefix,
2727
                ' FlexiBee ' . str_replace('://', '://' . $this->user . '@',
2728
                        $this->getApiUrl()) . ' FlexiBeeHP v' . self::$libVersion . ' (FlexiBee ' . EvidenceList::$version . ') EasePHP Framework v' . \Ease\Atom::$frameworkVersion . ' ' .
2729
                $suffix
2730
        );
2731
    }
2732
2733
    /**
2734
     * Get Last operation type
2735
     * 
2736
     * @return string create|read|update|delete or update,insert for some inserted and updated in one transaction
2737
     */
2738
    public function getLastOperationType() {
2739
        return implode(',', array_keys(array_filter($this->responseStats)));
2740
    }
2741
2742
    /**
2743
     * Last operation errors 
2744
     * 
2745
     * @return array FlexiBee error meassages
2746
     */
2747
    public function getErrors() {
2748
        return $this->errors;
2749
    }
2750
2751
    /**
2752
     * Reconnect After unserialization
2753
     */
2754
    public function __wakeup() {
2755
        $this->curlInit();
2756
    }
2757
2758
}
2759