Completed
Pull Request — 2.0 (#37)
by Raphaël
10:32
created

AbstractZohoDao::getBeansFromZCRMRecords()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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