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 Client 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 Client, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
20 | abstract class Client |
||
21 | { |
||
22 | /** |
||
23 | * @var array Options for the Client object. |
||
24 | * @since 1.0 |
||
25 | */ |
||
26 | protected $options; |
||
27 | |||
28 | /** |
||
29 | * @var array Contains access token key, secret and verifier. |
||
30 | * @since 1.0 |
||
31 | */ |
||
32 | protected $token = array(); |
||
33 | |||
34 | /** |
||
35 | * @var Http The HTTP client object to use in sending HTTP requests. |
||
36 | * @since 1.0 |
||
37 | */ |
||
38 | protected $client; |
||
39 | |||
40 | /** |
||
41 | * @var Input The input object to use in retrieving GET/POST data. |
||
42 | * @since 1.0 |
||
43 | */ |
||
44 | protected $input; |
||
45 | |||
46 | /** |
||
47 | * @var AbstractWebApplication The application object to send HTTP headers for redirects. |
||
48 | * @since 1.0 |
||
49 | */ |
||
50 | protected $application; |
||
51 | |||
52 | /** |
||
53 | * @var string Selects which version of OAuth to use: 1.0 or 1.0a. |
||
54 | * @since 1.0 |
||
55 | */ |
||
56 | protected $version; |
||
57 | |||
58 | /** |
||
59 | * Constructor. |
||
60 | * |
||
61 | * @param array $options OAuth1 Client options array. |
||
62 | * @param Http $client The HTTP client object. |
||
63 | * @param Input $input The input object |
||
64 | * @param AbstractWebApplication $application The application object |
||
65 | * @param string $version Specify the OAuth version. By default we are using 1.0a. |
||
66 | * |
||
67 | * @since 1.0 |
||
68 | */ |
||
69 | public function __construct($options = array(), Http $client, Input $input, AbstractWebApplication $application, $version = '1.0a') |
||
77 | |||
78 | /** |
||
79 | * Method to form the oauth flow. |
||
80 | * |
||
81 | * @return string The access token. |
||
82 | * |
||
83 | * @since 1.0 |
||
84 | * @throws \DomainException |
||
85 | */ |
||
86 | public function authenticate() |
||
147 | |||
148 | /** |
||
149 | * Method used to get a request token. |
||
150 | * |
||
151 | * @return void |
||
152 | * |
||
153 | * @since 1.1.2 |
||
154 | * @throws \DomainException |
||
155 | */ |
||
156 | private function generateRequestToken() |
||
188 | |||
189 | /** |
||
190 | * Method used to authorise the application. |
||
191 | * |
||
192 | * @return void |
||
193 | * |
||
194 | * @since 1.1.2 |
||
195 | */ |
||
196 | private function authorise() |
||
211 | |||
212 | /** |
||
213 | * Method used to get an access token. |
||
214 | * |
||
215 | * @return void |
||
216 | * |
||
217 | * @since 1.1.2 |
||
218 | */ |
||
219 | private function generateAccessToken() |
||
239 | |||
240 | /** |
||
241 | * Method used to make an OAuth request. |
||
242 | * |
||
243 | * @param string $url The request URL. |
||
244 | * @param string $method The request method. |
||
245 | * @param array $parameters Array containing request parameters. |
||
246 | * @param mixed $data The POST request data. |
||
247 | * @param array $headers An array of name-value pairs to include in the header of the request |
||
248 | * |
||
249 | * @return object The Response object. |
||
250 | * |
||
251 | * @since 1.0 |
||
252 | * @throws \DomainException |
||
253 | */ |
||
254 | public function oauthRequest($url, $method, $parameters, $data = array(), $headers = array()) |
||
320 | |||
321 | /** |
||
322 | * Method to validate a response. |
||
323 | * |
||
324 | * @param string $url The request URL. |
||
325 | * @param Response $response The response to validate. |
||
326 | * |
||
327 | * @return void |
||
328 | * |
||
329 | * @since 1.0 |
||
330 | * @throws \DomainException |
||
331 | */ |
||
332 | abstract public function validateResponse($url, $response); |
||
333 | |||
334 | /** |
||
335 | * Method used to create the header for the POST request. |
||
336 | * |
||
337 | * @param array $parameters Array containing request parameters. |
||
338 | * |
||
339 | * @return string The header. |
||
340 | * |
||
341 | * @since 1.1.2 |
||
342 | */ |
||
343 | private function createHeader($parameters) |
||
361 | |||
362 | /** |
||
363 | * Method to create the URL formed string with the parameters. |
||
364 | * |
||
365 | * @param string $url The request URL. |
||
366 | * @param array $parameters Array containing request parameters. |
||
367 | * |
||
368 | * @return string The formed URL. |
||
369 | * |
||
370 | * @since 1.0 |
||
371 | */ |
||
372 | public function toUrl($url, $parameters) |
||
410 | |||
411 | /** |
||
412 | * Method used to sign requests. |
||
413 | * |
||
414 | * @param string $url The URL to sign. |
||
415 | * @param string $method The request method. |
||
416 | * @param array $parameters Array containing request parameters. |
||
417 | * |
||
418 | * @return array The array containing the request parameters, including signature. |
||
419 | * |
||
420 | * @since 1.1.2 |
||
421 | */ |
||
422 | private function signRequest($url, $method, $parameters) |
||
435 | |||
436 | /** |
||
437 | * Prepare the signature base string. |
||
438 | * |
||
439 | * @param string $url The URL to sign. |
||
440 | * @param string $method The request method. |
||
441 | * @param array $parameters Array containing request parameters. |
||
442 | * |
||
443 | * @return string The base string. |
||
444 | * |
||
445 | * @since 1.1.2 |
||
446 | */ |
||
447 | private function baseString($url, $method, $parameters) |
||
485 | |||
486 | /** |
||
487 | * Encodes the string or array passed in a way compatible with OAuth. |
||
488 | * If an array is passed each array value will will be encoded. |
||
489 | * |
||
490 | * @param mixed $data The scalar or array to encode. |
||
491 | * |
||
492 | * @return string $data encoded in a way compatible with OAuth. |
||
493 | * |
||
494 | * @since 1.0 |
||
495 | */ |
||
496 | public function safeEncode($data) |
||
514 | |||
515 | /** |
||
516 | * Method used to generate the current nonce. |
||
517 | * |
||
518 | * @return string The current nonce. |
||
519 | * |
||
520 | * @since 1.0 |
||
521 | */ |
||
522 | public static function generateNonce() |
||
530 | |||
531 | /** |
||
532 | * Prepares the OAuth signing key. |
||
533 | * |
||
534 | * @return string The prepared signing key. |
||
535 | * |
||
536 | * @since 1.1.2 |
||
537 | */ |
||
538 | private function prepareSigningKey() |
||
542 | |||
543 | /** |
||
544 | * Returns an HTTP 200 OK response code and a representation of the requesting user if authentication was successful; |
||
545 | * returns a 401 status code and an error message if not. |
||
546 | * |
||
547 | * @return array The decoded JSON response |
||
548 | * |
||
549 | * @since 1.0 |
||
550 | */ |
||
551 | abstract public function verifyCredentials(); |
||
552 | |||
553 | /** |
||
554 | * Get an option from the OAuth1 Client instance. |
||
555 | * |
||
556 | * @param string $key The name of the option to get |
||
557 | * |
||
558 | * @return mixed The option value |
||
559 | * |
||
560 | * @since 1.0 |
||
561 | */ |
||
562 | public function getOption($key) |
||
566 | |||
567 | /** |
||
568 | * Set an option for the OAuth1 Client instance. |
||
569 | * |
||
570 | * @param string $key The name of the option to set |
||
571 | * @param mixed $value The option value to set |
||
572 | * |
||
573 | * @return Client This object for method chaining |
||
574 | * |
||
575 | * @since 1.0 |
||
576 | */ |
||
577 | public function setOption($key, $value) |
||
583 | |||
584 | /** |
||
585 | * Get the oauth token key or secret. |
||
586 | * |
||
587 | * @return array The oauth token key and secret. |
||
588 | * |
||
589 | * @since 1.0 |
||
590 | */ |
||
591 | public function getToken() |
||
595 | |||
596 | /** |
||
597 | * Set the oauth token. |
||
598 | * |
||
599 | * @param array $token The access token key and secret. |
||
600 | * |
||
601 | * @return Client This object for method chaining. |
||
602 | * |
||
603 | * @since 1.0 |
||
604 | */ |
||
605 | public function setToken($token) |
||
611 | } |
||
612 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.