Issues (152)

src/FlexiPeeHP/FlexiBeeRW.php (2 issues)

1
<?php
2
/**
3
 * FlexiPeeHP - Třída pro zápis do FlexiBee.
4
 *
5
 * @author     Vítězslav Dvořák <[email protected]>
6
 * @copyright  (C) 2015-2017 Spoje.Net
7
 */
8
9
namespace FlexiPeeHP;
10
11
/**
12
 * Základní třída pro zápis do FlexiBee
13
 *
14
 * @url https://demo.flexibee.eu/devdoc/http-operations
15
 */
16
class FlexiBeeRW extends FlexiBeeRO
17
{
18
    /**
19
     * Sloupeček obsahující datum vložení záznamu do shopu.
20
     *
21
     * @var string
22
     */
23
    public $myCreateColumn = 'false';
24
25
    /**
26
     * Slopecek obsahujici datum poslení modifikace záznamu do shopu.
27
     *
28
     * @var string
29
     */
30
    public $myLastModifiedColumn = 'lastUpdate';
31
32
    /**
33
     * Last Inserted ID.
34
     *
35
     * @var int
36
     */
37
    public $lastInsertedID = null;
38
39
    /**
40
     * Array of fields for next curl POST operation
41
     * 
42
     * @var string
43
     */
44
    public $postFields = null;
45
46
    /**
47
     * Transaction processing mode
48
     * 
49
     * @link https://www.flexibee.eu/api/dokumentace/ref/tx/ Transakční zpracování
50
     * @var boolean
51
     */
52
    public $atomic = null;
53
54
    /**
55 17
     * SetUp Object to be ready for work
56
     *
57 17
     * @param array $options Object Options (authSessionId,user,password,
58 17
     *                                       url,company,evidence,
59 17
     *                                       prefix,defaultUrlParams,debug,
60
     *                                       detail,offline,atomic,filter,ignore404
61
     */
62 17
    public function setUp($options = array())
63
    {
64
        if (array_key_exists('atomic', $options)) {
65 17
            $this->atomic = (boolean) $options['atomic'];
66 7
        }
67
        return parent::setUp($options);
68
    }
69
70
    /**
71 7
     * Save record (if evidence allow to).
72 10
     * Uloží záznam (pokud to evidence dovoluje)
73 10
     *
74 10
     * @param array $data Data to save
75 17
     * @throws Exception Evidence does not support Import
76
     *
77 17
     * @return array odpověď
78
     */
79
    public function insertToFlexiBee($data = null)
80 17
    {
81 17
        if (is_null($data)) {
82
            $data = $this->getData();
83
        }
84
        $this->postFields = $this->getJsonizedData($data,
85
            $this->debug ? JSON_PRETTY_PRINT : 0);
86
        return $this->performRequest(null, 'PUT');
87
    }
88
89
    /**
90
     * Parse Response array
91
     *
92
     * @param array $responseDecoded
93
     * @param int $responseCode Request Response Code
94
     *
95
     * @return array main data part of response
96
     */
97
    public function parseResponse($responseDecoded, $responseCode)
98
    {
99
        switch ($responseCode) {
100
            case 201: //Success Write
101
                if (isset($responseDecoded[$this->resultField][0]['id'])) {
102
                    $this->lastInsertedID = $responseDecoded[$this->resultField][0]['id'];
103
                    $this->setMyKey($this->lastInsertedID);
104
                } else {
105
                    $this->lastInsertedID = null;
106
                }
107
                if (count($this->chained)) {
108
                    $this->assignResultIDs($this->extractResultIDs($responseDecoded[$this->resultField]));
109
                }
110
        }
111
        return parent::parseResponse($responseDecoded, $responseCode);
112
    }
113
114
    /**
115
     * Assign result IDs to its source objects
116
     * 
117
     * @param array $candidates FlexiBee insert IDs  prepared by extractResultIDs()
118
     */
119
    public function assignResultIDs($candidates)
120
    {
121
        foreach ($this->chained as $chid => $chained) {
122
            $chainedEvidence = $chained->getEvidence();
123
            $chainedExtid    = $chained->getRecordID();
124
            if (is_array($chainedExtid)) { //if there are more IDs
125
                foreach ($chainedExtid as $extId) { //find external ID in format ext:.....
126
                    if (stripos($extId, 'ext:') === 0) {
127
                        $chainedExtid = $extId;
128
                        break;
129
                    }
130
                }
131
            }
132
            $chained->getData();
133
            if (isset($candidates[$chainedEvidence][$chainedExtid])) {
134
                $chained->setMyKey($candidates[$chainedEvidence][$chainedExtid]);
135
                $chained->setDataValue('external-ids', [$chainedExtid]);
136
            }
137
            if (count($this->chained[$chid]->chained)) {
138
                $this->chained[$chid]->assignResultIDs($candidates);
139
            }
140
        }
141
    }
142
143
    /**
144
     * Extract IDs from FlexiBee response Array
145
     * 
146
     * @param array $resultInfo FlexiBee response
147
     * 
148
     * @return array List of [ 'evidence1'=>[ 'original-id'=>numericID,'original-id2'=>numericID2 ], 'evidence2'=> ... ]
149
     */
150
    public function extractResultIDs($resultInfo)
151
    {
152
        $candidates = [];
153
        foreach ($resultInfo as $insertResult) {
154
            $newID = $insertResult['id'];
155
            if (array_key_exists('request-id', $insertResult)) {
156
                $extid = $insertResult['request-id'];
157
            } else {
158
                $extid = null;
159
            }
160
            $evidence                      = explode('/', $insertResult['ref'])[3];
161
            $candidates[$evidence][$extid] = $newID;
162
        }
163
        return $candidates;
164
    }
165
166
    /**
167
     * Give you last inserted record ID.
168
     * 
169
     * @return int
170
     */
171
    public function getLastInsertedId()
172
    {
173
        return $this->lastInsertedID;
174
    }
175
176
    /**
177
     * Smaže záznam
178
     * Delete record in FlexiBee
179
     *
180
     * @param int|string $id identifikátor záznamu
181
     * 
182
     * @return boolean Response code is 200 ?
183
     */
184
    public function deleteFromFlexiBee($id = null)
185
    {
186
        if (is_null($id)) {
187
            $id = $this->getMyKey();
188
        }
189
190
        $this->performRequest($this->getEvidenceUrl().'/'.self::urlizeId($id),
191
            'DELETE');
192
        return $this->lastResponseCode == 200;
193
    }
194
195
    /**
196
     * Control for existing column names in evidence and take data
197
     *
198
     * @param array $data Data to keep
199
     * 
200
     * @return int number of records taken
201
     */
202
    public function takeData($data)
203
    {
204 17
        if ($this->debug === true) {
205
            $fbRelations = [];
206 17
            $fbColumns   = $this->getColumnsInfo();
207 17
            foreach ($this->getRelationsInfo() as $relation) {
208 17
                if (is_array($relation) && isset($relation['url'])) {
209 17
                    $fbRelations[$relation['url']] = $relation['url'];
210 17
                }
211 17
            }
212 17
            if (count($fbColumns)) {
213
                foreach ($data as $key => $value) {
214
                    if (!array_key_exists($key, $fbColumns)) {
215
216
                        if (!array_key_exists($key, $fbRelations)) {
217
                            $this->addStatusMessage(sprintf('unknown column %s for evidence %s',
218
                                    $key, $this->getEvidence()), 'warning');
219
                        } else {
220
                            if (!is_array($value)) {
221
                                $this->addStatusMessage(sprintf('subevidence %s in evidence %s must bee an array',
222 17
                                        $key, $this->getEvidence()), 'warning');
223
                            }
224 17
                        }
225 17
                    }
226 17
                }
227 17
            }
228 17
        }
229 17
        return parent::takeData($data);
230 17
    }
231
232
    /**
233
     * Control data for mandatory columns presence.
234
     *
235
     * @deprecated since version 1.8.7
236
     * 
237
     * @param array $data
238
     * 
239
     * @return array List of missing columns. Empty if all is ok
240
     */
241
    public function controlMandatoryColumns($data = null)
242
    {
243
        if (is_null($data)) {
244
            $data = $this->getData();
245
        }
246
        $missingMandatoryColumns = [];
247
        if (!empty($data) && count($data)) {
248
            $fbColumns = $this->getColumnsInfo();
249
            if (count($fbColumns)) {
250
                foreach ($fbColumns as $columnName => $columnInfo) {
251
                    $mandatory = ($columnInfo['mandatory'] == 'true');
252
                    if ($mandatory && !array_key_exists($columnName, $data)) {
253
                        $missingMandatoryColumns[$columnName] = $columnInfo['name'];
254
                    }
255
                }
256
            }
257
        }
258
        return $missingMandatoryColumns;
259
    }
260
261
    /**
262
     * Control data for readonly columns presence.
263
     *
264
     * @param array $data
265
     * 
266
     * @return array List of ReadOnly columns. Empty if all is ok
267
     */
268
    public function controlReadOnlyColumns($data = null)
269
    {
270
        if (is_null($data)) {
271
            $data = $this->getData();
272
        }
273
274
        $readonlyColumns = [];
275
276
        $fbColumns = $this->getColumnsInfo();
277
        if (!empty($fbColumns) && count($fbColumns)) {
278
            foreach ($fbColumns as $columnName => $columnInfo) {
279
                $writable = ($columnInfo['isWritable'] == 'true');
280
                if (!$writable && !array_key_exists($columnName, $data)) {
281
                    $readonlyColumns[$columnName] = $columnInfo['name'];
282
                }
283
            }
284
        }
285
        return $readonlyColumns;
286
    }
287
288
    /**
289
     * Convert Timestamp to FlexiBee Date format.
290
     *
291
     * @param int $timpestamp
292
     *
293
     * @return string FlexiBee Date or NULL
294
     */
295
    public static function timestampToFlexiDate($timpestamp = null)
296
    {
297
        $flexiDate = null;
298
        if (!is_null($timpestamp)) {
299
            $date      = new \DateTime();
300
            $date->setTimestamp($timpestamp);
301
            $flexiDate = $date->format('Y-m-d');
302
        }
303
        return $flexiDate;
304
    }
305
306
    /**
307
     * Convert Timestamp to Flexi DateTime format.
308
     *
309
     * @param int $timpestamp
310
     *
311
     * @return string FlexiBee DateTime or NULL
312
     */
313
    public static function timestampToFlexiDateTime($timpestamp = null)
314
    {
315
        $flexiDateTime = null;
316
        if (!is_null($timpestamp)) {
317
            $date          = new \DateTime();
318
            $date->setTimestamp($timpestamp);
319
            $flexiDateTime = $date->format('Y-m-dTH:i:s');
320
        }
321
        return $flexiDateTime;
322
    }
323
324
    /**
325
     * Add Data to evidence Branch
326
     * Přidá data do větve
327
     *
328
     * @thanksto Karel Běl
329
     *
330
     * @see Relations
331
     *
332
     * @param array   $data pole dat
333
     * @param string  $relationPath path evidence (relation) pro vkládaná data
334
     * @param boolean $removeAll
335
     *
336
     * @return boolean Operation success
337
     */
338
    public function addArrayToBranch($data, $relationPath = 'polozkyDokladu', $removeAll = false)
339
    {
340
        $currentBranchData = $this->getDataValue($relationPath);
341
        $branchData        = $currentBranchData;
342
        $branchData[]      = $data;
343 17
        if (is_array($this->getEvidence()) && array_key_exists('bezPolozek',
0 ignored issues
show
The condition is_array($this->getEvidence()) is always false.
Loading history...
344
                $this->getColumnsInfo())) {
345 17
            $this->setDataValue('bezPolozek', false);
346
        }
347 17
        if($removeAll === true){
348 17
            $this->setDataValue($relationPath.'@removeAll', true);
349 15
        }
350 15
        return $this->setDataValue($relationPath, $branchData);
351 15
    }
352 4
353 4
    /**
354
     * Vloží do větve data z objektu
355 15
     *
356 15
     * @param FlexiBeeRO $object    objekt evidence
357 15
     * @param boolean    $removeAll flush older items 
358 15
     */
359
    public function addObjectToBranch($object,$removeAll = false)
360
    {
361 15
        $this->addArrayToBranch([$object->getEvidence() => $object->getData()],'polozkyDokladu',$removeAll);
362 4
    }
363 4
364 4
    /**
365 4
     * Přidá uživatelskou vazbu
366 4
     *
367
     * @see https://www.flexibee.eu/api/dokumentace/ref/uzivatelske-vazby/
368 15
     * @param string $vazba
369 15
     */
370 15
    public function vazbaAdd($vazba)
371 15
    {
372 15
        $this->addArrayToBranch(['uzivatelska-vazba' => $vazba],
373 15
            'uzivatelske-vazby');
374 17
    }
375 17
376
    /**
377
     * Smaže uživatelskou vazbu
378 15
     *
379
     * @see https://www.flexibee.eu/api/dokumentace/ref/uzivatelske-vazby/
380
     * @param string $vazba
381
     */
382
    public function vazbaDel($vazba)
383
    {
384
        $this->setDataValue('uzivatelska-vazba@action', 'delete');
385
        $this->addArrayToBranch(['uzivatelska-vazba' => $vazba],
386
            'uzivatelske-vazby');
387
    }
388
389
    /**
390
     * Převede data do Json formátu pro FlexiBee.
391
     * Pokud jsou štítky pole, jsou převedeny na seznam oddělený čárkou.
392
     * Convert data to FlexiBee like Json format.
393
     * Array of Labels is converted to coma separated list
394
     *
395
     * @param array $data
396
     * @param int   $options json_encode options like JSON_PRETTY_PRINT etc 
397
     *
398
     * @return string
399
     */
400
    public function getJsonizedData($data = null, $options = 0)
401
    {
402
        if (is_null($data)) {
403
            $data = $this->getData();
404
        }
405
406
        if (array_key_exists('stitky', $data)) {
407
            if (is_array($data['stitky'])) {
408
                $data['stitky'] = implode(',', $data['stitky']);
409
            }
410
        }
411
        $dataToJsonize = parent::getJsonizedData($data, $options);
412
        return $dataToJsonize;
413
    }
414
415
    /**
416
     * Get Data Fragment specific for current object
417
     * 
418
     * @param array $data
419
     * 
420
     * @return array
421
     */
422
    public function getDataForJSON($data = null)
423
    {
424
        if (is_null($data)) {
425
            $data = $this->getData();
426
        }
427
        $dataForJSON = parent::getDataForJSON($data);
428
        if (!is_null($this->atomic)) {
0 ignored issues
show
The condition is_null($this->atomic) is always false.
Loading history...
429
            $dataForJSON['@atomic'] = $this->atomic;
430
        }
431
        return $dataForJSON;
432
    }
433
434
    /**
435
     * Insert current data into FlexiBee and load actual record data back
436
     *
437
     * @param array $data Initial data to save
438
     * 
439
     * @return boolean Operation success
440
     */
441
    public function sync($data = null)
442
    {
443
        $this->insertToFlexiBee($data);
444
        $insertResult = $this->lastResponseCode;
445
        if ($insertResult == 201) {
446
            $this->reload();
447
        }
448
        $loadResult = $this->lastResponseCode;
449
        return ($insertResult + $loadResult) == 401;
450
    }
451
452
    /**
453
     * Perform given action (if availble) on current evidence/record
454
     * @url https://demo.flexibee.eu/devdoc/actions
455
     *
456
     * @param string $action one of evidence actions
457
     * @param string $method ext|int External method call operation in URL.
458
     *                               Internal add the @action element to request body
459
     *
460
     * @return boolean operation success
461
     */
462
    public function performAction($action, $method = 'int')
463
    {
464
        $actionsAvailble = $this->getActionsInfo();
465
466
        if (is_array($actionsAvailble) && array_key_exists($action,
467
                $actionsAvailble)) {
468
            switch ($actionsAvailble[$action]['actionMakesSense']) {
469
                case 'ONLY_WITH_INSTANCE_AND_NOT_IN_EDIT':
470
                case 'ONLY_WITH_INSTANCE': //Add instance
471
                    $urlSuffix = '/'.$this->__toString().'/'.$action;
472
                    break;
473
474
                default:
475
                    $urlSuffix = '/'.$action;
476
                    break;
477
            }
478
479
            switch ($method) {
480
                case 'int':
481
                    $this->setAction($action);
482
                    $this->setPostFields($this->getJsonizedData(['id' => $this]));
483
                    $this->performRequest(null, 'POST');
484
                    $result = $this->lastResponseCode == 201;
485
                    break;
486
487
                default:
488
                    $result = $this->performRequest($this->evidenceUrlWithSuffix($urlSuffix),
489
                        'GET');
490
                    break;
491
            }
492
        } else {
493
            throw new \Exception(sprintf(_('Unsupported action %s for evidence %s'),
494
                $action, $this->getEvidence()));
495
        }
496
497
        return $result;
498
    }
499
500
    /**
501
     * Add External ID to Current Record
502
     * 
503
     * @param string $extId ext:whatever:123 or simplay whatever:123
504
     * 
505
     * @return array Insert result
506
     */
507
    public function addExternalID($extId)
508
    {
509
        return $this->insertToFlexiBee(['id' => [$this->getRecordID(), 'ext:'.preg_replace('/^ext:/',
510
                        '', $extId)]]);
511
    }
512
513
    /**
514
     * Change Value of external id identified by selector. Add new if not exists
515
     * 
516
     * @param string     $selector ext:$selector:$newValue
517
     * @param string|int $newValue string or number
518
     * @param string|int $forID    Other than current record id
519
     * 
520
     * @return array operation result
521
     */
522
    public function changeExternalID($selector, $newValue, $forID = null)
523
    {
524
        $change['@removeExternalIds'] = 'ext:'.$selector.':';
525
        $change['id']                 = [is_null($forID) ? $this->getRecordID() : $forID,
526
            'ext:'.$selector.':'.$newValue];
527
        return $this->insertToFlexiBee($change);
528
    }
529
}
530