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 Telegram 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 Telegram, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
26 | class Telegram |
||
27 | { |
||
28 | /** |
||
29 | * Version |
||
30 | * |
||
31 | * @var string |
||
32 | */ |
||
33 | protected $version = '0.56.0'; |
||
34 | |||
35 | /** |
||
36 | * Telegram API key |
||
37 | * |
||
38 | * @var string |
||
39 | */ |
||
40 | protected $api_key = ''; |
||
41 | |||
42 | /** |
||
43 | * Telegram Bot username |
||
44 | * |
||
45 | * @var string |
||
46 | */ |
||
47 | protected $bot_username = ''; |
||
48 | |||
49 | /** |
||
50 | * Telegram Bot id |
||
51 | * |
||
52 | * @var string |
||
53 | */ |
||
54 | protected $bot_id = ''; |
||
55 | |||
56 | /** |
||
57 | * Raw request data (json) for webhook methods |
||
58 | * |
||
59 | * @var string |
||
60 | */ |
||
61 | protected $input; |
||
62 | |||
63 | /** |
||
64 | * Custom commands paths |
||
65 | * |
||
66 | * @var array |
||
67 | */ |
||
68 | protected $commands_paths = []; |
||
69 | |||
70 | /** |
||
71 | * Current Update object |
||
72 | * |
||
73 | * @var \Longman\TelegramBot\Entities\Update |
||
74 | */ |
||
75 | protected $update; |
||
76 | |||
77 | /** |
||
78 | * Upload path |
||
79 | * |
||
80 | * @var string |
||
81 | */ |
||
82 | protected $upload_path; |
||
83 | |||
84 | /** |
||
85 | * Download path |
||
86 | * |
||
87 | * @var string |
||
88 | */ |
||
89 | protected $download_path; |
||
90 | |||
91 | /** |
||
92 | * MySQL integration |
||
93 | * |
||
94 | * @var boolean |
||
95 | */ |
||
96 | protected $mysql_enabled = false; |
||
97 | |||
98 | /** |
||
99 | * PDO object |
||
100 | * |
||
101 | * @var \PDO |
||
102 | */ |
||
103 | protected $pdo; |
||
104 | |||
105 | /** |
||
106 | * Commands config |
||
107 | * |
||
108 | * @var array |
||
109 | */ |
||
110 | protected $commands_config = []; |
||
111 | |||
112 | /** |
||
113 | * Admins list |
||
114 | * |
||
115 | * @var array |
||
116 | */ |
||
117 | protected $admins_list = []; |
||
118 | |||
119 | /** |
||
120 | * ServerResponse of the last Command execution |
||
121 | * |
||
122 | * @var \Longman\TelegramBot\Entities\ServerResponse |
||
123 | */ |
||
124 | protected $last_command_response; |
||
125 | |||
126 | /** |
||
127 | * Check if runCommands() is running in this session |
||
128 | * |
||
129 | * @var boolean |
||
130 | */ |
||
131 | protected $run_commands = false; |
||
132 | |||
133 | /** |
||
134 | * Is running getUpdates without DB enabled |
||
135 | * |
||
136 | * @var bool |
||
137 | */ |
||
138 | protected $getupdates_without_database = false; |
||
139 | |||
140 | /** |
||
141 | * Last update ID |
||
142 | * Only used when running getUpdates without a database |
||
143 | * |
||
144 | * @var integer |
||
145 | */ |
||
146 | protected $last_update_id = null; |
||
147 | |||
148 | /** |
||
149 | * Telegram constructor. |
||
150 | * |
||
151 | * @param string $api_key |
||
152 | * @param string $bot_username |
||
153 | * |
||
154 | * @throws \Longman\TelegramBot\Exception\TelegramException |
||
155 | */ |
||
156 | 30 | public function __construct($api_key, $bot_username = '') |
|
177 | |||
178 | /** |
||
179 | * Initialize Database connection |
||
180 | * |
||
181 | * @param array $credential |
||
182 | * @param string $table_prefix |
||
183 | * @param string $encoding |
||
184 | * |
||
185 | * @return \Longman\TelegramBot\Telegram |
||
186 | * @throws \Longman\TelegramBot\Exception\TelegramException |
||
187 | */ |
||
188 | 9 | View Code Duplication | public function enableMySql(array $credential, $table_prefix = null, $encoding = 'utf8mb4') |
196 | |||
197 | /** |
||
198 | * Initialize Database external connection |
||
199 | * |
||
200 | * @param PDO $external_pdo_connection PDO database object |
||
201 | * @param string $table_prefix |
||
202 | * |
||
203 | * @return \Longman\TelegramBot\Telegram |
||
204 | * @throws \Longman\TelegramBot\Exception\TelegramException |
||
205 | */ |
||
206 | View Code Duplication | public function enableExternalMySql($external_pdo_connection, $table_prefix = null) |
|
214 | |||
215 | /** |
||
216 | * Get commands list |
||
217 | * |
||
218 | * @return array $commands |
||
219 | * @throws \Longman\TelegramBot\Exception\TelegramException |
||
220 | */ |
||
221 | 1 | public function getCommandsList() |
|
258 | |||
259 | /** |
||
260 | * Get an object instance of the passed command |
||
261 | * |
||
262 | * @param string $command |
||
263 | * |
||
264 | * @return \Longman\TelegramBot\Commands\Command|null |
||
265 | */ |
||
266 | 1 | public function getCommandObject($command) |
|
281 | |||
282 | /** |
||
283 | * Set custom input string for debug purposes |
||
284 | * |
||
285 | * @param string $input (json format) |
||
286 | * |
||
287 | * @return \Longman\TelegramBot\Telegram |
||
288 | */ |
||
289 | public function setCustomInput($input) |
||
295 | |||
296 | /** |
||
297 | * Get custom input string for debug purposes |
||
298 | * |
||
299 | * @return string |
||
300 | */ |
||
301 | public function getCustomInput() |
||
305 | |||
306 | /** |
||
307 | * Get the ServerResponse of the last Command execution |
||
308 | * |
||
309 | * @return \Longman\TelegramBot\Entities\ServerResponse |
||
310 | */ |
||
311 | public function getLastCommandResponse() |
||
315 | |||
316 | /** |
||
317 | * Handle getUpdates method |
||
318 | * |
||
319 | * @param int|null $limit |
||
320 | * @param int|null $timeout |
||
321 | * |
||
322 | * @return \Longman\TelegramBot\Entities\ServerResponse |
||
323 | * @throws \Longman\TelegramBot\Exception\TelegramException |
||
324 | */ |
||
325 | public function handleGetUpdates($limit = null, $timeout = null) |
||
391 | |||
392 | /** |
||
393 | * Handle bot request from webhook |
||
394 | * |
||
395 | * @return bool |
||
396 | * |
||
397 | * @throws \Longman\TelegramBot\Exception\TelegramException |
||
398 | */ |
||
399 | public function handle() |
||
422 | |||
423 | /** |
||
424 | * Get the command name from the command type |
||
425 | * |
||
426 | * @param string $type |
||
427 | * |
||
428 | * @return string |
||
429 | */ |
||
430 | protected function getCommandFromType($type) |
||
434 | |||
435 | /** |
||
436 | * Process bot Update request |
||
437 | * |
||
438 | * @param \Longman\TelegramBot\Entities\Update $update |
||
439 | * |
||
440 | * @return \Longman\TelegramBot\Entities\ServerResponse |
||
441 | * @throws \Longman\TelegramBot\Exception\TelegramException |
||
442 | */ |
||
443 | public function processUpdate(Update $update) |
||
489 | |||
490 | /** |
||
491 | * Execute /command |
||
492 | * |
||
493 | * @param string $command |
||
494 | * |
||
495 | * @return mixed |
||
496 | * @throws \Longman\TelegramBot\Exception\TelegramException |
||
497 | */ |
||
498 | public function executeCommand($command) |
||
519 | |||
520 | /** |
||
521 | * Sanitize Command |
||
522 | * |
||
523 | * @param string $command |
||
524 | * |
||
525 | * @return string |
||
526 | */ |
||
527 | 1 | protected function sanitizeCommand($command) |
|
531 | |||
532 | /** |
||
533 | * Enable a single Admin account |
||
534 | * |
||
535 | * @param integer $admin_id Single admin id |
||
536 | * |
||
537 | * @return \Longman\TelegramBot\Telegram |
||
538 | */ |
||
539 | 1 | public function enableAdmin($admin_id) |
|
549 | |||
550 | /** |
||
551 | * Enable a list of Admin Accounts |
||
552 | * |
||
553 | * @param array $admin_ids List of admin ids |
||
554 | * |
||
555 | * @return \Longman\TelegramBot\Telegram |
||
556 | */ |
||
557 | 1 | public function enableAdmins(array $admin_ids) |
|
565 | |||
566 | /** |
||
567 | * Get list of admins |
||
568 | * |
||
569 | * @return array |
||
570 | */ |
||
571 | 1 | public function getAdminList() |
|
575 | |||
576 | /** |
||
577 | * Check if the passed user is an admin |
||
578 | * |
||
579 | * If no user id is passed, the current update is checked for a valid message sender. |
||
580 | * |
||
581 | * @param int|null $user_id |
||
582 | * |
||
583 | * @return bool |
||
584 | */ |
||
585 | 1 | public function isAdmin($user_id = null) |
|
609 | |||
610 | /** |
||
611 | * Check if user required the db connection |
||
612 | * |
||
613 | * @return bool |
||
614 | */ |
||
615 | public function isDbEnabled() |
||
623 | |||
624 | /** |
||
625 | * Add a single custom commands path |
||
626 | * |
||
627 | * @param string $path Custom commands path to add |
||
628 | * @param bool $before If the path should be prepended or appended to the list |
||
629 | * |
||
630 | * @return \Longman\TelegramBot\Telegram |
||
631 | */ |
||
632 | 30 | public function addCommandsPath($path, $before = true) |
|
646 | |||
647 | /** |
||
648 | * Add multiple custom commands paths |
||
649 | * |
||
650 | * @param array $paths Custom commands paths to add |
||
651 | * @param bool $before If the paths should be prepended or appended to the list |
||
652 | * |
||
653 | * @return \Longman\TelegramBot\Telegram |
||
654 | */ |
||
655 | 1 | public function addCommandsPaths(array $paths, $before = true) |
|
663 | |||
664 | /** |
||
665 | * Return the list of commands paths |
||
666 | * |
||
667 | * @return array |
||
668 | */ |
||
669 | 1 | public function getCommandsPaths() |
|
673 | |||
674 | /** |
||
675 | * Set custom upload path |
||
676 | * |
||
677 | * @param string $path Custom upload path |
||
678 | * |
||
679 | * @return \Longman\TelegramBot\Telegram |
||
680 | */ |
||
681 | public function setUploadPath($path) |
||
687 | |||
688 | /** |
||
689 | * Get custom upload path |
||
690 | * |
||
691 | * @return string |
||
692 | */ |
||
693 | public function getUploadPath() |
||
697 | |||
698 | /** |
||
699 | * Set custom download path |
||
700 | * |
||
701 | * @param string $path Custom download path |
||
702 | * |
||
703 | * @return \Longman\TelegramBot\Telegram |
||
704 | */ |
||
705 | public function setDownloadPath($path) |
||
711 | |||
712 | /** |
||
713 | * Get custom download path |
||
714 | * |
||
715 | * @return string |
||
716 | */ |
||
717 | public function getDownloadPath() |
||
721 | |||
722 | /** |
||
723 | * Set command config |
||
724 | * |
||
725 | * Provide further variables to a particular commands. |
||
726 | * For example you can add the channel name at the command /sendtochannel |
||
727 | * Or you can add the api key for external service. |
||
728 | * |
||
729 | * @param string $command |
||
730 | * @param array $config |
||
731 | * |
||
732 | * @return \Longman\TelegramBot\Telegram |
||
733 | */ |
||
734 | 14 | public function setCommandConfig($command, array $config) |
|
740 | |||
741 | /** |
||
742 | * Get command config |
||
743 | * |
||
744 | * @param string $command |
||
745 | * |
||
746 | * @return array |
||
747 | */ |
||
748 | 15 | public function getCommandConfig($command) |
|
752 | |||
753 | /** |
||
754 | * Get API key |
||
755 | * |
||
756 | * @return string |
||
757 | */ |
||
758 | 1 | public function getApiKey() |
|
762 | |||
763 | /** |
||
764 | * Get Bot name |
||
765 | * |
||
766 | * @return string |
||
767 | */ |
||
768 | 1 | public function getBotUsername() |
|
772 | |||
773 | /** |
||
774 | * Get Bot Id |
||
775 | * |
||
776 | * @return string |
||
777 | */ |
||
778 | public function getBotId() |
||
782 | |||
783 | /** |
||
784 | * Get Version |
||
785 | * |
||
786 | * @return string |
||
787 | */ |
||
788 | public function getVersion() |
||
792 | |||
793 | /** |
||
794 | * Set Webhook for bot |
||
795 | * |
||
796 | * @param string $url |
||
797 | * @param array $data Optional parameters. |
||
798 | * |
||
799 | * @return \Longman\TelegramBot\Entities\ServerResponse |
||
800 | * @throws \Longman\TelegramBot\Exception\TelegramException |
||
801 | */ |
||
802 | public function setWebhook($url, array $data = []) |
||
830 | |||
831 | /** |
||
832 | * Delete any assigned webhook |
||
833 | * |
||
834 | * @return mixed |
||
835 | * @throws \Longman\TelegramBot\Exception\TelegramException |
||
836 | */ |
||
837 | public function deleteWebhook() |
||
849 | |||
850 | /** |
||
851 | * Replace function `ucwords` for UTF-8 characters in the class definition and commands |
||
852 | * |
||
853 | * @param string $str |
||
854 | * @param string $encoding (default = 'UTF-8') |
||
855 | * |
||
856 | * @return string |
||
857 | */ |
||
858 | 1 | protected function ucwordsUnicode($str, $encoding = 'UTF-8') |
|
862 | |||
863 | /** |
||
864 | * Replace function `ucfirst` for UTF-8 characters in the class definition and commands |
||
865 | * |
||
866 | * @param string $str |
||
867 | * @param string $encoding (default = 'UTF-8') |
||
868 | * |
||
869 | * @return string |
||
870 | */ |
||
871 | 1 | protected function ucfirstUnicode($str, $encoding = 'UTF-8') |
|
876 | |||
877 | /** |
||
878 | * Enable Botan.io integration |
||
879 | * |
||
880 | * @deprecated Botan.io service is no longer working |
||
881 | * |
||
882 | * @param string $token |
||
883 | * @param array $options |
||
884 | * |
||
885 | * @return \Longman\TelegramBot\Telegram |
||
886 | */ |
||
887 | public function enableBotan($token, array $options = []) |
||
893 | |||
894 | /** |
||
895 | * Enable requests limiter |
||
896 | * |
||
897 | * @param array $options |
||
898 | * |
||
899 | * @return \Longman\TelegramBot\Telegram |
||
900 | */ |
||
901 | public function enableLimiter(array $options = []) |
||
907 | |||
908 | /** |
||
909 | * Run provided commands |
||
910 | * |
||
911 | * @param array $commands |
||
912 | * |
||
913 | * @throws TelegramException |
||
914 | */ |
||
915 | public function runCommands($commands) |
||
965 | |||
966 | /** |
||
967 | * Is this session initiated by runCommands() |
||
968 | * |
||
969 | * @return bool |
||
970 | */ |
||
971 | public function isRunCommands() |
||
975 | |||
976 | /** |
||
977 | * Switch to enable running getUpdates without a database |
||
978 | * |
||
979 | * @param bool $enable |
||
980 | */ |
||
981 | public function useGetUpdatesWithoutDatabase($enable = true) |
||
985 | |||
986 | /** |
||
987 | * Return last update id |
||
988 | * |
||
989 | * @return int |
||
990 | */ |
||
991 | public function getLastUpdateId() |
||
995 | } |
||
996 |
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.