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 Paystack 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 Paystack, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
18 | class Paystack |
||
19 | { |
||
20 | /** |
||
21 | * Transaction Verification Successful |
||
22 | */ |
||
23 | const VERIFICATION_SUCCESSFUL = 'Verification successful'; |
||
24 | |||
25 | /** |
||
26 | * Invalid Transaction reference |
||
27 | */ |
||
28 | const INVALID_TRANSACTION_REFERENCE = "Invalid transaction reference"; |
||
29 | |||
30 | /** |
||
31 | * Response from requests made to Paystack |
||
32 | * @var array |
||
33 | */ |
||
34 | protected $response; |
||
35 | |||
36 | /** |
||
37 | * Authorization Url - Paystack payment page |
||
38 | * @var string |
||
39 | */ |
||
40 | protected $authorizationUrl; |
||
41 | |||
42 | /** |
||
43 | * @var \Xeviant\Paystack\Client |
||
44 | */ |
||
45 | private $paystack; |
||
46 | |||
47 | /** |
||
48 | * Authorization URL |
||
49 | * |
||
50 | * @var string |
||
51 | */ |
||
52 | private $url; |
||
53 | |||
54 | /** |
||
55 | * Paystack constructor. |
||
56 | */ |
||
57 | public function __construct() |
||
61 | |||
62 | |||
63 | /** |
||
64 | * Initiate a payment request to Paystack |
||
65 | * Included the option to pass the payload to this method for situations |
||
66 | * when the payload is built on the fly (not passed to the controller from a view) |
||
67 | * @param null $data |
||
68 | * @return Paystack |
||
69 | */ |
||
70 | public function makePaymentRequest($data = null) |
||
105 | |||
106 | /** |
||
107 | * Get the authorization url from the callback response |
||
108 | * @return Paystack |
||
109 | */ |
||
110 | public function getAuthorizationUrl() |
||
118 | |||
119 | /** |
||
120 | * Get the authorization callback response |
||
121 | * In situations where Laravel serves as an backend for a detached UI, the api cannot redirect |
||
122 | * and might need to take different actions based on the success or not of the transaction |
||
123 | * @param $data |
||
124 | * @return array |
||
125 | */ |
||
126 | public function getAuthorizationResponse($data) |
||
134 | |||
135 | /** |
||
136 | * Hit Paystack Gateway to Verify that the transaction is valid |
||
137 | */ |
||
138 | private function verifyTransactionAtGateway() |
||
144 | |||
145 | /** |
||
146 | * True or false condition whether the transaction is verified |
||
147 | * @return boolean |
||
148 | */ |
||
149 | public function isTransactionVerificationValid() |
||
169 | |||
170 | /** |
||
171 | * Get Payment details if the transaction was verified successfully |
||
172 | * @return array |
||
173 | * @throws PaymentVerificationFailedException |
||
174 | */ |
||
175 | public function getPaymentData() |
||
183 | |||
184 | /** |
||
185 | * Fluent method to redirect to Paystack Payment Page |
||
186 | */ |
||
187 | public function redirectNow() |
||
191 | |||
192 | /** |
||
193 | * Get Access code from transaction callback response |
||
194 | * @return string |
||
195 | */ |
||
196 | public function getAccessCode() |
||
200 | |||
201 | /** |
||
202 | * Generate a Unique Transaction Reference |
||
203 | * @return string |
||
204 | */ |
||
205 | public function genTranxRef() |
||
209 | |||
210 | /** |
||
211 | * Get all the customers that have made transactions on your platform |
||
212 | * @return array |
||
213 | */ |
||
214 | public function getAllCustomers() |
||
218 | |||
219 | /** |
||
220 | * Get all the plans that you have on Paystack |
||
221 | * @return array |
||
222 | */ |
||
223 | public function getAllPlans() |
||
227 | |||
228 | /** |
||
229 | * Get all the transactions that have happened overtime |
||
230 | * @return array |
||
231 | */ |
||
232 | public function getAllTransactions() |
||
236 | |||
237 | /** |
||
238 | * Get the whole response from a get operation |
||
239 | * @return array |
||
240 | */ |
||
241 | private function getResponse() |
||
245 | |||
246 | /** |
||
247 | * Create a plan |
||
248 | */ |
||
249 | View Code Duplication | public function createPlan() |
|
263 | |||
264 | /** |
||
265 | * Fetch any plan based on its plan id or code |
||
266 | * @param $planCode |
||
267 | * @return array |
||
268 | */ |
||
269 | public function fetchPlan($planCode) |
||
273 | |||
274 | /** |
||
275 | * Update any plan's details based on its id or code |
||
276 | * @param $planCode |
||
277 | * @return array |
||
278 | */ |
||
279 | View Code Duplication | public function updatePlan($planCode) |
|
293 | |||
294 | /** |
||
295 | * Create a customer |
||
296 | */ |
||
297 | View Code Duplication | public function createCustomer() |
|
310 | |||
311 | /** |
||
312 | * Fetch a customer based on id or code |
||
313 | * @param $customerId |
||
314 | * @return array |
||
315 | */ |
||
316 | public function fetchCustomer($customerId) |
||
320 | |||
321 | /** |
||
322 | * Update a customer's details based on their id or code |
||
323 | * @param $customerId |
||
324 | * @return array |
||
325 | */ |
||
326 | View Code Duplication | public function updateCustomer($customerId) |
|
339 | |||
340 | /** |
||
341 | * Export transactions in .CSV |
||
342 | * @return array |
||
343 | */ |
||
344 | public function exportTransactions() |
||
354 | |||
355 | /** |
||
356 | * Create a subscription to a plan from a customer. |
||
357 | */ |
||
358 | public function createSubscription() |
||
368 | |||
369 | /** |
||
370 | * Get all the subscriptions made on Paystack. |
||
371 | * |
||
372 | * @return array |
||
373 | */ |
||
374 | public function getAllSubscriptions() |
||
378 | |||
379 | /** |
||
380 | * Get customer subscriptions |
||
381 | * |
||
382 | * @param integer $customerId |
||
383 | * @return array |
||
384 | */ |
||
385 | public function getCustomerSubscriptions($customerId) |
||
389 | |||
390 | /** |
||
391 | * Get plan subscriptions |
||
392 | * |
||
393 | * @param integer $planId |
||
394 | * @return array |
||
395 | */ |
||
396 | public function getPlanSubscriptions($planId) |
||
400 | |||
401 | /** |
||
402 | * Enable a subscription using the subscription code and token |
||
403 | * @return array |
||
404 | */ |
||
405 | public function enableSubscription() |
||
414 | |||
415 | /** |
||
416 | * Disable a subscription using the subscription code and token |
||
417 | * @return array |
||
418 | */ |
||
419 | public function disableSubscription() |
||
428 | |||
429 | /** |
||
430 | * Fetch details about a certain subscription |
||
431 | * @param mixed $subscriptionId |
||
432 | * @return array |
||
433 | */ |
||
434 | public function fetchSubscription($subscriptionId) |
||
438 | |||
439 | /** |
||
440 | * Create pages you can share with users using the returned slug |
||
441 | */ |
||
442 | View Code Duplication | public function createPage() |
|
452 | |||
453 | /** |
||
454 | * Fetches all the pages the merchant has |
||
455 | * @return array |
||
456 | */ |
||
457 | public function getAllPages() |
||
461 | |||
462 | /** |
||
463 | * Fetch details about a certain page using its id or slug |
||
464 | * @param mixed $pageId |
||
465 | * @return array |
||
466 | */ |
||
467 | public function fetchPage($pageId) |
||
471 | |||
472 | /** |
||
473 | * Update the details about a particular page |
||
474 | * @param $pageId |
||
475 | * @return array |
||
476 | */ |
||
477 | View Code Duplication | public function updatePage($pageId) |
|
487 | |||
488 | /** |
||
489 | * Creates a subaccount to be used for split payments . Required params are business_name , settlement_bank , account_number , percentage_charge |
||
490 | * |
||
491 | * @return array |
||
492 | */ |
||
493 | |||
494 | View Code Duplication | public function createSubAccount() |
|
510 | |||
511 | /** |
||
512 | * Fetches details of a subaccount |
||
513 | * @param subaccount code |
||
514 | * @return array |
||
515 | */ |
||
516 | public function fetchSubAccount($subAccountCode) |
||
520 | |||
521 | /** |
||
522 | * Lists all the subaccounts associated with the account |
||
523 | * @param $perPage - Specifies how many records to retrieve per page , $page - SPecifies exactly what page to retrieve |
||
524 | * @param $page |
||
525 | * @return array |
||
526 | */ |
||
527 | public function listSubAccounts($perPage = null, $page = null) |
||
531 | |||
532 | |||
533 | /** |
||
534 | * Updates a sub-account to be used for split payments . Required params are business_name , settlement_bank , account_number , percentage_charge |
||
535 | * @param sub-account code |
||
536 | * @return array |
||
537 | */ |
||
538 | |||
539 | View Code Duplication | public function updateSubAccount($subAccountCode) |
|
556 | } |
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.