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 |
||
| 18 | class Client extends GenericClient |
||
| 19 | { |
||
| 20 | /* json status codes */ |
||
| 21 | const STATUS_CODE_CAPCHA_NOT_READY = 0; |
||
| 22 | const STATUS_CODE_OK = 1; |
||
| 23 | |||
| 24 | /* status codes */ |
||
| 25 | const STATUS_OK_REPORT_RECORDED = 'OK_REPORT_RECORDED'; |
||
| 26 | |||
| 27 | /** |
||
| 28 | * @var int |
||
| 29 | */ |
||
| 30 | protected $recaptchaRTimeout = 15; |
||
| 31 | |||
| 32 | /** |
||
| 33 | * @var string |
||
| 34 | */ |
||
| 35 | protected $serverBaseUri = 'http://rucaptcha.com'; |
||
| 36 | |||
| 37 | /** |
||
| 38 | * Your application ID in Rucaptcha catalog. |
||
| 39 | * The value `1013` is ID of this library. Set in false if you want to turn off sending any ID. |
||
| 40 | * |
||
| 41 | * @see https://rucaptcha.com/software/view/php-api-client |
||
| 42 | * @var string |
||
| 43 | */ |
||
| 44 | protected $softId = '1013'; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * @inheritdoc |
||
| 48 | */ |
||
| 49 | public function sendCaptcha($content, array $extra = []) |
||
| 56 | |||
| 57 | /** |
||
| 58 | * Bulk captcha result. |
||
| 59 | * |
||
| 60 | * @param int[] $captchaIds # Captcha task Ids array |
||
| 61 | * @return string[] # Array $captchaId => $captchaText or false if is not ready |
||
| 62 | * @throws GuzzleException |
||
| 63 | */ |
||
| 64 | public function getCaptchaResultBulk(array $captchaIds) |
||
| 88 | |||
| 89 | /** |
||
| 90 | * Returns balance of account. |
||
| 91 | * |
||
| 92 | * @return string |
||
| 93 | * @throws GuzzleException |
||
| 94 | */ |
||
| 95 | public function getBalance() |
||
| 103 | |||
| 104 | /** |
||
| 105 | * Alias of $this->reportBad(); |
||
| 106 | * |
||
| 107 | * @param string $captchaId |
||
| 108 | * @return bool |
||
| 109 | * @throws ErrorResponseException |
||
| 110 | * @throws GuzzleException |
||
| 111 | */ |
||
| 112 | public function badCaptcha($captchaId) |
||
| 116 | |||
| 117 | /** |
||
| 118 | * Alias of $this->reportGood(); |
||
| 119 | * |
||
| 120 | * @param string $captchaId |
||
| 121 | * @return bool |
||
| 122 | * @throws ErrorResponseException |
||
| 123 | * @throws GuzzleException |
||
| 124 | */ |
||
| 125 | public function goodCaptcha($captchaId) |
||
| 129 | |||
| 130 | /** |
||
| 131 | * Report of wrong recognition. |
||
| 132 | * |
||
| 133 | * @param string $captchaId |
||
| 134 | * @return bool |
||
| 135 | * @throws ErrorResponseException |
||
| 136 | * @throws GuzzleException |
||
| 137 | */ |
||
| 138 | public function reportBad($captchaId) |
||
| 155 | |||
| 156 | |||
| 157 | /** |
||
| 158 | * Reports rucaptcha for good recognition. |
||
| 159 | * |
||
| 160 | * @param $captchaId |
||
| 161 | * @return bool |
||
| 162 | * @throws ErrorResponseException |
||
| 163 | * @throws GuzzleException |
||
| 164 | */ |
||
| 165 | public function reportGood($captchaId) |
||
| 182 | |||
| 183 | /** |
||
| 184 | * Returns server health data. |
||
| 185 | * |
||
| 186 | * @param string|string[] $paramsList # List of metrics to be returned |
||
| 187 | * @return string[]|string # Array of load metrics $metric => $value formatted |
||
| 188 | * @throws GuzzleException |
||
| 189 | */ |
||
| 190 | public function getLoad($paramsList = ['waiting', 'load', 'minbid', 'averageRecognitionTime']) |
||
| 206 | |||
| 207 | /** |
||
| 208 | * Returns load data as XML. |
||
| 209 | * |
||
| 210 | * @return SimpleXMLElement |
||
| 211 | * @throws GuzzleException |
||
| 212 | */ |
||
| 213 | public function getLoadXml() |
||
| 221 | |||
| 222 | /** |
||
| 223 | * @param string $captchaId # Captcha task ID |
||
| 224 | * @return array | false # Solved captcha and cost array or false if captcha is not ready |
||
| 225 | * @throws ErrorResponseException |
||
| 226 | * @throws GuzzleException |
||
| 227 | */ |
||
| 228 | public function getCaptchaResultWithCost($captchaId) |
||
| 254 | |||
| 255 | /** |
||
| 256 | * Add pingback url to rucaptcha whitelist. |
||
| 257 | * |
||
| 258 | * @param string $url |
||
| 259 | * @return bool # true if added and exception if fail |
||
| 260 | * @throws ErrorResponseException |
||
| 261 | * @throws GuzzleException |
||
| 262 | */ |
||
| 263 | public function addPingback($url) |
||
| 280 | |||
| 281 | /** |
||
| 282 | * Returns pingback whitelist items. |
||
| 283 | * |
||
| 284 | * @return string[] # List of urls |
||
| 285 | * @throws ErrorResponseException |
||
| 286 | * @throws GuzzleException |
||
| 287 | */ |
||
| 288 | public function getPingbacks() |
||
| 307 | |||
| 308 | /** |
||
| 309 | * Remove pingback url from whitelist. |
||
| 310 | * |
||
| 311 | * @param string $uri |
||
| 312 | * @return bool |
||
| 313 | * @throws ErrorResponseException |
||
| 314 | * @throws GuzzleException |
||
| 315 | */ |
||
| 316 | public function deletePingback($uri) |
||
| 332 | |||
| 333 | /** |
||
| 334 | * Truncate pingback whitelist. |
||
| 335 | * |
||
| 336 | * @return bool |
||
| 337 | * @throws ErrorResponseException |
||
| 338 | * @throws GuzzleException |
||
| 339 | */ |
||
| 340 | public function deleteAllPingbacks() |
||
| 344 | |||
| 345 | /* Recaptcha v2 */ |
||
| 346 | |||
| 347 | /** |
||
| 348 | * Sent recaptcha v2 |
||
| 349 | * |
||
| 350 | * @param string $googleKey |
||
| 351 | * @param string $pageUrl |
||
| 352 | * @param array $extra |
||
| 353 | * @return string |
||
| 354 | * @throws ErrorResponseException |
||
| 355 | * @throws GuzzleException |
||
| 356 | */ |
||
| 357 | public function sendRecaptchaV2($googleKey, $pageUrl, $extra = []) |
||
| 384 | |||
| 385 | /** |
||
| 386 | * Alias for bc |
||
| 387 | * @param $googleKey |
||
| 388 | * @param $pageUrl |
||
| 389 | * @param array $extra |
||
| 390 | * @return string |
||
| 391 | * @throws ErrorResponseException |
||
| 392 | * @throws GuzzleException |
||
| 393 | * @deprecated |
||
| 394 | */ |
||
| 395 | public function sendRecapthaV2($googleKey, $pageUrl, $extra = []) |
||
| 399 | |||
| 400 | /** |
||
| 401 | * Recaptcha V2 recognition. |
||
| 402 | * |
||
| 403 | * @param string $googleKey |
||
| 404 | * @param string $pageUrl |
||
| 405 | * @param array $extra # Captcha options |
||
| 406 | * @return string # Code to place in hidden form |
||
| 407 | * @throws ErrorResponseException |
||
| 408 | * @throws InvalidArgumentException |
||
| 409 | * @throws RuntimeException |
||
| 410 | * @throws GuzzleException |
||
| 411 | */ |
||
| 412 | public function recognizeRecaptchaV2($googleKey, $pageUrl, $extra = []) |
||
| 439 | |||
| 440 | /* Recaptcha v3 */ |
||
| 441 | |||
| 442 | /** |
||
| 443 | * @param string $googleKey |
||
| 444 | * @param string $pageUrl |
||
| 445 | * @param string $action |
||
| 446 | * @param string $minScore |
||
| 447 | * @param array $extra |
||
| 448 | * @return string |
||
| 449 | * @throws ErrorResponseException |
||
| 450 | * @throws GuzzleException |
||
| 451 | * @see https://rucaptcha.com/blog/for_webmaster/recaptcha-v3-obhod |
||
| 452 | */ |
||
| 453 | public function sendRecaptchaV3($googleKey, $pageUrl, $action, $minScore = '0.3', $extra = []) |
||
| 483 | |||
| 484 | /** |
||
| 485 | * @param string $googleKey |
||
| 486 | * @param string $pageUrl |
||
| 487 | * @param string $action |
||
| 488 | * @param string $minScore |
||
| 489 | * @param array $extra |
||
| 490 | * @return false|string |
||
| 491 | * @throws ErrorResponseException |
||
| 492 | * @throws InvalidArgumentException |
||
| 493 | * @throws RuntimeException |
||
| 494 | * @throws GuzzleException |
||
| 495 | */ |
||
| 496 | public function recognizeRecaptchaV3($googleKey, $pageUrl, $action, $minScore = '0.3', $extra = []) |
||
| 523 | |||
| 524 | /** |
||
| 525 | * Keycaptcha recognition. |
||
| 526 | * |
||
| 527 | * @param string $SSCUserId |
||
| 528 | * @param string $SSCSessionId |
||
| 529 | * @param string $SSCWebServerSign |
||
| 530 | * @param string $SSCWebServerSign2 |
||
| 531 | * @param string $pageUrl |
||
| 532 | * @param array $extra |
||
| 533 | * @return string # Captcha ID |
||
| 534 | * @throws ErrorResponseException |
||
| 535 | * @throws GuzzleException |
||
| 536 | */ |
||
| 537 | public function sendKeyCaptcha( |
||
| 574 | |||
| 575 | /** |
||
| 576 | * Keycaptcha recognition. |
||
| 577 | * |
||
| 578 | * @param string $SSCUserId |
||
| 579 | * @param string $SSCSessionId |
||
| 580 | * @param string $SSCWebServerSign |
||
| 581 | * @param string $SSCWebServerSign2 |
||
| 582 | * @param string $pageUrl |
||
| 583 | * @param array $extra |
||
| 584 | * @return string # Code to place into id="capcode" input value |
||
| 585 | * @throws ErrorResponseException |
||
| 586 | * @throws InvalidArgumentException |
||
| 587 | * @throws RuntimeException |
||
| 588 | * @throws GuzzleException |
||
| 589 | */ |
||
| 590 | public function recognizeKeyCaptcha( |
||
| 625 | |||
| 626 | /** |
||
| 627 | * Override generic method for using json response. |
||
| 628 | * |
||
| 629 | * @param string $captchaId # Captcha task ID |
||
| 630 | * @return false|string # Solved captcha text or false if captcha is not ready |
||
| 631 | * @throws ErrorResponseException |
||
| 632 | * @throws InvalidArgumentException |
||
| 633 | * @throws GuzzleException |
||
| 634 | */ |
||
| 635 | public function getCaptchaResult($captchaId) |
||
| 665 | |||
| 666 | /** |
||
| 667 | * Match error code by response. |
||
| 668 | * |
||
| 669 | * @param string $responseText |
||
| 670 | * @return int |
||
| 671 | */ |
||
| 672 | private function getErrorCode($responseText) |
||
| 679 | } |
||
| 680 |
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_functionexpects aPostobject, and outputs the author of the post. The base classPostreturns a simple string and outputting a simple string will work just fine. However, the child classBlogPostwhich is a sub-type ofPostinstead decided to return anobject, and is therefore violating the SOLID principles. If aBlogPostwere passed tomy_function, PHP would not complain, but ultimately fail when executing thestrtouppercall in its body.