Completed
Push — 2.1 ( 30a116 )
by
unknown
01:29
created

AbstractZohoDao::isLogResponses()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Wabel\Zoho\CRM;
4
5
use Wabel\Zoho\CRM\BeanComponents\Field;
6
use Wabel\Zoho\CRM\Exceptions\ExceptionZohoClient;
7
use Wabel\Zoho\CRM\Exceptions\ZohoCRMORMException;
8
use Wabel\Zoho\CRM\Helpers\BeanHelper;
9
use Wabel\Zoho\CRM\Helpers\ComponentHelper;
10
use Wabel\Zoho\CRM\Helpers\ZCRMModuleHelper;
11
use zcrmsdk\crm\crud\ZCRMRecord;
12
use zcrmsdk\crm\crud\ZCRMModule;
13
use zcrmsdk\crm\api\response\EntityResponse;
14
15
/**
16
 * Base class that provides access to Zoho through Zoho beans.
17
 */
18
abstract class AbstractZohoDao
19
{
20
21
    /**
22
     * The class implementing API methods not directly related to a specific module.
23
     *
24
     * @var ZohoClient
25
     */
26
    protected $zohoClient;
27
28
    /**
29
     * Wether or not to log Zoho Api Reponses
30
     *
31
     * @var bool
32
     */
33
    protected $logResponses = false;
34
35
36
    /**
37
     * Array that contains fields that can't be managed
38
     * with the ORM and are manually added with the
39
     * addUnmanagedField method
40
     * @var array
41
     */
42
    protected $unmanagedFields =  [];
43
44
    public function __construct(ZohoClient $zohoClient)
45
    {
46
        $this->zohoClient = $zohoClient;
47
    }
48
49
    abstract public function getModule();
50
    abstract public function getSingularModuleName();
51
    abstract public function getPluralModuleName();
52
    abstract public function getBeanClassName();
53
    abstract public function getFieldsDetails();
54
55
    /**
56
     * @return bool
57
     */
58
    public function isLogResponses(): bool {
59
        return $this->logResponses;
60
    }
61
62
    /**
63
     * @param bool $logResponses
64
     */
65
    public function setLogResponses( bool $logResponses ): void {
66
        $this->logResponses = $logResponses;
67
    }
68
69
    /**
70
     * @return ZohoClient
71
     */
72
    public function getZohoClient(): ZohoClient
73
    {
74
        return $this->zohoClient;
75
    }
76
77
78
    /**
79
     * @return Field[]
80
     */
81
    public function getFields()
82
    {
83
        return array_map(
84
            function (array $fieldDetails) {
85
                return ComponentHelper::createFieldFromArray($fieldDetails);
86
            }, $this->getFieldsDetails()
87
        );
88
    }
89
90
91
    /**
92
     * Returns a module from Zoho.
93
     *
94
     * @return ZCRMModule
95
     */
96
    public function getZCRMModule()
97
    {
98
        return $this->zohoClient->getModule($this->getModule());
99
    }
100
101
    /**
102
     * Parse a Zoho Response in order to retrieve one or several ZohoBeans from it.
103
     *
104
     * @param  ZCRMRecord[] $ZCRMRecords
105
     * @return ZohoBeanInterface[] The array of Zoho Beans parsed from the response
106
     * @throws ZohoCRMORMException
107
     */
108
    public function getBeansFromZCRMRecords(array $ZCRMRecords)
109
    {
110
        $beanClass = $this->getBeanClassName();
111
        $beanArray = array();
112
113
        foreach ($ZCRMRecords as $record) {
114
115
            /**
116
 * @var ZohoBeanInterface $bean 
117
*/
118
            $bean = new $beanClass();
119
            BeanHelper::updateZCRMRecordToBean($this, $bean, $record);
120
            $beanArray[] = $bean;
121
        }
122
123
        return $beanArray;
124
    }
125
126
    /**
127
     * Implements deleteRecords API method.
128
     *
129
     * @param  string $id
130
     * @return ZohoBeanInterface[]
131
     * @throws ZohoCRMORMException
132
     */
133
    public function delete($id): array
134
    {
135
        /***
136
         * @var $ZCRMRecordDeleted EntityResponse[]
137
         */
138
        $ZCRMRecordsDeleted = $this->zohoClient->deleteRecords($this->getModule(), $id);
139
140
        $recordsToDeleted = array_map(
141
            function (EntityResponse $ZCRMRecordDeleted) {
142
                return $ZCRMRecordDeleted->getData();
143
            }, $ZCRMRecordsDeleted
144
        );
145
146
        return $this->getBeansFromZCRMRecords($recordsToDeleted);
147
    }
148
149
    /**
150
     * Implements getRecordById API method.
151
     *
152
     * @param string $id Zoho Id of the record to retrieve OR an array of IDs
153
     *
154
     * @return ZohoBeanInterface The array of Zoho Beans parsed from the response
155
     * @throws ZohoCRMORMException
156
     */
157
    public function getById($id): ZohoBeanInterface
158
    {
159
            $module = $this->getModule();
160
            $ZCRMRecord = $this->zohoClient->getRecordById($module, $id);
161
            $beans =  $this->getBeansFromZCRMRecords([$ZCRMRecord]);
0 ignored issues
show
Documentation introduced by
array($ZCRMRecord) is of type array<integer,object<ZCR...ect<ZCRMRecord>|null"}>, but the function expects a array<integer,object<zcr...k\crm\crud\ZCRMRecord>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
162
163
            return $beans[0];
164
    }
165
166
    /**
167
     * Implements getRecords API method.
168
     *
169
     * @param  string|null    $cvId
170
     * @param  string|null    $sortColumnString
171
     * @param  string|null    $sortOrderString
172
     * @param  \DateTime|null $lastModifiedTime
173
     * @param  int            $page
174
     * @param  int            $perPage
175
     * @return ZohoBeanInterface[]
176
     * @throws ZohoCRMORMException
177
     * @throws \ZCRMException
178
     */
179
    public function getRecords($cvId = null, $sortColumnString = null, $sortOrderString = null, \DateTime $lastModifiedTime = null, $page = 1, $perPage = 200): array
180
    {
181
        try{
182
            $ZCRMRecords =  ZCRMModuleHelper::getAllZCRMRecordsFromPagination($this->zohoClient, $this->getModule(),
183
                $cvId, $sortColumnString, $sortOrderString, $page, $perPage, $lastModifiedTime);
184
        } catch(\ZCRMException $exception){
185
            if(ExceptionZohoClient::exceptionCodeFormat($exception->getExceptionCode()) === ExceptionZohoClient::EXCEPTION_CODE_NO__CONTENT) {
186
                $ZCRMRecords = [];
187
            } else{
188
                $this->zohoClient->logException($exception);
189
                throw $exception;
190
            }
191
        }
192
        return $this->getBeansFromZCRMRecords($ZCRMRecords);
193
    }
194
195
    /**
196
     * Returns the list of deleted records.
197
     *
198
     * @param  \DateTimeInterface|null $lastModifiedTime
199
     * @param  int                     $page
200
     * @param  int                     $perPage
201
     * @return \ZCRMTrashRecord[]
202
     * @throws \ZCRMException
203
     */
204
    public function getDeletedRecordIds(\DateTimeInterface $lastModifiedTime = null, $page = 1, $perPage = 200)
205
    {
206
        return ZCRMModuleHelper::getAllZCRMTrashRecordsFromPagination($this->zohoClient, $this->getModule(), 'all', $lastModifiedTime, $page, $perPage);
207
    }
208
209
    /**
210
     * @Todo
211
     */
212
    // public function getRelatedRecords
213
    // public function searchRecords
214
    // public function uploadFile
215
    // public function downloadFile
216
217
    /**
218
     * Implements insertRecords or updateRecords or upsertRecords API method.
219
     *
220
     * @param ZohoBeanInterface[] $beans
221
     * @param bool                $wfTrigger Whether or not the call should
222
     *                                       trigger the workflows related to a
223
     *                                       "created" event
224
     * @param string              $action
225
     *
226
     * @return array
227
     * @throws \Wabel\Zoho\CRM\Exceptions\ZohoCRMORMException
228
     * @throws \zcrmsdk\crm\exception\ZCRMException
229
     */
230
    public function createOrUpdate( array $beans, bool $wfTrigger = false, $action = 'upsert'): array
231
    {
232
        /**
233
         * @var $records ZCRMRecord[]
234
         */
235
        $records = [];
236
        /** @var \zcrmsdk\crm\api\response\EntityResponse[] $responses */
237
        $responses = [];
238
239
        $dao = $this;
240
        $processAction = ($action === 'update')?'updating':$action.'ing';
241
242
        foreach (array_chunk($beans, 100) as $beansPool) {
243
            /**
244
             * @var $beansPool ZohoBeanInterface[]
245
             */
246
            $recordsToMerge = array_map(
247
                function ($beanPool) use ($dao) {
248
                    /**
249
                     * @var $beanPool ZohoBeanInterface
250
                     */
251
                    BeanHelper::createOrUpdateBeanToZCRMRecord($dao, $beanPool);
252
                    return $beanPool->getZCRMRecord();
253
                }, $beansPool
254
            );
255
            $records = array_merge($records, $recordsToMerge);
256
            switch ($action){
257
            case 'insert':
258
                 $responses = $this->zohoClient->insertRecords($this->getModule(), $records, $wfTrigger);
259
                break;
260
            case 'update':
261
                $responses = $this->zohoClient->updateRecords($this->getModule(), $records, $wfTrigger);
262
                break;
263
            case 'upsert':
264
            default:
265
                $responses = $this->zohoClient->upsertRecords($this->getModule(), $records);
266
            }
267
        }
268
        if ($this->isLogResponses()) {
269
          foreach ( $responses as $response ) {
0 ignored issues
show
Bug introduced by
The expression $responses of type array|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
270
            $this->getZohoClient()->getLogger()->debug( json_encode( $response->getResponseJSON(), JSON_PRETTY_PRINT ) );
0 ignored issues
show
Bug introduced by
The method getLogger() does not seem to exist on object<Wabel\Zoho\CRM\ZohoClient>.

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

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

Loading history...
271
          }
272
        }
273
        if (count($records) != count($beans)) {
274
            throw new ZohoCRMORMException('Error while '.$processAction.' beans in Zoho. '.count($beans).' passed in parameter, but '.count($records).' returned.');
275
        }
276
277
        foreach ($beans as $key => $bean) {
278
            BeanHelper::updateZCRMRecordToBean($dao, $bean, $records[$key]);
279
        }
280
281
        return $responses;
282
    }
283
284
    /**
285
     * Implements insertRecords API method.
286
     *
287
     * @param ZohoBeanInterface[] $beans
288
     * @param bool                $wfTrigger Whether or not the call should
289
     *                                       trigger the workflows related to a
290
     *                                       "created" event
291
     *
292
     * @return array
293
     * @throws ZohoCRMORMException
294
     * @throws \zcrmsdk\crm\exception\ZCRMException
295
     */
296
    public function insertRecords( array $beans, bool $wfTrigger = false): array
297
    {
298
        return $this->createOrUpdate($beans, $wfTrigger, 'insert');
299
    }
300
301
    /**
302
     * Implements updateRecords API method.
303
     *
304
     * @param ZohoBeanInterface[] $beans
305
     * @param bool                $wfTrigger
306
     *
307
     * @return array
308
     * @throws ZohoCRMORMException
309
     * @throws \zcrmsdk\crm\exception\ZCRMException
310
     */
311
    public function updateRecords(array $beans, bool $wfTrigger = false): array
312
    {
313
        return $this->createOrUpdate($beans, $wfTrigger, 'update');
314
    }
315
316
    /**
317
     * Saves the bean or array of beans passed in Zoho.
318
     * It will perform an insert if the bean has no ZohoID or an update if the
319
     * bean has a ZohoID. wfTrigger only usable for a single record
320
     * update/insert.
321
     *
322
     * @param ZohoBeanInterface|ZohoBeanInterface[] $beans A bean or an array
323
     *                                                     of beans.
324
     * @param bool                                  $wfTrigger
325
     *
326
     * @return array
327
     * @throws ZohoCRMORMException
328
     * @throws \zcrmsdk\crm\exception\ZCRMException
329
     */
330
    public function save( $beans, $wfTrigger = false ): array
331
    {
332
333
        if (!is_array($beans)) {
334
            $beans = [$beans];
335
        }
336
337
        $toInsert = [];
338
        $toUpdate = [];
339
        $insertResponses = [];
340
        $updateResponses = [];
341
342
        foreach ($beans as $bean) {
343
            if ($bean->getZohoId()) {
344
                $toUpdate[] = $bean;
345
            } else {
346
                $toInsert[] = $bean;
347
            }
348
        }
349
350
        if ($toInsert) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $toInsert of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
351
            $insertResponses = $this->insertRecords($toInsert, $wfTrigger);
352
        }
353
        if ($toUpdate) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $toUpdate of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
354
            $updateResponses = $this->updateRecords($toUpdate, $wfTrigger);
355
        }
356
357
        return array_merge($insertResponses, $updateResponses);
358
    }
359
360
    /**
361
     * @return ZohoBeanInterface
362
     * @throws ZohoCRMORMException
363
     */
364
    public function create()
365
    {
366
        $record = ZCRMRecord::getInstance($this->getModule(), null);
367
        $beanClassName = $this->getBeanClassName();
368
        $bean = new $beanClassName();
369
        BeanHelper::updateZCRMRecordToBean($this, $bean, $record);
370
        return $bean;
371
    }
372
373
    /**
374
     * @param  $fieldName
375
     * @return null|Field
376
     */
377
    public function getFieldFromFieldName($fieldName)
378
    {
379
        $fields = $this->getFields();
380
        /**
381
         * @var Field[] $field
382
         */
383
        $field = array_values(
384
            array_filter(
385
                $fields, function (Field $fiedObj) use ($fieldName) {
386
                    return $fiedObj->getName() === $fieldName;
387
                }
388
            )
389
        );
390
391
        return count($field) === 1?$field[0] :null;
392
    }
393
394
395
    /**
396
     * Add a field that can't be managed with the ORM
397
     *
398
     * @param $fieldApiName
399
     * @param $value
400
     */
401
    public function addUnmanagedField($fieldApiName, $value) {
402
        $this->unmanagedFields[$fieldApiName] = $value;
403
    }
404
405
    /**
406
     * @return array
407
     */
408
    public function getUnamanagedFields() {
409
        return $this->unmanagedFields;
410
    }
411
}
412