Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like AbstractZohoDao often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use AbstractZohoDao, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 13 | abstract class AbstractZohoDao |
||
| 14 | { |
||
| 15 | const ON_DUPLICATE_THROW = 1; |
||
| 16 | const ON_DUPLICATE_MERGE = 2; |
||
| 17 | const MAX_GET_RECORDS = 200; |
||
| 18 | const MAX_GET_RECORDS_BY_ID = 100; |
||
| 19 | const MAX_SIMULTANEOUS_SAVE = 100; |
||
| 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 | public function __construct(ZohoClient $zohoClient) |
||
| 29 | { |
||
| 30 | $this->zohoClient = $zohoClient; |
||
| 31 | } |
||
| 32 | |||
| 33 | abstract protected function getModule(); |
||
| 38 | |||
| 39 | protected $flatFields; |
||
| 40 | |||
| 41 | /** |
||
| 42 | * Returns a flat list of all fields. |
||
| 43 | * |
||
| 44 | * @return array The array of field names for a module |
||
| 45 | */ |
||
| 46 | protected function getFlatFields() |
||
| 57 | |||
| 58 | protected $duplicateCheck = self::ON_DUPLICATE_MERGE; |
||
| 59 | |||
| 60 | public function setDuplicateCheck($duplicateCheck) |
||
| 64 | |||
| 65 | protected $wfTrigger = false; |
||
| 66 | |||
| 67 | public function setWorkflowTrigger($wfTrigger) |
||
| 71 | |||
| 72 | /** |
||
| 73 | * Parse a Zoho Response in order to retrieve one or several ZohoBeans from it. |
||
| 74 | * |
||
| 75 | * @param Response $zohoResponse The response returned by the ZohoClient->call() method |
||
| 76 | * |
||
| 77 | * @return ZohoBeanInterface[] The array of Zoho Beans parsed from the response |
||
| 78 | */ |
||
| 79 | protected function getBeansFromResponse(Response $zohoResponse) |
||
| 137 | |||
| 138 | /** |
||
| 139 | * Convert an array of ZohoBeans into a SimpleXMLElement for use when inserting/updating related records. |
||
| 140 | * |
||
| 141 | * @param $zohoBeans ZohoBeanInterface[] |
||
| 142 | * |
||
| 143 | * @return \SimpleXMLElement The SimpleXMLElement containing the XML for a request |
||
| 144 | */ |
||
| 145 | public function toXmlRelatedRecords($zohoBeans) |
||
| 149 | |||
| 150 | /** |
||
| 151 | * Convert an array of ZohoBeans into a SimpleXMLElement. |
||
| 152 | * |
||
| 153 | * @param $zohoBeans ZohoBeanInterface[] |
||
| 154 | * |
||
| 155 | * @return \SimpleXMLElement The SimpleXMLElement containing the XML for a request |
||
| 156 | */ |
||
| 157 | public function toXml($zohoBeans, $isRelatedRecords = 0) |
||
| 220 | |||
| 221 | /** |
||
| 222 | * Implements deleteRecords API method. |
||
| 223 | * |
||
| 224 | * @param string $id Zoho Id of the record to delete |
||
| 225 | * |
||
| 226 | * @throws ZohoCRMResponseException |
||
| 227 | */ |
||
| 228 | public function delete($id) |
||
| 232 | |||
| 233 | /** |
||
| 234 | * Implements getRecordById API method. |
||
| 235 | * |
||
| 236 | * @param string|array $id Zoho Id of the record to retrieve OR an array of IDs |
||
| 237 | * |
||
| 238 | * @return ZohoBeanInterface[] The array of Zoho Beans parsed from the response |
||
| 239 | * |
||
| 240 | * @throws ZohoCRMResponseException |
||
| 241 | */ |
||
| 242 | public function getById($id) |
||
| 273 | |||
| 274 | /** |
||
| 275 | * Implements getRecords API method. |
||
| 276 | * |
||
| 277 | * @param $sortColumnString |
||
| 278 | * @param $sortOrderString |
||
| 279 | * @param \DateTime $lastModifiedTime |
||
| 280 | * @param $selectColumns |
||
| 281 | * @param $limit |
||
| 282 | * |
||
| 283 | * @return ZohoBeanInterface[] The array of Zoho Beans parsed from the response |
||
| 284 | * |
||
| 285 | * @throws ZohoCRMResponseException |
||
| 286 | */ |
||
| 287 | View Code Duplication | public function getRecords($sortColumnString = null, $sortOrderString = null, \DateTime $lastModifiedTime = null, $selectColumns = null, $limit = null) |
|
| 316 | |||
| 317 | /** |
||
| 318 | * Returns the list of deleted records. |
||
| 319 | * |
||
| 320 | * @param \DateTimeInterface|null $lastModifiedTime |
||
| 321 | * @param int $limit |
||
| 322 | * |
||
| 323 | * @return array |
||
| 324 | * |
||
| 325 | * @throws ZohoCRMResponseException |
||
| 326 | * @throws \Exception |
||
| 327 | */ |
||
| 328 | View Code Duplication | public function getDeletedRecordIds(\DateTimeInterface $lastModifiedTime = null, $limit = null) |
|
| 357 | |||
| 358 | /** |
||
| 359 | * Implements getRecords API method. |
||
| 360 | * |
||
| 361 | * @param string $id Zoho Id of the record to delete |
||
| 362 | * @param string $parentModule The parent module of the records |
||
| 363 | * @param int $limit The max number of records to fetch |
||
| 364 | * |
||
| 365 | * @return ZohoBeanInterface[] The array of Zoho Beans parsed from the response |
||
| 366 | * |
||
| 367 | * @throws ZohoCRMResponseException |
||
| 368 | */ |
||
| 369 | View Code Duplication | public function getRelatedRecords($id, $parentModule, $limit = null) |
|
| 398 | |||
| 399 | /** |
||
| 400 | * Implements searchRecords API method. |
||
| 401 | * |
||
| 402 | * @param string $searchCondition The search criteria formatted like |
||
| 403 | * @param int $limit The maximum number of beans returned from Zoho |
||
| 404 | * @param \DateTime $lastModifiedTime |
||
| 405 | * @param string $selectColumns The list |
||
| 406 | * |
||
| 407 | * @return ZohoBeanInterface[] The array of Zoho Beans parsed from the response |
||
| 408 | * |
||
| 409 | * @throws ZohoCRMResponseException |
||
| 410 | */ |
||
| 411 | View Code Duplication | public function searchRecords($searchCondition = null, $limit = null, \DateTime $lastModifiedTime = null, $selectColumns = null) |
|
| 440 | |||
| 441 | /** |
||
| 442 | * Implements insertRecords API method. |
||
| 443 | * |
||
| 444 | * WARNING : When setting wfTrigger to true, this method will use an API call per bean |
||
| 445 | * passed in argument. This is caused by Zoho limitation which forbids triggering any |
||
| 446 | * workflow when inserting several beans simultaneously. |
||
| 447 | * |
||
| 448 | * @param ZohoBeanInterface[] $beans The Zoho Beans to insert in the CRM |
||
| 449 | * @param bool $wfTrigger Whether or not the call should trigger the workflows related to a "created" event |
||
| 450 | * @param int $duplicateCheck 1 : Throwing error when a duplicate is found; 2 : Merging with existing duplicate |
||
| 451 | * @param bool $isApproval Whether or not to push the record into an approval sandbox first |
||
| 452 | * |
||
| 453 | * @throws ZohoCRMResponseException |
||
| 454 | */ |
||
| 455 | public function insertRecords($beans, $wfTrigger = null, $duplicateCheck = null, $isApproval = null) |
||
| 500 | |||
| 501 | /** |
||
| 502 | * Implements updateRecords API method. |
||
| 503 | * |
||
| 504 | * @param array $beans The list of beans to update. |
||
| 505 | * @param bool $wfTrigger Set value as true to trigger the workflow rule in Zoho |
||
| 506 | * |
||
| 507 | * @return Response The Response object |
||
| 508 | * |
||
| 509 | * @throws ZohoCRMException |
||
| 510 | */ |
||
| 511 | public function updateRecords(array $beans, $wfTrigger = null) |
||
| 564 | |||
| 565 | /** |
||
| 566 | * Implements uploadFile API method. |
||
| 567 | * |
||
| 568 | * @param string $id Zoho Id of the record to retrieve |
||
| 569 | * @param string $content The string containing the file |
||
| 570 | * |
||
| 571 | * @return Response The Response object |
||
| 572 | * |
||
| 573 | * @throws ZohoCRMResponseException |
||
| 574 | */ |
||
| 575 | public function uploadFile($id, $content) |
||
| 579 | |||
| 580 | /** |
||
| 581 | * Implements downloadFile API method. |
||
| 582 | * |
||
| 583 | * @param string $id unique ID of the attachment |
||
| 584 | * |
||
| 585 | * @return Response The Response object |
||
| 586 | */ |
||
| 587 | public function downloadFile($id) |
||
| 591 | |||
| 592 | /** |
||
| 593 | * Saves the bean or array of beans passed in Zoho. |
||
| 594 | * It will perform an insert if the bean has no ZohoID or an update if the bean has a ZohoID. |
||
| 595 | * |
||
| 596 | * @param array|object $beans A bean or an array of beans. |
||
| 597 | * |
||
| 598 | * TODO: isApproval is not used by each module. |
||
| 599 | * TODO: wfTrigger only usable for a single record update/insert. |
||
| 600 | */ |
||
| 601 | public function save($beans, $wfTrigger = null, $duplicateCheck = null, $isApproval = false) |
||
| 629 | } |
||
| 630 |