Test Failed
Push — master ( 1ea845...275c2e )
by Vítězslav
03:06
created

FlexiBeeRO   D

Complexity

Total Complexity 357

Size/Duplication

Total Lines 2307
Duplicated Lines 2.86 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
dl 66
loc 2307
rs 4
c 0
b 0
f 0
wmc 357
lcom 1
cbo 7

84 Methods

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

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 = '/usr/share/php/FlexiPeeHP/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
    /**
341
     * Formating string for \DateTime::format() for datetime columns
342
     * @var string
343
     */
344
    static public $DateTimeFormat = 'Y-m-d\TH:i:s.u+P';
345
346
    /**
347
     * Formating string for \DateTime::format() for date columns
348
     * @var string
349
     */
350
    static public $DateFormat = 'Y-m-d';
351
352
    /**
353
     * Last Request response stats
354
     * @var array 
355
     */
356
    private $responseStats = null;
357
358
    /**
359
     * Chained Objects
360
     * @var array
361
     */
362
    public $chained = [];
363
364
    /**
365
     * We Connect to server by default
366
     * @var boolean
367
     */
368
    public $offline = false;
369
370
    /**
371
     * Class for read only interaction with FlexiBee.
372
     *
373
     * @param mixed $init default record id or initial data
374
     * @param array $options Connection settings and other options override
375
     */
376
    public function __construct($init = null, $options = [])
377
    {
378
        $this->init = $init;
379
380
        parent::__construct();
381
        $this->setUp($options);
382
        $this->curlInit();
383
        if (!empty($init)) {
384
            $this->processInit($init);
385
        }
386
    }
387
388
    /**
389
     * SetUp Object to be ready for work
390
     *
391
     * @param array $options Object Options ( user,password,authSessionId
392
     *                                        company,url,evidence,
393
     *                                        prefix,defaultUrlParams,debug,
394
     *                                        detail,offline,filter,ignore404
395
     */
396
    public function setUp($options = [])
397
    {
398
        $this->setupProperty($options, 'company', 'FLEXIBEE_COMPANY');
399
        $this->setupProperty($options, 'url', 'FLEXIBEE_URL');
400
        $this->setupProperty($options, 'user', 'FLEXIBEE_LOGIN');
401
        $this->setupProperty($options, 'password', 'FLEXIBEE_PASSWORD');
402
        $this->setupProperty($options, 'authSessionId', 'FLEXIBEE_AUTHSESSID');
403
        if (!empty($this->authSessionId)) {
404
            $this->defaultHttpHeaders['X-authSessionId'] = $this->authSessionId;
405
        }
406
        if (isset($options['evidence'])) {
407
            $this->setEvidence($options['evidence']);
408
        }
409
        $this->setupProperty($options, 'defaultUrlParams');
410
        if (isset($options['prefix'])) {
411
            $this->setPrefix($options['prefix']);
412
        }
413
        if (array_key_exists('detail', $options)) {
414
            $this->defaultUrlParams['detail'] = $options['detail'];
415
        }
416
        $this->setupProperty($options, 'filter');
417
        if (array_key_exists('offline', $options)) {
418
            $this->offline = (boolean) $options['offline'];
419
        }
420
421
        if (array_key_exists('ignore404', $options)) {
422
            $this->ignore404($options['ignore404']);
423
        }
424
425
        $this->setupProperty($options, 'debug');
426
        $this->updateApiURL();
427
    }
428
429
    /**
430
     * Set up one of properties
431
     *
432
     * @param array  $options  array of given properties
433
     * @param string $name     name of property to process
434
     * @param string $constant load default property value from constant
435
     */
436
    public function setupProperty($options, $name, $constant = null)
437
    {
438
        if (array_key_exists($name, $options)) {
439
            $this->$name = $options[$name];
440
        } else {
441
            if (property_exists($this, $name) && !empty($constant) && defined($constant)) {
442
                $this->$name = constant($constant);
443
            }
444
        }
445
    }
446
447
    /**
448
     * Get Current connection options for use in another object
449
     *
450
     * @return array usable as second constructor parameter
451
     */
452
    public function getConnectionOptions()
453
    {
454
        $conOpts = ['url' => $this->url];
455
        if (empty($this->authSessionId)) {
456
            $conOpts ['user']    = $this->user;
457
            $conOpts['password'] = $this->password;
458
        } else {
459
            $conOpts['authSessionId'] = $this->authSessionId;
460
        }
461
        $company = $this->getCompany();
462
        if (!empty($company)) {
463
            $conOpts['company'] = $company;
464
        }
465
        return $conOpts;
466
    }
467
468
    /**
469
     * Inicializace CURL
470
     *
471
     * @return boolean Online Status
472
     */
473
    public function curlInit()
474
    {
475
        if ($this->offline === false) {
476
            $this->curl = \curl_init(); // create curl resource
477
            curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); // return content as a string from curl_exec
478
            curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); // follow redirects (compatibility for future changes in FlexiBee)
479
            curl_setopt($this->curl, CURLOPT_HTTPAUTH, true);       // HTTP authentication
480
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); // FlexiBee by default uses Self-Signed certificates
481
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
482
            curl_setopt($this->curl, CURLOPT_VERBOSE, ($this->debug === true)); // For debugging
483
            if (empty($this->authSessionId)) {
484
                curl_setopt($this->curl, CURLOPT_USERPWD,
485
                    $this->user.':'.$this->password); // set username and password
486
            }
487
        }
488
        return !$this->offline;
489
    }
490
491
    /**
492
     * Zinicializuje objekt dle daných dat. Možné hodnoty:
493
     *
494
     *  * 234                              - interní číslo záznamu k načtení
495
     *  * code:LOPATA                      - kód záznamu
496
     *  * BAGR                             - kód záznamu k načtení
497
     *  * ['id'=>24,'nazev'=>'hoblík']     - pole hodnot k předvyplnění
498
     *  * 743.json?relations=adresa,vazby  - část url s parametry k načtení
499
     *
500
     * @param mixed $init číslo/"(code:)kód"/(část)URI záznamu k načtení | pole hodnot k předvyplnění
501
     */
502
    public function processInit($init)
503
    {
504
        if (is_integer($init)) {
505
            $this->loadFromFlexiBee($init);
506
        } elseif (is_array($init)) {
507
            $this->takeData($init);
508
        } elseif (preg_match('/\.(json|xml|csv)/', $init)) {
509
            $this->takeData($this->getFlexiData((($init[0] != '/') ? $this->getEvidenceURL($init)
0 ignored issues
show
Unused Code introduced by
The call to FlexiBeeRO::getEvidenceURL() has too many arguments starting with $init.

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

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

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

Loading history...
510
                            : $init)));
511
        } else {
512
            $this->loadFromFlexiBee($init);
513
        }
514
    }
515
516
    /**
517
     * Set Data Field value
518
     *
519
     * @param string $columnName field name
520
     * @param mixed  $value      field data value
521
     *
522
     * @return bool Success
523
     */
524
    public function setDataValue($columnName, $value)
525
    {
526
        if (is_object($value)) {
527
            switch (get_class($value)) {
528
                case 'DateTime':
529
                    $columnInfo = $this->getColumnInfo($columnName);
530
                    switch ($columnInfo['type']) {
531
                        case 'date':
532
                            $value = $value->format(self::$DateFormat);
533
                            break;
534
                        case 'datetime':
535
                            $value = $value->format(self::$DateTimeFormat);
536
                            break;
537
                    }
538
                    break;
539
            }
540
        }
541
        return parent::setDataValue($columnName, $value);
542
    }
543
544
    /**
545
     * Set URL prefix
546
     *
547
     * @param string $prefix
548
     */
549
    public function setPrefix($prefix)
550
    {
551
        switch ($prefix) {
552
            case 'a': //Access
553
            case 'c': //Company
554
            case 'u': //User
555
            case 'g': //License Groups
556
            case 'admin':
557
            case 'status':
558
            case 'login-logout':
559
                $this->prefix = '/'.$prefix.'/';
560
                break;
561
            case null:
562
            case '':
563
            case '/':
564
                $this->prefix = '';
565
                break;
566
            default:
567
                throw new \Exception(sprintf('Unknown prefix %s', $prefix));
568
        }
569
    }
570
571
    /**
572
     * Set communication format.
573
     * One of html|xml|json|csv|dbf|xls|isdoc|isdocx|edi|pdf|pdf|vcf|ical
574
     *
575
     * @param string $format
576
     * @return boolen format is availble
577
     */
578
    public function setFormat($format)
579
    {
580
        $result = true;
581
        if (($this->debug === true) && !empty($this->evidence) && isset(Formats::$$this->evidence)) {
582
            if (array_key_exists($format, array_flip(Formats::$$this->evidence))
583
                === false) {
584
                $result = false;
585
            }
586
        }
587
        if ($result === true) {
588
            $this->format = $format;
589
            $this->updateApiURL();
590
        }
591
        return $result;
592
    }
593
594
    /**
595
     * Nastaví Evidenci pro Komunikaci.
596
     * Set evidence for communication
597
     *
598
     * @param string $evidence evidence pathName to use
599
     * @return boolean evidence switching status
600
     */
601
    public function setEvidence($evidence)
602
    {
603
        switch ($this->prefix) {
604
            case '/c/':
605
                if ($this->debug === true) {
606
                    if (array_key_exists($evidence, EvidenceList::$name)) {
607
                        $this->evidence = $evidence;
608
                        $result         = true;
609
                    } else {
610
                        throw new \Exception(sprintf('Try to set unsupported evidence %s',
611
                                $evidence));
612
                    }
613
                } else {
614
                    $this->evidence = $evidence;
615
                    $result         = true;
616
                }
617
                break;
618
            default:
619
                $this->evidence = $evidence;
620
                $result         = true;
621
                break;
622
        }
623
        $this->updateApiURL();
624
        return $result;
625
    }
626
627
    /**
628
     * Vrací právě používanou evidenci pro komunikaci
629
     * Obtain current used evidence
630
     *
631
     * @return string
632
     */
633
    public function getEvidence()
634
    {
635
        return $this->evidence;
636
    }
637
638
    /**
639
     * Set used company.
640
     * Nastaví Firmu.
641
     *
642
     * @param string $company
643
     */
644
    public function setCompany($company)
645
    {
646
        $this->company = $company;
647
    }
648
649
    /**
650
     * Obtain company now used
651
     * Vrací právě používanou firmu
652
     *
653
     * @return string
654
     */
655
    public function getCompany()
656
    {
657
        return $this->company;
658
    }
659
660
    /**
661
     * Vrací název evidence použité v odpovědích z FlexiBee
662
     *
663
     * @return string
664
     */
665
    public function getResponseEvidence()
666
    {
667
        switch ($this->evidence) {
668
            case 'c':
669
                $evidence = 'company';
670
                break;
671
            case 'evidence-list':
672
                $evidence = 'evidence';
673
                break;
674
            default:
675
                $evidence = $this->getEvidence();
676
                break;
677
        }
678
        return $evidence;
679
    }
680
681
    /**
682
     * Převede rekurzivně Objekt na pole.
683
     *
684
     * @param object|array $object
685
     *
686
     * @return array
687
     */
688
    public static function object2array($object)
689
    {
690
        $result = null;
691
        if (is_object($object)) {
692
            $objectData = get_object_vars($object);
693
            if (is_array($objectData) && count($objectData)) {
694
                $result = array_map('self::object2array', $objectData);
695
            }
696
        } else {
697
            if (is_array($object)) {
698
                foreach ($object as $item => $value) {
699
                    $result[$item] = self::object2array($value);
700
                }
701
            } else {
702
                $result = $object;
703
            }
704
        }
705
706
        return $result;
707
    }
708
709
    /**
710
     * Převede rekurzivně v poli všechny objekty na jejich identifikátory.
711
     *
712
     * @param object|array $object
713
     *
714
     * @return array
715
     */
716 View Code Duplication
    public static function objectToID($object)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
717
    {
718
        $resultID = null;
719
        if (is_object($object)) {
720
            $resultID = $object->__toString();
721
        } else {
722
            if (is_array($object)) {
723
                foreach ($object as $item => $value) {
724
                    $resultID[$item] = self::objectToID($value);
725
                }
726
            } else { //String
727
                $resultID = $object;
728
            }
729
        }
730
731
        return $resultID;
732
    }
733
734
    /**
735
     * Return basic URL for used Evidence
736
     *
737
     * @link https://www.flexibee.eu/api/dokumentace/ref/urls/ Sestavování URL
738
     *
739
     * @return string Evidence URL
740
     */
741
    public function getEvidenceURL()
742
    {
743
        $evidenceUrl = $this->url.$this->prefix.$this->company;
744
        $evidence    = $this->getEvidence();
745
        if (!empty($evidence)) {
746
            $evidenceUrl .= '/'.$evidence;
747
        }
748
        return $evidenceUrl;
749
    }
750
751
    /**
752
     * Add suffix to Evidence URL
753
     *
754
     * @param string $urlSuffix
755
     *
756
     * @return string
757
     */
758
    public function evidenceUrlWithSuffix($urlSuffix)
759
    {
760
        $evidenceUrl = $this->getEvidenceUrl();
761
        if (!empty($urlSuffix)) {
762
            if (($urlSuffix[0] != '/') && ($urlSuffix[0] != ';') && ($urlSuffix[0]
763
                != '?')) {
764
                $evidenceUrl .= '/';
765
            }
766
            $evidenceUrl .= $urlSuffix;
767
        }
768
        return $evidenceUrl;
769
    }
770
771
    /**
772
     * Update $this->apiURL
773
     */
774
    public function updateApiURL()
775
    {
776
        $this->apiURL = $this->getEvidenceURL();
777
        $id           = $this->__toString();
778
        if (!empty($id)) {
779
            $this->apiURL .= '/'.self::urlEncode($id);
780
        }
781
        $this->apiURL .= '.'.$this->format;
782
    }
783
784
    /**
785
     * Add params to url
786
     *
787
     * @param string  $url      originall url
788
     * @param array   $params   value to add
789
     * @param boolean $override replace already existing values ?
790
     *
791
     * @return string url with parameters added
792
     */
793
    public function addUrlParams($url, $params, $override = false)
794
    {
795
        $urlParts = parse_url($url);
796
        $urlFinal = '';
797
        if (array_key_exists('scheme', $urlParts)) {
798
            $urlFinal .= $urlParts['scheme'].'://'.$urlParts['host'];
799
        }
800
        if (array_key_exists('port', $urlParts)) {
801
            $urlFinal .= ':'.$urlParts['port'];
802
        }
803
        if (array_key_exists('path', $urlParts)) {
804
            $urlFinal .= $urlParts['path'];
805
        }
806
        if (array_key_exists('query', $urlParts)) {
807
            parse_str($urlParts['query'], $queryUrlParams);
808
            $urlParams = $override ? array_merge($params, $queryUrlParams) : array_merge($queryUrlParams,
809
                    $params);
810
        } else {
811
            $urlParams = $params;
812
        }
813
814
        if (!empty($urlParams)) {
815
            $urlFinal .= '?';
816
            if (is_array($urlParams)) {
817
                $urlFinal .= http_build_query($urlParams);
818
            } else {
819
                $urlFinal .= $urlParams;
820
            }
821
        }
822
        return $urlFinal;
823
    }
824
825
    /**
826
     * Add Default Url params to given url if not overrided
827
     *
828
     * @param string $urlRaw
829
     *
830
     * @return string url with default params added
831
     */
832
    public function addDefaultUrlParams($urlRaw)
833
    {
834
        return $this->addUrlParams($urlRaw, $this->defaultUrlParams, false);
835
    }
836
837
    /**
838
     * Funkce, která provede I/O operaci a vyhodnotí výsledek.
839
     *
840
     * @param string $urlSuffix část URL za identifikátorem firmy.
841
     * @param string $method    HTTP/REST metoda
842
     * @param string $format    Requested format
843
     * @return array|boolean Výsledek operace
844
     */
845
    public function performRequest($urlSuffix = null, $method = 'GET',
846
                                   $format = null)
847
    {
848
        $this->rowCount      = null;
849
        $this->responseStats = [];
850
851
        if (preg_match('/^http/', $urlSuffix)) {
852
            $url = $urlSuffix;
853
        } elseif (strlen($urlSuffix) && ($urlSuffix[0] == '/')) {
854
            $url = $this->url.$urlSuffix;
855
        } else {
856
            $url = $this->evidenceUrlWithSuffix($urlSuffix);
857
        }
858
859
        $responseCode = $this->doCurlRequest($this->addDefaultUrlParams($url),
860
            $method, $format);
861
862
        return $this->parseResponse($this->rawResponseToArray($this->lastCurlResponse,
0 ignored issues
show
Bug introduced by
It seems like $this->rawResponseToArra... $this->responseFormat) targeting FlexiPeeHP\FlexiBeeRO::rawResponseToArray() can also be of type string; however, FlexiPeeHP\FlexiBeeRO::parseResponse() does only seem to accept array, maybe add an additional type check?

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

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

An additional type check may prevent trouble.

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

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1455
                                           $indexBy = null)
1456
    {
1457
        $detail = 'full';
1458
        switch (gettype($columnsList)) {
1459
            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...
1460
                $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...
1461
            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...
1462
                if (!is_null($indexBy) && !array_key_exists($indexBy,
1463
                        $columnsList)) {
1464
                    $columnsList[] = $indexBy;
1465
                }
1466
                $columns = implode(',', array_unique($columnsList));
1467
                $detail  = 'custom:'.$columns;
1468
            default:
1469
                switch ($columnsList) {
1470
                    case 'id':
1471
                        $detail = 'id';
1472
                        break;
1473
                    case 'summary':
1474
                        $detail = 'summary';
1475
                        break;
1476
                    default:
1477
                        break;
1478
                }
1479
                break;
1480
        }
1481
1482
        $conditions['detail'] = $detail;
1483
1484
        $flexiData = $this->getFlexiData(null, $conditions);
1485
1486
        if (!is_null($indexBy) && count($flexiData) && count(current($flexiData))) {
1487
            $flexiData = $this->reindexArrayBy($flexiData, $indexBy);
1488
        }
1489
1490
        return $flexiData;
1491
    }
1492
1493
    /**
1494
     * Vrací kód záznamu.
1495
     * Obtain record CODE
1496
     *
1497
     * @param mixed $data
1498
     *
1499
     * @return string
1500
     */
1501
    public function getKod($data = null, $unique = true)
1502
    {
1503
        $kod = null;
1504
1505
        if (is_null($data)) {
1506
            $data = $this->getData();
1507
        }
1508
1509
        if (is_string($data)) {
1510
            $data = [$this->nameColumn => $data];
1511
        }
1512
1513
        if (isset($data['kod'])) {
1514
            $kod = $data['kod'];
1515
        } else {
1516
            if (isset($data[$this->nameColumn])) {
1517
                $kod = preg_replace('/[^a-zA-Z0-9]/', '',
1518
                    \Ease\Sand::rip($data[$this->nameColumn]));
1519
            } else {
1520
                if (isset($data[$this->keyColumn])) {
1521
                    $kod = \Ease\Sand::rip($data[$this->keyColumn]);
1522
                }
1523
            }
1524
            $kod = substr($kod, 0, 20);
1525
        }
1526
1527
        if (!strlen($kod)) {
1528
            $kod = 'NOTSET';
1529
        }
1530
1531
        if (strlen($kod) > 18) {
1532
            $kodfinal = strtoupper(substr($kod, 0, 18));
1533
        } else {
1534
            $kodfinal = strtoupper($kod);
1535
        }
1536
1537
        if ($unique) {
1538
            $counter = 0;
1539
            if (count($this->codes)) {
1540
                foreach ($this->codes as $codesearch => $keystring) {
1541
                    if (strstr($codesearch, $kodfinal)) {
1542
                        ++$counter;
1543
                    }
1544
                }
1545
            }
1546
            if ($counter) {
1547
                $kodfinal = $kodfinal.$counter;
1548
            }
1549
1550
            $this->codes[$kodfinal] = $kod;
1551
        }
1552
1553
        return self::code($kodfinal);
1554
    }
1555
1556
    /**
1557
     * Write Operation Result.
1558
     *
1559
     * @param array  $resultData
1560
     * @param string $url        URL
1561
     * @return boolean Log save success
1562
     */
1563
    public function logResult($resultData = null, $url = null)
1564
    {
1565
        $logResult = false;
1566
        if (isset($resultData['success']) && ($resultData['success'] == 'false')) {
1567
            if (isset($resultData['message'])) {
1568
                $this->addStatusMessage($resultData['message'], 'warning');
1569
            }
1570
            $this->addStatusMessage('Error '.$this->lastResponseCode.': '.urldecode($url),
1571
                'warning');
1572
            unset($url);
1573
        }
1574
        if (is_null($resultData)) {
1575
            $resultData = $this->lastResult;
1576
        }
1577
        if (isset($url)) {
1578
            $this->logger->addStatusMessage($this->lastResponseCode.':'.urldecode($url));
1579
        }
1580
1581
        if (isset($resultData['results'])) {
1582
            if ($resultData['success'] == 'false') {
1583
                $status = 'error';
1584
            } else {
1585
                $status = 'success';
1586
            }
1587
            foreach ($resultData['results'] as $result) {
1588
                if (isset($result['request-id'])) {
1589
                    $rid = $result['request-id'];
1590
                } else {
1591
                    $rid = '';
1592
                }
1593
                if (isset($result['errors'])) {
1594
                    foreach ($result['errors'] as $error) {
1595
                        $message = $error['message'];
1596
                        if (isset($error['for'])) {
1597
                            $message .= ' for: '.$error['for'];
1598
                        }
1599
                        if (isset($error['value'])) {
1600
                            $message .= ' value:'.$error['value'];
1601
                        }
1602
                        if (isset($error['code'])) {
1603
                            $message .= ' code:'.$error['code'];
1604
                        }
1605
                        $this->addStatusMessage($rid.': '.$message, $status);
1606
                    }
1607
                }
1608
            }
1609
        }
1610
        return $logResult;
1611
    }
1612
1613
    /**
1614
     * Save RAW Curl Request & Response to files in Temp directory
1615
     */
1616
    public function saveDebugFiles()
1617
    {
1618
        $tmpdir   = sys_get_temp_dir();
1619
        $fname    = $this->evidence.'-'.$this->curlInfo['when'].'.'.$this->format;
1620
        $reqname  = $tmpdir.'/request-'.$fname;
1621
        $respname = $tmpdir.'/response-'.$fname;
1622
        file_put_contents($reqname, $this->postFields);
1623
        file_put_contents($respname, $this->lastCurlResponse);
1624
    }
1625
1626
    /**
1627
     * Připraví data pro odeslání do FlexiBee
1628
     *
1629
     * @param string $data
1630
     */
1631
    public function setPostFields($data)
1632
    {
1633
        $this->postFields = $data;
1634
    }
1635
1636
    /**
1637
     * Generuje fragment url pro filtrování.
1638
     *
1639
     * @see https://www.flexibee.eu/api/dokumentace/ref/filters
1640
     *
1641
     * @param array  $data
1642
     * @param string $joiner default and/or
1643
     * @param string $defop  default operator
1644
     *
1645
     * @return string
1646
     */
1647
    public static function flexiUrl(array $data, $joiner = 'and', $defop = 'eq')
1648
    {
1649
        $parts = [];
1650
1651
        foreach ($data as $column => $value) {
1652
            if (!is_numeric($column)) {
1653
                if (is_integer($data[$column]) || is_float($data[$column])) {
1654
                    $parts[$column] = $column.' eq \''.$data[$column].'\'';
1655
                } elseif (is_bool($data[$column])) {
1656
                    $parts[$column] = $data[$column] ? $column.' eq true' : $column.' eq false';
1657
                } elseif (is_null($data[$column])) {
1658
                    $parts[$column] = $column." is null";
1659
                } else {
1660
                    switch ($value) {
1661
                        case '!null':
1662
                            $parts[$column] = $column." is not null";
1663
                            break;
1664
                        case 'is empty':
1665
                        case 'is not empty':
1666
                            $parts[$column] = $column.' '.$value;
1667
                            break;
1668
                        default:
1669
                            if ($column == 'stitky') {
1670
                                $parts[$column] = $column."='".self::code($data[$column])."'";
1671
                            } else {
1672
                                $parts[$column] = $column." $defop '".$data[$column]."'";
1673
                            }
1674
                            break;
1675
                    }
1676
                }
1677
            } else {
1678
                $parts[] = $value;
1679
            }
1680
        }
1681
        return implode(' '.$joiner.' ', $parts);
1682
    }
1683
1684
    /**
1685
     * Obtain record/object numeric identificator id:
1686
     * Vrací číselný identifikátor objektu id:
1687
     *
1688
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1689
     *
1690
     * @return null|int indentifikátor záznamu reprezentovaného objektem
1691
     */
1692
    public function getRecordID()
1693
    {
1694
        $id = $this->getDataValue('id');
1695
        return is_null($id) ? null : is_numeric($id) ? intval($id) : $id;
1696
    }
1697
1698
    /**
1699
     * Obtain record/object identificator code:
1700
     * Vrací identifikátor objektu code:
1701
     *
1702
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1703
     *
1704
     * @return string record code identifier
1705
     */
1706
    public function getRecordCode()
1707
    {
1708
        return empty($this->getDataValue('kod')) ? null : self::code($this->getDataValue('kod'));
1709
    }
1710
1711
    /**
1712
     * Obtain record/object identificator extId: code: or id:
1713
     * Vrací identifikátor objektu extId: code: nebo id:
1714
     *
1715
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1716
     *
1717
     * @return string|int|null record code identifier
1718
     */
1719
    public function getRecordIdent()
1720
    {
1721
        $ident = $this->getExternalID();
1722
        if (empty($ident)) {
1723
            $ident = $this->getRecordCode();
1724
        }
1725
        if (empty($ident)) {
1726
            $ident = $this->getRecordID();
1727
        }
1728
        return $ident;
1729
    }
1730
1731
    /**
1732
     * Obtain record/object identificator code: or id:
1733
     * Vrací identifikátor objektu code: nebo id:
1734
     *
1735
     * @link https://demo.flexibee.eu/devdoc/identifiers Identifikátory záznamů
1736
     * @return string indentifikátor záznamu reprezentovaného objektem
1737
     */
1738
    public function __toString()
1739
    {
1740
        return strval($this->getRecordIdent());
1741
    }
1742
1743
    /**
1744
     * Gives you FlexiPeeHP class name for Given Evidence
1745
     *
1746
     * @param string $evidence
1747
     * @return string Class name
1748
     */
1749
    public static function evidenceToClassName($evidence)
1750
    {
1751
        return str_replace(' ', '', ucwords(str_replace('-', ' ', $evidence)));
1752
    }
1753
1754
    /**
1755
     * Obtain ID of first record in evidence
1756
     *
1757
     * @return string|null id or null if no records
1758
     */
1759 View Code Duplication
    public function getFirstRecordID()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1760
    {
1761
        $firstID    = null;
1762
        $keyColumn  = $this->getKeyColumn();
1763
        $firstIdRaw = $this->getColumnsFromFlexibee([$keyColumn],
1764
            ['limit' => 1, 'order' => $keyColumn], $keyColumn);
1765
        if (!empty($firstIdRaw)) {
1766
            $firstID = current($firstIdRaw)[$keyColumn];
1767
        }
1768
        return is_numeric($firstID) ? intval($firstID) : $firstID;
1769
    }
1770
1771
    /**
1772
     * Vrací hodnotu daného externího ID
1773
     *
1774
     * @param string $want Which ? If empty,you obtain the first one.
1775
     * @return string
1776
     */
1777
    public function getExternalID($want = null)
1778
    {
1779
        $extid = null;
1780
        $ids   = $this->getDataValue('external-ids');
1781
        if (is_null($want)) {
1782
            if (!empty($ids)) {
1783
                $extid = current($ids);
1784
            }
1785
        } else {
1786
            if (!is_null($ids) && is_array($ids)) {
1787
                foreach ($ids as $id) {
1788
                    if (strstr($id, 'ext:'.$want)) {
1789
                        $extid = str_replace('ext:'.$want.':', '', $id);
1790
                    }
1791
                }
1792
            }
1793
        }
1794
        return $extid;
1795
    }
1796
1797
    /**
1798
     * Obtain actual GlobalVersion
1799
     * Vrací aktuální globální verzi změn
1800
     *
1801
     * @link https://www.flexibee.eu/api/dokumentace/ref/changes-api#globalVersion Globální Verze
1802
     * @return type
1803
     */
1804
    public function getGlobalVersion()
1805
    {
1806
        $this->getFlexiData(null, ['add-global-version' => 'true', 'limit' => 1]);
1807
1808
        return $this->globalVersion;
1809
    }
1810
1811
    /**
1812
     * Gives you current ApiURL with given format suffix
1813
     * 
1814
     * @param string $format json|html|xml|...
1815
     * 
1816
     * @return string API URL for current record or object/evidence
1817
     */
1818
    public function getApiURL($format = null)
1819
    {
1820
        $apiUrl = str_replace(['.'.$this->format, '?limit=0'], '', $this->apiURL);
1821
        return $apiUrl.(empty($format) ? '' : '.'.$format );
1822
    }
1823
1824
    /**
1825
     * Obtain content type of last response
1826
     *
1827
     * @return string
1828
     */
1829
    public function getResponseFormat()
1830
    {
1831
        if (isset($this->curlInfo['content_type'])) {
1832
            $responseFormat = $this->curlInfo['content_type'];
1833
        } else {
1834
            $responseFormat = null;
1835
        }
1836
        return $responseFormat;
1837
    }
1838
1839
    /**
1840
     * Return the same response format for one and multiplete results
1841
     *
1842
     * @param array $responseBody
1843
     * @return array
1844
     */
1845
    public function unifyResponseFormat($responseBody)
1846
    {
1847
        if (!is_array($responseBody) || array_key_exists('message',
1848
                $responseBody)) { //Unifi response format
1849
            $response = $responseBody;
1850
        } else {
1851
            $evidence = $this->getResponseEvidence();
1852
            if (array_key_exists($evidence, $responseBody)) {
1853
                $response        = [];
1854
                $evidenceContent = $responseBody[$evidence];
1855
                if (array_key_exists(0, $evidenceContent)) {
1856
                    $response[$evidence] = $evidenceContent; //Multiplete Results
1857
                } else {
1858
                    $response[$evidence][0] = $evidenceContent; //One result
1859
                }
1860
            } else {
1861
                if (isset($responseBody['priloha'])) {
1862
                    $response = $responseBody['priloha'];
1863
                } else {
1864
                    if (array_key_exists('results', $responseBody)) {
1865
                        $response = $responseBody['results'];
1866
                    } else {
1867
                        $response = $responseBody;
1868
                    }
1869
                }
1870
            }
1871
        }
1872
        return $response;
1873
    }
1874
1875
    /**
1876
     * Obtain structure for current (or given) evidence
1877
     *
1878
     * @param string $evidence
1879
     * @return array Evidence structure
1880
     */
1881
    public function getColumnsInfo($evidence = null)
1882
    {
1883
        $columnsInfo = null;
1884
        $infoSource  = self::$infoDir.'/Properties.'.(empty($evidence) ? $this->getEvidence()
1885
                : $evidence).'.json';
1886
        if (file_exists($infoSource)) {
1887
            $columnsInfo = json_decode(file_get_contents($infoSource), true);
1888
        }
1889
        return $columnsInfo;
1890
    }
1891
1892
    /**
1893
     * Gives you properties for (current) evidence column
1894
     *
1895
     * @param string $column    name of column
1896
     * @param string $evidence  evidence name if different
1897
     *
1898
     * @return array column properties or null if column not exits
1899
     */
1900
    public function getColumnInfo($column, $evidence = null)
1901
    {
1902
        $columnsInfo = $this->getColumnsInfo(empty($evidence) ? $this->getEvidence()
1903
                : $evidence);
1904
        return array_key_exists($column, $columnsInfo) ? $columnsInfo[$column] : null;
1905
    }
1906
1907
    /**
1908
     * Obtain actions for current (or given) evidence
1909
     *
1910
     * @param string $evidence
1911
     * @return array Evidence structure
1912
     */
1913
    public function getActionsInfo($evidence = null)
1914
    {
1915
        $actionsInfo = null;
1916
        if (is_null($evidence)) {
1917
            $evidence = $this->getEvidence();
1918
        }
1919
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
1920
        if (isset(\FlexiPeeHP\Actions::$$propsName)) {
1921
            $actionsInfo = Actions::$$propsName;
1922
        }
1923
        return $actionsInfo;
1924
    }
1925
1926
    /**
1927
     * Obtain relations for current (or given) evidence
1928
     *
1929
     * @param string $evidence
1930
     * @return array Evidence structure
1931
     */
1932
    public function getRelationsInfo($evidence = null)
1933
    {
1934
        $relationsInfo = null;
1935
        if (is_null($evidence)) {
1936
            $evidence = $this->getEvidence();
1937
        }
1938
        $propsName = lcfirst(FlexiBeeRO::evidenceToClassName($evidence));
1939
        if (isset(\FlexiPeeHP\Relations::$$propsName)) {
1940
            $relationsInfo = Relations::$$propsName;
1941
        }
1942
        return $relationsInfo;
1943
    }
1944
1945
    /**
1946
     * Obtain info for current (or given) evidence
1947
     *
1948
     * @param string $evidence
1949
     * @return array Evidence info
1950
     */
1951
    public function getEvidenceInfo($evidence = null)
1952
    {
1953
        $evidencesInfo = null;
1954
        if (is_null($evidence)) {
1955
            $evidence = $this->getEvidence();
1956
        }
1957
        if (isset(EvidenceList::$evidences[$evidence])) {
1958
            $evidencesInfo = EvidenceList::$evidences[$evidence];
1959
        }
1960
        return $evidencesInfo;
1961
    }
1962
1963
    /**
1964
     * Obtain name for current (or given) evidence path
1965
     *
1966
     * @param string $evidence Evidence Path
1967
     * @return array Evidence info
1968
     */
1969
    public function getEvidenceName($evidence = null)
1970
    {
1971
        $evidenceName = null;
1972
        if (is_null($evidence)) {
1973
            $evidence = $this->getEvidence();
1974
        }
1975
        if (isset(EvidenceList::$name[$evidence])) {
1976
            $evidenceName = EvidenceList::$name[$evidence];
1977
        }
1978
        return $evidenceName;
1979
    }
1980
1981
    /**
1982
     * Save current object to file
1983
     *
1984
     * @param string $destfile path to file
1985
     */
1986
    public function saveResponseToFile($destfile)
1987
    {
1988
        if (strlen($this->lastCurlResponse)) {
1989
            $this->doCurlRequest($this->apiURL, 'GET', $this->format);
1990
        }
1991
        file_put_contents($destfile, $this->lastCurlResponse);
1992
    }
1993
1994
    /**
1995
     * Obtain established relations listing
1996
     *
1997
     * @return array Null or Relations
1998
     */
1999
    public function getVazby($id = null)
2000
    {
2001
        if (is_null($id)) {
2002
            $id = $this->getRecordID();
2003
        }
2004
        if (!empty($id)) {
2005
            $vazbyRaw = $this->getColumnsFromFlexibee(['vazby'],
2006
                ['relations' => 'vazby', 'id' => $id]);
2007
            $vazby    = array_key_exists('vazby', $vazbyRaw[0]) ? $vazbyRaw[0]['vazby']
2008
                    : null;
2009
        } else {
2010
            throw new \Exception(_('ID requied to get record relations '));
2011
        }
2012
        return $vazby;
2013
    }
2014
2015
    /**
2016
     * Gives You URL for Current Record in FlexiBee web interface
2017
     *
2018
     * @return string url
2019
     */
2020
    public function getFlexiBeeURL()
2021
    {
2022
        $parsed_url = parse_url(str_replace('.'.$this->format, '', $this->apiURL));
2023
        $scheme     = isset($parsed_url['scheme']) ? $parsed_url['scheme'].'://'
2024
                : '';
2025
        $host       = isset($parsed_url['host']) ? $parsed_url['host'] : '';
2026
        $port       = isset($parsed_url['port']) ? ':'.$parsed_url['port'] : '';
2027
        $user       = isset($parsed_url['user']) ? $parsed_url['user'] : '';
2028
        $pass       = isset($parsed_url['pass']) ? ':'.$parsed_url['pass'] : '';
2029
        $pass       = ($user || $pass) ? "$pass@" : '';
2030
        $path       = isset($parsed_url['path']) ? $parsed_url['path'] : '';
2031
        return $scheme.$user.$pass.$host.$port.$path;
2032
    }
2033
2034
    /**
2035
     * Set Record Key
2036
     *
2037
     * @param int|string $myKeyValue
2038
     * @return boolean
2039
     */
2040
    public function setMyKey($myKeyValue)
2041
    {
2042
        if (substr($myKeyValue, 0, 4) == 'ext:') {
2043
            $extIds = $this->getDataValue('external-ids');
2044
            if (count($extIds)) {
2045
                $extIds = array_combine($extIds, $extIds);
2046
            }
2047
            $extIds[$myKeyValue] = $myKeyValue;
2048
            $res                 = $this->setDataValue('external-ids', $extIds);
2049
        } else {
2050
            $res = parent::setMyKey($myKeyValue);
2051
        }
2052
        $this->updateApiURL();
2053
        return $res;
2054
    }
2055
2056
    /**
2057
     * Set or get ignore not found pages flag
2058
     *
2059
     * @param boolean $ignore set flag to
2060
     *
2061
     * @return boolean get flag state
2062
     */
2063
    public function ignore404($ignore = null)
2064
    {
2065
        if (!is_null($ignore)) {
2066
            $this->ignoreNotFound = $ignore;
2067
        }
2068
        return $this->ignoreNotFound;
2069
    }
2070
2071
    /**
2072
     * Send Document by mail
2073
     *
2074
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
2075
     *
2076
     * @param string $to         Email ecipient
2077
     * @param string $subject    Email Subject
2078
     * @param string $body       Email Text
2079
     *
2080
     * @return int http response code
2081
     */
2082
    public function sendByMail($to, $subject, $body, $cc = null)
2083
    {
2084
        $this->setPostFields($body);
2085
2086
        $this->performRequest(rawurlencode($this->getRecordID()).'/odeslani-dokladu?to='.$to.'&subject='.urlencode($subject).'&cc='.$cc
2087
            , 'PUT', 'xml');
2088
2089
        return $this->lastResponseCode == 200;
2090
    }
2091
2092
    /**
2093
     * Send all unsent Invoices by mail
2094
     *
2095
     * @url https://www.flexibee.eu/api/dokumentace/ref/odesilani-mailem/
2096
     * @return int http response code
2097
     */
2098
    public function sendUnsent()
2099
    {
2100
        return $this->doCurlRequest('automaticky-odeslat-neodeslane', 'PUT',
2101
                'xml');
2102
    }
2103
2104
    /**
2105
     * FlexiBee date to PHP DateTime conversion
2106
     *
2107
     * @param string $flexidate 2017-05-26+02:00
2108
     *
2109
     * @return \DateTime | false
2110
     */
2111
    public static function flexiDateToDateTime($flexidate)
2112
    {
2113
        return \DateTime::createFromFormat(self::$DateFormat.'O', $flexidate)->setTime(0,
2114
                0);
2115
    }
2116
2117
    /**
2118
     * FlexiBee dateTime to PHP DateTime conversion
2119
     *
2120
     * @param string $flexidatetime 2017-09-26T10:00:53.755+02:00 or older 2017-05-19T00:00:00+02:00
2121
     *
2122
     * @return \DateTime | false
2123
     */
2124
    public static function flexiDateTimeToDateTime($flexidatetime)
2125
    {
2126
        if (strchr($flexidatetime, '.')) { //NewFormat
2127
            $format = self::$DateTimeFormat;
2128
        } else { // Old format
2129
            $format = 'Y-m-d\TH:i:s+P';
2130
        }
2131
        return \DateTime::createFromFormat($format, $flexidatetime);
2132
    }
2133
2134
    /**
2135
     * Získá dokument v daném formátu
2136
     * Obtain document in given format
2137
     *
2138
     * @param string $format  pdf/csv/xml/json/ ...
2139
     * @param string $reportName Template used to generate PDF
0 ignored issues
show
Bug introduced by
There is no parameter named $reportName. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
2140
     *
2141
     * @return string|null filename downloaded or none
2142
     */
2143
    public function getInFormat($format)
2144
    {
2145
        $response = null;
2146
        if ($this->setFormat($format)) {
2147
            $urlParams = [];
2148
            if (!empty($reportName)) {
0 ignored issues
show
Bug introduced by
The variable $reportName seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
2149
                $urlParams['report-name'] = $reportName;
2150
            }
2151
            if ($format == 'html') {
2152
                $urlParams['inDesktopApp'] = 'true';
2153
            }
2154
            if (($this->doCurlRequest($this->addUrlParams($this->apiURL,
2155
                        $urlParams), 'GET') == 200)) {
2156
                $response = $this->lastCurlResponse;
2157
            }
2158
        }
2159
        return $response;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression \DateTime::createFromFor...ormat, $flexidatetime); of type DateTime|false adds false to the return on line 2159 which is incompatible with the return type documented by FlexiPeeHP\FlexiBeeRO::flexiDateTimeToDateTime of type DateTime. It seems like you forgot to handle an error condition.
Loading history...
2160
    }
2161
2162
    /**
2163
     * Uloží dokument v daném formátu do složky v systému souborů
2164
     * Save document in given format to directory in filesystem
2165
     *
2166
     * @param string $format  pdf/csv/xml/json/ ...
2167
     * @param string $destDir where to put file (prefix)
2168
     * @param string $reportName Template used to generate PDF
2169
     *
2170
     * @return string|null filename downloaded or none
2171
     */
2172
    public function downloadInFormat($format, $destDir = './',
2173
                                     $reportName = null)
2174
    {
2175
        $fileOnDisk   = null;
2176
        $formatBackup = $this->format;
2177
        if ($this->setFormat($format)) {
2178
            $downloadTo = $destDir.$this->getEvidence().'_'.$this->getMyKey().'.'.$format;
2179
            if (($this->doCurlRequest(empty($reportName) ? $this->apiURL : $this->addUrlParams($this->apiURL,
2180
                            ['report-name' => $reportName]), 'GET') == 200) && (file_put_contents($downloadTo,
2181
                    $this->lastCurlResponse) !== false)) {
2182
                $fileOnDisk = $downloadTo;
2183
            }
2184
            $this->setFormat($formatBackup);
2185
        }
2186
        return $fileOnDisk;
2187
    }
2188
2189
    /**
2190
     * Compile and send Report about Error500 to FlexiBee developers
2191
     * If FlexiBee is running on localost try also include java backtrace
2192
     *
2193
     * @param array $errorResponse result of parseError();
2194
     */
2195
    public function error500Reporter($errorResponse)
2196
    {
2197
        $ur = str_replace('/c/'.$this->company, '',
2198
            str_replace($this->url, '', $this->curlInfo['url']));
2199
        if (!array_key_exists($ur, $this->reports)) {
2200
            $tmpdir   = sys_get_temp_dir();
2201
            $myTime   = $this->curlInfo['when'];
2202
            $curlname = $tmpdir.'/curl-'.$this->evidence.'-'.$myTime.'.json';
2203
            file_put_contents($curlname,
2204
                json_encode($this->curlInfo, JSON_PRETTY_PRINT));
2205
2206
            $report = new \Ease\Mailer($this->reportRecipient,
2207
                'Error report 500 - '.$ur);
2208
2209
            $d     = dir($tmpdir);
2210
            while (false !== ($entry = $d->read())) {
2211
                if (strstr($entry, $myTime)) {
2212
                    $ext  = pathinfo($tmpdir.'/'.$entry, PATHINFO_EXTENSION);
2213
                    $mime = Formats::suffixToContentType($ext);
2214
                    $report->addFile($tmpdir.'/'.$entry,
2215
                        empty($mime) ? 'text/plain' : $mime);
2216
                }
2217
            }
2218
            $d->close();
2219
2220
            if ((strstr($this->url, '://localhost') || strstr($this->url,
2221
                    '://127.')) && file_exists('/var/log/flexibee.log')) {
2222
2223
                $fl = fopen('/var/log/'.'flexibee.log', 'r');
2224
                if ($fl) {
2225
                    $tracelog = [];
2226
                    for ($x_pos = 0, $ln = 0, $output = array(); fseek($fl,
2227
                            $x_pos, SEEK_END) !== -1; $x_pos--) {
2228
                        $char = fgetc($fl);
2229
                        if ($char === "\n") {
2230
                            $tracelog[] = $output[$ln];
2231
                            if (strstr($output[$ln], $errorResponse['message'])) {
2232
                                break;
2233
                            }
2234
                            $ln++;
2235
                            continue;
2236
                        }
2237
                        $output[$ln] = $char.((array_key_exists($ln, $output)) ? $output[$ln]
2238
                                : '');
2239
                    }
2240
2241
                    $trace     = implode("\n", array_reverse($tracelog));
2242
                    $tracefile = $tmpdir.'/trace-'.$this->evidence.'-'.$myTime.'.log';
2243
                    file_put_contents($tracefile, $trace);
2244
                    $report->addItem("\n\n".$trace);
2245
                    fclose($fl);
2246
                }
2247
            } else {
2248
                $report->addItem($errorResponse['message']);
2249
            }
2250
2251
            $licenseInfo = $this->performRequest($this->url.'/default-license.json');
2252
2253
            $report->addItem("\n\n".json_encode($licenseInfo['license'],
2254
                    JSON_PRETTY_PRINT));
2255
2256
            if ($report->send()) {
2257
                $this->reports[$ur] = $myTime;
2258
            }
2259
        }
2260
    }
2261
2262
    /**
2263
     * Returns code:CODE
2264
     *
2265
     * @param string $code
2266
     *
2267
     * @return string
2268
     */
2269
    public static function code($code)
2270
    {
2271
        return 'code:'.strtoupper(self::uncode($code));
2272
    }
2273
2274
    /**
2275
     * Returns CODE without code: prefix
2276
     *
2277
     * @param string $code
2278
     *
2279
     * @return string
2280
     */
2281
    public static function uncode($code)
2282
    {
2283
        return str_replace(['code:', 'code%3A'], '', $code);
2284
    }
2285
2286
    /**
2287
     * Remove all @ items from array
2288
     *
2289
     * @param array $data original data
2290
     *
2291
     * @return array data without @ columns
2292
     */
2293
    public static function arrayCleanUP($data)
2294
    {
2295
        return array_filter(
2296
            $data,
2297
            function ($key) {
2298
            return !strchr($key, '@');
2299
        }, ARRAY_FILTER_USE_KEY);
2300
    }
2301
2302
    /**
2303
     * Add Info about used user, server and libraries
2304
     *
2305
     * @param string $additions Additional note text
2306
     */
2307
    public function logBanner($additions = null)
2308
    {
2309
        $this->addStatusMessage('FlexiBee '.str_replace('://',
2310
                '://'.$this->user.'@', str_replace('.json', '', $this->apiURL)).' FlexiPeeHP v'.self::$libVersion.' (FlexiBee '.EvidenceList::$version.') EasePHP Framework v'.\Ease\Atom::$frameworkVersion.' '.$additions,
2311
            'debug');
2312
    }
2313
2314
    /**
2315
     * Reconnect After unserialization
2316
     */
2317
    public function __wakeup()
2318
    {
2319
        parent::__wakeup();
2320
        $this->curlInit();
2321
    }
2322
}
2323