Completed
Push — master ( 5f010e...717f04 )
by Vítězslav
25:12 queued 10s
created

FlexiBeeRO::setUp()   D

Complexity

Conditions 10
Paths 512

Size

Total Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
nc 512
nop 1
dl 0
loc 44
rs 4.1777
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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-2020 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.37';
33
34
    /**
35
     * Basic namespace for communication with FlexiBee
36
     *
37
     * @var string Jmený prostor datového bloku odpovědi
38
     */
39
    public $nameSpace = 'winstrom';
40
41
    /**
42
     * URL of object data in FlexiBee
43
     * @var string url
44
     */
45
    public $apiURL = null;
46
47
    /**
48
     * Data block in response field.
49
     *
50
     * @var string
51
     */
52
    public $resultField = 'results';
53
54
    /**
55
     * Communication protocol version used.
56
     *
57
     * @var string Verze použitého API
58
     */
59
    public $protoVersion = '1.0';
60
61
    /**
62
     * Evidence used by object
63
     *
64
     * @link https://demo.flexibee.eu/c/demo/evidence-list Přehled evidencí
65
     * 
66
     * @var string
67
     */
68
    public $evidence = null;
69
70
    /**
71
     * Detaily evidence užité objektem
72
     * 
73
     * @var array 
74
     */
75
    public $evidenceInfo = [];
76
77
    /**
78
     * Default communication format.
79
     *
80
     * @link https://www.flexibee.eu/api/dokumentace/ref/format-types Přehled možných formátů
81
     *
82
     * @var string json|xml|...
83
     */
84
    public $format = 'json';
85
86
    /**
87
     * requested response format
88
     *
89
     * @link https://www.flexibee.eu/api/dokumentace/ref/format-types Přehled možných formátů
90
     *
91
     * @var string json|xml|...
92
     */
93
    public $responseFormat = 'json';
94
95
    /**
96
     * Curl Handle.
97
     *
98
     * @var resource
99
     */
100
    public $curl = null;
101
102
    /**
103
     * @link https://demo.flexibee.eu/devdoc/company-identifier Identifikátor firmy
104
     * @var string
105
     */
106
    public $company = null;
107
108
    /**
109
     * [protocol://]Server[:port]
110
     * @var string
111
     */
112
    public $url = null;
113
114
    /**
115
     * REST API Username
116
     * @var string
117
     */
118
    public $user = null;
119
120
    /**
121
     * REST API Password
122
     * @var string
123
     */
124
    public $password = null;
125
126
    /**
127
     * @var array Pole HTTP hlaviček odesílaných s každým požadavkem
128
     */
129
    public $defaultHttpHeaders = [];
130
131
    /**
132
     * Default additional request url parameters after question mark
133
     *
134
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls   Common params
135
     * @link https://www.flexibee.eu/api/dokumentace/ref/paging Paging params
136
     * @var array
137
     */
138
    public $defaultUrlParams = [];
139
140
    /**
141
     * Identifikační řetězec.
142
     *
143
     * @var string
144
     */
145
    public $init = null;
146
147
    /**
148
     * Sloupeček s názvem.
149
     *
150
     * @var string
151
     */
152
    public $nameColumn = 'nazev';
153
154
    /**
155
     * Sloupeček obsahující datum vložení záznamu do shopu.
156
     *
157
     * @var string
158
     */
159
    public $myCreateColumn = 'false';
160
161
    /**
162
     * Slopecek obsahujici datum poslení modifikace záznamu do shopu.
163
     *
164
     * @var string
165
     */
166
    public $myLastModifiedColumn = 'lastUpdate';
167
168
    /**
169
     * Klíčový idendifikátor záznamu.
170
     *
171
     * @var string
172
     */
173
    public $fbKeyColumn = 'id';
174
175
    /**
176
     * Informace o posledním HTTP requestu.
177
     *
178
     * @var *
179
     */
180
    public $curlInfo;
181
182
    /**
183
     * Informace o poslední HTTP chybě.
184
     *
185
     * @var string
186
     */
187
    public $lastCurlError = null;
188
189
    /**
190
     * Used codes storage.
191
     *
192
     * @var array
193
     */
194
    public $codes = null;
195
196
    /**
197
     * Last Inserted ID.
198
     *
199
     * @var int
200
     */
201
    public $lastInsertedID = null;
202
203
    /**
204
     * Default Line Prefix.
205
     *
206
     * @var string
207
     */
208
    public $prefix = '/c/';
209
210
    /**
211
     * Raw Content of last curl response
212
     *
213
     * @var string
214
     */
215
    public $lastCurlResponse;
216
217
    /**
218
     * HTTP Response code of last request
219
     *
220
     * @var int
221
     */
222
    public $lastResponseCode = null;
223
224
    /**
225
     * Body data  for next curl POST operation
226
     *
227
     * @var string
228
     */
229
    public $postFields = null;
230
231
    /**
232
     * Last operation result data or message(s)
233
     *
234
     * @var array
235
     */
236
    public $lastResult = null;
237
238
    /**
239
     * Number from  @rowCount in response
240
     * @var int
241
     */
242
    public $rowCount = null;
243
244
    /**
245
     * Number from  @globalVersion
246
     * @var int
247
     */
248
    public $globalVersion = null;
249
250
    /**
251
     * @link https://www.flexibee.eu/api/dokumentace/ref/zamykani-odemykani/
252
     * @var string filter query
253
     */
254
    public $filter;
255
256
    /**
257
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
258
     * @var string
259
     */
260
    protected $action;
261
262
    /**
263
     * Pole akcí které podporuje ta která evidence
264
     * @link https://demo.flexibee.eu/c/demo/faktura-vydana/actions.json Např. Akce faktury
265
     * @var array
266
     */
267
    public $actionsAvailable = null;
268
269
    /**
270
     * Parmetry pro URL
271
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Všechny podporované parametry
272
     * @var array
273
     */
274
    public $urlParams = [
275
        'add-global-version' => ['type' => 'boolean', 'description' => 'The response will contain the global version number of the current export'],
276
        'add-row-count' => ['type' => 'boolean', 'description' => 'Adding Total Records to Output (Pagination)'],
277
        'as-gui' => ['type' => 'boolean', 'description' => 'Turns on functions that complement the GUI processing outputs'],
278
        '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.'],
279
        'authSessionId' => ['type' => 'string', 'description' => 'Authentification Session ID'],
280
        '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>'],
281
        'code-in-response' => ['type' => 'boolean', 'description' => 'The response will contain not only ID and URL for each object, but also code.'],
282
        'delimeter' => ['type' => 'string', 'description' => 'Specifies the input / output file separator in CSV format.',
283
            'example' => ';'],
284
        'detail' => ['type' => 'string', 'description' => 'Definition of the level of detail'], //See: https://www.flexibee.eu/api/dokumentace/ref/detail-levels
285
        'dir' => ['type' => 'string', 'description' => 'Sorting direction.', 'example' => 'desc'],
286
        'dry-run' => ['type' => 'boolean', 'description' => 'Test run (dry-run)'], // See: https://www.flexibee.eu/api/dokumentace/ref/dry-run/
287
        'encoding' => ['type' => 'string', 'description' => 'Specifies the encoding of the input / output file in CSV format.'],
288
        'export-settings' => ['type' => 'boolean', 'description' => 'Export one extra entry with current settings at the beginning'],
289
        'fail-on-warning' => ['type' => 'boolean', 'description' => 'If a warning occurs, do not save a record (Data Validation)'],
290
        'filter' => ['type' => 'string', 'description' => 'filter results by this param'],
291
        'format' => ['type' => 'string', 'description' => 'One of the compiled XSL transforms will be applied to the output XML.'],
292
        'idUcetniObdobi' => ['type' => 'string', 'description' => ''], //See: https://www.flexibee.eu/api/dokumentace/ref/stavy-uctu/
293
        'includes' => ['type' => 'string', 'description' => 'Include related detail level object ',
294
            'example' => 'faktura-vydana/stredisko'],
295
        'inDesktopApp' => ['type' => 'boolean', 'description' => 'Hide menu and navigation in html format'], // Note: Undocumented function (html only)
296
        'limit' => ['type' => 'integer', 'description' => 'number of requested results'],
297
        'mode' => ['type' => 'string', 'description' => 'Support for RubyOnRails',
298
            'example' => 'ruby'],
299
        'no-ext-ids' => ['type' => 'boolean', 'description' => 'The answer will not contain external identifiers (performance optimization)'],
300
        'no-http-errors' => ['type' => 'boolean', 'description' => 'If a 4xx error occurs while processing a request, the server sends 200 OK anyway'],
301
        'no-ids' => ['type' => 'boolean', 'description' => 'The response will not contain any primary identifiers (performance optimization). It only affects the main records.'],
302
        '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.'],
303
        'order' => ['type' => 'string', 'description' => 'Sorting records', 'example' => 'nazev@A'],
304
        'relations' => ['type' => 'string', 'description' => 'Adding session data (see detail levels) A session overview can be obtained for each record (/ relations).'],
305
        'report-lang' => ['type' => 'string', 'description' => 'The language in which to print the output when exporting to PDF',
306
            'example' => 'en'],
307
        'report-name' => ['type' => 'string', 'description' => 'The name of the printout when exporting to PDF',
308
            'example' => 'invoice'],
309
        'report-sign' => ['type' => 'string', 'description' => 'Whether the PDF should be exported electronically signed'],
310
        'skupina-stitku' => ['type' => 'string', 'description' => 'Enables grouping of labels when exporting by group (multiple labels)'],
311
        'sort' => ['type' => 'string', 'description' => 'Sorting records for ExtJS'],
312
        'start' => ['type' => 'integer', 'description' => 'Pagination'],
313
        'stitky-as-ids' => ['type' => 'boolean', 'description' => 'Labels will be exported and imported not as a code list but as a list of numeric IDs'],
314
        'use-ext-id' => ['type' => 'boolean', 'description' => 'If the object contains an external ESHOP or MY ID, use it as a bind.'],
315
        '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'],
316
        'xpath' => ['type' => 'string', 'description' => 'Apply XPATH to result',
317
            'example' => '//winstrom/adresar/email/text()'] // See: https://www.flexibee.eu/api/dokumentace/ref/xpath/
318
    ];
319
320
    /**
321
     * Session ID
322
     * @var string
323
     */
324
    public $authSessionId = null;
325
326
    /**
327
     * Token obtained during login procedure
328
     * @var string 
329
     */
330
    public $refreshToken = null;
331
332
    /**
333
     * Save 404 results to log ?
334
     * @var boolean
335
     */
336
    protected $ignoreNotFound = false;
337
338
    /**
339
     * Array of errors caused by last request
340
     * @var array
341
     */
342
    protected $errors = [];
343
344
    /**
345
     * List of Error500 reports sent
346
     * @var array
347
     */
348
    private $reports = [];
349
350
    /**
351
     * Send Error500 Report to
352
     * @var string email address
353
     */
354
    public $reportRecipient = '[email protected]';
355
356
    /**
357
     * Formating string for \DateTime::format() for datetime columns
358
     * @var string
359
     */
360
    static public $DateTimeFormat = 'Y-m-d\TH:i:s.u+P';
361
362
    /**
363
     * Formating string for \DateTime::format() for date columns
364
     * @var string
365
     */
366
    static public $DateFormat = 'Y-m-d';
367
368
    /**
369
     * Last Request response stats
370
     * @var array 
371
     */
372
    protected $responseStats = null;
373
374
    /**
375
     * Chained Objects
376
     * @var array
377
     */
378
    public $chained = [];
379
380
    /**
381
     * We Connect to server by default
382
     * @var boolean
383
     */
384
    public $offline = false;
385
386
    /**
387
     * Override cURL timeout
388
     * @var int seconds
389
     */
390
    public $timeout = null;
391
392
    /**
393
     * Columns Info for serveral evidencies
394
     * @var array 
395
     */
396
    private $columnsInfo = [];
397
398
    /**
399
     * Throw Exception in case of FlexiBee error
400
     * @var boolean 
401
     */
402
    public $throwException = false;
403
404
    /**
405
     * Class for read only interaction with FlexiBee.
406
     *
407
     * @param mixed $init default record id or initial data. See processInit()
408
     * @param array $options Connection settings and other options override
409
     */
410
    public function __construct($init = null, $options = []) {
411
        $this->init = $init;
412
413
        $this->setUp($options);
414
        $this->curlInit();
415
        if (!empty($init)) {
416
            $this->processInit($init);
417
        }
418
    }
419
420
    /**
421
     * Set internal Object name
422
     *
423
     * @param string $objectName
424
     *
425
     * @return string Jméno objektu
426
     */
427
    public function setObjectName($objectName = null) {
428
        return parent::setObjectName(is_null($objectName) ? ( empty($this->getRecordIdent()) ? $this->getObjectName() : $this->getRecordIdent() . '@' . $this->getObjectName() ) : $objectName);
429
    }
430
431
    /**
432
     * SetUp Object to be ready for work
433
     *
434
     * @param array $options Object Options ( user,password,authSessionId
435
     *                                        company,url,evidence,
436
     *                                        prefix,defaultUrlParams,debug,
437
     *                                        detail,offline,filter,ignore404
438
     *                                        timeout,companyUrl,ver,throwException
439
     */
440
    public function setUp($options = []) {
441
        if (array_key_exists('ver', $options)) {
442
            $this->protoVersion = $options['ver'];
443
            $this->prefix = 'v' . round($this->protoVersion) . '/c/';
444
        }
445
        if (array_key_exists('companyUrl', $options)) {
446
            $options = array_merge(self::companyUrlToOptions($options['companyUrl']),
447
                    $options);
448
        }
449
450
        $this->setupProperty($options, 'company', 'FLEXIBEE_COMPANY');
451
        $this->setupProperty($options, 'url', 'FLEXIBEE_URL');
452
        $this->setupProperty($options, 'user', 'FLEXIBEE_LOGIN');
453
        $this->setupProperty($options, 'password', 'FLEXIBEE_PASSWORD');
454
        $this->setupProperty($options, 'authSessionId', 'FLEXIBEE_AUTHSESSID');
455
        $this->setupProperty($options, 'timeout', 'FLEXIBEE_TIMEOUT');
456
        if (!empty($this->authSessionId)) {
457
            $this->defaultHttpHeaders['X-authSessionId'] = $this->authSessionId;
458
        }
459
        if (isset($options['evidence'])) {
460
            $this->setEvidence($options['evidence']);
461
        }
462
        if(array_key_exists('defaultUrlParams',$options)){
463
            $this->defaultUrlParams = $options['defaultUrlParams'];
464
        }
465
        if (isset($options['prefix'])) {
466
            $this->setPrefix($options['prefix']);
467
        }
468
        if (array_key_exists('detail', $options)) {
469
            $this->defaultUrlParams['detail'] = $options['detail'];
470
        }
471
        $this->setupProperty($options, 'filter');
472
        if (array_key_exists('offline', $options)) {
473
            $this->offline = (boolean) $options['offline'];
474
        }
475
476
        if (array_key_exists('ignore404', $options)) {
477
            $this->ignore404($options['ignore404']);
478
        }
479
480
        $this->setupProperty($options, 'throwException', 'FLEXIBEE_EXCEPTIONS');
481
        $this->setupProperty($options, 'debug');
482
        $this->updateApiURL();
483
    }
484
485
    /**
486
     * Convert companyUrl provided by CustomButton to options array
487
     * 
488
     * @param string $companyUrl
489
     * 
490
     * @return array Options
491
     */
492
    public static function companyUrlToOptions($companyUrl) {
493
        $urlParts = parse_url($companyUrl);
494
        $scheme = isset($urlParts['scheme']) ? $urlParts['scheme'] . '://' : '';
495
        $host = isset($urlParts['host']) ? $urlParts['host'] : '';
496
        $port = isset($urlParts['port']) ? ':' . $urlParts['port'] : '';
497
        $path = isset($urlParts['path']) ? $urlParts['path'] : '';
498
499
        $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...
500
        $options['url'] = $scheme . $host . $port;
501
        return $options;
502
    }
503
504
    /**
505
     * Get Current connection options for use in another object
506
     *
507
     * @return array usable as second constructor parameter
508
     */
509
    public function getConnectionOptions() {
510
        $conOpts = ['url' => $this->url];
511
        if (empty($this->authSessionId)) {
512
            $conOpts ['user'] = $this->user;
513
            $conOpts['password'] = $this->password;
514
        } else {
515
            $conOpts['authSessionId'] = $this->authSessionId;
516
        }
517
        $company = $this->getCompany();
518
        if (!empty($company)) {
519
            $conOpts['company'] = $company;
520
        }
521
        if (!is_null($this->timeout)) {
522
            $conOpts['timeout'] = $this->timeout;
523
        }
524
        return $conOpts;
525
    }
526
527
    /**
528
     * Export current/given configutation into Environment  
529
     * @param array $opts
530
     */
531
    public function configToEnv($opts = null) {
532
        $options = is_null($opts) ? $this->getConnectionOptions() : $opts;
533
        if (array_key_exists('url', $options)) {
534
            putenv('FLEXIBEE_URL=' . $options['URL']);
535
        }
536
        if (array_key_exists('user', $options)) {
537
            putenv('FLEXIBEE_LOGIN=' . $options['user']);
538
        }
539
        if (array_key_exists('password', $options)) {
540
            putenv('FLEXIBEE_PASSWORD=' . $options['password']);
541
        }
542
        if (array_key_exists('company', $options)) {
543
            putenv('FLEXIBEE_COMPANY=' . $options['company']);
544
        }
545
        if (array_key_exists('authSessionId', $options)) {
546
            putenv('FLEXIBEE_AUTHSESSID=' . $options['authSessionId']);
547
        }
548
    }
549
550
    /**
551
     * Inicializace CURL
552
     *
553
     * @return boolean Online Status
554
     */
555
    public function curlInit() {
556
        if ($this->offline === false) {
557
            $this->curl = \curl_init(); // create curl resource
558
            \curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); // return content as a string from curl_exec
559
            \curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); // follow redirects (compatibility for future changes in FlexiBee)
560
            \curl_setopt($this->curl, CURLOPT_HTTPAUTH, true);       // HTTP authentication
561
            \curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); // FlexiBee by default uses Self-Signed certificates
562
            \curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
563
            \curl_setopt($this->curl, CURLOPT_VERBOSE, ($this->debug === true)); // For debugging
564
            if (empty($this->authSessionId)) {
565
                \curl_setopt($this->curl, CURLOPT_USERPWD,
566
                        $this->user . ':' . $this->password); // set username and password
567
            }
568
            if (!is_null($this->timeout)) {
569
                \curl_setopt($this->curl, CURLOPT_TIMEOUT, $this->timeout);
570
            }
571
572
            \curl_setopt($this->curl, CURLOPT_USERAGENT, 'phpFlexiBee  v' . self::$libVersion . ' https://github.com/Spoje-NET/php-flexibee');
573
        }
574
        return !$this->offline;
575
    }
576
577
    /**
578
     * Initialise object with given data. Availble value types:
579
     *
580
     *  * 234                              - interní číslo záznamu k načtení
581
     *  * code:LOPATA                      - kód záznamu
582
     *  * BAGR                             - kód záznamu k načtení
583
     *  * ['id'=>24,'nazev'=>'hoblík']     - pole hodnot k předvyplnění
584
     *  * 743.json?relations=adresa,vazby  - část url s parametry k načtení
585
     *
586
     * @param mixed $init číslo/"(code:)kód"/(část)URI záznamu k načtení | pole hodnot k předvyplnění
587
     */
588
    public function processInit($init) {
589
        if (is_integer($init)) {
590
            $this->loadFromFlexiBee($init);
591
        } elseif (is_array($init)) {
592
            $this->takeData($init);
593
        } elseif (preg_match('/\.(json|xml|csv)/', $init)) {
594
            $this->takeData($this->getFlexiData((($init[0] != '/') ? $this->evidenceUrlWithSuffix($init) : $init)));
595
        } else {
596
            $this->loadFromFlexiBee($init);
597
        }
598
    }
599
600
    /**
601
     * Set Data Field value
602
     *
603
     * @param string $columnName field name
604
     * @param mixed  $value      field data value
605
     *
606
     * @return bool Success
607
     */
608
    public function setDataValue($columnName, $value) {
609
        switch ($columnName) {
610
            case 'kod':
611
                $value = self::uncode($value); //Alwyas uncode "kod" column
612
613
            default:
614
                if (is_object($value)) {
615
                    switch (get_class($value)) {
616
                        case 'DateTime':
617
                            $columnInfo = $this->getColumnInfo($columnName);
618
                            switch ($columnInfo['type']) {
619
                                case 'date':
620
                                    $value = self::dateToFlexiDate($value);
621
                                    break;
622
                                case 'datetime':
623
                                    $value = self::dateToFlexiDateTime($value);
624
                                    break;
625
                            }
626
                            break;
627
                    }
628
                }
629
                $result = parent::setDataValue($columnName, $value);
630
                break;
631
        }
632
        return $result;
633
    }
634
635
    /**
636
     * PHP Date object to FlexiBee date format
637
     * 
638
     * @param \DateTime $date
639
     */
640
    public static function dateToFlexiDate($date) {
641
        return $date->format(self::$DateFormat);
642
    }
643
644
    /**
645
     * PHP Date object to FlexiBee date format
646
     * 
647
     * @param \DateTime $dateTime
648
     */
649
    public static function dateToFlexiDateTime($dateTime) {
650
        return $dateTime->format(self::$DateTimeFormat);
651
    }
652
653
    /**
654
     * Set URL prefix
655
     *
656
     * @param string $prefix
657
     */
658
    public function setPrefix($prefix) {
659
        switch ($prefix) {
660
            case 'a': //Access
661
            case 'c': //Company
662
            case 'u': //User
663
            case 'g': //License Groups
664
            case 'admin':
665
            case 'status':
666
            case 'login-logout':
667
                $this->prefix = '/' . $prefix . '/';
668
                break;
669
            case null:
670
            case '':
671
            case '/':
672
                $this->prefix = '';
673
                break;
674
            default:
675
                throw new \Exception(sprintf('Unknown prefix %s', $prefix));
676
        }
677
    }
678
679
    /**
680
     * Set communication format.
681
     * One of html|xml|json|csv|dbf|xls|isdoc|isdocx|edi|pdf|pdf|vcf|ical
682
     *
683
     * @param string $format
684
     * 
685
     * @return boolean format is availble
686
     */
687
    public function setFormat($format) {
688
        $result = true;
689
        if (($this->debug === true) && !empty($this->evidence) && isset(Formats::$$this->evidence)) {
690
            if (array_key_exists($format, array_flip(Formats::$$this->evidence)) === false) {
691
                $result = false;
692
            }
693
        }
694
        if ($result === true) {
695
            $this->format = $format;
696
            $this->updateApiURL();
697
        }
698
        return $result;
699
    }
700
701
    /**
702
     * Nastaví Evidenci pro Komunikaci.
703
     * Set evidence for communication
704
     *
705
     * @param string $evidence evidence pathName to use
706
     * 
707
     * @return boolean evidence switching status
708
     */
709
    public function setEvidence($evidence) {
710
        switch ($this->prefix) {
711
            case '/c/':
712
                if ($this->debug === true) {
713
                    if (array_key_exists($evidence, EvidenceList::$name)) {
714
                        $this->evidence = $evidence;
715
                        $result = true;
716
                    } else {
717
                        throw new \Exception(sprintf('Try to set unsupported evidence %s',
718
                                        $evidence));
719
                    }
720
                } else {
721
                    $this->evidence = $evidence;
722
                    $result = true;
723
                }
724
                break;
725
            default:
726
                $this->evidence = $evidence;
727
                $result = true;
728
                break;
729
        }
730
        $this->updateApiURL();
731
        $this->evidenceInfo = $this->getEvidenceInfo();
732
        return $result;
733
    }
734
735
    /**
736
     * Vrací právě používanou evidenci pro komunikaci
737
     * Obtain current used evidence
738
     *
739
     * @return string
740
     */
741
    public function getEvidence() {
742
        return $this->evidence;
743
    }
744
745
    /**
746
     * Set used company.
747
     * Nastaví Firmu.
748
     *
749
     * @param string $company
750
     */
751
    public function setCompany($company) {
752
        $this->company = $company;
753
    }
754
755
    /**
756
     * Obtain company now used
757
     * Vrací právě používanou firmu
758
     *
759
     * @return string
760
     */
761
    public function getCompany() {
762
        return $this->company;
763
    }
764
765
    /**
766
     * Vrací název evidence použité v odpovědích z FlexiBee
767
     *
768
     * @return string
769
     */
770
    public function getResponseEvidence() {
771
        switch ($this->evidence) {
772
            case 'c':
773
                $evidence = 'company';
774
                break;
775
            case 'evidence-list':
776
                $evidence = 'evidence';
777
                break;
778
            default:
779
                $evidence = $this->getEvidence();
780
                break;
781
        }
782
        return $evidence;
783
    }
784
785
    /**
786
     * Převede rekurzivně Objekt na pole.
787
     *
788
     * @param object|array $object
789
     *
790
     * @return array
791
     */
792
    public static function object2array($object) {
793
        $result = null;
794
        if (is_object($object)) {
795
            $objectData = get_object_vars($object);
796
            if (is_array($objectData) && count($objectData)) {
797
                $result = array_map('self::object2array', $objectData);
798
            }
799
        } else {
800
            if (is_array($object)) {
801
                foreach ($object as $item => $value) {
802
                    $result[$item] = self::object2array($value);
803
                }
804
            } else {
805
                $result = $object;
806
            }
807
        }
808
809
        return $result;
810
    }
811
812
    /**
813
     * Převede rekurzivně v poli všechny objekty na jejich identifikátory.
814
     *
815
     * @param object|array $object
816
     *
817
     * @return array
818
     */
819
    public static function objectToID($object) {
820
        $resultID = null;
821
        if (is_object($object) && method_exists($object, '__toString')
822
        ) {
823
            $resultID = $object->__toString();
824
        } else {
825
            if (is_array($object)) {
826
                foreach ($object as $item => $value) {
827
                    $resultID[$item] = self::objectToID($value);
828
                }
829
            } else { //String
830
                $resultID = $object;
831
            }
832
        }
833
834
        return $resultID;
835
    }
836
837
    /**
838
     * Return basic URL for used Evidence
839
     *
840
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
841
     *
842
     * @return string Evidence URL
843
     */
844
    public function getEvidenceURL() {
845
        $evidenceUrl = $this->url . $this->prefix . $this->company;
846
        $evidence = $this->getEvidence();
847
        if (!empty($evidence)) {
848
            $evidenceUrl .= '/' . $evidence;
849
        }
850
        return $evidenceUrl;
851
    }
852
853
    /**
854
     * Add suffix to Evidence URL
855
     *
856
     * @param string $urlSuffix
857
     *
858
     * @return string
859
     */
860
    public function evidenceUrlWithSuffix($urlSuffix) {
861
        $evidenceUrl = $this->getEvidenceUrl();
862
        if (!empty($urlSuffix)) {
863
            if (($urlSuffix[0] != '/') && ($urlSuffix[0] != ';') && ($urlSuffix[0] != '?')) {
864
                $evidenceUrl .= '/';
865
            }
866
            $evidenceUrl .= $urlSuffix;
867
        }
868
        return $evidenceUrl;
869
    }
870
871
    /**
872
     * Update $this->apiURL
873
     */
874
    public function updateApiURL() {
875
        $this->apiURL = $this->getEvidenceURL();
876
        $rowIdentifier = $this->getRecordIdent();
877
        if (empty($rowIdentifier)) {
878
            $rowIdentifier = $this->getRecordCode();
879
            if (empty($rowIdentifier)) {
880
                $rowIdentifier = $this->getExternalID();
881
            }
882
        }
883
        if (!empty($rowIdentifier)) {
884
            $this->apiURL .= '/' . self::urlEncode($rowIdentifier);
885
        }
886
        $this->apiURL .= '.' . $this->format;
887
    }
888
889
    /*
890
     * Add Default Url params to given url if not overrided
891
     *
892
     * @param string $urlRaw
893
     *
894
     * @return string url with default params added
895
     */
896
897
    public function addDefaultUrlParams($urlRaw) {
898
        return \Ease\Functions::addUrlParams($urlRaw, $this->defaultUrlParams,
899
                        false);
900
    }
901
902
    /**
903
     * Funkce, která provede I/O operaci a vyhodnotí výsledek.
904
     *
905
     * @param string $urlSuffix část URL za identifikátorem firmy.
906
     * @param string $method    HTTP/REST metoda
907
     * @param string $format    Requested format
908
     * 
909
     * @return array|boolean Výsledek operace
910
     */
911
    public function performRequest($urlSuffix = null, $method = 'GET',
912
            $format = null) {
913
        $this->rowCount = null;
914
        $this->responseStats = [];
915
        $this->errors = [];
916
917
        if (preg_match('/^http/', $urlSuffix)) {
918
            $url = $urlSuffix;
919
        } elseif (strlen($urlSuffix) && ($urlSuffix[0] == '/')) {
920
            $url = $this->url . $urlSuffix;
921
        } else {
922
            $url = $this->evidenceUrlWithSuffix($urlSuffix);
923
        }
924
925
        $responseCode = $this->doCurlRequest($this->addDefaultUrlParams($url),
926
                $method, $format);
927
928
        return $this->parseResponse($this->rawResponseToArray($this->lastCurlResponse,
929
                                $this->responseFormat), $responseCode);
930
    }
931
932
    /**
933
     * Parse Raw FlexiBee response in several formats
934
     *
935
     * @param string $responseRaw raw response body
936
     * @param string $format      Raw Response format json|xml|etc
937
     *
938
     * @return array
939
     */
940
    public function rawResponseToArray($responseRaw, $format) {
941
        $responseDecoded = [];
942
        if (!empty(trim($responseRaw))) {
943
            switch ($format) {
944
                case 'json':
945
                    $responseDecoded = $this->rawJsonToArray($responseRaw);
946
                    break;
947
                case 'xml':
948
                    $responseDecoded = $this->rawXmlToArray($this->lastCurlResponse);
949
                    break;
950
                case 'txt':
951
                default:
952
                    $responseDecoded = [$this->lastCurlResponse];
953
                    break;
954
            }
955
        }
956
        return $responseDecoded;
957
    }
958
959
    /**
960
     * Convert FlexiBee Response JSON to Array
961
     *
962
     * @param string $rawJson
963
     *
964
     * @return array
965
     */
966
    public function rawJsonToArray($rawJson) {
967
        $responseDecoded = json_decode($rawJson, true, 10);
968
        $decodeError = json_last_error_msg();
969
        if ($decodeError == 'No error') {
970
            if (array_key_exists($this->nameSpace, $responseDecoded)) {
971
                $responseDecoded = $responseDecoded[$this->nameSpace];
972
            }
973
        } else {
974
            if ($this->debug) {
975
                $this->addStatusMessage('JSON Decoder: ' . $decodeError, 'error');
976
                $this->addStatusMessage($rawJson, 'debug');
977
            }
978
        }
979
        return $responseDecoded;
980
    }
981
982
    /**
983
     * Convert FlexiBee Response XML to Array
984
     *
985
     * @param string $rawXML
986
     *
987
     * @return array
988
     */
989
    public function rawXmlToArray($rawXML) {
990
        return self::xml2array($rawXML);
991
    }
992
993
    /**
994
     * Parse Response array
995
     *
996
     * @param array $responseDecoded
997
     * @param int $responseCode Request Response Code
998
     *
999
     * @return array main data part of response
1000
     */
1001
    public function parseResponse($responseDecoded, $responseCode) {
1002
        $mainResult = null;
1003
        switch ($responseCode) {
1004
            case 201: //We do not care about Success Write here
1005
                break;
1006
            case 200: //Success Read
1007
1008
                if (is_array($responseDecoded)) {
1009
                    if (isset($responseDecoded['@rowCount'])) {
1010
                        $this->rowCount = (int) $responseDecoded['@rowCount'];
1011
                    }
1012
                    if (isset($responseDecoded['@globalVersion'])) {
1013
                        $this->globalVersion = (int) $responseDecoded['@globalVersion'];
1014
                    }
1015
1016
                    $mainResult = $this->unifyResponseFormat($responseDecoded);
1017
1018
                    if (array_key_exists('stats', $responseDecoded)) {
1019
                        $this->responseStats = $responseDecoded['stats'];
1020
                    } elseif (!empty($mainResult)) {
1021
                        if (array_key_exists('success', $mainResult) && ($mainResult['success'] == 'false')) {
1022
                            $this->responseStats = ['read' => 0];
1023
                        } elseif (array_key_exists('properties', $mainResult)) {
1024
                            $this->responseStats = ['read' => 1];
1025
                        } else {
1026
                            $responseEvidence = $this->getResponseEvidence();
1027
                            if (!empty($this->rowCount)) {
1028
                                $this->responseStats = ['read' => $this->rowCount];
1029
                            } elseif (array_key_exists($responseEvidence,
1030
                                            $mainResult)) {
1031
                                $this->responseStats = ['read' => count($mainResult[$responseEvidence])];
1032
                            } else {
1033
                                $this->responseStats = ['read' => count($mainResult)];
1034
                            }
1035
                        }
1036
                    }
1037
                } else {
1038
                    $mainResult = $responseDecoded;
1039
                }
1040
1041
                $this->lastResult = $mainResult;
1042
                break;
1043
1044
            case 500: // Internal Server Error
1045
                if ($this->debug === true) {
1046
                    $this->error500Reporter($responseDecoded);
1047
                }
1048
            case 404: // Page not found
1049
                if ($this->ignoreNotFound === true) {
1050
                    break;
1051
                }
1052
            case 400: //Bad Request parameters
1053
            default: //Something goes wrong
1054
                if (is_array($responseDecoded)) {
1055
                    $this->parseError($responseDecoded);
1056
                }
1057
1058
                if ($this->throwException === true) {
1059
                    throw new \Ease\Exception(json_encode($this->getErrors()), $this->lastResponseCode);
1060
                } else {
1061
                    $this->addStatusMessage($this->lastResponseCode . ': ' . $this->curlInfo['url'],
1062
                            'warning');
1063
                    $this->logResult($responseDecoded, $this->curlInfo['url']);
1064
                }
1065
                break;
1066
        }
1067
        return $mainResult;
1068
    }
1069
1070
    /**
1071
     * Parse error message response
1072
     *
1073
     * @param array $responseDecoded
1074
     * 
1075
     * @return int number of errors processed
1076
     */
1077
    public function parseError(array $responseDecoded) {
1078
        if (array_key_exists('success', $responseDecoded)) {
1079
            $this->errors = [['message' => array_key_exists('message', $responseDecoded) ? $responseDecoded['message'] : '']];
1080
        } else {
1081
            throw new \Ease\Exception('Unparsed error: ' . $this->lastCurlResponse);
1082
        }
1083
        return count($this->errors);
1084
    }
1085
1086
    /**
1087
     * Vykonej HTTP požadavek
1088
     *
1089
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
1090
     * @param string $url    URL požadavku
1091
     * @param string $method HTTP Method GET|POST|PUT|OPTIONS|DELETE
1092
     * @param string $format požadovaný formát komunikace
1093
     * 
1094
     * @return int HTTP Response CODE
1095
     */
1096
    public function doCurlRequest($url, $method, $format = null) {
1097
        if (is_null($format)) {
1098
            $format = $this->format;
1099
        }
1100
        curl_setopt($this->curl, CURLOPT_URL, $url);
1101
// Nastavení samotné operace
1102
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, strtoupper($method));
1103
//Vždy nastavíme byť i prázná postdata jako ochranu před chybou 411
1104
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->postFields);
1105
1106
        $httpHeaders = $this->defaultHttpHeaders;
1107
1108
        $formats = Formats::bySuffix();
1109
1110
        if (!isset($httpHeaders['Accept'])) {
1111
            $httpHeaders['Accept'] = $formats[$format]['content-type'];
1112
        }
1113
        if (!isset($httpHeaders['Content-Type'])) {
1114
            $httpHeaders['Content-Type'] = $formats[$format]['content-type'];
1115
        }
1116
1117
        array_walk($httpHeaders, function (&$value,$header) { $value = $header .': '.$value; } );
1118
        curl_setopt($this->curl, CURLOPT_HTTPHEADER, $httpHeaders);
1119
1120
// Proveď samotnou operaci
1121
        $this->lastCurlResponse = curl_exec($this->curl);
1122
        $this->curlInfo = curl_getinfo($this->curl);
1123
        $this->curlInfo['when'] = microtime();
1124
        $this->curlInfo['request_headers'] = $httpHeaders;
1125
        $this->responseFormat = $this->contentTypeToResponseFormat($this->curlInfo['content_type'],
1126
                $url);
1127
        $this->lastResponseCode = $this->curlInfo['http_code'];
1128
        $this->lastCurlError = curl_error($this->curl);
1129
        if (strlen($this->lastCurlError)) {
1130
            $this->addStatusMessage(sprintf('Curl Error (HTTP %d): %s',
1131
                            $this->lastResponseCode, $this->lastCurlError), 'error');
1132
        }
1133
1134
        if ($this->debug === true) {
1135
            $this->saveDebugFiles();
1136
        }
1137
        return $this->lastResponseCode;
1138
    }
1139
1140
    /**
1141
     * Obtain json for application/json
1142
     * 
1143
     * @param string $contentType
1144
     * @param string $url
1145
     * 
1146
     * @return string response format
1147
     */
1148
    public function contentTypeToResponseFormat($contentType, $url = null) {
1149
        if (!empty($url)) {
1150
            $url = parse_url($url, PHP_URL_PATH);
1151
        }
1152
1153
        $contentTypeClean = strstr($contentType, ';') ? substr($contentType, 0,
1154
                        strpos($contentType, ';')) : $contentType;
1155
1156
        switch ($url) {
1157
            case '/login-logout/login';
1158
                $responseFormat = 'json';
1159
                break;
1160
            default :
1161
                switch ($contentTypeClean) {
1162
                    case 'text/javascript':
1163
                        $responseFormat = 'js';
1164
                        break;
1165
1166
                    default:
1167
                        $responseFormat = Formats::contentTypeToSuffix($contentTypeClean);
1168
                        break;
1169
                }
1170
                break;
1171
        }
1172
1173
        return $responseFormat;
1174
    }
1175
1176
    /**
1177
     * Nastaví druh prováděné akce.
1178
     *
1179
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
1180
     * @param string $action
1181
     * 
1182
     * @return boolean
1183
     */
1184
    public function setAction($action) {
1185
        $result = false;
1186
        $actionsAvailable = $this->getActionsInfo();
1187
        if (is_array($actionsAvailable) && array_key_exists($action,
1188
                        $actionsAvailable)) {
1189
            $this->action = $action;
1190
            $result = true;
1191
        }
1192
        return $result;
1193
    }
1194
1195
    /**
1196
     * Convert XML to array.
1197
     *
1198
     * @param string $xml
1199
     *
1200
     * @return array
1201
     */
1202
    public static function xml2array($xml) {
1203
        $arr = [];
1204
        if (!empty($xml)) {
1205
            if (is_string($xml)) {
1206
                $xml = simplexml_load_string($xml);
1207
            }
1208
            foreach ($xml->attributes() as $a) {
1209
                $arr['@' . $a->getName()] = strval($a);
1210
            }
1211
            foreach ($xml->children() as $r) {
1212
                if (count($r->children()) == 0) {
1213
                    $arr[$r->getName()] = strval($r);
1214
                } else {
1215
                    $arr[$r->getName()][] = self::xml2array($r);
1216
                }
1217
            }
1218
        }
1219
        return $arr;
1220
    }
1221
1222
    /**
1223
     * Odpojení od FlexiBee.
1224
     */
1225
    public function disconnect() {
1226
        if (is_resource($this->curl)) {
1227
            curl_close($this->curl);
1228
        }
1229
        $this->curl = null;
1230
    }
1231
1232
    /**
1233
     * Disconnect CURL befere pass away
1234
     */
1235
    public function __destruct() {
1236
        $this->disconnect();
1237
    }
1238
1239
    /**
1240
     * Načte řádek dat z FlexiBee.
1241
     *
1242
     * @param int $recordID id požadovaného záznamu
1243
     *
1244
     * @return array
1245
     */
1246
    public function getFlexiRow($recordID) {
1247
        $record = null;
1248
        $response = $this->performRequest($this->evidence . '/' . $recordID . '.json');
1249
        if (isset($response[$this->evidence])) {
1250
            $record = $response[$this->evidence][0];
1251
        }
1252
1253
        return $record;
1254
    }
1255
1256
    /**
1257
     * Oddělí z pole podmínek ty jenž patří za ? v URL požadavku
1258
     *
1259
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
1260
     * @param array $conditions pole podmínek   - rendrují se do ()
1261
     * @param array $urlParams  pole parametrů  - rendrují za ?
1262
     */
1263
    public function extractUrlParams(&$conditions, &$urlParams) {
1264
        foreach (array_keys($this->urlParams) as $urlParam) {
1265
            if (isset($conditions[$urlParam])) {
1266
                \Ease\Functions::divDataArray($conditions, $urlParams, $urlParam);
1267
            }
1268
        }
1269
    }
1270
1271
    /**
1272
     * convert unicode to entities for use with FlexiBee queries
1273
     *
1274
     * @param string $urlRaw
1275
     * 
1276
     * @return string
1277
     */
1278
    public static function urlEncode($urlRaw) {
1279
        return str_replace(['%27', '%3A'], ["'", ':'], rawurlencode($urlRaw));
1280
    }
1281
1282
    /**
1283
     * Načte data z FlexiBee.
1284
     *
1285
     * @param string $suffix     dotaz
1286
     * @param string|array       $conditions Custom filters or modifiers
1287
     *
1288
     * @return array Data obtained
1289
     */
1290
    public function getFlexiData($suffix = null, $conditions = null) {
1291
        $finalUrl = '';
1292
        $evidenceToRestore = null;
1293
        $urlParams = $this->defaultUrlParams;
1294
1295
        if (!empty($conditions)) {
1296
            if (is_array($conditions)) {
1297
                $this->extractUrlParams($conditions, $urlParams);
1298
                if (array_key_exists('evidence', $conditions) && is_null($this->getColumnInfo('evidence'))) {
1299
                    $evidenceToRestore = $this->getEvidence();
1300
                    $this->setEvidence($conditions['evidence']);
1301
                    unset($conditions['evidence']);
1302
                }
1303
                $conditions = $this->flexiUrl($conditions);
1304
            }
1305
1306
            if (strlen($conditions) && ($conditions[0] != '/')) {
1307
                $conditions = '(' . self::urlEncode($conditions) . ')';
1308
            }
1309
        }
1310
1311
        if (strlen($suffix) && ($suffix != '$sum')) {
1312
            if (preg_match('/^http/', $suffix) || ($suffix[0] == '/') || is_numeric($suffix)) {
1313
                $finalUrl = $suffix;
1314
            } else {
1315
                if (preg_match('/^(code|ext):(.*)/', $suffix)) {
1316
                    $finalUrl = self::urlizeId($suffix);
1317
                } else {
1318
                    $finalUrl = $suffix;
1319
                }
1320
            }
1321
        }
1322
1323
        $finalUrl .= $conditions;
1324
1325
        if ($suffix == '$sum') {
1326
            $finalUrl .= '/$sum';
1327
        }
1328
1329
        if (!empty($urlParams)) {
1330
            if (strstr($finalUrl, '?')) {
1331
                $finalUrl .= '&';
1332
            } else {
1333
                $finalUrl .= '?';
1334
            }
1335
            $finalUrl .= http_build_query(array_map(function($a) {
1336
                        return is_bool($a) ? ($a ? 'true' : 'false' ) : $a;
1337
                    }, $urlParams), null, '&', PHP_QUERY_RFC3986);
1338
        }
1339
1340
        $transactions = $this->performRequest($finalUrl, 'GET');
1341
        $responseEvidence = $this->getResponseEvidence();
1342
        if (is_array($transactions) && array_key_exists($responseEvidence,
1343
                        $transactions)) {
1344
            $result = $transactions[$responseEvidence];
1345
            if ((count($result) == 1) && empty(current($result))) {
1346
                $result = []; // Response is empty Array
1347
            }
1348
        } else {
1349
            $result = $transactions;
1350
        }
1351
        if (!is_null($evidenceToRestore)) {
1352
            $this->setEvidence($evidenceToRestore);
1353
        }
1354
        return $result;
1355
    }
1356
1357
    /**
1358
     * Načte záznam z FlexiBee a uloží v sobě jeho data
1359
     * Read FlexiBee record and store it inside od object
1360
     *
1361
     * @param int|string $id ID or conditions
1362
     *
1363
     * @return int počet načtených položek
1364
     */
1365
    public function loadFromFlexiBee($id = null) {
1366
        $data = [];
1367
        if (is_null($id)) {
1368
            $id = $this->getMyKey();
1369
        }
1370
        $flexidata = $this->getFlexiData($this->getEvidenceUrl() . '/' . self::urlizeId($id));
1371
        if ($this->lastResponseCode == 200) {
1372
            $this->apiURL = $this->curlInfo['url'];
1373
            if (is_array($flexidata) && (count($flexidata) == 1) && is_array(current($flexidata))) {
1374
                $data = current($flexidata);
1375
            }
1376
        }
1377
        return $this->takeData($data);
1378
    }
1379
1380
    /**
1381
     * Reload current record from FlexiBee
1382
     * 
1383
     * @return boolean 
1384
     */
1385
    public function reload() {
1386
        $id = $this->getRecordIdent();
1387
        $this->dataReset();
1388
        $this->loadFromFlexiBee($id);
1389
        return $this->lastResponseCode == 200;
1390
    }
1391
1392
    /**
1393
     * Set Filter code for requests
1394
     *
1395
     * @link https://www.flexibee.eu/api/dokumentace/ref/zamykani-odemykani/
1396
     *
1397
     * @param array|string $filter filter formula or ['key'=>'value']
1398
     *
1399
     * @return string Filter code
1400
     */
1401
    public function setFilter($filter) {
1402
        return $this->filter = is_array($filter) ? self::flexiUrl($filter) : $filter;
1403
    }
1404
1405
    /**
1406
     * Převede data do Json formátu pro FlexiBee.
1407
     * Convert data to FlexiBee like Json format
1408
     *
1409
     * @url https://www.flexibee.eu/api/dokumentace/ref/actions/
1410
     * @url https://www.flexibee.eu/api/dokumentace/ref/zamykani-odemykani/
1411
     *
1412
     * @param array $data    object data
1413
     * @param int   $options json_encode options like JSON_PRETTY_PRINT etc
1414
     *
1415
     * @return string
1416
     */
1417
    public function getJsonizedData($data = null, $options = 0) {
1418
        if (is_null($data)) {
1419
            $data = $this->getData();
1420
        }
1421
1422
        $dataToJsonize = array_merge(['@version' => $this->protoVersion],
1423
                $this->getDataForJSON($data));
1424
        $jsonRaw = json_encode([$this->nameSpace => $dataToJsonize],
1425
                $options);
1426
1427
        return $jsonRaw;
1428
    }
1429
1430
    /**
1431
     * Get Data Fragment specific for current object
1432
     *
1433
     * @param array $data
1434
     *
1435
     * @return array
1436
     */
1437
    public function getDataForJSON($data = null) {
1438
        if (is_null($data)) {
1439
            $data = $this->getData();
1440
        }
1441
1442
        $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...
1443
1444
        if (!is_null($this->action)) {
1445
            $dataForJson[$this->evidence . '@action'] = $this->action;
1446
            $this->action = null;
1447
        }
1448
1449
        if (!is_null($this->filter)) {
1450
            $dataForJson[$this->evidence . '@filter'] = $this->filter;
1451
        }
1452
1453
1454
        foreach ($this->chained as $chained) {
1455
            $chainedData = $chained->getDataForJSON();
1456
            foreach ($chainedData as $chainedItemEvidence => $chainedItemData) {
1457
                if (array_key_exists($chainedItemEvidence, $dataForJson)) {
1458
                    if (is_string(key($dataForJson[$chainedItemEvidence]))) {
1459
                        $dataBackup = $dataForJson[$chainedItemEvidence];
1460
                        $dataForJson[$chainedItemEvidence] = [];
1461
                        $dataForJson[$chainedItemEvidence][] = $dataBackup;
1462
                    }
1463
                    if (array_key_exists(0, $chainedItemData)) {
1464
                        foreach ($chainedItemData as $chainedItem) {
1465
                            $dataForJson[$chainedItemEvidence][] = $chainedItem;
1466
                        }
1467
                    } else {
1468
                        $dataForJson[$chainedItemEvidence][] = $chainedItemData;
1469
                    }
1470
                } else {
1471
                    $dataForJson[$chainedItemEvidence] = $chainedItemData;
1472
                }
1473
            }
1474
        }
1475
1476
1477
        return $dataForJson;
1478
    }
1479
1480
    /**
1481
     * Join another FlexiPeeHP Object
1482
     *
1483
     * @param FlexiBeeRO $object
1484
     *
1485
     * @return boolean adding to stack success
1486
     */
1487
    public function join(&$object) {
1488
        $result = true;
1489
        if (method_exists($object, 'getDataForJSON')) {
1490
            $this->chained[] = $object;
1491
        } else {
1492
            throw new \Ease\Exception('$object->getDataForJSON() does not exist');
1493
        }
1494
1495
        return $result;
1496
    }
1497
1498
    /**
1499
     * Prepare record ID to use in URL
1500
     * 
1501
     * @param mixed $id
1502
     * 
1503
     * @return string id ready for use in URL
1504
     */
1505
    public static function urlizeId($id) {
1506
        if (is_array($id)) {
1507
            $id = rawurlencode('(' . self::flexiUrl($id) . ')');
1508
        } else if (preg_match('/^ext:/', $id)) {
1509
            $id = self::urlEncode($id);
1510
        } else if (preg_match('/^code:/', $id)) {
1511
            $id = self::code(self::urlEncode(self::uncode($id)));
1512
        }
1513
        return $id;
1514
    }
1515
1516
    /**
1517
     * Test if given record ID exists in FlexiBee.
1518
     *
1519
     * @param mixed $identifer presence state
1520
     *
1521
     * @return boolean
1522
     */
1523
    public function idExists($identifer = null) {
1524
        if (is_null($identifer)) {
1525
            $identifer = $this->getMyKey();
1526
        }
1527
        $ignorestate = $this->ignore404();
1528
        $this->ignore404(true);
1529
        $cands = $this->getFlexiData(null,
1530
                [
1531
                    'detail' => 'custom:' . $this->getKeyColumn(),
1532
                    $this->getKeyColumn() => $identifer
1533
        ]);
1534
        $this->ignore404($ignorestate);
1535
        return ($this->lastResponseCode == 200) && !empty($cands);
1536
    }
1537
1538
    /**
1539
     * Test if given record exists in FlexiBee.
1540
     *
1541
     * @param array|string|int $data ext:id:23|code:ITEM|['id'=>23]|23
1542
     * 
1543
     * @return boolean Record presence status
1544
     */
1545
    public function recordExists($data = []) {
1546
1547
        if (empty($data)) {
1548
            $data = $this->getData();
1549
        }
1550
        $ignorestate = $this->ignore404();
1551
        $this->ignore404(true);
1552
        $keyColumn = $this->getKeyColumn();
1553
        $res = $this->getColumnsFromFlexibee([$keyColumn],
1554
                is_array($data) ? $data : [$keyColumn => $data]);
1555
1556
        if (empty($res) || (isset($res['success']) && ($res['success'] == 'false')) || ((isset($res) && is_array($res)) && !isset($res[0]) )) {
1557
            $found = false;
1558
        } else {
1559
            $found = true;
1560
        }
1561
        $this->ignore404($ignorestate);
1562
        return $found;
1563
    }
1564
1565
    /**
1566
     * Vrací z FlexiBee sloupečky podle podmínek.
1567
     *
1568
     * @param array|int|string $conditions pole podmínek nebo ID záznamu
1569
     * @param string           $indexBy    klice vysledku naplnit hodnotou ze
1570
     *                                     sloupečku
1571
     * @return array
1572
     */
1573
    public function getAllFromFlexibee($conditions = null, $indexBy = null) {
1574
        if (is_int($conditions)) {
1575
            $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...
1576
        }
1577
1578
        $flexiData = $this->getFlexiData('', $conditions);
1579
1580
        if (!is_null($indexBy)) {
1581
            $flexiData = \Ease\Functions::reindexArrayBy($flexiData);
1582
        }
1583
1584
        return $flexiData;
1585
    }
1586
1587
    /**
1588
     * Vrací z FlexiBee sloupečky podle podmínek.
1589
     *
1590
     * @param string|string[] $columnsList seznam položek nebo úrověň detailu: id|summary|full
1591
     * @param array           $conditions  pole podmínek nebo ID záznamu
1592
     * @param string          $indexBy     Sloupeček podle kterého indexovat záznamy
1593
     *
1594
     * @return array
1595
     */
1596
    public function getColumnsFromFlexibee($columnsList, $conditions = [],
1597
            $indexBy = null) {
1598
        $detail = 'full';
1599
        switch (gettype($columnsList)) {
1600
            case 'integer': //Record ID
1601
                $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...
1602
            case 'array': //Few Conditions
1603
                if (!is_null($indexBy) && !array_key_exists($indexBy,
1604
                                $columnsList)) {
1605
                    $columnsList[] = $indexBy;
1606
                }
1607
                $columns = implode(',', array_unique($columnsList));
1608
                $detail = 'custom:' . $columns;
1609
            default:
1610
                switch ($columnsList) {
1611
                    case 'id':
1612
                        $detail = 'id';
1613
                        break;
1614
                    case 'summary':
1615
                        $detail = 'summary';
1616
                        break;
1617
                    default:
1618
                        break;
1619
                }
1620
                break;
1621
        }
1622
1623
        $conditions['detail'] = $detail;
1624
1625
        $flexiData = $this->getFlexiData(null, $conditions);
1626
1627
        if (is_string($indexBy) && is_array($flexiData) && array_key_exists(0,
1628
                        $flexiData) && array_key_exists($indexBy, $flexiData[0])) {
1629
            $flexiData = \Ease\Functions::reindexArrayBy($flexiData, $indexBy);
1630
        }
1631
1632
        return $flexiData;
1633
    }
1634
1635
    /**
1636
     * Vrací kód záznamu.
1637
     * Obtain record CODE
1638
     *
1639
     * @param mixed $data
1640
     *
1641
     * @return string
1642
     */
1643
    public function getKod($data = null, $unique = true) {
1644
        $kod = null;
1645
1646
        if (is_null($data)) {
1647
            $data = $this->getData();
1648
        }
1649
1650
        if (is_string($data)) {
1651
            $data = [$this->nameColumn => $data];
1652
        }
1653
1654
        if (isset($data['kod'])) {
1655
            $kod = $data['kod'];
1656
        } else {
1657
            if (isset($data[$this->nameColumn])) {
1658
                $kod = preg_replace('/[^a-zA-Z0-9]/', '',
1659
                        \Ease\Functions::rip($data[$this->nameColumn]));
1660
            } else {
1661
                if (isset($data[$this->keyColumn])) {
1662
                    $kod = \Ease\Functions::rip($data[$this->keyColumn]);
1663
                }
1664
            }
1665
            $kod = substr($kod, 0, 20);
1666
        }
1667
1668
        if (!strlen($kod)) {
1669
            $kod = 'NOTSET';
1670
        }
1671
1672
        if (strlen($kod) > 18) {
1673
            $kodfinal = strtoupper(substr($kod, 0, 18));
1674
        } else {
1675
            $kodfinal = strtoupper($kod);
1676
        }
1677
1678
        if ($unique) {
1679
            $counter = 0;
1680
            if (!empty($this->codes) && count($this->codes)) {
1681
                foreach ($this->codes as $codesearch => $keystring) {
1682
                    if (strstr($codesearch, $kodfinal)) {
1683
                        ++$counter;
1684
                    }
1685
                }
1686
            }
1687
            if ($counter) {
1688
                $kodfinal = $kodfinal . $counter;
1689
            }
1690
1691
            $this->codes[$kodfinal] = $kod;
1692
        }
1693
1694
        return self::code($kodfinal);
1695
    }
1696
1697
    /**
1698
     * Write Operation Result.
1699
     *
1700
     * @param array  $resultData
1701
     * @param string $url        URL
1702
     * 
1703
     * @return boolean Log save success
1704
     */
1705
    public function logResult($resultData = null, $url = null) {
1706
        $logResult = false;
1707
        if (isset($resultData['success']) && ($resultData['success'] == 'false')) {
1708
            $this->addStatusMessage('Error ' . $this->lastResponseCode . ': ' . urldecode($url) . (array_key_exists('message',
1709
                            $resultData) ? ' ' . $resultData['message'] : ''), 'warning');
1710
            unset($url);
1711
        }
1712
        if (is_null($resultData)) {
1713
            $resultData = $this->lastResult;
1714
        }
1715
        if (isset($url)) {
1716
            \Ease\Shared::logger()->addToLog($this, $this->lastResponseCode . ':' . urldecode($url));
1717
        }
1718
1719
        if (isset($resultData['results'])) {
1720
            if ($resultData['success'] == 'false') {
1721
                $status = 'error';
1722
            } else {
1723
                $status = 'success';
1724
            }
1725
            foreach ($resultData['results'] as $result) {
1726
                if (isset($result['request-id'])) {
1727
                    $rid = $result['request-id'];
1728
                } else {
1729
                    $rid = '';
1730
                }
1731
                if (isset($result['errors'])) {
1732
                    foreach ($result['errors'] as $error) {
1733
                        $message = $error['message'];
1734
                        if (isset($error['for'])) {
1735
                            $message .= ' for: ' . $error['for'];
1736
                        }
1737
                        if (isset($error['value'])) {
1738
                            $message .= ' value:' . $error['value'];
1739
                        }
1740
                        if (isset($error['code'])) {
1741
                            $message .= ' code:' . $error['code'];
1742
                        }
1743
                        $this->addStatusMessage($rid . ': ' . $message, $status);
1744
                    }
1745
                }
1746
            }
1747
        }
1748
        return $logResult;
1749
    }
1750
1751
    /**
1752
     * Save RAW Curl Request & Response to files in Temp directory
1753
     */
1754
    public function saveDebugFiles() {
1755
        $tmpdir = sys_get_temp_dir();
1756
        $fname = $this->evidence . '-' . $this->curlInfo['when'] . '.' . $this->format;
1757
        $reqname = $tmpdir . '/request-' . $fname;
1758
        $respname = $tmpdir . '/response-' . $fname;
1759
        $header = '# ' . (new \DateTime())->format('Y-m-d\TH:i:s.u') . ' ' . $this->curlInfo['url'] . ' (' . urldecode($this->curlInfo['url']) . ')';
1760
        if (file_put_contents($reqname, $header . "\n" . $this->postFields)) {
1761
            $this->addStatusMessage($reqname, 'debug');
1762
        }
1763
        if (file_put_contents($respname, $header . "\n" . $this->lastCurlResponse)) {
1764
            $this->addStatusMessage($respname, 'debug');
1765
        }
1766
    }
1767
1768
    /**
1769
     * Připraví data pro odeslání do FlexiBee
1770
     *
1771
     * @param string $data
1772
     */
1773
    public function setPostFields($data) {
1774
        $this->postFields = $data;
1775
    }
1776
1777
    /**
1778
     * Get Content ready to be send as POST body
1779
     * @return string
1780
     */
1781
    public function getPostFields() {
1782
        return $this->postFields;
1783
    }
1784
1785
    /**
1786
     * Generuje fragment url pro filtrování.
1787
     *
1788
     * @see https://www.flexibee.eu/api/dokumentace/ref/filters
1789
     *
1790
     * @param array  $data   key=>values; value can bee class DatePeriod, DateTime or Array
1791
     * @param string $joiner default and/or
1792
     * @param string $defop  default operator
1793
     *
1794
     * @return string
1795
     */
1796
    public static function flexiUrl(array $data, $joiner = 'and', $defop = 'eq') {
1797
        $parts = [];
1798
1799
        foreach ($data as $column => $value) {
1800
            if (!is_numeric($column)) {
1801
                if (is_integer($data[$column]) || is_float($data[$column])) {
1802
                    $parts[$column] = $column . ' eq \'' . $data[$column] . '\'';
1803
                } elseif (is_bool($data[$column])) {
1804
                    $parts[$column] = $data[$column] ? $column . ' eq true' : $column . ' eq false';
1805
                } elseif (is_null($data[$column])) {
1806
                    $parts[$column] = $column . " is null";
1807
                } elseif (is_array($data[$column])) {
1808
                    $parts[$column] = $column . " in (" . implode(',',
1809
                                    array_map(function($a, $column) {
1810
                                        return $column == 'stitky' ? "'" . self::code($a) . "'" : "'$a'";
1811
                                    }, $data[$column],
1812
                                            array_fill(0, count($data[$column]), $column))) . ")";
1813
                } elseif (is_object($data[$column])) {
1814
                    switch (get_class($data[$column])) {
1815
                        case 'DatePeriod':
1816
                            $parts[$column] = $column . " between '" . $data[$column]->getStartDate()->format(self::$DateFormat) . "' '" . $data[$column]->getEndDate()->format(self::$DateFormat) . "'";
1817
                            break;
1818
                        case 'DateTime':
1819
                            $parts[$column] = $column . " eq '" . $data[$column]->format(self::$DateFormat) . "'";
1820
                            break;
1821
                        default:
1822
                            $parts[$column] = $column . " $defop '" . $data[$column] . "'";
1823
                            break;
1824
                    }
1825
                } else {
1826
                    switch ($value) {
1827
                        case '!null':
1828
                            $parts[$column] = $column . " is not null";
1829
                            break;
1830
                        case 'is empty':
1831
                        case 'is not empty':
1832
                        case 'is true':
1833
                        case 'is false':
1834
                            $parts[$column] = $column . ' ' . $value;
1835
                            break;
1836
                        default:
1837
                            $condParts = explode(' ', trim($value));
1838
                            switch ($condParts[0]) {
1839
                                case '<>':
1840
                                case '!=':
1841
                                case 'ne':
1842
                                case 'neq':
1843
                                case '<':
1844
                                case 'lt':
1845
                                case '<=':
1846
                                case 'lte':
1847
                                case '>':
1848
                                case 'gt':
1849
                                case '>=':
1850
                                case 'gte':
1851
                                case 'like':
1852
                                case 'begins':
1853
                                case 'between':
1854
                                case 'ends':
1855
                                    if (count($condParts) == 1) {
1856
                                        $parts[$column] = $column .= ' ' . $value;
1857
                                    } else {
1858
                                        $parts[$column] = $column .= ' ' . $condParts[0] . " '" . $condParts[1] . "'";
1859
                                    }
1860
                                    break;
1861
                                default:
1862
                                    if ($column == 'stitky') {
1863
                                        $parts[$column] = $column . "='" . self::code($data[$column]) . "'";
1864
                                    } else {
1865
                                        $parts[$column] = $column . " $defop '" . $data[$column] . "'";
1866
                                    }
1867
                                    break;
1868
                            }
1869
1870
                            break;
1871
                    }
1872
                }
1873
            } else {
1874
                $parts[] = $value;
1875
            }
1876
        }
1877
        return implode(' ' . $joiner . ' ', $parts);
1878
    }
1879
1880
    /**
1881
     * Obtain record/object numeric identificator id:
1882
     * Vrací číselný identifikátor objektu id:
1883
     *
1884
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1885
     *
1886
     * @return null|int indentifikátor záznamu reprezentovaného objektem
1887
     */
1888
    public function getRecordID() {
1889
        $id = $this->getDataValue('id');
1890
        return is_null($id) ? null : (is_numeric($id) ? intval($id) : $id);
1891
    }
1892
1893
    /**
1894
     * Obtain record/object identificator code:
1895
     * Vrací identifikátor objektu code:
1896
     *
1897
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1898
     *
1899
     * @return string record code identifier
1900
     */
1901
    public function getRecordCode() {
1902
        return empty($this->getDataValue('kod')) ? null : self::code($this->getDataValue('kod'));
1903
    }
1904
1905
    /**
1906
     * Obtain record/object identificator extId: code: or id:
1907
     * Vrací identifikátor objektu extId: code: nebo id:
1908
     *
1909
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1910
     *
1911
     * @return string|int|null record code identifier
1912
     */
1913
    public function getRecordIdent() {
1914
        $ident = $this->getExternalID();
1915
        if (empty($ident)) {
1916
            $ident = $this->getRecordCode();
1917
        }
1918
        if (empty($ident)) {
1919
            $ident = $this->getRecordID();
1920
        }
1921
        return $ident;
1922
    }
1923
1924
    /**
1925
     * Obtain record/object identificator code: or id:
1926
     * Vrací identifikátor objektu code: nebo id:
1927
     *
1928
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1929
     * 
1930
     * @return string indentifikátor záznamu reprezentovaného objektem
1931
     */
1932
    public function __toString() {
1933
        return strval($this->getRecordIdent());
1934
    }
1935
1936
    /**
1937
     * Gives you FlexiPeeHP class name for Given Evidence
1938
     *
1939
     * @param string $evidence
1940
     * 
1941
     * @return string Class name
1942
     */
1943
    public static function evidenceToClassName($evidence) {
1944
        return str_replace(' ', '', ucwords(str_replace('-', ' ', $evidence)));
1945
    }
1946
1947
    /**
1948
     * Obtain ID of first record in evidence
1949
     *
1950
     * @return string|null id or null if no records
1951
     */
1952
    public function getFirstRecordID() {
1953
        $firstID = null;
1954
        $keyColumn = $this->getKeyColumn();
1955
        $firstIdRaw = $this->getColumnsFromFlexibee([$keyColumn],
1956
                ['limit' => 1, 'order' => $keyColumn], $keyColumn);
1957
        if (!empty($firstIdRaw) && isset(current($firstIdRaw)[$keyColumn])) {
1958
            $firstID = current($firstIdRaw)[$keyColumn];
1959
        }
1960
        return is_numeric($firstID) ? intval($firstID) : $firstID;
1961
    }
1962
1963
    /**
1964
     * Get previous record ID
1965
     * 
1966
     * @param array $conditions optional
1967
     * 
1968
     * @return int|null
1969
     */
1970
    public function getNextRecordID($conditions = []) {
1971
        $conditions['order'] = 'id@D';
1972
        $conditions['limit'] = 1;
1973
        $conditions[] = 'id gt ' . $this->getRecordID();
1974
        $next = $this->getColumnsFromFlexibee(['id'], $conditions);
1975
        return (is_array($next) && array_key_exists(0, $next) && array_key_exists('id',
1976
                        $next[0])) ? intval($next[0]['id']) : null;
1977
    }
1978
1979
    /**
1980
     * Get next record ID
1981
     * 
1982
     * @param array $conditions optional
1983
     * 
1984
     * @return int|null
1985
     */
1986
    public function getPrevRecordID($conditions = []) {
1987
        $conditions['order'] = 'id@A';
1988
        $conditions['limit'] = 1;
1989
        $conditions[] = 'id lt ' . $this->getRecordID();
1990
        $prev = $this->getColumnsFromFlexibee(['id'], $conditions);
1991
        return (is_array($prev) && array_key_exists(0, $prev) && array_key_exists('id',
1992
                        $prev[0])) ? intval($prev[0]['id']) : null;
1993
    }
1994
1995
    /**
1996
     * Vrací hodnotu daného externího ID
1997
     *
1998
     * @param string $want Namespace Selector. If empty,you obtain the first one.
1999
     * 
2000
     * @return string|array one id or array if multiplete
2001
     */
2002
    public function getExternalID($want = null) {
2003
        $extid = null;
2004
        $ids = $this->getExternalIDs();
2005
        if (is_null($want)) {
2006
            if (!empty($ids)) {
2007
                $extid = current($ids);
2008
            }
2009
        } else {
2010
            if (!is_null($ids) && is_array($ids)) {
2011
                foreach ($ids as $id) {
2012
                    if (strstr($id, 'ext:' . $want)) {
2013
                        if (is_null($extid)) {
2014
                            $extid = str_replace('ext:' . $want . ':', '', $id);
2015
                        } else {
2016
                            if (is_array($extid)) {
2017
                                $extid[] = str_replace('ext:' . $want . ':', '', $id);
2018
                            } else {
2019
                                $extid = [$extid, str_replace('ext:' . $want . ':',
2020
                                            '', $id)];
2021
                            }
2022
                        }
2023
                    }
2024
                }
2025
            }
2026
        }
2027
        return $extid;
2028
    }
2029
2030
    /**
2031
     * gives you currently loaded extermal IDs
2032
     * 
2033
     * @return array
2034
     */
2035
    public function getExternalIDs() {
2036
        return $this->getDataValue('external-ids');
2037
    }
2038
2039
    /**
2040
     * Obtain actual GlobalVersion
2041
     * Vrací aktuální globální verzi změn
2042
     *
2043
     * @link https://www.flexibee.eu/api/dokumentace/ref/changes-api#globalVersion Globální Verze
2044
     * 
2045
     * @return int
2046
     */
2047
    public function getGlobalVersion() {
2048
        $this->getFlexiData(null, ['add-global-version' => 'true', 'limit' => 1]);
2049
2050
        return $this->globalVersion;
2051
    }
2052
2053
    /**
2054
     * Gives you current ApiURL with given format suffix
2055
     * 
2056
     * @param string $format json|html|xml|...
2057
     * 
2058
     * @return string API URL for current record or object/evidence
2059
     */
2060
    public function getApiURL($format = null) {
2061
        $apiUrl = str_replace(['.' . $this->format, '?limit=0'], '', $this->apiURL);
2062
        return $apiUrl . (empty($format) ? '' : '.' . $format );
2063
    }
2064
2065
    /**
2066
     * Obtain content type of last response
2067
     *
2068
     * @return string
2069
     */
2070
    public function getResponseFormat() {
2071
        return $this->responseFormat;
2072
    }
2073
2074
    /**
2075
     * Return the same response format for one and multiplete results
2076
     *
2077
     * @param array $responseBody
2078
     * 
2079
     * @return array
2080
     */
2081
    public function unifyResponseFormat($responseBody) {
2082
        if (!is_array($responseBody) || array_key_exists('message',
2083
                        $responseBody)) { //Unifi response format
2084
            $response = $responseBody;
2085
        } else {
2086
            $evidence = $this->getResponseEvidence();
2087
            if (array_key_exists($evidence, $responseBody)) {
2088
                $response = [];
2089
                $evidenceContent = $responseBody[$evidence];
2090
                if (array_key_exists(0, $evidenceContent)) {
2091
                    $response[$evidence] = $evidenceContent; //Multiplete Results
2092
                } else {
2093
                    $response[$evidence][0] = $evidenceContent; //One result
2094
                }
2095
            } else {
2096
                if (isset($responseBody['priloha'])) {
2097
                    $response = $responseBody['priloha'];
2098
                } else {
2099
                    if (array_key_exists('results', $responseBody)) {
2100
                        $response = $responseBody['results'];
2101
                    } else {
2102
                        $response = $responseBody;
2103
                    }
2104
                }
2105
            }
2106
        }
2107
        return $response;
2108
    }
2109
2110
    /**
2111
     * Obtain structure for current (or given) evidence
2112
     *
2113
     * @param string $evidence
2114
     * 
2115
     * @return array Evidence structure
2116
     */
2117
    public function getOfflineColumnsInfo($evidence = null) {
2118
        $columnsInfo = null;
2119
        $infoSource = self::$infoDir . '/Properties.' . (empty($evidence) ? $this->getEvidence() : $evidence) . '.json';
2120
        if (file_exists($infoSource)) {
2121
            $columnsInfo = json_decode(file_get_contents($infoSource), true);
2122
        }
2123
        return $columnsInfo;
2124
    }
2125
2126
    /**
2127
     * Obtain Current evidence Live structure
2128
     * 
2129
     * @param string $evidence
2130
     * 
2131
     * @return array structure
2132
     */
2133
    public function getOnlineColumnsInfo($evidence = null) {
2134
        $properties = [];
2135
        $evidence = is_null($evidence) ? $this->getEvidence() : $evidence;
2136
        $flexinfo = $this->performRequest('/c/' . $this->company . '/' . $evidence . '/properties.json');
2137
        if (!empty($flexinfo) && array_key_exists('properties', $flexinfo)) {
2138
            foreach ($flexinfo['properties']['property'] as $evidenceProperty) {
2139
                $key = $evidenceProperty['propertyName'];
2140
                $properties[$key] = $evidenceProperty;
2141
                if (array_key_exists('name', $evidenceProperty)) {
2142
                    $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...
2143
                }
2144
                $properties[$key]['type'] = $evidenceProperty['type'];
2145
                if (array_key_exists('url', $evidenceProperty)) {
2146
                    $properties[$key]['url'] = str_replace('?limit=0', '',
2147
                            $evidenceProperty['url']);
2148
                }
2149
            }
2150
        }
2151
        return $properties;
2152
    }
2153
2154
    /**
2155
     * Update evidence info from array or online from properties.json or offline
2156
     * 
2157
     * @param array  $columnsInfo
2158
     * @param string $evidence
2159
     */
2160
    public function updateColumnsInfo($columnsInfo = null, $evidence = null) {
2161
        $evidence = is_null($evidence) ? $this->getEvidence() : $evidence;
2162
        if (is_null($columnsInfo)) {
2163
            $this->columnsInfo[$evidence] = $this->offline ? $this->getOfflineColumnsInfo($evidence) : $this->getOnlineColumnsInfo($evidence);
2164
        } else {
2165
            $this->columnsInfo[$evidence] = $columnsInfo;
2166
        }
2167
    }
2168
2169
    /**
2170
     * Gives you evidence structure. You can obtain current online by pre-calling:
2171
     * $this->updateColumnsInfo($evidence, $this->getOnlineColumnsInfo($evidence));
2172
     * 
2173
     * @param string $evidence
2174
     * 
2175
     * @return array
2176
     */
2177
    public function getColumnsInfo($evidence = null) {
2178
        $evidence = is_null($evidence) ? $this->getEvidence() : $evidence;
2179
        if (!array_key_exists($evidence, $this->columnsInfo)) {
2180
            $this->updateColumnsInfo($this->getOfflineColumnsInfo($evidence),
2181
                    $evidence);
2182
        }
2183
        return $this->columnsInfo[$evidence];
2184
    }
2185
2186
    /**
2187
     * Gives you properties for (current) evidence column
2188
     *
2189
     * @param string $column    name of column
2190
     * @param string $evidence  evidence name if different
2191
     *
2192
     * @return array column properties or null if column not exits
2193
     */
2194
    public function getColumnInfo($column, $evidence = null) {
2195
        $columnsInfo = $this->getColumnsInfo(empty($evidence) ? $this->getEvidence() : $evidence);
2196
        return (empty($column) || empty($columnsInfo) || !is_array($columnsInfo)) ? null : (array_key_exists($column, $columnsInfo) ? $columnsInfo[$column] : null);
2197
    }
2198
2199
    /**
2200
     * Obtain actions for current (or given) evidence
2201
     *
2202
     * @param string $evidence
2203
     * 
2204
     * @return array Evidence structure
2205
     */
2206
    public function getActionsInfo($evidence = null) {
2207
        $actionsInfo = null;
2208
        if (is_null($evidence)) {
2209
            $evidence = $this->getEvidence();
2210
        }
2211
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
2212
        if (isset(\FlexiPeeHP\Actions::$$propsName)) {
2213
            $actionsInfo = Actions::$$propsName;
2214
        }
2215
        return $actionsInfo;
2216
    }
2217
2218
    /**
2219
     * Obtain relations for current (or given) evidence
2220
     *
2221
     * @param string $evidence
2222
     * 
2223
     * @return array Evidence structure
2224
     */
2225
    public function getRelationsInfo($evidence = null) {
2226
        $relationsInfo = null;
2227
        if (is_null($evidence)) {
2228
            $evidence = $this->getEvidence();
2229
        }
2230
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
2231
        if (isset(\FlexiPeeHP\Relations::$$propsName)) {
2232
            $relationsInfo = Relations::$$propsName;
2233
        }
2234
        return $relationsInfo;
2235
    }
2236
2237
    /**
2238
     * Obtain info for current (or given) evidence
2239
     *
2240
     * @param string $evidence
2241
     * 
2242
     * @return array Evidence info
2243
     */
2244
    public function getEvidenceInfo($evidence = null) {
2245
        $evidencesInfo = null;
2246
        if (is_null($evidence)) {
2247
            $evidence = $this->getEvidence();
2248
        }
2249
        if (isset(EvidenceList::$evidences[$evidence])) {
2250
            $evidencesInfo = EvidenceList::$evidences[$evidence];
2251
            $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
2252
            if (isset(Formats::$$propsName)) {
2253
                $evidencesInfo['formats'] = Formats::$$propsName;
2254
            }
2255
        }
2256
        return $evidencesInfo;
2257
    }
2258
2259
    /**
2260
     * Obtain name for current (or given) evidence path
2261
     *
2262
     * @param string $evidence Evidence Path
2263
     * 
2264
     * @return array Evidence info
2265
     */
2266
    public function getEvidenceName($evidence = null) {
2267
        $evidenceName = null;
2268
        if (is_null($evidence)) {
2269
            $evidence = $this->getEvidence();
2270
        }
2271
        if (isset(EvidenceList::$name[$evidence])) {
2272
            $evidenceName = EvidenceList::$name[$evidence];
2273
        }
2274
        return $evidenceName;
2275
    }
2276
2277
    /**
2278
     * Save current object to file
2279
     *
2280
     * @param string $destfile path to file
2281
     */
2282
    public function saveResponseToFile($destfile) {
2283
        if (strlen($this->lastCurlResponse)) {
2284
            $this->doCurlRequest($this->apiURL, 'GET', $this->format);
2285
        }
2286
        file_put_contents($destfile, $this->lastCurlResponse);
2287
    }
2288
2289
    /**
2290
     * Obtain established relations listing
2291
     *
2292
     * @return array Null or Relations
2293
     */
2294
    public function getVazby($id = null) {
2295
        if (is_null($id)) {
2296
            $id = $this->getRecordID();
2297
        }
2298
        if (!empty($id)) {
2299
            $vazbyRaw = $this->getColumnsFromFlexibee(['vazby'],
2300
                    ['relations' => 'vazby', 'id' => $id]);
2301
            $vazby = array_key_exists('vazby', $vazbyRaw[0]) ? $vazbyRaw[0]['vazby'] : null;
2302
        } else {
2303
            throw new \Exception(_('ID requied to get record relations '));
2304
        }
2305
        return $vazby;
2306
    }
2307
2308
    /**
2309
     * Gives You URL for Current Record in FlexiBee web interface
2310
     *
2311
     * @return string url
2312
     */
2313
    public function getFlexiBeeURL() {
2314
        $parsed_url = parse_url(str_replace('.' . $this->format, '', $this->apiURL));
2315
        $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
2316
        $host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
2317
        $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
2318
        $user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
2319
        $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
2320
        $pass = ($user || $pass) ? "$pass@" : '';
2321
        $path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
2322
        return $scheme . $user . $pass . $host . $port . $path;
2323
    }
2324
2325
    /**
2326
     * Set Record Key
2327
     *
2328
     * @param int|string $myKeyValue
2329
     * 
2330
     * @return boolean
2331
     */
2332
    public function setMyKey($myKeyValue) {
2333
        if (substr($myKeyValue, 0, 4) == 'ext:') {
2334
            if (empty($this->evidenceInfo) || ($this->evidenceInfo['extIdSupported'] == 'false')) {
2335
                $this->addStatusMessage(sprintf(_('Evidence %s does not support extIDs'),
2336
                                $this->getEvidence()), 'warning');
2337
                $res = false;
2338
            } else {
2339
                $extIds = $this->getDataValue('external-ids');
2340
                if (!empty($extIds) && count($extIds)) {
2341
                    $extIds = array_combine($extIds, $extIds);
2342
                }
2343
2344
                $extIds[$myKeyValue] = $myKeyValue;
2345
                $res = $this->setDataValue('external-ids',
2346
                        $extIds);
2347
            }
2348
        } else {
2349
            $res = $this->setDataValue($this->getKeyColumn(), $myKeyValue);
2350
        }
2351
        $this->updateApiURL();
2352
        return $res;
2353
    }
2354
2355
    /**
2356
     * Set or get ignore not found pages flag
2357
     *
2358
     * @param boolean $ignore set flag to
2359
     *
2360
     * @return boolean get flag state
2361
     */
2362
    public function ignore404($ignore = null) {
2363
        if (!is_null($ignore)) {
2364
            $this->ignoreNotFound = $ignore;
2365
        }
2366
        return $this->ignoreNotFound;
2367
    }
2368
2369
    /**
2370
     * Send Document by mail
2371
     *
2372
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
2373
     *
2374
     * @param string $to         Email ecipient
2375
     * @param string $subject    Email Subject
2376
     * @param string $body       Email Text
2377
     *
2378
     * @return boolean mail sent status
2379
     */
2380
    public function sendByMail($to, $subject, $body, $cc = null) {
2381
        $this->setPostFields($body);
2382
2383
        $this->performRequest(rawurlencode($this->getRecordID()) . '/odeslani-dokladu?to=' . $to . '&subject=' . urlencode($subject) . '&cc=' . $cc
2384
                , 'PUT', 'xml');
2385
2386
        return $this->lastResponseCode == 200;
2387
    }
2388
2389
    /**
2390
     * FlexiBee date to PHP DateTime conversion
2391
     *
2392
     * @param string $flexidate 2017-05-26 or 2017-05-26+02:00
2393
     *
2394
     * @return \DateTime | false
2395
     */
2396
    public static function flexiDateToDateTime($flexidate) {
2397
        return \DateTime::createFromFormat(strstr($flexidate, '+') ? self::$DateFormat . 'O' : self::$DateFormat, $flexidate)->setTime(0, 0);
2398
    }
2399
2400
    /**
2401
     * FlexiBee dateTime to PHP DateTime conversion
2402
     *
2403
     * @param string $flexidatetime 2017-09-26T10:00:53.755+02:00 or older 2017-05-19T00:00:00+02:00
2404
     *
2405
     * @return \DateTime | false
2406
     */
2407
    public static function flexiDateTimeToDateTime($flexidatetime) {
2408
        if (strchr($flexidatetime, '.')) { //NewFormat
2409
            $format = self::$DateTimeFormat;
2410
        } else { // Old format
2411
            $format = 'Y-m-d\TH:i:s+P';
2412
        }
2413
        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 2413 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...
2414
    }
2415
2416
    /**
2417
     * Získá dokument v daném formátu
2418
     * Obtain document in given format
2419
     *
2420
     * @link https://www.flexibee.eu/api/dokumentace/ref/pdf/ PDF Exports
2421
     *
2422
     * @param string  $format     pdf/csv/xml/json/ ...
2423
     * @param string  $reportName Template used to generate PDF
2424
     * @param string  $lang       cs|sk|en|de Template language used to generate PDF
2425
     * @param boolean $sign       sign resulting PDF by certificate ?
2426
     *
2427
     * @return string|null filename downloaded or none
2428
     */
2429
    public function getInFormat($format, $reportName = null, $lang = null,
2430
            $sign = false) {
2431
        $response = null;
2432
        if ($this->setFormat($format)) {
2433
            $urlParams = [];
2434
            switch ($format) {
2435
                case 'pdf':
2436
                    switch ($lang) {
2437
                        case 'cs':
2438
                        case 'sk':
2439
                        case 'en':
2440
                        case 'de':
2441
                            $urlParams['report-lang'] = $lang;
2442
                            break;
2443
                        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...
2444
                        case '':
2445
                            break;
2446
                        default:
2447
                            throw new \Ease\Exception('Unknown language ' . $lang . ' for PDF export');
2448
                            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...
2449
                    }
2450
                    if (boolval($sign) === true) {
2451
                        $urlParams['report-sign'] = 'true';
2452
                    }
2453
                    break;
2454
                case 'html':
2455
                    $urlParams['inDesktopApp'] = 'true';
2456
                    break;
2457
            }
2458
            if (!empty($reportName)) {
2459
                $urlParams['report-name'] = $reportName;
2460
            }
2461
            if (($this->doCurlRequest(\Ease\Functions::addUrlParams($this->apiURL,
2462
                                    $urlParams), 'GET') == 200)) {
2463
                $response = $this->lastCurlResponse;
2464
            }
2465
        }
2466
        return $response;
2467
    }
2468
2469
    /**
2470
     * Uloží dokument v daném formátu do složky v systému souborů
2471
     * Save document in given format to directory in filesystem
2472
     *
2473
     * @param string $format  pdf/csv/xml/json/ ...
2474
     * @param string $destDir where to put file (prefix)
2475
     * @param string $reportName Template used to generate PDF
2476
     *
2477
     * @return string|null filename downloaded or none
2478
     */
2479
    public function downloadInFormat($format, $destDir = './',
2480
            $reportName = null) {
2481
        $fileOnDisk = null;
2482
        $formatBackup = $this->format;
2483
        if ($this->setFormat($format)) {
2484
            $downloadTo = $destDir . $this->getEvidence() . '_' . $this->getMyKey() . '.' . $format;
2485
            if (($this->doCurlRequest(empty($reportName) ? $this->apiURL : \Ease\Functions::addUrlParams($this->apiURL,
2486
                                            ['report-name' => $reportName]), 'GET') == 200) && (file_put_contents($downloadTo,
2487
                            $this->lastCurlResponse) !== false)) {
2488
                $fileOnDisk = $downloadTo;
2489
            }
2490
            $this->setFormat($formatBackup);
2491
        }
2492
        return $fileOnDisk;
2493
    }
2494
2495
    /**
2496
     * Take data for object. separate external IDs
2497
     *
2498
     * @param array $data Data to keep
2499
     * 
2500
     * @return int number of records taken
2501
     */
2502
    public function takeData($data) {
2503
        $keyColumn = $this->getKeyColumn();
2504
        if (array_key_exists($keyColumn, $data) && is_array($data[$keyColumn])) {
2505
            foreach ($data[$keyColumn] as $recPos => $recordKey) {
2506
                if (substr($recordKey, 0, 4) == 'ext:') {
2507
                    $data['external-ids'][] = $recordKey;
2508
                    unset($data[$keyColumn][$recPos]);
2509
                }
2510
            }
2511
            if (count($data[$keyColumn]) == 1) {
2512
                $data[$keyColumn] = current($data[$keyColumn]);
2513
            }
2514
        }
2515
        $result = parent::takeData($data);
2516
2517
        if (array_key_exists($keyColumn, $data) || array_key_exists('kod', $data)) {
2518
            $this->updateApiURL();
2519
        }
2520
2521
        return $result;
2522
    }
2523
2524
    /**
2525
     * Get Current Evidence reports listing
2526
     * 
2527
     * @link https://www.flexibee.eu/api/dokumentace/casto-kladene-dotazy-pro-api/vyber-reportu-do-pdf/ Výběr reportu do PDF
2528
     * 
2529
     * @return array
2530
     */
2531
    public function getReportsInfo() {
2532
        $reports = [];
2533
        $reportsRaw = $this->getFlexiData($this->getEvidenceURL() . '/reports');
2534
        if (!empty($reportsRaw) && array_key_exists('reports', $reportsRaw) && !empty($reportsRaw['reports']) && array_key_exists('report', $reportsRaw['reports']) &&
2535
                !empty($reportsRaw['reports']['report'])) {
2536
            if (\Ease\jQuery\Part::isAssoc($reportsRaw['reports']['report'])) {
2537
                $reports = [$reportsRaw['reports']['report']['reportId'] => $reportsRaw['reports']['report']];
2538
            } else {
2539
                $reports = \Ease\Functions::reindexArrayBy($reportsRaw['reports']['report'],
2540
                                'reportId');
2541
            }
2542
        }
2543
        return $reports;
2544
    }
2545
2546
    /**
2547
     * Request authSessionId from current server
2548
     * 
2549
     * @link https://www.flexibee.eu/api/dokumentace/ref/login/ description
2550
     * 
2551
     * @param string $username
2552
     * @param string $password
2553
     * @param string $otp       optional onetime password
2554
     * 
2555
     * @return string authUserId or null in case of problems
2556
     */
2557
    public function requestAuthSessionID($username, $password, $otp = null) {
2558
        $this->postFields = http_build_query(is_null($otp) ? ['username' => $username,
2559
            'password' => $password] : ['username' => $username, 'password' => $password,
2560
            'otp' => $otp]);
2561
        $response = $this->performRequest('/login-logout/login', 'POST',
2562
                'json');
2563
        if (array_key_exists('refreshToken', $response)) {
2564
            $this->refreshToken = $response['refreshToken'];
2565
        } else {
2566
            $this->refreshToken = null;
2567
        }
2568
        return array_key_exists('authSessionId', $response) ? $response['authSessionId'] : null;
2569
    }
2570
2571
    /**
2572
     * Try to Sign in current user to FlexiBee and keep authSessionId
2573
     * 
2574
     * @return boolean sign in success
2575
     */
2576
    public function login() {
2577
        $this->authSessionId = $this->requestAuthSessionID($this->user,
2578
                $this->password);
2579
        return $this->lastResponseCode == 200;
2580
    }
2581
2582
    /**
2583
     * End (current's user) session
2584
     * 
2585
     * 
2586
     * @link https://www.flexibee.eu/api/dokumentace/ref/logout Logout Reference
2587
     * 
2588
     * @param string $username force username to sign off
2589
     * 
2590
     * @return array server response
2591
     */
2592
    public function logout($username = null) {
2593
        return $this->performRequest('/status/user/' . (is_null($username) ? $this->user : $username) . '/logout', 'POST');
2594
    }
2595
2596
    /**
2597
     * Compile and send Report about Error500 to FlexiBee developers
2598
     * If FlexiBee is running on localost try also include java backtrace
2599
     *
2600
     * @param array $errorResponse result of parseError();
2601
     */
2602
    public function error500Reporter($errorResponse) {
2603
        $ur = str_replace('/c/' . $this->company, '',
2604
                str_replace($this->url, '', $this->curlInfo['url']));
2605
        if (!array_key_exists($ur, $this->reports)) {
2606
            $tmpdir = sys_get_temp_dir();
2607
            $myTime = $this->curlInfo['when'];
2608
            $curlname = $tmpdir . '/curl-' . $this->evidence . '-' . $myTime . '.json';
2609
            file_put_contents($curlname,
2610
                    json_encode($this->curlInfo, JSON_PRETTY_PRINT));
2611
2612
            $report = new \Ease\Mailer($this->reportRecipient,
2613
                    'Error report 500 - ' . $ur);
2614
2615
            $d = dir($tmpdir);
2616
            while (false !== ($entry = $d->read())) {
2617
                if (strstr($entry, $myTime)) {
2618
                    $ext = pathinfo($tmpdir . '/' . $entry, PATHINFO_EXTENSION);
2619
                    $mime = Formats::suffixToContentType($ext);
2620
                    $report->addFile($tmpdir . '/' . $entry,
2621
                            empty($mime) ? 'text/plain' : $mime);
2622
                }
2623
            }
2624
            $d->close();
2625
2626
            if ((strstr($this->url, '://localhost') || strstr($this->url,
2627
                            '://127.')) && file_exists('/var/log/flexibee.log')) {
2628
2629
                $fl = fopen('/var/log/' . 'flexibee.log', 'r');
2630
                if ($fl) {
2631
                    $tracelog = [];
2632
                    for ($x_pos = 0, $ln = 0, $output = array(); fseek($fl,
2633
                                    $x_pos, SEEK_END) !== -1; $x_pos--) {
2634
                        $char = fgetc($fl);
2635
                        if ($char === "\n") {
2636
                            $tracelog[] = $output[$ln];
2637
                            if (strstr($output[$ln], $errorResponse['message'])) {
2638
                                break;
2639
                            }
2640
                            $ln++;
2641
                            continue;
2642
                        }
2643
                        $output[$ln] = $char . ((array_key_exists($ln, $output)) ? $output[$ln] : '');
2644
                    }
2645
2646
                    $trace = implode("\n", array_reverse($tracelog));
2647
                    $tracefile = $tmpdir . '/trace-' . $this->evidence . '-' . $myTime . '.log';
2648
                    file_put_contents($tracefile, $trace);
2649
                    $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...
2650
                    fclose($fl);
2651
                }
2652
            } else {
2653
                $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...
2654
            }
2655
2656
            $licenseInfo = $this->performRequest($this->url . '/default-license.json');
2657
2658
            $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...
2659
                            JSON_PRETTY_PRINT));
2660
2661
            if ($report->send()) {
2662
                $this->reports[$ur] = $myTime;
2663
            }
2664
        }
2665
    }
2666
2667
    /**
2668
     * Returns code:CODE
2669
     *
2670
     * @param string $code
2671
     *
2672
     * @return string
2673
     */
2674
    public static function code($code) {
2675
        return ((substr($code, 0, 4) == 'ext:') ? $code : 'code:' . strtoupper(self::uncode($code)));
2676
    }
2677
2678
    /**
2679
     * Returns CODE without code: prefix
2680
     *
2681
     * @param string $code
2682
     *
2683
     * @return string
2684
     */
2685
    public static function uncode($code) {
2686
        return str_replace(['code:', 'code%3A'], '', $code);
2687
    }
2688
2689
    /**
2690
     * Remove all @ items from array
2691
     *
2692
     * @param array $data original data
2693
     *
2694
     * @return array data without @ columns
2695
     */
2696
    public static function arrayCleanUP($data) {
2697
        return array_filter(
2698
                $data,
2699
                function ($key) {
2700
            return !strchr($key, '@');
2701
        }, ARRAY_FILTER_USE_KEY);
2702
    }
2703
2704
    /**
2705
     * Add Info about used user, server and libraries
2706
     *
2707
     * @param string $prefix banner prefix text
2708
     * @param string $suffix banner suffix text
2709
     */
2710
    public function logBanner($prefix = null, $suffix = null) {
2711
        parent::logBanner($prefix,
2712
                ' FlexiBee ' . str_replace('://', '://' . $this->user . '@',
2713
                        $this->getApiUrl()) . ' FlexiBeeHP v' . self::$libVersion . ' (FlexiBee ' . EvidenceList::$version . ') EasePHP Framework v' . \Ease\Atom::$frameworkVersion . ' ' .
2714
                $suffix
2715
        );
2716
    }
2717
2718
    /**
2719
     * Get Last operation type
2720
     * 
2721
     * @return string create|read|update|delete or update,insert for some inserted and updated in one transaction
2722
     */
2723
    public function getLastOperationType() {
2724
        return implode(',', array_keys(array_filter($this->responseStats)));
2725
    }
2726
2727
    /**
2728
     * Last operation errors 
2729
     * 
2730
     * @return array FlexiBee error meassages
2731
     */
2732
    public function getErrors() {
2733
        return $this->errors;
2734
    }
2735
2736
    /**
2737
     * Reconnect After unserialization
2738
     */
2739
    public function __wakeup() {
2740
        $this->curlInit();
2741
    }
2742
2743
}
2744