Completed
Pull Request — 2.0 (#52)
by
unknown
01:08
created

AbstractZohoDao::getUnamanagedFields()   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
12
/**
13
 * Base class that provides access to Zoho through Zoho beans.
14
 */
15
abstract class AbstractZohoDao
16
{
17
18
    /**
19
     * The class implementing API methods not directly related to a specific module.
20
     *
21
     * @var ZohoClient
22
     */
23
    protected $zohoClient;
24
25
26
    /**
27
     * Array that contains fields that can't be managed
28
     * with the ORM and are manually added with the
29
     * addUnmanagedField method
30
     * @var array
31
     */
32
    protected $unmanagedFields =  [];
33
34
    public function __construct(ZohoClient $zohoClient)
35
    {
36
        $this->zohoClient = $zohoClient;
37
    }
38
39
    abstract protected function getModule();
40
    abstract protected function getSingularModuleName();
41
    abstract protected function getPluralModuleName();
42
    abstract protected function getBeanClassName();
43
    abstract protected function getFieldsDetails();
44
45
    /**
46
     * @return ZohoClient
47
     */
48
    public function getZohoClient(): ZohoClient
49
    {
50
        return $this->zohoClient;
51
    }
52
53
54
    /**
55
     * @return Field[]
56
     */
57
    public function getFields()
58
    {
59
        return array_map(
60
            function (array $fieldDetails) {
61
                return ComponentHelper::createFieldFromArray($fieldDetails);
62
            }, $this->getFieldsDetails()
63
        );
64
    }
65
66
67
    /**
68
     * Returns a module from Zoho.
69
     *
70
     * @return \ZCRMModule
71
     */
72
    public function getZCRMModule()
73
    {
74
        return $this->zohoClient->getModule($this->getModule());
75
    }
76
77
    /**
78
     * Parse a Zoho Response in order to retrieve one or several ZohoBeans from it.
79
     *
80
     * @param  \ZCRMRecord[] $ZCRMRecords
81
     * @return ZohoBeanInterface[] The array of Zoho Beans parsed from the response
82
     * @throws ZohoCRMORMException
83
     */
84
    protected function getBeansFromZCRMRecords(array $ZCRMRecords)
85
    {
86
        $beanClass = $this->getBeanClassName();
87
        $beanArray = array();
88
89
        foreach ($ZCRMRecords as $record) {
90
91
            /**
92
 * @var ZohoBeanInterface $bean 
93
*/
94
            $bean = new $beanClass();
95
            BeanHelper::updateZCRMRecordToBean($this, $bean, $record);
96
            $beanArray[] = $bean;
97
        }
98
99
        return $beanArray;
100
    }
101
102
    /**
103
     * Implements deleteRecords API method.
104
     *
105
     * @param  string $id
106
     * @return ZohoBeanInterface[]
107
     * @throws ZohoCRMORMException
108
     */
109
    public function delete($id): array
110
    {
111
        /***
112
         * @var $ZCRMRecordDeleted \EntityResponse[]
113
         */
114
        $ZCRMRecordsDeleted = $this->zohoClient->deleteRecords($this->getModule(), $id);
115
116
        $recordsToDeleted = array_map(
117
            function (\EntityResponse $ZCRMRecordDeleted) {
118
                return $ZCRMRecordDeleted->getData();
119
            }, $ZCRMRecordsDeleted
120
        );
121
122
        return $this->getBeansFromZCRMRecords($recordsToDeleted);
123
    }
124
125
    /**
126
     * Implements getRecordById API method.
127
     *
128
     * @param string $id Zoho Id of the record to retrieve OR an array of IDs
129
     *
130
     * @return ZohoBeanInterface The array of Zoho Beans parsed from the response
131
     * @throws ZohoCRMORMException
132
     */
133
    public function getById($id): ZohoBeanInterface
134
    {
135
            $module = $this->getModule();
136
            $ZCRMRecord = $this->zohoClient->getRecordById($module, $id);
137
            $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<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...
138
139
            return $beans[0];
140
    }
141
142
    /**
143
     * Implements getRecords API method.
144
     *
145
     * @param  string|null    $cvId
146
     * @param  string|null    $sortColumnString
147
     * @param  string|null    $sortOrderString
148
     * @param  \DateTime|null $lastModifiedTime
149
     * @param  int            $page
150
     * @param  int            $perPage
151
     * @return ZohoBeanInterface[]
152
     * @throws ZohoCRMORMException
153
     * @throws \ZCRMException
154
     */
155
    public function getRecords($cvId = null, $sortColumnString = null, $sortOrderString = null, \DateTime $lastModifiedTime = null, $page = 1, $perPage = 200): array
156
    {
157
        try{
158
            $ZCRMRecords =  ZCRMModuleHelper::getAllZCRMRecordsFromPagination($this->zohoClient, $this->getModule(),
159
                $cvId, $sortColumnString, $sortOrderString, $page, $perPage, $lastModifiedTime);
160
        } catch(\ZCRMException $exception){
161
            if(ExceptionZohoClient::exceptionCodeFormat($exception->getExceptionCode()) === ExceptionZohoClient::EXCEPTION_CODE_NO__CONTENT) {
162
                $ZCRMRecords = [];
163
            } else{
164
                $this->zohoClient->logException($exception);
165
                throw $exception;
166
            }
167
        }
168
        return $this->getBeansFromZCRMRecords($ZCRMRecords);
169
    }
170
171
    /**
172
     * Returns the list of deleted records.
173
     *
174
     * @param  \DateTimeInterface|null $lastModifiedTime
175
     * @param  int                     $page
176
     * @param  int                     $perPage
177
     * @return \ZCRMTrashRecord[]
178
     * @throws \ZCRMException
179
     */
180
    public function getDeletedRecordIds(\DateTimeInterface $lastModifiedTime = null, $page = 1, $perPage = 200)
181
    {
182
        return ZCRMModuleHelper::getAllZCRMTrashRecordsFromPagination($this->zohoClient, $this->getModule(), 'all', $lastModifiedTime, $page, $perPage);
183
    }
184
185
    /**
186
     * @Todo
187
     */
188
    // public function getRelatedRecords
189
    // public function searchRecords
190
    // public function uploadFile
191
    // public function downloadFile
192
193
    /**
194
     * Implements insertRecords or updateRecords or upsertRecords API method.
195
     *
196
     * @param  ZohoBeanInterface[] $beans
197
     * @param  bool                $wfTrigger Whether or not the call should trigger the workflows related to a "created" event
198
     * @throws ZohoCRMORMException
199
     */
200
    public function createOrUpdate( array $beans, bool $wfTrigger = false, $action = 'upsert'): void
201
    {
202
        /**
203
         * @var $records \ZCRMRecord[]
204
         */
205
        $records = [];
206
207
        $dao = $this;
208
        $processAction = ($action === 'update')?'updating':$action.'ing';
209
210
        foreach (array_chunk($beans, 100) as $beansPool) {
211
            /**
212
             * @var $beansPool ZohoBeanInterface[]
213
             */
214
            $recordsToMerge = array_map(
215
                function ($beanPool) use ($dao) {
216
                    /**
217
                     * @var $beanPool ZohoBeanInterface
218
                     */
219
                    BeanHelper::createOrUpdateBeanToZCRMRecord($dao, $beanPool);
220
                    return $beanPool->getZCRMRecord();
221
                }, $beansPool
222
            );
223
            $records = array_merge($records, $recordsToMerge);
224
            switch ($action){
225
            case 'insert':
226
                 $this->zohoClient->insertRecords($this->getModule(), $records, $wfTrigger);
227
                break;
228
            case 'update':
229
                $this->zohoClient->updateRecords($this->getModule(), $records, $wfTrigger);
230
                break;
231
            case 'upsert':
232
            default:
233
                $this->zohoClient->upsertRecords($this->getModule(), $records);
234
            }
235
        }
236
        if (count($records) != count($beans)) {
237
            throw new ZohoCRMORMException('Error while '.$processAction.' beans in Zoho. '.count($beans).' passed in parameter, but '.count($records).' returned.');
238
        }
239
240
        foreach ($beans as $key => $bean) {
241
            BeanHelper::updateZCRMRecordToBean($dao, $bean, $records[$key]);
242
        }
243
    }
244
245
    /**
246
     * Implements insertRecords API method.
247
     *
248
     * @param  ZohoBeanInterface[] $beans
249
     * @param  bool                $wfTrigger Whether or not the call should trigger the workflows related to a "created" event
250
     * @throws ZohoCRMORMException
251
     */
252
    public function insertRecords( array $beans, bool $wfTrigger = false): void
253
    {
254
        $this->createOrUpdate($beans, $wfTrigger, 'insert');
255
    }
256
257
    /**
258
     * Implements updateRecords API method.
259
     *
260
     * @param  ZohoBeanInterface[] $beans
261
     * @param  bool                $wfTrigger
262
     * @throws ZohoCRMORMException
263
     */
264
    public function updateRecords(array $beans, bool $wfTrigger = false): void
265
    {
266
        $this->createOrUpdate($beans, $wfTrigger, 'update');
267
    }
268
269
    /**
270
     * Saves the bean or array of beans passed in Zoho.
271
     * It will perform an insert if the bean has no ZohoID or an update if the bean has a ZohoID.
272
     * wfTrigger only usable for a single record update/insert.
273
     *
274
     * @param ZohoBeanInterface|ZohoBeanInterface[] $beans     A bean or an array of beans.
275
     * @param bool                                  $wfTrigger
276
     */
277
    public function save($beans, $wfTrigger = false): void
278
    {
279
280
        if (!is_array($beans)) {
281
            $beans = [$beans];
282
        }
283
284
        $toInsert = [];
285
        $toUpdate = [];
286
287
        foreach ($beans as $bean) {
288
            if ($bean->getZohoId()) {
289
                $toUpdate[] = $bean;
290
            } else {
291
                $toInsert[] = $bean;
292
            }
293
        }
294
295
        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...
296
            $this->insertRecords($toInsert, $wfTrigger);
297
        }
298
        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...
299
            $this->updateRecords($toUpdate, $wfTrigger);
300
        }
301
    }
302
303
    /**
304
     * @return ZohoBeanInterface
305
     * @throws ZohoCRMORMException
306
     */
307
    public function create()
308
    {
309
        $record = \ZCRMRecord::getInstance($this->getModule(), null);
310
        $beanClassName = $this->getBeanClassName();
311
        $bean = new $beanClassName();
312
        BeanHelper::updateZCRMRecordToBean($this, $bean, $record);
313
        return $bean;
314
    }
315
316
    /**
317
     * @param  $fieldName
318
     * @return null|Field
319
     */
320
    public function getFieldFromFieldName($fieldName)
321
    {
322
        $fields = $this->getFields();
323
        /**
324
         * @var Field[] $field
325
         */
326
        $field = array_values(
327
            array_filter(
328
                $fields, function (Field $fiedObj) use ($fieldName) {
329
                    return $fiedObj->getName() === $fieldName;
330
                }
331
            )
332
        );
333
334
        return count($field) === 1?$field[0] :null;
335
    }
336
337
338
    /**
339
     * Add a field that can't be managed with the ORM
340
     *
341
     * @param $fieldApiName
342
     * @param $value
343
     */
344
    public function addUnmanagedField($fieldApiName, $value) {
345
        $this->unmanagedFields[$fieldApiName] = $value;
346
    }
347
348
    /**
349
     * @return array
350
     */
351
    public function getUnamanagedFields() {
352
        return $this->unmanagedFields;
353
    }
354
}
355