1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Wabel\Zoho\CRM\Copy; |
4
|
|
|
|
5
|
|
|
use Doctrine\DBAL\Connection; |
6
|
|
|
use Psr\Log\LoggerInterface; |
7
|
|
|
use Psr\Log\NullLogger; |
8
|
|
|
use Wabel\Zoho\CRM\AbstractZohoDao; |
9
|
|
|
use Wabel\Zoho\CRM\Service\EntitiesGeneratorService; |
10
|
|
|
use Wabel\Zoho\CRM\ZohoBeanInterface; |
11
|
|
|
use zcrmsdk\crm\api\response\EntityResponse; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* Description of ZohoDatabasePusher. |
15
|
|
|
* |
16
|
|
|
* @author rbergina |
17
|
|
|
*/ |
18
|
|
|
class ZohoDatabasePusher |
19
|
|
|
{ |
20
|
|
|
/** |
21
|
|
|
* @var Connection |
22
|
|
|
*/ |
23
|
|
|
private $connection; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @var LoggerInterface |
27
|
|
|
*/ |
28
|
|
|
private $logger; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @var string |
32
|
|
|
*/ |
33
|
|
|
private $prefix; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @param Connection $connection |
37
|
|
|
* @param int $apiLimitInsertUpdateDelete |
38
|
|
|
* @param string $prefix |
39
|
|
|
* @param LoggerInterface $logger |
40
|
|
|
*/ |
41
|
|
|
public function __construct(Connection $connection, $apiLimitInsertUpdateDelete = 100, $prefix = 'zoho_', LoggerInterface $logger = null) |
42
|
|
|
{ |
43
|
|
|
$this->connection = $connection; |
44
|
|
|
$this->prefix = $prefix; |
45
|
|
|
if ($logger === null) { |
46
|
|
|
$this->logger = new NullLogger(); |
47
|
|
|
} else { |
48
|
|
|
$this->logger = $logger; |
49
|
|
|
} |
50
|
|
|
$this->apiLimitInsertUpdateDelete = $apiLimitInsertUpdateDelete; |
51
|
|
|
if ($apiLimitInsertUpdateDelete === null) { |
52
|
|
|
$this->apiLimitInsertUpdateDelete = 100; |
53
|
|
|
} |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* @var int |
58
|
|
|
*/ |
59
|
|
|
private $apiLimitInsertUpdateDelete; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @param AbstractZohoDao $zohoDao |
63
|
|
|
* @param bool $update |
64
|
|
|
* @return int |
65
|
|
|
*/ |
66
|
|
|
private function countElementInTable(AbstractZohoDao $zohoDao, $update = false) |
67
|
|
|
{ |
68
|
|
|
$tableName = ZohoDatabaseHelper::getTableName($zohoDao, $this->prefix); |
69
|
|
|
if ($update) { |
70
|
|
|
return (int)$this->connection->executeQuery('SELECT COUNT(DISTINCT uid) AS nb FROM `local_update` WHERE table_name LIKE :tableName AND error IS NULL', ['tableName' => $tableName])->fetchColumn(); |
71
|
|
|
} |
72
|
|
|
return (int)$this->connection->executeQuery('SELECT COUNT(uid) AS nb FROM `local_insert` WHERE table_name LIKE :tableName AND error IS NULL', ['tableName' => $tableName])->fetchColumn(); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Insert or Update rows. |
77
|
|
|
* |
78
|
|
|
* @param AbstractZohoDao $zohoDao |
79
|
|
|
*/ |
80
|
|
|
public function pushDataToZoho(AbstractZohoDao $zohoDao, $update = false) |
81
|
|
|
{ |
82
|
|
|
$localTable = $update ? 'local_update' : 'local_insert'; |
83
|
|
|
$tableName = ZohoDatabaseHelper::getTableName($zohoDao, $this->prefix); |
84
|
|
|
$countToPush = $this->countElementInTable($zohoDao, $update); |
85
|
|
|
$this->logger->notice($countToPush . ' records to ' . ($update ? 'update' : 'insert') . ' into Zoho for module ' . $zohoDao->getPluralModuleName()); |
86
|
|
|
if ($countToPush) { |
87
|
|
|
do { |
88
|
|
|
$rowsDeleted = []; |
89
|
|
|
$zohoBeans = []; |
90
|
|
|
//@see https://www.zoho.com/crm/help/api/v2/#ra-update-records |
91
|
|
|
//To optimize your API usage, get maximum 200 records with each request and insert, update or delete maximum 100 records with each request. |
92
|
|
|
|
93
|
|
|
if ($update) { |
94
|
|
|
$recordsToUpdateQuery = $this->connection->createQueryBuilder(); |
95
|
|
|
$recordsToUpdateQuery |
96
|
|
|
->select('DISTINCT table_name, uid') |
97
|
|
|
->from($localTable) |
98
|
|
|
->where('error IS NULL') |
99
|
|
|
->andWhere('table_name = :table_name') |
100
|
|
|
->setMaxResults($this->apiLimitInsertUpdateDelete) |
101
|
|
|
->setParameters([ |
102
|
|
|
'table_name' => $tableName |
103
|
|
|
]); |
104
|
|
|
$recordsToUpdateResults = $recordsToUpdateQuery->execute()->fetchAll(); |
105
|
|
|
$this->logger->info(sprintf('Processing %s records to update...', count($recordsToUpdateResults))); |
106
|
|
|
foreach ($recordsToUpdateResults as $result) { |
107
|
|
|
$recordQuery = $this->connection->createQueryBuilder(); |
108
|
|
|
$recordQuery |
109
|
|
|
->select('*') |
110
|
|
|
->from($tableName) |
111
|
|
|
->where('uid = :uid') |
112
|
|
|
->setParameters([ |
113
|
|
|
'uid' => $result['uid'] |
114
|
|
|
]); |
115
|
|
|
$record = $recordQuery->execute()->fetch(); |
116
|
|
|
|
117
|
|
View Code Duplication |
if (!$record) { |
|
|
|
|
118
|
|
|
$errorMessage = sprintf('Impossible to find row with uid %s in the table %s', $result['uid'], $tableName); |
119
|
|
|
$this->logger->warning($errorMessage); |
120
|
|
|
$this->connection->update($localTable, [ |
121
|
|
|
'error' => $errorMessage, |
122
|
|
|
'errorTime' => date('Y-m-d H:i:s'), |
123
|
|
|
], [ |
124
|
|
|
'uid' => $result['uid'], |
125
|
|
|
'table_name' => $tableName |
126
|
|
|
]); |
127
|
|
|
continue; |
128
|
|
|
} |
129
|
|
|
|
130
|
|
View Code Duplication |
if (isset($zohoBeans[$record['uid']])) { |
|
|
|
|
131
|
|
|
$zohoBean = $zohoBeans[$record['uid']]; |
132
|
|
|
} else { |
133
|
|
|
$zohoBean = $zohoDao->create(); |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
if ($record['id'] && !$zohoBean->getZohoId()) { |
137
|
|
|
$zohoBean->setZohoId($record['id']); |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
$fieldsUpdatedQuery = $this->connection->createQueryBuilder(); |
141
|
|
|
$fieldsUpdatedQuery |
142
|
|
|
->select('field_name') |
143
|
|
|
->from($localTable) |
144
|
|
|
->where('uid = :uid') |
145
|
|
|
->andWhere('table_name = :table_name') |
146
|
|
|
->andWhere('error IS NULL') |
147
|
|
|
->setParameters([ |
148
|
|
|
'uid' => $result['uid'], |
149
|
|
|
'table_name' => $tableName, |
150
|
|
|
]); |
151
|
|
|
$fieldsUpdatedResults = $fieldsUpdatedQuery->execute()->fetchAll(); |
152
|
|
|
|
153
|
|
|
foreach ($fieldsUpdatedResults as $fieldResults) { |
154
|
|
|
$columnName = $fieldResults['field_name']; |
155
|
|
|
if (array_key_exists($columnName, $record)) { |
156
|
|
|
$this->updateDataZohoBean($zohoDao, $zohoBean, $columnName, $record[$columnName]); |
157
|
|
View Code Duplication |
} else { |
|
|
|
|
158
|
|
|
$errorMessage = sprintf('Impossible to find the column %s for row with uid %s in the table %s', $columnName, $result['uid'], $tableName); |
159
|
|
|
$this->logger->warning($errorMessage); |
160
|
|
|
$this->connection->update($localTable, [ |
161
|
|
|
'error' => $errorMessage, |
162
|
|
|
'errorTime' => date('Y-m-d H:i:s'), |
163
|
|
|
], [ |
164
|
|
|
'uid' => $result['uid'], |
165
|
|
|
'table_name' => $tableName, |
166
|
|
|
'field_name' => $columnName |
167
|
|
|
]); |
168
|
|
|
continue; |
169
|
|
|
} |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
$this->logger->debug(sprintf('Updated row %s (id: \'%s\') from table %s added in queue to be pushed.', $record['uid'], $record['id'], $tableName)); |
173
|
|
|
$zohoBeans[$record['uid']] = $zohoBean; |
174
|
|
|
$rowsDeleted[] = $record['uid']; |
175
|
|
|
} |
176
|
|
|
} else { |
177
|
|
|
$recordsToInsertQuery = $this->connection->createQueryBuilder(); |
178
|
|
|
$recordsToInsertQuery |
179
|
|
|
->select('DISTINCT table_name, uid') |
180
|
|
|
->from($localTable) |
181
|
|
|
->where('error IS NULL') |
182
|
|
|
->andWhere('table_name = :table_name') |
183
|
|
|
->setMaxResults($this->apiLimitInsertUpdateDelete) |
184
|
|
|
->setParameters([ |
185
|
|
|
'table_name' => $tableName |
186
|
|
|
]); |
187
|
|
|
$recordsToInsertResults = $recordsToInsertQuery->execute()->fetchAll(); |
188
|
|
|
$this->logger->info(sprintf('Processing %s records to insert...', count($recordsToInsertResults))); |
189
|
|
|
foreach ($recordsToInsertResults as $result) { |
190
|
|
|
$recordQuery = $this->connection->createQueryBuilder(); |
191
|
|
|
$recordQuery |
192
|
|
|
->select('*') |
193
|
|
|
->from($tableName) |
194
|
|
|
->where('uid = :uid') |
195
|
|
|
->setParameters([ |
196
|
|
|
'uid' => $result['uid'] |
197
|
|
|
]); |
198
|
|
|
$record = $recordQuery->execute()->fetch(); |
199
|
|
|
|
200
|
|
View Code Duplication |
if (!$record) { |
|
|
|
|
201
|
|
|
$errorMessage = sprintf('Impossible to find row with uid %s in the table %s', $result['uid'], $tableName); |
202
|
|
|
$this->logger->warning($errorMessage); |
203
|
|
|
$this->connection->update($localTable, [ |
204
|
|
|
'error' => $errorMessage, |
205
|
|
|
'errorTime' => date('Y-m-d H:i:s'), |
206
|
|
|
], [ |
207
|
|
|
'uid' => $result['uid'], |
208
|
|
|
'table_name' => $tableName |
209
|
|
|
]); |
210
|
|
|
continue; |
211
|
|
|
} |
212
|
|
|
|
213
|
|
View Code Duplication |
if (isset($zohoBeans[$record['uid']])) { |
|
|
|
|
214
|
|
|
$zohoBean = $zohoBeans[$record['uid']]; |
215
|
|
|
} else { |
216
|
|
|
$zohoBean = $zohoDao->create(); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
$this->logger->debug(sprintf('New row with uid %s from table %s added in queue to be pushed.', $record['uid'], $tableName)); |
220
|
|
|
$this->insertDataZohoBean($zohoDao, $zohoBean, $record); |
221
|
|
|
$zohoBeans[$record['uid']] = $zohoBean; |
222
|
|
|
$rowsDeleted[] = $record['uid']; |
223
|
|
|
} |
224
|
|
|
} |
225
|
|
|
if (count($zohoBeans)) { |
226
|
|
|
$this->sendDataToZohoCleanLocal($zohoDao, $zohoBeans, $rowsDeleted, $update); |
227
|
|
|
} |
228
|
|
|
$countToPush = $this->countElementInTable($zohoDao, $update); |
229
|
|
|
} while ($countToPush > 0); |
230
|
|
|
} |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* @param AbstractZohoDao $zohoDao |
235
|
|
|
* @param ZohoBeanInterface[] $zohoBeans |
236
|
|
|
* @param string[] $rowsDeleted |
237
|
|
|
* @param bool $update |
238
|
|
|
*/ |
239
|
|
|
private function sendDataToZohoCleanLocal(AbstractZohoDao $zohoDao, array $zohoBeans, $rowsDeleted, $update = false) |
|
|
|
|
240
|
|
|
{ |
241
|
|
|
$local_table = $update ? 'local_update' : 'local_insert'; |
242
|
|
|
$tableName = ZohoDatabaseHelper::getTableName($zohoDao, $this->prefix); |
243
|
|
|
$entityResponses = $zohoDao->save($zohoBeans); |
244
|
|
|
$responseKey = 0; |
245
|
|
|
foreach ($zohoBeans as $uid => $zohoBean) { |
246
|
|
|
$response = $entityResponses[$responseKey]->getResponseJSON(); |
247
|
|
|
if (strtolower($response['code']) === 'success') { |
248
|
|
|
if ($update) { |
249
|
|
|
$this->logger->debug(sprintf('Updated successfully the record with uid %s (id \'%s\') from the table %s', $uid, $zohoBean->getZohoId(), $tableName)); |
250
|
|
|
$this->connection->executeQuery( |
251
|
|
|
'DELETE FROM local_update WHERE uid LIKE :uid AND table_name = :table_name AND error IS NULL', |
252
|
|
|
[ |
253
|
|
|
'uid' => $uid, |
254
|
|
|
'table_name' => $tableName |
255
|
|
|
] |
256
|
|
|
); |
257
|
|
|
} else { |
258
|
|
|
$countResult = (int)$this->connection->fetchColumn('select count(id) from ' . $tableName . ' where id = :id', ['id' => $zohoBean->getZohoId()]); |
259
|
|
|
//If the sent data were duplicates Zoho can merged so we need to check if the Zoho ID already exist. |
260
|
|
|
if ($countResult === 0) { |
261
|
|
|
// ID not exist we can update the new row with the Zoho ID |
262
|
|
|
$this->connection->beginTransaction(); |
263
|
|
|
$this->connection->update($tableName, ['id' => $zohoBean->getZohoId()], ['uid' => $uid]); |
264
|
|
|
$this->connection->delete('local_insert', ['table_name' => $tableName, 'uid' => $uid]); |
265
|
|
|
$this->connection->commit(); |
266
|
|
|
$this->logger->debug(sprintf('Inserted successfully the record with uid %s (id \'%s\') from the table %s', $uid, $zohoBean->getZohoId(), $tableName)); |
267
|
|
|
} else { |
268
|
|
|
//ID already exist we need to delete the duplicate row. |
269
|
|
|
$this->connection->beginTransaction(); |
270
|
|
|
$this->connection->delete($tableName, ['uid' => $uid]); |
271
|
|
|
$this->connection->delete('local_insert', ['table_name' => $tableName, 'uid' => $uid]); |
272
|
|
|
$this->connection->commit(); |
273
|
|
|
$this->logger->warning(sprintf('Duplicate record found when inserting record with uid %s from the table %s. ID updated: %s. UID deleted: %s', $uid, $tableName, $zohoBean->getZohoId(), $uid)); |
274
|
|
|
} |
275
|
|
|
} |
276
|
|
|
} else { |
277
|
|
|
$errorMessage = sprintf('An error occurred when %s record with uid %s from table %s into Zoho: %s', ($update ? 'updating' : 'inserting'), $uid, $tableName, json_encode($response)); |
278
|
|
|
$this->logger->error($errorMessage); |
279
|
|
|
$this->connection->update($local_table, [ |
280
|
|
|
'error' => $errorMessage, |
281
|
|
|
'errorTime' => date('Y-m-d H:i:s') |
282
|
|
|
], [ |
283
|
|
|
'uid' => $uid, |
284
|
|
|
'table_name' => $tableName |
285
|
|
|
]); |
286
|
|
|
} |
287
|
|
|
$responseKey++; |
288
|
|
|
} |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
private function endsWith($haystack, $needle) { |
292
|
|
|
return substr_compare($haystack, $needle, -strlen($needle)) === 0; |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
/** |
296
|
|
|
* Insert data to bean in order to insert zoho records. |
297
|
|
|
* |
298
|
|
|
* @param AbstractZohoDao $dao |
299
|
|
|
* @param ZohoBeanInterface $zohoBean |
300
|
|
|
* @param array $row |
301
|
|
|
*/ |
302
|
|
|
private function insertDataZohoBean(AbstractZohoDao $dao, ZohoBeanInterface $zohoBean, array $row) |
303
|
|
|
{ |
304
|
|
|
foreach ($row as $columnName => $columnValue) { |
305
|
|
|
$fieldMethod = $dao->getFieldFromFieldName($columnName); |
306
|
|
View Code Duplication |
if (!in_array($columnName, EntitiesGeneratorService::$defaultDateFields) && $fieldMethod |
|
|
|
|
307
|
|
|
&& (!in_array($columnName, ['id', 'uid'])) && !is_null($columnValue) |
308
|
|
|
) { |
309
|
|
|
// Changing only Name doesn't work properly on Zoho |
310
|
|
|
if ($this->endsWith($columnName, '_OwnerName') || $this->endsWith($columnName, '_Name')) { |
311
|
|
|
continue; |
312
|
|
|
} |
313
|
|
|
$type = $fieldMethod->getType(); |
314
|
|
|
$value = $this->formatValueToBeans($type, $columnValue); |
315
|
|
|
$setterMethod = $fieldMethod->getSetter(); |
316
|
|
|
$zohoBean->{$setterMethod}($value); |
317
|
|
|
} |
318
|
|
|
} |
319
|
|
|
} |
320
|
|
|
|
321
|
|
|
/** |
322
|
|
|
* Insert data to bean in order to update zoho records. |
323
|
|
|
* |
324
|
|
|
* @param ZohoBeanInterface $zohoBean |
325
|
|
|
* @param array $fieldsMatching |
|
|
|
|
326
|
|
|
* @param type $columnName |
327
|
|
|
* @param type $valueDb |
328
|
|
|
*/ |
329
|
|
|
private function updateDataZohoBean(AbstractZohoDao $dao, ZohoBeanInterface $zohoBean, $columnName, $valueDb) |
330
|
|
|
{ |
331
|
|
|
$fieldMethod = $dao->getFieldFromFieldName($columnName); |
332
|
|
View Code Duplication |
if (!in_array($columnName, EntitiesGeneratorService::$defaultDateFields) && $fieldMethod |
|
|
|
|
333
|
|
|
&& !in_array($columnName, ['id', 'uid']) |
334
|
|
|
) { |
335
|
|
|
// Changing only Name doesn't work properly on Zoho |
336
|
|
|
if ($this->endsWith($columnName, '_OwnerName') || $this->endsWith($columnName, '_Name')) { |
337
|
|
|
return; |
338
|
|
|
} |
339
|
|
|
$type = $fieldMethod->getType(); |
340
|
|
|
$value = is_null($valueDb) ? $valueDb : $this->formatValueToBeans($type, $valueDb); |
341
|
|
|
$setterMethod = $fieldMethod->getSetter(); |
342
|
|
|
$zohoBean->{$setterMethod}($value); |
343
|
|
|
} |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
/** |
347
|
|
|
* Change the value to the good format. |
348
|
|
|
* |
349
|
|
|
* @param string $type |
350
|
|
|
* @param mixed $value |
351
|
|
|
* |
352
|
|
|
* @return mixed |
353
|
|
|
*/ |
354
|
|
|
private function formatValueToBeans($type, $value) |
355
|
|
|
{ |
356
|
|
|
switch ($type) { |
357
|
|
|
case 'date': |
358
|
|
|
$value = \DateTime::createFromFormat('Y-m-d', $value) ?: null; |
359
|
|
|
break; |
360
|
|
|
case 'datetime': |
361
|
|
|
$value = \DateTime::createFromFormat('Y-m-d H:i:s', $value) ?: null; |
362
|
|
|
break; |
363
|
|
|
case 'boolean' : |
364
|
|
|
$value = (bool)$value; |
365
|
|
|
break; |
366
|
|
|
case 'percent' : |
367
|
|
|
$value = (int)$value; |
368
|
|
|
break; |
369
|
|
|
case 'double' : |
370
|
|
|
$value = number_format($value, 2); |
371
|
|
|
break; |
372
|
|
|
case 'multiselectlookup': |
373
|
|
|
case 'multiuserlookup': |
374
|
|
|
case 'multiselectpicklist': |
375
|
|
|
$value = explode(';', $value); |
376
|
|
|
break; |
377
|
|
|
} |
378
|
|
|
|
379
|
|
|
return $value; |
380
|
|
|
} |
381
|
|
|
|
382
|
|
|
/** |
383
|
|
|
* Run deleted rows to Zoho : local_delete. |
384
|
|
|
* |
385
|
|
|
* @param AbstractZohoDao $zohoDao |
386
|
|
|
*/ |
387
|
|
|
public function pushDeletedRows(AbstractZohoDao $zohoDao) |
388
|
|
|
{ |
389
|
|
|
$localTable = 'local_delete'; |
390
|
|
|
$tableName = ZohoDatabaseHelper::getTableName($zohoDao, $this->prefix); |
391
|
|
|
$statement = $this->connection->createQueryBuilder(); |
392
|
|
|
$statement->select('l.id') |
393
|
|
|
->from($localTable, 'l') |
394
|
|
|
->where('l.table_name=:table_name') |
395
|
|
|
->setParameters( |
396
|
|
|
[ |
397
|
|
|
'table_name' => $tableName, |
398
|
|
|
] |
399
|
|
|
); |
400
|
|
|
$results = $statement->execute(); |
401
|
|
|
while ($row = $results->fetch()) { |
402
|
|
|
$zohoDao->delete($row['id']); |
403
|
|
|
$this->connection->delete($localTable, ['table_name' => $tableName, 'id' => $row['id']]); |
404
|
|
|
} |
405
|
|
|
} |
406
|
|
|
|
407
|
|
|
/** |
408
|
|
|
* Run inserted rows to Zoho : local_insert. |
409
|
|
|
* |
410
|
|
|
* @param AbstractZohoDao $zohoDao |
411
|
|
|
*/ |
412
|
|
|
public function pushInsertedRows(AbstractZohoDao $zohoDao) |
413
|
|
|
{ |
414
|
|
|
$this->pushDataToZoho($zohoDao); |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
/** |
418
|
|
|
* Run updated rows to Zoho : local_update. |
419
|
|
|
* |
420
|
|
|
* @param AbstractZohoDao $zohoDao |
421
|
|
|
*/ |
422
|
|
|
public function pushUpdatedRows(AbstractZohoDao $zohoDao) |
423
|
|
|
{ |
424
|
|
|
$this->pushDataToZoho($zohoDao, true); |
425
|
|
|
} |
426
|
|
|
|
427
|
|
|
/** |
428
|
|
|
* Push data from db to Zoho. |
429
|
|
|
* |
430
|
|
|
* @param AbstractZohoDao $zohoDao |
431
|
|
|
*/ |
432
|
|
|
public function pushToZoho(AbstractZohoDao $zohoDao) |
433
|
|
|
{ |
434
|
|
|
$this->logger->info(sprintf('Pushing inserted rows for module %s into Zoho...', $zohoDao->getPluralModuleName())); |
435
|
|
|
$this->pushInsertedRows($zohoDao); |
436
|
|
|
$this->logger->info(sprintf('Pushing updated rows for module %s into Zoho...', $zohoDao->getPluralModuleName())); |
437
|
|
|
$this->pushUpdatedRows($zohoDao); |
438
|
|
|
$this->logger->info(sprintf('Pushing deleted rows for module %s into Zoho...', $zohoDao->getPluralModuleName())); |
439
|
|
|
$this->pushDeletedRows($zohoDao); |
440
|
|
|
} |
441
|
|
|
} |
442
|
|
|
|
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.