Complex classes like ServiceRestProxy 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 ServiceRestProxy, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 58 | class ServiceRestProxy extends RestProxy |
||
| 59 | { |
||
| 60 | private $accountName; |
||
| 61 | private $psrPrimaryUri; |
||
| 62 | private $psrSecondaryUri; |
||
| 63 | private $options; |
||
| 64 | private $client; |
||
| 65 | |||
| 66 | /** |
||
| 67 | * Initializes new ServiceRestProxy object. |
||
| 68 | * |
||
| 69 | * @param string $primaryUri The storage account |
||
| 70 | * primary uri. |
||
| 71 | * @param string $secondaryUri The storage account |
||
| 72 | * secondary uri. |
||
| 73 | * @param string $accountName The name of the account. |
||
| 74 | * @param Serialization\ISerializer $dataSerializer The data serializer. |
||
| 75 | * @param array $options Array of options for |
||
| 76 | * the service |
||
| 77 | */ |
||
| 78 | public function __construct( |
||
| 79 | $primaryUri, |
||
| 80 | $secondaryUri, |
||
| 81 | $accountName, |
||
| 82 | Serialization\ISerializer $dataSerializer, |
||
| 83 | array $options = [] |
||
| 84 | ) { |
||
| 85 | $primaryUri = Utilities::appendDelimiter($primaryUri, '/'); |
||
| 86 | $secondaryUri = Utilities::appendDelimiter($secondaryUri, '/'); |
||
| 87 | |||
| 88 | parent::__construct($dataSerializer); |
||
| 89 | |||
| 90 | $this->accountName = $accountName; |
||
| 91 | $this->psrPrimaryUri = new Uri($primaryUri); |
||
| 92 | $this->psrSecondaryUri = new Uri($secondaryUri); |
||
| 93 | $this->options = array_merge(array('http' => array()), $options); |
||
| 94 | $this->client = self::createClient($this->options['http']); |
||
| 95 | } |
||
| 96 | |||
| 97 | /** |
||
| 98 | * Create a Guzzle client for future usage. |
||
| 99 | * |
||
| 100 | * @param array $options Optional parameters for the client. |
||
| 101 | * |
||
| 102 | * @return Client |
||
| 103 | */ |
||
| 104 | private static function createClient(array $options) |
||
| 105 | { |
||
| 106 | $verify = true; |
||
| 107 | //Disable SSL if proxy has been set, and set the proxy in the client. |
||
| 108 | $proxy = getenv('HTTP_PROXY'); |
||
| 109 | // For testing with Fiddler |
||
| 110 | // $proxy = 'localhost:8888'; |
||
| 111 | // $verify = false; |
||
| 112 | if (!empty($proxy)) { |
||
| 113 | $options['proxy'] = $proxy; |
||
| 114 | } |
||
| 115 | |||
| 116 | return (new \GuzzleHttp\Client( |
||
| 117 | array_merge( |
||
| 118 | $options, |
||
| 119 | array( |
||
| 120 | "defaults" => array( |
||
| 121 | "allow_redirects" => true, |
||
| 122 | "exceptions" => true, |
||
| 123 | "decode_content" => true, |
||
| 124 | ), |
||
| 125 | 'cookies' => true, |
||
| 126 | 'verify' => $verify, |
||
| 127 | ) |
||
| 128 | ) |
||
| 129 | )); |
||
| 130 | } |
||
| 131 | |||
| 132 | /** |
||
| 133 | * Gets the account name. |
||
| 134 | * |
||
| 135 | * @return string |
||
| 136 | */ |
||
| 137 | public function getAccountName() |
||
| 138 | { |
||
| 139 | return $this->accountName; |
||
| 140 | } |
||
| 141 | |||
| 142 | /** |
||
| 143 | * Create a middleware stack with given middleware. |
||
| 144 | * |
||
| 145 | * @param ServiceOptions $serviceOptions The options user passed in. |
||
| 146 | * |
||
| 147 | * @return MiddlewareStack |
||
| 148 | */ |
||
| 149 | protected function createMiddlewareStack(ServiceOptions $serviceOptions) |
||
| 186 | |||
| 187 | /** |
||
| 188 | * Send the requests concurrently. Number of concurrency can be modified |
||
| 189 | * by inserting a new key/value pair with the key 'number_of_concurrency' |
||
| 190 | * into the $requestOptions of $serviceOptions. Return only the promise. |
||
| 191 | * |
||
| 192 | * @param callable $generator the generator function to generate |
||
| 193 | * request upon fullfilment |
||
| 194 | * @param int $statusCode The expected status code for each of the |
||
| 195 | * request generated by generator. |
||
| 196 | * @param array $requestOptions The service options for the concurrent |
||
| 197 | * requests. |
||
| 198 | * |
||
| 199 | * @return array |
||
| 200 | */ |
||
| 201 | protected function sendConcurrentAsync( |
||
| 250 | |||
| 251 | |||
| 252 | /** |
||
| 253 | * Create the request to be sent. |
||
| 254 | * |
||
| 255 | * @param string $method The method of the HTTP request |
||
| 256 | * @param array $headers The header field of the request |
||
| 257 | * @param array $queryParams The query parameter of the request |
||
| 258 | * @param array $postParameters The HTTP POST parameters |
||
| 259 | * @param string $path URL path |
||
| 260 | * @param string $body Request body |
||
| 261 | * |
||
| 262 | * @return \GuzzleHttp\Psr7\Request |
||
| 263 | */ |
||
| 264 | protected function createRequest( |
||
| 265 | $method, |
||
| 266 | array $headers, |
||
| 267 | array $queryParams, |
||
| 268 | array $postParameters, |
||
| 269 | $path, |
||
| 270 | $locationMode, |
||
| 271 | $body = Resources::EMPTY_STRING |
||
| 272 | ) { |
||
| 273 | if ($locationMode == LocationMode::SECONDARY_ONLY || |
||
| 274 | $locationMode == LocationMode::SECONDARY_THEN_PRIMARY) { |
||
| 275 | $uri = $this->psrSecondaryUri; |
||
| 276 | } else { |
||
| 277 | $uri = $this->psrPrimaryUri; |
||
| 278 | } |
||
| 279 | |||
| 280 | //Append the path, not replacing it. |
||
| 281 | if ($path != null) { |
||
| 282 | $exPath = $uri->getPath(); |
||
| 283 | if ($exPath != '') { |
||
| 284 | //Remove the duplicated slash in the path. |
||
| 285 | if ($path != '' && $path[0] == '/') { |
||
| 286 | $path = $exPath . substr($path, 1); |
||
| 287 | } else { |
||
| 288 | $path = $exPath . $path; |
||
| 289 | } |
||
| 290 | } |
||
| 291 | $uri = $uri->withPath($path); |
||
| 292 | } |
||
| 293 | |||
| 294 | // add query parameters into headers |
||
| 295 | if ($queryParams != null) { |
||
| 296 | $queryString = Psr7\build_query($queryParams); |
||
| 297 | $uri = $uri->withQuery($queryString); |
||
| 298 | } |
||
| 299 | |||
| 300 | // add post parameters into bodys |
||
| 301 | $actualBody = null; |
||
| 302 | if (empty($body)) { |
||
| 303 | if (empty($headers['content-type'])) { |
||
| 304 | $headers['content-type'] = 'application/x-www-form-urlencoded'; |
||
| 305 | $actualBody = Psr7\build_query($postParameters); |
||
| 306 | } |
||
| 307 | } else { |
||
| 308 | $actualBody = $body; |
||
| 309 | } |
||
| 310 | |||
| 311 | $request = new Request( |
||
| 312 | $method, |
||
| 313 | $uri, |
||
| 314 | $headers, |
||
| 315 | $actualBody |
||
| 316 | ); |
||
| 317 | |||
| 318 | //add content-length to header |
||
| 319 | $bodySize = $request->getBody()->getSize(); |
||
| 320 | if ($bodySize > 0) { |
||
| 321 | $request = $request->withHeader('content-length', $bodySize); |
||
| 322 | } |
||
| 323 | return $request; |
||
| 324 | } |
||
| 325 | |||
| 326 | /** |
||
| 327 | * Create promise of sending HTTP request with the specified parameters. |
||
| 328 | * |
||
| 329 | * @param string $method HTTP method used in the request |
||
| 330 | * @param array $headers HTTP headers. |
||
| 331 | * @param array $queryParams URL query parameters. |
||
| 332 | * @param array $postParameters The HTTP POST parameters. |
||
| 333 | * @param string $path URL path |
||
| 334 | * @param array|int $expected Expected Status Codes. |
||
| 335 | * @param string $body Request body |
||
| 336 | * @param ServiceOptions $options Service options |
||
| 337 | * |
||
| 338 | * @return \GuzzleHttp\Promise\PromiseInterface |
||
| 339 | */ |
||
| 340 | protected function sendAsync( |
||
| 418 | |||
| 419 | /** |
||
| 420 | * Generate the request options using the given service options and stored |
||
| 421 | * information. |
||
| 422 | * |
||
| 423 | * @param ServiceOptions $serviceOptions The service options used to |
||
| 424 | * generate request options. |
||
| 425 | * @param callable $handler The handler used to send the |
||
| 426 | * request. |
||
| 427 | * @return array |
||
| 428 | */ |
||
| 429 | protected function generateRequestOptions( |
||
| 443 | |||
| 444 | /** |
||
| 445 | * Sends the context. |
||
| 446 | * |
||
| 447 | * @param HttpCallContext $context The context of the request. |
||
| 448 | * @return \GuzzleHttp\Psr7\Response |
||
| 449 | */ |
||
| 450 | protected function sendContext(HttpCallContext $context) |
||
| 451 | { |
||
| 452 | return $this->sendContextAsync($context)->wait(); |
||
| 453 | } |
||
| 454 | |||
| 455 | /** |
||
| 456 | * Creates the promise to send the context. |
||
| 457 | * |
||
| 458 | * @param HttpCallContext $context The context of the request. |
||
| 459 | * |
||
| 460 | * @return \GuzzleHttp\Promise\PromiseInterface |
||
| 461 | */ |
||
| 462 | protected function sendContextAsync(HttpCallContext $context) |
||
| 475 | |||
| 476 | /** |
||
| 477 | * Throws ServiceException if the recieved status code is not expected. |
||
| 478 | * |
||
| 479 | * @param ResponseInterface $response The response received |
||
| 480 | * @param array|int $expected The expected status codes. |
||
| 481 | * |
||
| 482 | * @return void |
||
| 483 | * |
||
| 484 | * @throws ServiceException |
||
| 485 | */ |
||
| 486 | public static function throwIfError(ResponseInterface $response, $expected) |
||
| 487 | { |
||
| 488 | $expectedStatusCodes = is_array($expected) ? $expected : array($expected); |
||
| 489 | |||
| 490 | if (!in_array($response->getStatusCode(), $expectedStatusCodes)) { |
||
| 491 | throw new ServiceException($response); |
||
| 492 | } |
||
| 493 | } |
||
| 494 | |||
| 495 | /** |
||
| 496 | * Adds HTTP POST parameter to the specified |
||
| 497 | * |
||
| 498 | * @param array $postParameters An array of HTTP POST parameters. |
||
| 499 | * @param string $key The key of a HTTP POST parameter. |
||
| 500 | * @param string $value the value of a HTTP POST parameter. |
||
| 501 | * |
||
| 502 | * @return array |
||
| 503 | */ |
||
| 504 | public function addPostParameter( |
||
| 505 | array $postParameters, |
||
| 506 | $key, |
||
| 507 | $value |
||
| 508 | ) { |
||
| 509 | Validate::isArray($postParameters, 'postParameters'); |
||
| 510 | $postParameters[$key] = $value; |
||
| 511 | return $postParameters; |
||
| 512 | } |
||
| 513 | |||
| 514 | /** |
||
| 515 | * Groups set of values into one value separated with Resources::SEPARATOR |
||
| 516 | * |
||
| 517 | * @param array $values array of values to be grouped. |
||
| 518 | * |
||
| 519 | * @return string |
||
| 520 | */ |
||
| 521 | public static function groupQueryValues(array $values) |
||
| 522 | { |
||
| 523 | Validate::isArray($values, 'values'); |
||
| 524 | $joined = Resources::EMPTY_STRING; |
||
| 525 | |||
| 526 | sort($values); |
||
| 527 | |||
| 528 | foreach ($values as $value) { |
||
| 529 | if (!is_null($value) && !empty($value)) { |
||
| 530 | $joined .= $value . Resources::SEPARATOR; |
||
| 531 | } |
||
| 532 | } |
||
| 533 | |||
| 534 | return trim($joined, Resources::SEPARATOR); |
||
| 535 | } |
||
| 536 | |||
| 537 | /** |
||
| 538 | * Adds metadata elements to headers array |
||
| 539 | * |
||
| 540 | * @param array $headers HTTP request headers |
||
| 541 | * @param array $metadata user specified metadata |
||
| 542 | * |
||
| 543 | * @return array |
||
| 544 | */ |
||
| 545 | protected function addMetadataHeaders(array $headers, array $metadata = null) |
||
| 546 | { |
||
| 547 | Utilities::validateMetadata($metadata); |
||
| 548 | |||
| 549 | $metadata = $this->generateMetadataHeaders($metadata); |
||
| 550 | $headers = array_merge($headers, $metadata); |
||
| 551 | |||
| 552 | return $headers; |
||
| 553 | } |
||
| 554 | |||
| 555 | /** |
||
| 556 | * Generates metadata headers by prefixing each element with 'x-ms-meta'. |
||
| 557 | * |
||
| 558 | * @param array $metadata user defined metadata. |
||
| 559 | * |
||
| 560 | * @return array |
||
| 561 | */ |
||
| 562 | public function generateMetadataHeaders(array $metadata = null) |
||
| 563 | { |
||
| 564 | $metadataHeaders = array(); |
||
| 565 | |||
| 566 | if (is_array($metadata) && !is_null($metadata)) { |
||
| 567 | foreach ($metadata as $key => $value) { |
||
| 568 | $headerName = Resources::X_MS_META_HEADER_PREFIX; |
||
| 569 | if (strpos($value, "\r") !== false |
||
| 570 | || strpos($value, "\n") !== false |
||
| 571 | ) { |
||
| 572 | throw new \InvalidArgumentException(Resources::INVALID_META_MSG); |
||
| 573 | } |
||
| 574 | |||
| 575 | // Metadata name is case-presrved and case insensitive |
||
| 576 | $headerName .= $key; |
||
| 577 | $metadataHeaders[$headerName] = $value; |
||
| 578 | } |
||
| 579 | } |
||
| 580 | |||
| 581 | return $metadataHeaders; |
||
| 582 | } |
||
| 583 | |||
| 584 | /** |
||
| 585 | * Get the primary URI in PSR form. |
||
| 586 | * |
||
| 587 | * @return Uri |
||
| 588 | */ |
||
| 589 | public function getPsrPrimaryUri() |
||
| 593 | |||
| 594 | /** |
||
| 595 | * Get the secondary URI in PSR form. |
||
| 596 | * |
||
| 597 | * @return Uri |
||
| 598 | */ |
||
| 599 | public function getPsrSecondaryUri() |
||
| 603 | |||
| 604 | /** |
||
| 605 | * Adds the header that indicates the location mode to the response header. |
||
| 606 | * |
||
| 607 | * @return ResponseInterface |
||
| 608 | */ |
||
| 609 | private static function addLocationHeaderToResponse( |
||
| 640 | } |
||
| 641 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVarassignment in line 1 and the$higherassignment in line 2 are dead. The first because$myVaris never used and the second because$higheris always overwritten for every possible time line.