Passed
Push — master ( 6d8a3f...ef71b6 )
by Vítězslav
03:10
created

FlexiBeeRO   F

Complexity

Total Complexity 360

Size/Duplication

Total Lines 2359
Duplicated Lines 0 %

Test Coverage

Coverage 68.69%

Importance

Changes 0
Metric Value
wmc 360
dl 0
loc 2359
c 0
b 0
f 0
rs 0.6314
ccs 621
cts 904
cp 0.6869

86 Methods

Rating   Name   Duplication   Size   Complexity  
A getVazby() 0 14 4
A __wakeup() 0 4 1
B setEvidence() 0 24 4
A getColumnInfo() 0 6 4
A updateApiURL() 0 8 2
A saveDebugFiles() 0 8 1
D getDataForJSON() 0 42 10
A disconnect() 0 6 2
C doCurlRequest() 0 50 10
A urlEncode() 0 3 1
B setPrefix() 0 19 11
A setFilter() 0 3 2
B processInit() 0 11 5
C getColumnsFromFlexibee() 0 38 11
A getFirstRecordID() 0 10 4
A rawXmlToArray() 0 3 1
B loadFromFlexiBee() 0 20 7
A uncode() 0 3 1
B objectToID() 0 17 5
A getResponseEvidence() 0 14 3
C unifyResponseFormat() 0 28 7
B xml2array() 0 19 6
A idExists() 0 14 2
A addDefaultUrlParams() 0 3 1
A evidenceToClassName() 0 3 1
A ignore404() 0 6 2
C getFlexiBeeURL() 0 12 9
A sendUnsent() 0 4 1
A getEvidenceName() 0 10 3
B recordExists() 0 20 9
D parseResponse() 0 42 15
C error500Reporter() 0 63 14
A getRecordCode() 0 3 2
B downloadInFormat() 0 15 5
A rawJsonToArray() 0 13 3
A setAction() 0 10 3
A getRelationsInfo() 0 11 3
A flexiDateToDateTime() 0 4 1
A sendByMail() 0 8 1
A setCompany() 0 3 1
C logResult() 0 48 15
A dateToFlexiDateTime() 0 3 1
B getInFormat() 0 17 5
A __toString() 0 3 1
A getAllFromFlexibee() 0 13 3
A saveResponseToFile() 0 6 2
D getKod() 0 53 13
A __construct() 0 9 2
A __destruct() 0 3 1
A getFlexiRow() 0 9 2
A performRequest() 0 19 4
A getConnectionOptions() 0 17 4
B setupProperty() 0 7 5
A getPostFields() 0 3 1
B evidenceUrlWithSuffix() 0 11 5
A flexiDateTimeToDateTime() 0 8 2
C flexiUrl() 0 35 12
A extractUrlParams() 0 5 3
A arrayCleanUP() 0 7 1
B parseError() 0 17 5
A curlInit() 0 19 4
A logBanner() 0 5 1
D getExternalID() 0 27 9
A getResponseFormat() 0 8 2
A getRecordID() 0 4 3
C getFlexiData() 0 52 16
A getRecordIdent() 0 10 3
A getGlobalVersion() 0 5 1
A getColumnsInfo() 0 9 3
A setMyKey() 0 14 3
A dateToFlexiDate() 0 3 1
A code() 0 3 1
B setFormat() 0 14 6
C setUp() 0 32 7
A getCompany() 0 3 1
A getJsonizedData() 0 12 2
B rawResponseToArray() 0 18 5
A join() 0 10 2
A getEvidence() 0 3 1
A getActionsInfo() 0 11 3
A setPostFields() 0 3 1
A getApiURL() 0 4 2
B object2array() 0 19 6
A getEvidenceURL() 0 8 2
A getEvidenceInfo() 0 14 4
B setDataValue() 0 25 6

How to fix   Complexity   

Complex Class

Complex classes like FlexiBeeRO often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FlexiBeeRO, and based on these observations, apply Extract Interface, too.

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

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

523
            $this->takeData($this->getFlexiData((($init[0] != '/') ? $this->/** @scrutinizer ignore-call */ getEvidenceURL($init)

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

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

Loading history...
524
                            : $init)));
525
        } else {
526 69
            $this->loadFromFlexiBee($init);
527
        }
528 69
    }
529
530
    /**
531
     * Set Data Field value
532
     *
533
     * @param string $columnName field name
534
     * @param mixed  $value      field data value
535
     *
536
     * @return bool Success
537 23
     */
538
    public function setDataValue($columnName, $value)
539 23
    {
540 23
        switch ($columnName) {
541
            case 'kod':
542
                $value = self::uncode($value); //Alwyas uncode "kod" column
543
                break;
544
            default:
545
                break;
546
        }
547
        if (is_object($value)) {
548 23
            switch (get_class($value)) {
549
                case 'DateTime':
550 23
                    $columnInfo = $this->getColumnInfo($columnName);
551
                    switch ($columnInfo['type']) {
552
                        case 'date':
553
                            $value = self::dateToFlexiDate($value);
554
                            break;
555
                        case 'datetime':
556
                            $value = self::dateToFlexiDateTime($value);
557
                            break;
558 25
                    }
559
                    break;
560 25
            }
561 25
        }
562
        return parent::setDataValue($columnName, $value);
563
    }
564 25
565 1
    /**
566 1
     * PHP Date object to FlexiBee date format
567 24
     * 
568 24
     * @param \DateTime $date
569 24
     */
570 25
    public static function dateToFlexiDate($date)
571 25
    {
572
        return $date->format(self::$DateFormat);
573
    }
574
575
    /**
576
     * PHP Date object to FlexiBee date format
577
     * 
578
     * @param \DateTime $dateTime
579
     */
580
    public static function dateToFlexiDateTime($dateTime)
581 23
    {
582
        return $dateTime->format(self::$DateTimeFormat);
583 23
    }
584 23
585 23
    /**
586 23
     * Set URL prefix
587 23
     *
588 23
     * @param string $prefix
589 23
     */
590 23
    public function setPrefix($prefix)
591 23
    {
592 23
        switch ($prefix) {
593 23
            case 'a': //Access
594 23
            case 'c': //Company
595 23
            case 'u': //User
596
            case 'g': //License Groups
597
            case 'admin':
598
            case 'status':
599 23
            case 'login-logout':
600
                $this->prefix = '/'.$prefix.'/';
601
                break;
602
            case null:
603
            case '':
604
            case '/':
605
                $this->prefix = '';
606
                break;
607
            default:
608
                throw new \Exception(sprintf('Unknown prefix %s', $prefix));
609 23
        }
610
    }
611 23
612 23
    /**
613 22
     * Set communication format.
614 22
     * One of html|xml|json|csv|dbf|xls|isdoc|isdocx|edi|pdf|pdf|vcf|ical
615 23
     *
616 17
     * @param string $format
617 17
     * 
618 17
     * @return boolen format is availble
0 ignored issues
show
Bug introduced by
The type FlexiPeeHP\boolen was not found. Maybe you did not declare it correctly or list all dependencies?

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

filter:
    dependency_paths: ["lib/*"]

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

Loading history...
619 17
     */
620 23
    public function setFormat($format)
621
    {
622
        $result = true;
623
        if (($this->debug === true) && !empty($this->evidence) && isset(Formats::$$this->evidence)) {
624 23
            if (array_key_exists($format, array_flip(Formats::$$this->evidence))
625
                === false) {
626
                $result = false;
627
            }
628
        }
629
        if ($result === true) {
630
            $this->format = $format;
631
            $this->updateApiURL();
632
        }
633
        return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result returns the type boolean which is incompatible with the documented return type FlexiPeeHP\boolen.
Loading history...
634 68
    }
635
636 68
    /**
637 68
     * Nastaví Evidenci pro Komunikaci.
638 68
     * Set evidence for communication
639 62
     *
640 62
     * @param string $evidence evidence pathName to use
641 68
     * 
642
     * @return boolean evidence switching status
643
     */
644
    public function setEvidence($evidence)
645
    {
646
        switch ($this->prefix) {
647
            case '/c/':
648
                if ($this->debug === true) {
649
                    if (array_key_exists($evidence, EvidenceList::$name)) {
650
                        $this->evidence = $evidence;
651 23
                        $result         = true;
652
                    } else {
653 23
                        throw new \Exception(sprintf('Try to set unsupported evidence %s',
654 23
                                $evidence));
655 23
                    }
656 23
                } else {
657 23
                    $this->evidence = $evidence;
658 23
                    $result         = true;
659 23
                }
660 23
                break;
661 23
            default:
662
                $this->evidence = $evidence;
663
                $result         = true;
664
                break;
665
        }
666
        $this->updateApiURL();
667 48
        return $result;
668
    }
669 48
670 48
    /**
671 48
     * Vrací právě používanou evidenci pro komunikaci
672
     * Obtain current used evidence
673
     *
674 48
     * @return string
675 48
     */
676
    public function getEvidence()
677
    {
678
        return $this->evidence;
679
    }
680
681
    /**
682
     * Set used company.
683
     * Nastaví Firmu.
684
     *
685
     * @param string $company
686 23
     */
687
    public function setCompany($company)
688 23
    {
689 23
        $this->company = $company;
690 23
    }
691 23
692 23
    /**
693 23
     * Obtain company now used
694 23
     * Vrací právě používanou firmu
695 23
     *
696 23
     * @return string
697 23
     */
698 23
    public function getCompany()
699 23
    {
700 23
        return $this->company;
701
    }
702
703 23
    /**
704 23
     * Vrací název evidence použité v odpovědích z FlexiBee
705 23
     *
706
     * @return string
707
     */
708 23
    public function getResponseEvidence()
709
    {
710
        switch ($this->evidence) {
711
            case 'c':
712
                $evidence = 'company';
713
                break;
714
            case 'evidence-list':
715
                $evidence = 'evidence';
716
                break;
717
            default:
718 23
                $evidence = $this->getEvidence();
719
                break;
720 23
        }
721
        return $evidence;
722
    }
723
724
    /**
725
     * Převede rekurzivně Objekt na pole.
726
     *
727
     * @param object|array $object
728
     *
729
     * @return array
730
     */
731 25
    public static function object2array($object)
732
    {
733
        $result = null;
734 25
        if (is_object($object)) {
735
            $objectData = get_object_vars($object);
736 25
            if (is_array($objectData) && count($objectData)) {
737
                $result = array_map('self::object2array', $objectData);
738 25
            }
739 4
        } else {
740 4
            if (is_array($object)) {
0 ignored issues
show
introduced by
The condition is_array($object) is always true.
Loading history...
741 22
                foreach ($object as $item => $value) {
742
                    $result[$item] = self::object2array($value);
743
                }
744 25
            } else {
745
                $result = $object;
746 25
            }
747 25
        }
748
749
        return $result;
750
    }
751
752
    /**
753
     * Převede rekurzivně v poli všechny objekty na jejich identifikátory.
754
     *
755
     * @param object|array $object
756
     *
757
     * @return array
758 3
     */
759
    public static function objectToID($object)
760 3
    {
761
        $resultID = null;
762 3
        if (is_object($object) && method_exists($object, '__toString')
763 3
        ) {
764 3
            $resultID = $object->__toString();
765
        } else {
766
            if (is_array($object)) {
767
                foreach ($object as $item => $value) {
768
                    $resultID[$item] = self::objectToID($value);
769
                }
770
            } else { //String
771
                $resultID = $object;
772
            }
773 3
        }
774
775 3
        return $resultID;
776
    }
777
778
    /**
779
     * Return basic URL for used Evidence
780
     *
781
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
782
     *
783
     * @return string Evidence URL
784
     */
785 3
    public function getEvidenceURL()
786
    {
787 3
        $evidenceUrl = $this->url.$this->prefix.$this->company;
788 3
        $evidence    = $this->getEvidence();
789 3
        if (!empty($evidence)) {
790 3
            $evidenceUrl .= '/'.$evidence;
791
        }
792
        return $evidenceUrl;
793 3
    }
794
795
    /**
796
     * Add suffix to Evidence URL
797 3
     *
798
     * @param string $urlSuffix
799
     *
800
     * @return string
801
     */
802
    public function evidenceUrlWithSuffix($urlSuffix)
803
    {
804
        $evidenceUrl = $this->getEvidenceUrl();
805
        if (!empty($urlSuffix)) {
806
            if (($urlSuffix[0] != '/') && ($urlSuffix[0] != ';') && ($urlSuffix[0]
807
                != '?')) {
808
                $evidenceUrl .= '/';
809
            }
810
            $evidenceUrl .= $urlSuffix;
811
        }
812
        return $evidenceUrl;
813
    }
814
815
    /**
816
     * Update $this->apiURL
817
     */
818
    public function updateApiURL()
819
    {
820 3
        $this->apiURL = $this->getEvidenceURL();
821
        $id           = $this->__toString();
822 3
        if (!empty($id)) {
823
            $this->apiURL .= '/'.self::urlEncode($id);
824 3
        }
825
        $this->apiURL .= '.'.$this->format;
826
    }
827
828
    /**;
829
     * Add Default Url params to given url if not overrided
830
     *
831
     * @param string $urlRaw
832 3
     *
833 3
     * @return string url with default params added
834 3
     */
835
    public function addDefaultUrlParams($urlRaw)
836
    {
837 3
        return \Ease\Shared::addUrlParams($urlRaw, $this->defaultUrlParams, false);
838
    }
839
840 3
    /**
841
     * Funkce, která provede I/O operaci a vyhodnotí výsledek.
842
     *
843
     * @param string $urlSuffix část URL za identifikátorem firmy.
844
     * @param string $method    HTTP/REST metoda
845
     * @param string $format    Requested format
846
     * 
847
     * @return array|boolean Výsledek operace
848
     */
849
    public function performRequest($urlSuffix = null, $method = 'GET',
850
                                   $format = null)
851
    {
852
        $this->rowCount      = null;
853
        $this->responseStats = [];
854
855
        if (preg_match('/^http/', $urlSuffix)) {
856
            $url = $urlSuffix;
857
        } elseif (strlen($urlSuffix) && ($urlSuffix[0] == '/')) {
858
            $url = $this->url.$urlSuffix;
859
        } else {
860 3
            $url = $this->evidenceUrlWithSuffix($urlSuffix);
861
        }
862
863
        $responseCode = $this->doCurlRequest($this->addDefaultUrlParams($url),
864
            $method, $format);
865
866
        return $this->parseResponse($this->rawResponseToArray($this->lastCurlResponse,
867
                    $this->responseFormat), $responseCode);
868
    }
869
870
    /**
871
     * Parse Raw FlexiBee response in several formats
872
     *
873
     * @param string $responseRaw raw response body
874
     * @param string $format      Raw Response format json|xml|etc
875
     *
876
     * @return array
877
     */
878
    public function rawResponseToArray($responseRaw, $format)
879
    {
880
        $responseDecoded = [];
881
        if (!empty(trim($responseRaw))) {
882
            switch ($format) {
883
                case 'json':
884
                    $responseDecoded = $this->rawJsonToArray($responseRaw);
885
                    break;
886
                case 'xml':
887
                    $responseDecoded = $this->rawXmlToArray($this->lastCurlResponse);
888
                    break;
889
                case 'txt':
890 3
                default:
891
                    $responseDecoded = [$this->lastCurlResponse];
892 3
                    break;
893 3
            }
894 3
        }
895 3
        return $responseDecoded;
896
    }
897 3
898
    /**
899 3
     * Convert FlexiBee Response JSON to Array
900
     *
901 3
     * @param string $rawJson
902
     *
903 3
     * @return array
904
     */
905 3
    public function rawJsonToArray($rawJson)
906 3
    {
907 3
        $responseDecoded = json_decode($rawJson, true, 10);
908 3
        $decodeError     = json_last_error_msg();
909 3
        if ($decodeError == 'No error') {
910 3
            if (array_key_exists($this->nameSpace, $responseDecoded)) {
911 3
                $responseDecoded = $responseDecoded[$this->nameSpace];
912 3
            }
913 3
        } else {
914 3
            $this->addStatusMessage('JSON Decoder: '.$decodeError, 'error');
915 3
            $this->addStatusMessage($rawJson, 'debug');
916 3
        }
917 3
        return $responseDecoded;
918
    }
919 3
920
    /**
921
     * Convert FlexiBee Response XML to Array
922 3
     *
923 3
     * @param string $rawXML
924 3
     *
925 3
     * @return array
926 3
     */
927 3
    public function rawXmlToArray($rawXML)
928 3
    {
929 3
        return self::xml2array($rawXML);
930 3
    }
931
932
    /**
933
     * Parse Response array
934
     *
935 3
     * @param array $responseDecoded
936
     * @param int $responseCode Request Response Code
937
     *
938
     * @return array main data part of response
939 3
     */
940
    public function parseResponse($responseDecoded, $responseCode)
941
    {
942
        if (is_array($responseDecoded)) {
0 ignored issues
show
introduced by
The condition is_array($responseDecoded) is always true.
Loading history...
943
            $mainResult          = $this->unifyResponseFormat($responseDecoded);
944
            $this->responseStats = array_key_exists('stats', $responseDecoded) ? (isset($responseDecoded['stats'][0])
945
                    ? $responseDecoded['stats'][0] : $responseDecoded['stats']) : null;
946
        } else {
947
            $mainResult = $responseDecoded;
948
        }
949 23
        switch ($responseCode) {
950
            case 201: //Success Write
951 23
            case 200: //Success Read
952 23
                if (is_array($responseDecoded)) {
0 ignored issues
show
introduced by
The condition is_array($responseDecoded) is always true.
Loading history...
953 23
                    $this->lastResult = $mainResult;
954 23
                    if (isset($responseDecoded['@rowCount'])) {
955 15
                        $this->rowCount = (int) $responseDecoded['@rowCount'];
956 15
                    }
957 15
                    if (isset($responseDecoded['@globalVersion'])) {
958 23
                        $this->globalVersion = (int) $responseDecoded['@globalVersion'];
959
                    }
960
                }
961
                break;
962
963
            case 500: // Internal Server Error
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
964
                if ($this->debug === true) {
965
                    $this->error500Reporter($responseDecoded);
966
                }
967
            case 404: // Page not found
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
968 23
                if ($this->ignoreNotFound === true) {
969
                    break;
970 23
                }
971 23
            case 400: //Bad Request parameters
972 23
            default: //Something goes wrong
973 23
                $this->addStatusMessage($this->lastResponseCode.': '.$this->curlInfo['url'],
974 23
                    'warning');
975
                if (is_array($responseDecoded)) {
0 ignored issues
show
introduced by
The condition is_array($responseDecoded) is always true.
Loading history...
976 23
                    $this->parseError($responseDecoded);
977 23
                }
978 23
                $this->logResult($responseDecoded, $this->curlInfo['url']);
979 23
                break;
980 23
        }
981
        return $mainResult;
982 23
    }
983 23
984 23
    /**
985
     * Parse error message response
986
     *
987
     * @param array $responseDecoded
988
     * 
989
     * @return int number of errors processed
990 1
     */
991
    public function parseError(array $responseDecoded)
992 1
    {
993 1
        if (array_key_exists('results', $responseDecoded)) {
994 1
            $this->errors = $responseDecoded['results'][0]['errors'];
995 1
            foreach ($this->errors as $errorInfo) {
996 1
                $this->addStatusMessage($errorInfo['message'], 'error');
997
                if (array_key_exists('for', $errorInfo)) {
998
                    unset($errorInfo['message']);
999
                    $this->addStatusMessage(json_encode($errorInfo), 'debug');
1000
                }
1001 1
            }
1002
        } else {
1003 1
            if (array_key_exists('message', $responseDecoded)) {
1004 1
                $this->errors = [['message' => $responseDecoded['message']]];
1005
            }
1006
        }
1007
        return count($this->errors);
1008
    }
1009
1010
    /**
1011
     * Vykonej HTTP požadavek
1012
     *
1013 23
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
1014
     * @param string $url    URL požadavku
1015 23
     * @param string $method HTTP Method GET|POST|PUT|OPTIONS|DELETE
1016 23
     * @param string $format požadovaný formát komunikace
1017 22
     * 
1018
     * @return int HTTP Response CODE
1019
     */
1020
    public function doCurlRequest($url, $method, $format = null)
1021 22
    {
1022
        if (is_null($format)) {
1023
            $format = $this->format;
1024
        }
1025
        curl_setopt($this->curl, CURLOPT_URL, $url);
1026
// Nastavení samotné operace
1027
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, strtoupper($method));
1028
//Vždy nastavíme byť i prázná postdata jako ochranu před chybou 411
1029
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->postFields);
1030
1031
        $httpHeaders = $this->defaultHttpHeaders;
1032
1033
        $formats = Formats::bySuffix();
1034
1035
        if (!isset($httpHeaders['Accept'])) {
1036
            $httpHeaders['Accept'] = $formats[$format]['content-type'];
1037
        }
1038
        if (!isset($httpHeaders['Content-Type'])) {
1039
            $httpHeaders['Content-Type'] = $formats[$format]['content-type'];
1040
        }
1041
        $httpHeadersFinal = [];
1042
        foreach ($httpHeaders as $key => $value) {
1043
            if (($key == 'User-Agent') && ($value == 'FlexiPeeHP')) {
1044
                $value .= ' v'.self::$libVersion;
1045
            }
1046
            $httpHeadersFinal[] = $key.': '.$value;
1047
        }
1048
1049
        curl_setopt($this->curl, CURLOPT_HTTPHEADER, $httpHeadersFinal);
1050
1051
// Proveď samotnou operaci
1052
        $this->lastCurlResponse            = curl_exec($this->curl);
1053
        $this->curlInfo                    = curl_getinfo($this->curl);
1054
        $this->curlInfo['when']            = microtime();
1055
        $this->curlInfo['request_headers'] = $httpHeadersFinal;
1056
        $this->responseFormat              = isset($this->curlInfo['content_type'])
1057
                ? Formats::contentTypeToSuffix($this->curlInfo['content_type']) : 'txt';
1058
        $this->lastResponseCode            = $this->curlInfo['http_code'];
1059 15
        $this->lastCurlError               = curl_error($this->curl);
1060
        if (strlen($this->lastCurlError)) {
1061 15
            $this->addStatusMessage(sprintf('Curl Error (HTTP %d): %s',
1062 15
                    $this->lastResponseCode, $this->lastCurlError), 'error');
1063
        }
1064 15
1065 8
        if ($this->debug === true) {
1066 7
            $this->saveDebugFiles();
1067 7
        }
1068 7
1069
        return $this->lastResponseCode;
1070 8
    }
1071 1
1072 1
    /**
1073 8
     * Nastaví druh prováděné akce.
1074
     *
1075 15
     * @link https://demo.flexibee.eu/devdoc/actions Provádění akcí
1076 4
     * @param string $action
1077 4
     * 
1078 4
     * @return boolean
1079
     */
1080
    public function setAction($action)
1081
    {
1082
        $result           = false;
1083 4
        $actionsAvailable = $this->getActionsInfo();
1084
        if (is_array($actionsAvailable) && array_key_exists($action,
1085 15
                $actionsAvailable)) {
1086
            $this->action = $action;
1087 15
            $result       = true;
1088 15
        }
1089
        return $result;
1090
    }
1091 15
1092
    /**
1093 15
     * Convert XML to array.
1094 15
     *
1095 15
     * @param string $xml
1096
     *
1097 15
     * @return array
1098
     */
1099 15
    public static function xml2array($xml)
1100 15
    {
1101 15
        $arr = [];
1102 9
        if (!empty($xml)) {
1103 9
            if (is_string($xml)) {
0 ignored issues
show
introduced by
The condition is_string($xml) is always true.
Loading history...
1104 6
                $xml = simplexml_load_string($xml);
1105 6
            }
1106 9
            foreach ($xml->attributes() as $a) {
1107 6
                $arr['@'.$a->getName()] = strval($a);
1108
            }
1109
            foreach ($xml->children() as $r) {
1110 15
                if (count($r->children()) == 0) {
1111
                    $arr[$r->getName()] = strval($r);
1112
                } else {
1113
                    $arr[$r->getName()][] = self::xml2array($r);
1114
                }
1115
            }
1116
        }
1117
        return $arr;
1118
    }
1119
1120
    /**
1121 23
     * Odpojení od FlexiBee.
1122
     */
1123 23
    public function disconnect()
1124 23
    {
1125 23
        if (is_resource($this->curl)) {
1126 23
            curl_close($this->curl);
1127 23
        }
1128
        $this->curl = null;
1129
    }
1130
1131 23
    /**
1132
     * Disconnect CURL befere pass away
1133
     */
1134
    public function __destruct()
1135 23
    {
1136 22
        $this->disconnect();
1137 22
    }
1138 9
1139 9
    /**
1140 22
     * Načte řádek dat z FlexiBee.
1141
     *
1142
     * @param int $recordID id požadovaného záznamu
1143
     *
1144
     * @return array
1145
     */
1146
    public function getFlexiRow($recordID)
1147
    {
1148
        $record   = null;
1149
        $response = $this->performRequest($this->evidence.'/'.$recordID.'.json');
1150
        if (isset($response[$this->evidence])) {
1151 6
            $record = $response[$this->evidence][0];
1152
        }
1153
1154 6
        return $record;
1155 6
    }
1156 6
1157 6
    /**
1158 6
     * Oddělí z pole podmínek ty jenž patří za ? v URL požadavku
1159
     *
1160 6
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
1161
     * @param array $conditions pole podmínek   - rendrují se do ()
1162
     * @param array $urlParams  pole parametrů  - rendrují za ?
1163
     */
1164
    public function extractUrlParams(&$conditions, &$urlParams)
1165 6
    {
1166
        foreach ($this->urlParams as $urlParam) {
1167
            if (isset($conditions[$urlParam])) {
1168
                \Ease\Sand::divDataArray($conditions, $urlParams, $urlParam);
1169 6
            }
1170
        }
1171
    }
1172
1173
    /**
1174
     * convert unicode to entities for use with FlexiBee queries
1175
     *
1176
     * @param string $urlRaw
1177 16
     * 
1178
     * @return string
1179 16
     */
1180 9
    public static function urlEncode($urlRaw)
1181 9
    {
1182 16
        return str_replace(['%27', '%3A'], ["'", ':'], rawurlencode($urlRaw));
1183 16
    }
1184 16
1185
    /**
1186 16
     * Načte data z FlexiBee.
1187 16
     *
1188 16
     * @param string $suffix     dotaz
1189 15
     * @param string|array $conditions Volitelný filtrovací výraz
1190 15
     *
1191
     * @return array Data obtained
1192
     */
1193
    public function getFlexiData($suffix = null, $conditions = null)
1194
    {
1195
        $finalUrl  = '';
1196
        $urlParams = $this->defaultUrlParams;
1197
1198
        if (!empty($conditions)) {
1199 15
            if (is_array($conditions)) {
1200
                $this->extractUrlParams($conditions, $urlParams);
1201
                $conditions = $this->flexiUrl($conditions);
1202 15
            }
1203 10
1204 10
            if (strlen($conditions) && ($conditions[0] != '/')) {
1205 15
                $conditions = '('.self::urlEncode($conditions).')';
1206 15
            }
1207 15
        }
1208 15
1209
        if (strlen($suffix)) {
1210 14
            if (preg_match('/^http/', $suffix) || ($suffix[0] == '/') || is_numeric($suffix)) {
1211 14
                $finalUrl = $suffix;
1212 14
            } else {
1213 14
                if (preg_match('/^(code|ext):(.*)/', $suffix, $matches)) {
1214 10
                    $finalUrl = $matches[1].':'.rawurlencode($matches[2]);
1215
                }
1216 14
            }
1217 14
        }
1218
1219
        $finalUrl .= $conditions;
1220
1221
        if (count($urlParams)) {
1222
            if (strstr($finalUrl, '?')) {
1223
                $finalUrl .= '&';
1224
            } else {
1225
                $finalUrl .= '?';
1226
            }
1227
            $finalUrl .= http_build_query($urlParams, null, '&',
1228
                PHP_QUERY_RFC3986);
1229
        }
1230
1231
        $transactions = $this->performRequest($finalUrl, 'GET');
1232
1233
        $responseEvidence = $this->getResponseEvidence();
1234
        if (is_array($transactions) && array_key_exists($responseEvidence,
1235
                $transactions)) {
1236
            $result = $transactions[$responseEvidence];
1237
            if ((count($result) == 1) && (count(current($result)) == 0 )) {
1238
                $result = null; // Response is empty Array
1239
            }
1240
        } else {
1241
            $result = $transactions;
1242
        }
1243
1244
        return $result;
1245
    }
1246
1247
    /**
1248
     * Načte záznam z FlexiBee a uloží v sobě jeho data
1249
     * Read FlexiBee record and store it inside od object
1250
     *
1251
     * @param int $id ID or conditions
1252 15
     *
1253
     * @return int počet načtených položek
1254
     */
1255 15
    public function loadFromFlexiBee($id = null)
1256 15
    {
1257 15
        $data = [];
1258
        if (is_null($id)) {
1259 15
            $id = $this->getMyKey();
1260 15
        }
1261 15
        if (is_array($id)) {
0 ignored issues
show
introduced by
The condition is_array($id) is always false.
Loading history...
1262 15
            $id = rawurlencode('('.self::flexiUrl($id).')');
1263 15
        } else if (preg_match('/^ext:/', $id)) {
1264 15
            $id = self::urlEncode($id);
1265 15
        } else if (preg_match('/^code:/', $id)) {
1266 15
            $id = self::code(rawurlencode(self::uncode($id)));
1267
        }
1268 15
1269
        $flexidata    = $this->getFlexiData($this->getEvidenceUrl().'/'.$id);
1270
        $this->apiURL = $this->curlInfo['url'];
1271 15
        if (is_array($flexidata) && (count($flexidata) == 1)) {
1272
            $data = current($flexidata);
1273
        }
1274 15
        return $this->takeData($data);
1275 15
    }
1276 15
1277 15
    /**
1278 15
     * Set Filter code for requests
1279
     *
1280 15
     * @link https://www.flexibee.eu/api/dokumentace/ref/zamykani-odemykani/
1281
     *
1282 15
     * @param array|string $filter filter formula or ['key'=>'value']
1283
     *
1284 15
     * @return string Filter code
1285 9
     */
1286 9
    public function setFilter($filter)
1287
    {
1288 15
        return $this->filter = is_array($filter) ? self::flexiUrl($filter) : $filter;
1289
    }
1290
1291
    /**
1292
     * Převede data do Json formátu pro FlexiBee.
1293
     * Convert data to FlexiBee like Json format
1294
     *
1295
     * @url https://www.flexibee.eu/api/dokumentace/ref/actions/
1296
     * @url https://www.flexibee.eu/api/dokumentace/ref/zamykani-odemykani/
1297
     *
1298
     * @param array $data    object data
1299 23
     * @param int   $options json_encode options like JSON_PRETTY_PRINT etc
1300
     *
1301 23
     * @return string
1302
     */
1303 23
    public function getJsonizedData($data = null, $options = 0)
1304 23
    {
1305 23
        if (is_null($data)) {
1306
            $data = $this->getData();
1307 23
        }
1308 23
1309 23
        $dataToJsonize = array_merge(['@version' => $this->protoVersion],
1310
            $this->getDataForJSON($data));
1311 23
        $jsonRaw       = json_encode([$this->nameSpace => $dataToJsonize],
1312 23
            $options);
1313 23
1314 23
        return $jsonRaw;
1315 23
    }
1316 23
1317 23
    /**
1318 23
     * Get Data Fragment specific for current object
1319 23
     *
1320 23
     * @param array $data
1321
     *
1322
     * @return array
1323
     */
1324 23
    public function getDataForJSON($data = null)
1325 23
    {
1326 23
        if (is_null($data)) {
1327
            $data = $this->getData();
1328 23
        }
1329 23
1330 23
        $dataForJson = [$this->getEvidence() => $this->objectToID($data)];
1331 23
1332
        if (!is_null($this->action)) {
0 ignored issues
show
introduced by
The condition is_null($this->action) is always false.
Loading history...
1333
            $dataForJson[$this->evidence.'@action'] = $this->action;
1334 23
            $this->action                           = null;
1335 23
        }
1336 23
1337 23
        if (!is_null($this->filter)) {
0 ignored issues
show
introduced by
The condition is_null($this->filter) is always false.
Loading history...
1338 23
            $dataForJson[$this->evidence.'@filter'] = $this->filter;
1339 23
        }
1340 23
1341 23
1342 23
        foreach ($this->chained as $chained) {
1343 23
            $chainedData = $chained->getDataForJSON();
1344 23
            foreach ($chainedData as $chainedItemEvidence => $chainedItemData) {
1345 23
                if (array_key_exists($chainedItemEvidence, $dataForJson)) {
1346
                    if (is_string(key($dataForJson[$chainedItemEvidence]))) {
1347 23
                        $dataBackup                          = $dataForJson[$chainedItemEvidence];
1348 23
                        $dataForJson[$chainedItemEvidence]   = [];
1349
                        $dataForJson[$chainedItemEvidence][] = $dataBackup;
1350 23
                    }
1351
                    if (array_key_exists(0, $chainedItemData)) {
1352
                        foreach ($chainedItemData as $chainedItem) {
1353
                            $dataForJson[$chainedItemEvidence][] = $chainedItem;
1354
                        }
1355
                    } else {
1356
                        $dataForJson[$chainedItemEvidence][] = $chainedItemData;
1357
                    }
1358
                } else {
1359
                    $dataForJson[$chainedItemEvidence] = $chainedItemData;
1360 23
                }
1361
            }
1362 23
        }
1363 23
1364 23
1365
        return $dataForJson;
1366
    }
1367 23
1368 23
    /**
1369 23
     * Join another FlexiPeeHP Object
1370 23
     *
1371 23
     * @param FlexiBeeRO $object
1372
     *
1373
     * @return boolean adding to stack success
1374 23
     */
1375 23
    public function join(&$object)
1376 23
    {
1377
        $result = true;
1378 23
        if (method_exists($object, 'getDataForJSON')) {
1379 23
            $this->chained[] = $object;
1380 23
        } else {
1381 23
            throw new \Ease\Exception('$object->getDataForJSON() does not exist');
1382 23
        }
1383
1384 23
        return $result;
1385 23
    }
1386 23
1387 23
    /**
1388 23
     * Test if given record ID exists in FlexiBee.
1389
     *
1390 23
     * @param mixed $identifer presence state
1391 23
     *
1392 23
     * @return boolean
1393 23
     */
1394
    public function idExists($identifer = null)
1395
    {
1396 23
        if (is_null($identifer)) {
1397
            $identifer = $this->getMyKey();
1398
        }
1399 23
        $ignorestate = $this->ignore404();
1400
        $this->ignore404(true);
1401
        $this->getFlexiData(null,
1402 23
            [
1403 23
                'detail' => 'custom:'.$this->getKeyColumn(),
1404 23
                $this->getKeyColumn() => $identifer
1405 23
        ]);
1406 23
        $this->ignore404($ignorestate);
1407 23
        return $this->lastResponseCode == 200;
1408
    }
1409
1410
    /**
1411
     * Test if given record exists in FlexiBee.
1412
     *
1413
     * @param array|string|int $data ext:id:23|code:ITEM|['id'=>23]|23
1414
     * 
1415
     * @return boolean Record presence status
1416
     */
1417
    public function recordExists($data = [])
1418
    {
1419
1420
        if (empty($data)) {
1421
            $data = $this->getData();
1422
        }
1423
        $ignorestate = $this->ignore404();
1424
        $this->ignore404(true);
1425
        $keyColumn   = $this->getKeyColumn();
1426
        $res         = $this->getColumnsFromFlexibee([$keyColumn],
1427
            is_array($data) ? $data : [$keyColumn => $data]);
1428
1429
        if (!count($res) || (isset($res['success']) && ($res['success'] == 'false'))
1430
            || ((isset($res) && is_array($res)) && !isset($res[0]) )) {
1431
            $found = false;
1432
        } else {
1433
            $found = true;
1434
        }
1435
        $this->ignore404($ignorestate);
1436
        return $found;
1437
    }
1438
1439
    /**
1440
     * Vrací z FlexiBee sloupečky podle podmínek.
1441
     *
1442
     * @param array|int|string $conditions pole podmínek nebo ID záznamu
1443
     * @param string           $indexBy    klice vysledku naplnit hodnotou ze
1444 23
     *                                     sloupečku
1445
     * @return array
1446 23
     */
1447
    public function getAllFromFlexibee($conditions = null, $indexBy = null)
1448 23
    {
1449 23
        if (is_int($conditions)) {
1450 23
            $conditions = [$this->getmyKeyColumn() => $conditions];
0 ignored issues
show
Bug introduced by
The method getmyKeyColumn() does not exist on FlexiPeeHP\FlexiBeeRO. Did you maybe mean getKeyColumn()? ( Ignorable by Annotation )

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

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

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

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

Loading history...
1451 23
        }
1452 23
1453 23
        $flexiData = $this->getFlexiData('', $conditions);
1454 23
1455 23
        if (!is_null($indexBy)) {
1456 23
            $flexiData = $this->reindexArrayBy($flexiData);
1457
        }
1458 23
1459 23
        return $flexiData;
1460 23
    }
1461 23
1462 23
    /**
1463
     * Vrací z FlexiBee sloupečky podle podmínek.
1464
     *
1465 23
     * @param string[] $columnsList seznam položek
1466 23
     * @param array    $conditions  pole podmínek nebo ID záznamu
1467
     * @param string   $indexBy     Sloupeček podle kterého indexovat záznamy
1468
     *
1469 23
     * @return array
1470
     */
1471 23
    public function getColumnsFromFlexibee($columnsList, $conditions = [],
1472 23
                                           $indexBy = null)
1473
    {
1474 23
        $detail = 'full';
1475
        switch (gettype($columnsList)) {
1476
            case 'integer': //Record ID
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1477 23
                $conditions = [$this->getmyKeyColumn() => $conditions];
1478 23
            case 'array': //Few Conditions
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1479
                if (!is_null($indexBy) && !array_key_exists($indexBy,
1480
                        $columnsList)) {
1481
                    $columnsList[] = $indexBy;
1482
                }
1483
                $columns = implode(',', array_unique($columnsList));
1484
                $detail  = 'custom:'.$columns;
1485
            default:
1486
                switch ($columnsList) {
1487
                    case 'id':
1488
                        $detail = 'id';
1489 65
                        break;
1490
                    case 'summary':
1491 65
                        $detail = 'summary';
1492 65
                        break;
1493
                    default:
1494
                        break;
1495 65
                }
1496 65
                break;
1497
        }
1498
1499
        $conditions['detail'] = $detail;
1500
1501 65
        $flexiData = $this->getFlexiData(null, $conditions);
1502
1503
        if (is_string($indexBy) && is_array($flexiData) && array_key_exists(0,
1504
                $flexiData) && array_key_exists($indexBy, $flexiData[0])) {
1505
            $flexiData = $this->reindexArrayBy($flexiData, $indexBy);
1506
        }
1507
1508
        return $flexiData;
1509
    }
1510
1511 71
    /**
1512
     * Vrací kód záznamu.
1513 71
     * Obtain record CODE
1514
     *
1515
     * @param mixed $data
1516
     *
1517
     * @return string
1518
     */
1519
    public function getKod($data = null, $unique = true)
1520
    {
1521
        $kod = null;
1522 23
1523
        if (is_null($data)) {
1524 23
            $data = $this->getData();
1525
        }
1526
1527
        if (is_string($data)) {
1528
            $data = [$this->nameColumn => $data];
1529
        }
1530
1531
        if (isset($data['kod'])) {
1532 15
            $kod = $data['kod'];
1533
        } else {
1534 15
            if (isset($data[$this->nameColumn])) {
1535 15
                $kod = preg_replace('/[^a-zA-Z0-9]/', '',
1536 15
                    \Ease\Sand::rip($data[$this->nameColumn]));
1537 15
            } else {
1538 15
                if (isset($data[$this->keyColumn])) {
1539 9
                    $kod = \Ease\Sand::rip($data[$this->keyColumn]);
1540 9
                }
1541 15
            }
1542
            $kod = substr($kod, 0, 20);
1543
        }
1544
1545
        if (!strlen($kod)) {
1546
            $kod = 'NOTSET';
1547
        }
1548
1549
        if (strlen($kod) > 18) {
1550 23
            $kodfinal = strtoupper(substr($kod, 0, 18));
1551
        } else {
1552 23
            $kodfinal = strtoupper($kod);
1553 23
        }
1554 23
1555 23
        if ($unique) {
1556 23
            $counter = 0;
1557 23
            if (count($this->codes)) {
1558 23
                foreach ($this->codes as $codesearch => $keystring) {
1559 23
                    if (strstr($codesearch, $kodfinal)) {
1560 23
                        ++$counter;
1561 23
                    }
1562 23
                }
1563 23
            }
1564 23
            if ($counter) {
1565 23
                $kodfinal = $kodfinal.$counter;
1566
            }
1567 23
1568
            $this->codes[$kodfinal] = $kod;
1569
        }
1570
1571
        return self::code($kodfinal);
1572
    }
1573
1574
    /**
1575
     * Write Operation Result.
1576
     *
1577 22
     * @param array  $resultData
1578
     * @param string $url        URL
1579 22
     * 
1580
     * @return boolean Log save success
1581 21
     */
1582
    public function logResult($resultData = null, $url = null)
1583
    {
1584
        $logResult = false;
1585
        if (isset($resultData['success']) && ($resultData['success'] == 'false')) {
1586
            if (isset($resultData['message'])) {
1587
                $this->addStatusMessage($resultData['message'], 'warning');
1588
            }
1589 22
            $this->addStatusMessage('Error '.$this->lastResponseCode.': '.urldecode($url),
1590
                'warning');
1591 22
            unset($url);
1592 22
        }
1593 22
        if (is_null($resultData)) {
1594
            $resultData = $this->lastResult;
1595
        }
1596 22
        if (isset($url)) {
1597
            $this->logger->addStatusMessage($this->lastResponseCode.':'.urldecode($url));
1598
        }
1599
1600
        if (isset($resultData['results'])) {
1601
            if ($resultData['success'] == 'false') {
1602
                $status = 'error';
1603
            } else {
1604
                $status = 'success';
1605 22
            }
1606
            foreach ($resultData['results'] as $result) {
1607 22
                if (isset($result['request-id'])) {
1608 22
                    $rid = $result['request-id'];
1609 22
                } else {
1610 22
                    $rid = '';
1611 22
                }
1612 22
                if (isset($result['errors'])) {
1613 22
                    foreach ($result['errors'] as $error) {
1614 22
                        $message = $error['message'];
1615 22
                        if (isset($error['for'])) {
1616 22
                            $message .= ' for: '.$error['for'];
1617 22
                        }
1618 22
                        if (isset($error['value'])) {
1619
                            $message .= ' value:'.$error['value'];
1620 22
                        }
1621
                        if (isset($error['code'])) {
1622
                            $message .= ' code:'.$error['code'];
1623
                        }
1624
                        $this->addStatusMessage($rid.': '.$message, $status);
1625
                    }
1626
                }
1627
            }
1628
        }
1629
        return $logResult;
1630
    }
1631
1632 22
    /**
1633
     * Save RAW Curl Request & Response to files in Temp directory
1634
     */
1635
    public function saveDebugFiles()
1636
    {
1637
        $tmpdir   = sys_get_temp_dir();
1638
        $fname    = $this->evidence.'-'.$this->curlInfo['when'].'.'.$this->format;
1639
        $reqname  = $tmpdir.'/request-'.$fname;
1640
        $respname = $tmpdir.'/response-'.$fname;
1641 23
        file_put_contents($reqname, $this->postFields);
1642
        file_put_contents($respname, $this->lastCurlResponse);
1643 23
    }
1644 23
1645 23
    /**
1646 23
     * Připraví data pro odeslání do FlexiBee
1647 16
     *
1648 16
     * @param string $data
1649 23
     */
1650
    public function setPostFields($data)
1651
    {
1652
        $this->postFields = $data;
1653
    }
1654
1655
    /**
1656
     * Get Content ready to be send as POST body
1657
     * @return string
1658 23
     */
1659
    public function getPostFields()
1660 23
    {
1661 23
        return $this->postFields;
1662 23
    }
1663 23
1664 23
    /**
1665 23
     * Generuje fragment url pro filtrování.
1666 23
     *
1667 23
     * @see https://www.flexibee.eu/api/dokumentace/ref/filters
1668 23
     *
1669
     * @param array  $data
1670
     * @param string $joiner default and/or
1671
     * @param string $defop  default operator
1672
     *
1673
     * @return string
1674
     */
1675
    public static function flexiUrl(array $data, $joiner = 'and', $defop = 'eq')
1676
    {
1677 23
        $parts = [];
1678
1679 23
        foreach ($data as $column => $value) {
1680 23
            if (!is_numeric($column)) {
1681 23
                if (is_integer($data[$column]) || is_float($data[$column])) {
1682 23
                    $parts[$column] = $column.' eq \''.$data[$column].'\'';
1683 23
                } elseif (is_bool($data[$column])) {
1684 23
                    $parts[$column] = $data[$column] ? $column.' eq true' : $column.' eq false';
1685 13
                } elseif (is_null($data[$column])) {
1686 13
                    $parts[$column] = $column." is null";
1687 23
                } else {
1688
                    switch ($value) {
1689
                        case '!null':
1690
                            $parts[$column] = $column." is not null";
1691
                            break;
1692
                        case 'is empty':
1693
                        case 'is not empty':
1694
                            $parts[$column] = $column.' '.$value;
1695
                            break;
1696 23
                        default:
1697
                            if ($column == 'stitky') {
1698 23
                                $parts[$column] = $column."='".self::code($data[$column])."'";
1699 23
                            } else {
1700 23
                                $parts[$column] = $column." $defop '".$data[$column]."'";
1701 23
                            }
1702 23
                            break;
1703 16
                    }
1704 16
                }
1705 23
            } else {
1706
                $parts[] = $value;
1707
            }
1708
        }
1709
        return implode(' '.$joiner.' ', $parts);
1710
    }
1711
1712
    /**
1713
     * Obtain record/object numeric identificator id:
1714 23
     * Vrací číselný identifikátor objektu id:
1715
     *
1716 23
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1717 23
     *
1718 23
     * @return null|int indentifikátor záznamu reprezentovaného objektem
1719 23
     */
1720 23
    public function getRecordID()
1721 16
    {
1722 16
        $id = $this->getDataValue('id');
1723 23
        return is_null($id) ? null : is_numeric($id) ? intval($id) : $id;
1724
    }
1725
1726
    /**
1727
     * Obtain record/object identificator code:
1728
     * Vrací identifikátor objektu code:
1729
     *
1730
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1731 23
     *
1732
     * @return string record code identifier
1733 23
     */
1734 1
    public function getRecordCode()
1735 1
    {
1736 23
        return empty($this->getDataValue('kod')) ? null : self::code($this->getDataValue('kod'));
1737 23
    }
1738
1739
    /**
1740
     * Obtain record/object identificator extId: code: or id:
1741
     * Vrací identifikátor objektu extId: code: nebo id:
1742
     *
1743
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1744 20
     *
1745
     * @return string|int|null record code identifier
1746 20
     */
1747 20
    public function getRecordIdent()
1748 20
    {
1749 20
        $ident = $this->getExternalID();
1750
        if (empty($ident)) {
1751
            $ident = $this->getRecordCode();
1752
        }
1753
        if (empty($ident)) {
1754
            $ident = $this->getRecordID();
1755 20
        }
1756
        return $ident;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ident also could return the type array which is incompatible with the documented return type null|integer|string.
Loading history...
1757
    }
1758
1759
    /**
1760
     * Obtain record/object identificator code: or id:
1761
     * Vrací identifikátor objektu code: nebo id:
1762
     *
1763
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1764
     * 
1765
     * @return string indentifikátor záznamu reprezentovaného objektem
1766
     */
1767
    public function __toString()
1768
    {
1769
        return strval($this->getRecordIdent());
1770
    }
1771
1772
    /**
1773
     * Gives you FlexiPeeHP class name for Given Evidence
1774
     *
1775
     * @param string $evidence
1776
     * 
1777
     * @return string Class name
1778
     */
1779
    public static function evidenceToClassName($evidence)
1780
    {
1781
        return str_replace(' ', '', ucwords(str_replace('-', ' ', $evidence)));
1782
    }
1783
1784
    /**
1785
     * Obtain ID of first record in evidence
1786
     *
1787
     * @return string|null id or null if no records
1788
     */
1789
    public function getFirstRecordID()
1790
    {
1791
        $firstID    = null;
1792
        $keyColumn  = $this->getKeyColumn();
1793
        $firstIdRaw = $this->getColumnsFromFlexibee([$keyColumn],
1794
            ['limit' => 1, 'order' => $keyColumn], $keyColumn);
1795
        if (!empty($firstIdRaw) && isset(current($firstIdRaw)[$keyColumn])) {
1796
            $firstID = current($firstIdRaw)[$keyColumn];
1797
        }
1798
        return is_numeric($firstID) ? intval($firstID) : $firstID;
1799
    }
1800
1801
    /**
1802
     * Vrací hodnotu daného externího ID
1803
     *
1804
     * @param string $want Namespace Selector. If empty,you obtain the first one.
1805
     * 
1806
     * @return string|array one id or array if multiplete
1807
     */
1808
    public function getExternalID($want = null)
1809
    {
1810
        $extid = null;
1811
        $ids   = $this->getDataValue('external-ids');
1812
        if (is_null($want)) {
1813
            if (!empty($ids)) {
1814
                $extid = current($ids);
1815
            }
1816
        } else {
1817
            if (!is_null($ids) && is_array($ids)) {
1818
                foreach ($ids as $id) {
1819
                    if (strstr($id, 'ext:'.$want)) {
1820
                        if (is_null($extid)) {
1821
                            $extid = str_replace('ext:'.$want.':', '', $id);
1822
                        } else {
1823
                            if (is_array($extid)) {
1824
                                $extid[] = str_replace('ext:'.$want.':', '', $id);
1825
                            } else {
1826
                                $extid = [$extid, str_replace('ext:'.$want.':',
1827
                                        '', $id)];
1828
                            }
1829
                        }
1830
                    }
1831
                }
1832
            }
1833
        }
1834
        return $extid;
1835
    }
1836
1837
    /**
1838
     * Obtain actual GlobalVersion
1839
     * Vrací aktuální globální verzi změn
1840
     *
1841
     * @link https://www.flexibee.eu/api/dokumentace/ref/changes-api#globalVersion Globální Verze
1842
     * 
1843
     * @return type
0 ignored issues
show
Bug introduced by
The type FlexiPeeHP\type was not found. Maybe you did not declare it correctly or list all dependencies?

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

filter:
    dependency_paths: ["lib/*"]

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

Loading history...
1844
     */
1845 23
    public function getGlobalVersion()
1846
    {
1847 23
        $this->getFlexiData(null, ['add-global-version' => 'true', 'limit' => 1]);
1848
1849
        return $this->globalVersion;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->globalVersion returns the type integer which is incompatible with the documented return type FlexiPeeHP\type.
Loading history...
1850
    }
1851
1852
    /**
1853
     * Gives you current ApiURL with given format suffix
1854
     * 
1855
     * @param string $format json|html|xml|...
1856
     * 
1857 23
     * @return string API URL for current record or object/evidence
1858
     */
1859 23
    public function getApiURL($format = null)
1860
    {
1861
        $apiUrl = str_replace(['.'.$this->format, '?limit=0'], '', $this->apiURL);
1862
        return $apiUrl.(empty($format) ? '' : '.'.$format );
1863
    }
1864
1865
    /**
1866
     * Obtain content type of last response
1867
     *
1868
     * @return string
1869
     */
1870
    public function getResponseFormat()
1871
    {
1872
        if (isset($this->curlInfo['content_type'])) {
1873
            $responseFormat = $this->curlInfo['content_type'];
1874
        } else {
1875
            $responseFormat = null;
1876
        }
1877
        return $responseFormat;
1878
    }
1879
1880
    /**
1881
     * Return the same response format for one and multiplete results
1882
     *
1883
     * @param array $responseBody
1884
     * 
1885
     * @return array
1886
     */
1887
    public function unifyResponseFormat($responseBody)
1888
    {
1889
        if (!is_array($responseBody) || array_key_exists('message',
0 ignored issues
show
introduced by
The condition is_array($responseBody) is always true.
Loading history...
1890
                $responseBody)) { //Unifi response format
1891
            $response = $responseBody;
1892
        } else {
1893
            $evidence = $this->getResponseEvidence();
1894
            if (array_key_exists($evidence, $responseBody)) {
1895
                $response        = [];
1896
                $evidenceContent = $responseBody[$evidence];
1897
                if (array_key_exists(0, $evidenceContent)) {
1898
                    $response[$evidence] = $evidenceContent; //Multiplete Results
1899
                } else {
1900
                    $response[$evidence][0] = $evidenceContent; //One result
1901
                }
1902
            } else {
1903
                if (isset($responseBody['priloha'])) {
1904
                    $response = $responseBody['priloha'];
1905
                } else {
1906
                    if (array_key_exists('results', $responseBody)) {
1907
                        $response = $responseBody['results'];
1908
                    } else {
1909
                        $response = $responseBody;
1910
                    }
1911
                }
1912
            }
1913
        }
1914
        return $response;
1915
    }
1916
1917
    /**
1918
     * Obtain structure for current (or given) evidence
1919
     *
1920
     * @param string $evidence
1921
     * 
1922
     * @return array Evidence structure
1923
     */
1924
    public function getColumnsInfo($evidence = null)
1925
    {
1926
        $columnsInfo = null;
1927
        $infoSource  = self::$infoDir.'/Properties.'.(empty($evidence) ? $this->getEvidence()
1928
                : $evidence).'.json';
1929
        if (file_exists($infoSource)) {
1930
            $columnsInfo = json_decode(file_get_contents($infoSource), true);
1931
        }
1932
        return $columnsInfo;
1933
    }
1934
1935
    /**
1936
     * Gives you properties for (current) evidence column
1937
     *
1938
     * @param string $column    name of column
1939
     * @param string $evidence  evidence name if different
1940
     *
1941
     * @return array column properties or null if column not exits
1942
     */
1943
    public function getColumnInfo($column, $evidence = null)
1944
    {
1945
        $columnsInfo = $this->getColumnsInfo(empty($evidence) ? $this->getEvidence()
1946
                : $evidence);
1947
        return is_array($columnsInfo) ? array_key_exists($column, $columnsInfo) ? $columnsInfo[$column]
0 ignored issues
show
introduced by
The condition is_array($columnsInfo) is always true.
Loading history...
1948
                : null : null;
1949
    }
1950
1951
    /**
1952
     * Obtain actions for current (or given) evidence
1953
     *
1954
     * @param string $evidence
1955
     * 
1956
     * @return array Evidence structure
1957
     */
1958
    public function getActionsInfo($evidence = null)
1959
    {
1960
        $actionsInfo = null;
1961
        if (is_null($evidence)) {
1962
            $evidence = $this->getEvidence();
1963
        }
1964
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
1965
        if (isset(\FlexiPeeHP\Actions::$$propsName)) {
1966
            $actionsInfo = Actions::$$propsName;
1967
        }
1968
        return $actionsInfo;
1969
    }
1970
1971
    /**
1972
     * Obtain relations for current (or given) evidence
1973
     *
1974
     * @param string $evidence
1975
     * 
1976
     * @return array Evidence structure
1977
     */
1978
    public function getRelationsInfo($evidence = null)
1979
    {
1980
        $relationsInfo = null;
1981
        if (is_null($evidence)) {
1982
            $evidence = $this->getEvidence();
1983
        }
1984
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
1985
        if (isset(\FlexiPeeHP\Relations::$$propsName)) {
1986
            $relationsInfo = Relations::$$propsName;
1987
        }
1988
        return $relationsInfo;
1989
    }
1990
1991
    /**
1992
     * Obtain info for current (or given) evidence
1993
     *
1994
     * @param string $evidence
1995
     * 
1996
     * @return array Evidence info
1997
     */
1998
    public function getEvidenceInfo($evidence = null)
1999
    {
2000
        $evidencesInfo = null;
2001
        if (is_null($evidence)) {
2002
            $evidence = $this->getEvidence();
2003
        }
2004
        if (isset(EvidenceList::$evidences[$evidence])) {
2005
            $evidencesInfo = EvidenceList::$evidences[$evidence];
2006
            $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
2007
            if(isset(Formats::$$propsName)){
2008
                $evidencesInfo['formats'] = Formats::$$propsName;
2009
        }
2010
        }
2011
        return $evidencesInfo;
2012
    }
2013
2014
    /**
2015
     * Obtain name for current (or given) evidence path
2016
     *
2017
     * @param string $evidence Evidence Path
2018
     * 
2019
     * @return array Evidence info
2020
     */
2021
    public function getEvidenceName($evidence = null)
2022
    {
2023
        $evidenceName = null;
2024
        if (is_null($evidence)) {
2025
            $evidence = $this->getEvidence();
2026
        }
2027
        if (isset(EvidenceList::$name[$evidence])) {
2028
            $evidenceName = EvidenceList::$name[$evidence];
2029
        }
2030
        return $evidenceName;
2031
    }
2032
2033
    /**
2034
     * Save current object to file
2035 23
     *
2036
     * @param string $destfile path to file
2037 23
     */
2038 23
    public function saveResponseToFile($destfile)
2039 23
    {
2040 23
        if (strlen($this->lastCurlResponse)) {
2041
            $this->doCurlRequest($this->apiURL, 'GET', $this->format);
2042
        }
2043
        file_put_contents($destfile, $this->lastCurlResponse);
2044
    }
2045
2046
    /**
2047
     * Obtain established relations listing
2048
     *
2049
     * @return array Null or Relations
2050
     */
2051
    public function getVazby($id = null)
2052
    {
2053
        if (is_null($id)) {
2054
            $id = $this->getRecordID();
2055
        }
2056
        if (!empty($id)) {
2057
            $vazbyRaw = $this->getColumnsFromFlexibee(['vazby'],
2058
                ['relations' => 'vazby', 'id' => $id]);
2059
            $vazby    = array_key_exists('vazby', $vazbyRaw[0]) ? $vazbyRaw[0]['vazby']
2060
                    : null;
2061
        } else {
2062
            throw new \Exception(_('ID requied to get record relations '));
2063
        }
2064
        return $vazby;
2065
    }
2066
2067
    /**
2068
     * Gives You URL for Current Record in FlexiBee web interface
2069
     *
2070
     * @return string url
2071
     */
2072
    public function getFlexiBeeURL()
2073
    {
2074
        $parsed_url = parse_url(str_replace('.'.$this->format, '', $this->apiURL));
2075
        $scheme     = isset($parsed_url['scheme']) ? $parsed_url['scheme'].'://'
2076
                : '';
2077
        $host       = isset($parsed_url['host']) ? $parsed_url['host'] : '';
2078
        $port       = isset($parsed_url['port']) ? ':'.$parsed_url['port'] : '';
2079
        $user       = isset($parsed_url['user']) ? $parsed_url['user'] : '';
2080
        $pass       = isset($parsed_url['pass']) ? ':'.$parsed_url['pass'] : '';
2081
        $pass       = ($user || $pass) ? "$pass@" : '';
2082
        $path       = isset($parsed_url['path']) ? $parsed_url['path'] : '';
2083
        return $scheme.$user.$pass.$host.$port.$path;
2084
    }
2085
2086
    /**
2087
     * Set Record Key
2088
     *
2089
     * @param int|string $myKeyValue
2090
     * 
2091
     * @return boolean
2092
     */
2093
    public function setMyKey($myKeyValue)
2094
    {
2095
        if (substr($myKeyValue, 0, 4) == 'ext:') {
2096
            $extIds = $this->getDataValue('external-ids');
2097
            if (count($extIds)) {
2098
                $extIds = array_combine($extIds, $extIds);
2099
            }
2100
            $extIds[$myKeyValue] = $myKeyValue;
2101
            $res                 = $this->setDataValue('external-ids', $extIds);
2102
        } else {
2103
            $res = parent::setMyKey($myKeyValue);
2104
        }
2105
        $this->updateApiURL();
2106
        return $res;
2107
    }
2108
2109
    /**
2110
     * Set or get ignore not found pages flag
2111
     *
2112
     * @param boolean $ignore set flag to
2113
     *
2114
     * @return boolean get flag state
2115
     */
2116
    public function ignore404($ignore = null)
2117
    {
2118
        if (!is_null($ignore)) {
2119
            $this->ignoreNotFound = $ignore;
2120
        }
2121
        return $this->ignoreNotFound;
2122
    }
2123
2124
    /**
2125
     * Send Document by mail
2126
     *
2127
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
2128
     *
2129
     * @param string $to         Email ecipient
2130
     * @param string $subject    Email Subject
2131
     * @param string $body       Email Text
2132
     *
2133
     * @return int http response code
2134
     */
2135
    public function sendByMail($to, $subject, $body, $cc = null)
2136
    {
2137
        $this->setPostFields($body);
2138
2139
        $this->performRequest(rawurlencode($this->getRecordID()).'/odeslani-dokladu?to='.$to.'&subject='.urlencode($subject).'&cc='.$cc
2140
            , 'PUT', 'xml');
2141
2142
        return $this->lastResponseCode == 200;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->lastResponseCode == 200 returns the type boolean which is incompatible with the documented return type integer.
Loading history...
2143
    }
2144
2145
    /**
2146
     * Send all unsent Documents by eMail
2147
     *
2148
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
2149
     * 
2150
     * @return int http response code
2151
     */
2152
    public function sendUnsent()
2153
    {
2154
        return $this->doCurlRequest('automaticky-odeslat-neodeslane', 'PUT',
2155
                'xml');
2156
    }
2157
2158
    /**
2159
     * FlexiBee date to PHP DateTime conversion
2160
     *
2161
     * @param string $flexidate 2017-05-26+02:00
2162
     *
2163
     * @return \DateTime | false
2164
     */
2165
    public static function flexiDateToDateTime($flexidate)
2166
    {
2167
        return \DateTime::createFromFormat(self::$DateFormat.'O', $flexidate)->setTime(0,
2168
                0);
2169
    }
2170
2171
    /**
2172
     * FlexiBee dateTime to PHP DateTime conversion
2173
     *
2174
     * @param string $flexidatetime 2017-09-26T10:00:53.755+02:00 or older 2017-05-19T00:00:00+02:00
2175
     *
2176
     * @return \DateTime | false
2177
     */
2178
    public static function flexiDateTimeToDateTime($flexidatetime)
2179
    {
2180
        if (strchr($flexidatetime, '.')) { //NewFormat
2181
            $format = self::$DateTimeFormat;
2182
        } else { // Old format
2183
            $format = 'Y-m-d\TH:i:s+P';
2184
        }
2185
        return \DateTime::createFromFormat($format, $flexidatetime);
2186
    }
2187
2188
    /**
2189
     * Získá dokument v daném formátu
2190
     * Obtain document in given format
2191
     *
2192
     * @param string $format  pdf/csv/xml/json/ ...
2193
     * @param string $reportName Template used to generate PDF
2194
     *
2195
     * @return string|null filename downloaded or none
2196
     */
2197
    public function getInFormat($format, $reportName = null)
2198
    {
2199
        $response = null;
2200
        if ($this->setFormat($format)) {
2201
            $urlParams = [];
2202
            if (!empty($reportName)) {
2203
                $urlParams['report-name'] = $reportName;
2204
            }
2205
            if ($format == 'html') {
2206
                $urlParams['inDesktopApp'] = 'true';
2207
            }
2208
            if (($this->doCurlRequest(\Ease\Shared::addUrlParams($this->apiURL,
2209
                        $urlParams), 'GET') == 200)) {
2210
                $response = $this->lastCurlResponse;
2211
            }
2212
        }
2213
        return $response;
2214
    }
2215
2216
    /**
2217
     * Uloží dokument v daném formátu do složky v systému souborů
2218
     * Save document in given format to directory in filesystem
2219
     *
2220
     * @param string $format  pdf/csv/xml/json/ ...
2221
     * @param string $destDir where to put file (prefix)
2222
     * @param string $reportName Template used to generate PDF
2223
     *
2224
     * @return string|null filename downloaded or none
2225
     */
2226
    public function downloadInFormat($format, $destDir = './',
2227
                                     $reportName = null)
2228
    {
2229
        $fileOnDisk   = null;
2230
        $formatBackup = $this->format;
2231
        if ($this->setFormat($format)) {
2232
            $downloadTo = $destDir.$this->getEvidence().'_'.$this->getMyKey().'.'.$format;
2233
            if (($this->doCurlRequest(empty($reportName) ? $this->apiURL : \Ease\Shared::addUrlParams($this->apiURL,
2234
                            ['report-name' => $reportName]), 'GET') == 200) && (file_put_contents($downloadTo,
2235
                    $this->lastCurlResponse) !== false)) {
2236
                $fileOnDisk = $downloadTo;
2237
            }
2238
            $this->setFormat($formatBackup);
2239
        }
2240
        return $fileOnDisk;
2241
    }
2242
2243
    /**
2244
     * Compile and send Report about Error500 to FlexiBee developers
2245
     * If FlexiBee is running on localost try also include java backtrace
2246
     *
2247
     * @param array $errorResponse result of parseError();
2248
     */
2249
    public function error500Reporter($errorResponse)
2250
    {
2251
        $ur = str_replace('/c/'.$this->company, '',
2252
            str_replace($this->url, '', $this->curlInfo['url']));
2253
        if (!array_key_exists($ur, $this->reports)) {
2254
            $tmpdir   = sys_get_temp_dir();
2255
            $myTime   = $this->curlInfo['when'];
2256
            $curlname = $tmpdir.'/curl-'.$this->evidence.'-'.$myTime.'.json';
2257
            file_put_contents($curlname,
2258
                json_encode($this->curlInfo, JSON_PRETTY_PRINT));
2259
2260
            $report = new \Ease\Mailer($this->reportRecipient,
2261
                'Error report 500 - '.$ur);
2262
2263
            $d     = dir($tmpdir);
2264
            while (false !== ($entry = $d->read())) {
2265
                if (strstr($entry, $myTime)) {
2266
                    $ext  = pathinfo($tmpdir.'/'.$entry, PATHINFO_EXTENSION);
2267
                    $mime = Formats::suffixToContentType($ext);
2268
                    $report->addFile($tmpdir.'/'.$entry,
2269
                        empty($mime) ? 'text/plain' : $mime);
2270
                }
2271
            }
2272
            $d->close();
2273
2274
            if ((strstr($this->url, '://localhost') || strstr($this->url,
2275
                    '://127.')) && file_exists('/var/log/flexibee.log')) {
2276
2277
                $fl = fopen('/var/log/'.'flexibee.log', 'r');
2278
                if ($fl) {
0 ignored issues
show
introduced by
$fl is of type resource|false, thus it always evaluated to false.
Loading history...
2279
                    $tracelog = [];
2280
                    for ($x_pos = 0, $ln = 0, $output = array(); fseek($fl,
2281
                            $x_pos, SEEK_END) !== -1; $x_pos--) {
2282
                        $char = fgetc($fl);
2283
                        if ($char === "\n") {
2284
                            $tracelog[] = $output[$ln];
2285
                            if (strstr($output[$ln], $errorResponse['message'])) {
2286
                                break;
2287
                            }
2288
                            $ln++;
2289
                            continue;
2290
                        }
2291
                        $output[$ln] = $char.((array_key_exists($ln, $output)) ? $output[$ln]
2292
                                : '');
2293
                    }
2294
2295
                    $trace     = implode("\n", array_reverse($tracelog));
2296
                    $tracefile = $tmpdir.'/trace-'.$this->evidence.'-'.$myTime.'.log';
2297
                    file_put_contents($tracefile, $trace);
2298
                    $report->addItem("\n\n".$trace);
2299
                    fclose($fl);
2300
                }
2301
            } else {
2302
                $report->addItem($errorResponse['message']);
2303
            }
2304
2305
            $licenseInfo = $this->performRequest($this->url.'/default-license.json');
2306
2307
            $report->addItem("\n\n".json_encode($licenseInfo['license'],
2308
                    JSON_PRETTY_PRINT));
2309
2310
            if ($report->send()) {
2311
                $this->reports[$ur] = $myTime;
2312
            }
2313
        }
2314
    }
2315
2316
    /**
2317
     * Returns code:CODE
2318
     *
2319
     * @param string $code
2320
     *
2321
     * @return string
2322
     */
2323
    public static function code($code)
2324
    {
2325
        return 'code:'.strtoupper(self::uncode($code));
2326
    }
2327
2328
    /**
2329
     * Returns CODE without code: prefix
2330
     *
2331
     * @param string $code
2332
     *
2333
     * @return string
2334
     */
2335
    public static function uncode($code)
2336
    {
2337
        return str_replace(['code:', 'code%3A'], '', $code);
2338
    }
2339
2340
    /**
2341
     * Remove all @ items from array
2342
     *
2343
     * @param array $data original data
2344
     *
2345
     * @return array data without @ columns
2346
     */
2347
    public static function arrayCleanUP($data)
2348
    {
2349
        return array_filter(
2350
            $data,
2351
            function ($key) {
2352
            return !strchr($key, '@');
2353
        }, ARRAY_FILTER_USE_KEY);
2354
    }
2355
2356
    /**
2357
     * Add Info about used user, server and libraries
2358
     *
2359
     * @param string $additions Additional note text
2360
     */
2361
    public function logBanner($additions = null)
2362
    {
2363
        $this->addStatusMessage('FlexiBee '.str_replace('://',
2364
                '://'.$this->user.'@', str_replace('.json', '', $this->apiURL)).' FlexiPeeHP v'.self::$libVersion.' (FlexiBee '.EvidenceList::$version.') EasePHP Framework v'.\Ease\Atom::$frameworkVersion.' '.$additions,
2365
            'debug');
2366
    }
2367
2368
    /**
2369
     * Reconnect After unserialization
2370
     */
2371
    public function __wakeup()
2372
    {
2373
        parent::__wakeup();
2374
        $this->curlInit();
2375
    }
2376
}
2377