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:
1 | <?php |
||
9 | class Orange |
||
10 | { |
||
11 | |||
12 | public $url = 'https://www.orange.pl'; // orange.pl URL |
||
13 | private $user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4'; |
||
14 | private $login_request_uri = '/zaloguj.phtml'; // login form request uri |
||
15 | private $login_post_query_string = '?_DARGS=/ocp/gear/infoportal/portlets/login/login-box.jsp'; // login form POST query string |
||
16 | private $send_request_uri = '/portal/map/map/message_box?mbox_view=newsms'; // request uri of form for sending new messages |
||
17 | private $send_post_request_uri = '/portal/map/map/message_box?_DARGS=/gear/mapmessagebox/smsform.jsp'; // action target for POST request of the sending new messages form |
||
18 | public $max_length = '640'; // max. length of one SMS message according to the sending new messages form |
||
19 | |||
20 | /** |
||
21 | * Session placeholder during the whole execution |
||
22 | * @var \Requests_Session |
||
23 | */ |
||
24 | private $session; |
||
25 | |||
26 | /** |
||
27 | * Initialized DOM for response analyzing |
||
28 | * @var \simple_html_dom |
||
29 | */ |
||
30 | private $html; |
||
31 | |||
32 | /** |
||
33 | * Session data variable (not being cross-checked yet) |
||
34 | * @var string |
||
35 | */ |
||
36 | private $dynamic_session; |
||
37 | |||
38 | /** |
||
39 | * True if user logged in successfully |
||
40 | * @var boolean |
||
41 | */ |
||
42 | private $logged_in = false; |
||
43 | |||
44 | /** |
||
45 | * Form submission token placeholder |
||
46 | * @var string |
||
47 | */ |
||
48 | private $token; |
||
49 | |||
50 | /** |
||
51 | * Instantiates the Requests handler with session support. |
||
52 | */ |
||
53 | public function __construct() |
||
66 | |||
67 | /** |
||
68 | * Login at orange.pl |
||
69 | * |
||
70 | * You have to be register at orange.pl |
||
71 | * Head to: https://www.orange.pl/rejestracja.phtml |
||
72 | * |
||
73 | * @param string $login - login or the number assosciated with the service you use |
||
74 | * @param string $password - password (pol. "Hasło") |
||
75 | */ |
||
76 | public function login($login, $password) |
||
112 | |||
113 | /** |
||
114 | * Retrieves the token from the passed content |
||
115 | * |
||
116 | * @param string $content - content to be searched through |
||
117 | * @return string - token |
||
118 | */ |
||
119 | private function token($content) |
||
154 | |||
155 | /** |
||
156 | * Send a SMS through the webform at $this->send_post_request_uri |
||
157 | * |
||
158 | * @param string $recipient - addressable phone number of the recipient(s) |
||
159 | * + 9 digits without leading zero for national mobile numbers |
||
160 | * (e.g. 501234567) |
||
161 | * + for landline and international numbers plus sign or two leading |
||
162 | * zeros followed by international dialing code are allowed |
||
163 | * (e.g. 004912345678901 or +4912345678901) |
||
164 | * + integer values recommended (or strings with no special chars |
||
165 | * except plus sign); spaces seem to get trimmed |
||
166 | * + up to five recipients as a comma separeted string are allowed |
||
167 | * for one request (e.g. 501234567,004912345678901) |
||
168 | * @param string $text - content of the SMS |
||
169 | * @param boolean $multiple - should be true for multiple send requests in |
||
170 | * a session; in case of multiple send() |
||
171 | * function invokes during one session a new |
||
172 | * token for every request has to be retrieved |
||
173 | * (default: false) |
||
174 | */ |
||
175 | public function send($recipient, $text, $multiple = false) |
||
223 | |||
224 | /** |
||
225 | * Find element in HTML Dom |
||
226 | * |
||
227 | * @param string $content - content to be searched through |
||
228 | * @return object |
||
229 | */ |
||
230 | private function find($content, $selector, $nth = null) |
||
246 | |||
247 | /** |
||
248 | * Checks the remaining SMS left this month from the response body |
||
249 | * |
||
250 | * @param string $content - content to be searched through |
||
251 | * @return boolean|int|string - SMS remaining this month |
||
252 | * false if no content |
||
253 | * int if integer value present |
||
254 | * string in other cases |
||
255 | */ |
||
256 | private function remaining($content) |
||
293 | |||
294 | /** |
||
295 | * Get the amount of remaining SMS this month through a request |
||
296 | * |
||
297 | * @return boolean|array - false if not logged in, no valuable content |
||
298 | * otherwise array result of checkRemaining() function |
||
299 | */ |
||
300 | View Code Duplication | public function getRemaining() |
|
320 | |||
321 | /** |
||
322 | * Get the token through a request |
||
323 | * |
||
324 | * @return string - token |
||
325 | */ |
||
326 | View Code Duplication | public function getToken() |
|
348 | |||
349 | /** |
||
350 | * Check whether errors have been returned |
||
351 | * |
||
352 | * @param string $content - response body of a request |
||
353 | * @return boolean - false if no element described by the selector exists |
||
354 | */ |
||
355 | private function checkErrors($content, $selector, $function = null) |
||
377 | |||
378 | /** |
||
379 | * Checks whether user logged in |
||
380 | */ |
||
381 | private function checkLoggedIn() { |
||
390 | |||
391 | /** |
||
392 | * Checks value for the remaining() and getRemaing() functions |
||
393 | * |
||
394 | * @param string $value - input value |
||
395 | * @return array - information about the retrieved information |
||
396 | * boolean 'found' - false if no valuable content (default: false) |
||
397 | * int 'remaining' - remaining amount of SMS (default: 0) |
||
398 | * array 'errors' - array with errors, key is the index of |
||
399 | * the element with an error |
||
400 | */ |
||
401 | private function checkRemaining($elements) |
||
440 | } |
||
441 |
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.