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 CurlSoapClient 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 CurlSoapClient, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
17 | class CurlSoapClient extends SoapClient |
||
18 | { |
||
19 | protected $curl = null; ///< cURL handle |
||
20 | protected $redirect_max; ///< max redirect counts |
||
21 | protected $curl_timeout; ///< cURL request time-out seconds |
||
22 | private $redirect_count = 0; |
||
23 | |||
24 | 12 | public function __construct($wsdl, array $options) |
|
38 | |||
39 | 12 | public function __destruct() |
|
45 | |||
46 | 1 | public function ___curlSetOpt($option, $value) |
|
50 | |||
51 | 1 | public function __getCookies() |
|
55 | |||
56 | 1 | public function __setCookie($name, $value = null) |
|
64 | |||
65 | /** |
||
66 | * Execute SOAP requests. |
||
67 | * |
||
68 | * @param string $request SOAP request |
||
69 | * @param string $location SOAP address |
||
70 | * @param string $action SOAP action |
||
71 | * @param int $version SOAP version |
||
72 | * @param int $one_way |
||
73 | * @throws \Exception |
||
74 | * @throws \SoapFault |
||
75 | * @return string|object (string) SOAP response / (object) SoapFault object |
||
76 | */ |
||
77 | 12 | public function __doRequest($request, $location, $action, $version, $one_way = 0) |
|
78 | { |
||
79 | 12 | curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); |
|
80 | 12 | curl_setopt($this->curl, CURLOPT_HEADER, true); |
|
81 | 12 | curl_setopt($this->curl, CURLOPT_POSTFIELDS, $request); |
|
82 | 12 | if (isset($this->trace) && $this->trace) { |
|
83 | 3 | curl_setopt($this->curl, CURLINFO_HEADER_OUT, true); |
|
84 | 3 | } |
|
85 | |||
86 | 12 | $this->___configHeader($action, $version); |
|
87 | 12 | $this->___configCompression(); |
|
88 | 12 | $this->___configTimeout(); |
|
89 | 12 | if ($this->___isNotEmptyExtProperty('_user_agent')) { |
|
90 | 1 | curl_setopt($this->curl, CURLOPT_USERAGENT, $this->_user_agent); |
|
91 | 1 | } |
|
92 | 12 | $this->___configHttpAuthentication(); |
|
93 | 12 | $this->___configProxy(); |
|
94 | 12 | if (isset($this->_ssl_method) && is_int($this->_ssl_method)) { |
|
95 | switch ($this->_ssl_method) { |
||
96 | case SOAP_SSL_METHOD_SSLv2: |
||
97 | curl_setopt($this->curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv2); |
||
98 | break; |
||
99 | case SOAP_SSL_METHOD_SSLv3: |
||
100 | curl_setopt($this->curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3); |
||
101 | break; |
||
102 | default: |
||
103 | curl_setopt($this->curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT); |
||
104 | break; |
||
105 | } |
||
106 | } |
||
107 | |||
108 | try { |
||
109 | 12 | $response = $this->___curlCall($location); |
|
110 | 12 | } catch (\SoapFault $fault) { |
|
111 | 7 | if (isset($this->_exceptions) && empty($this->_exceptions)) { |
|
112 | // if exceptions option is false, return \SoapFault object |
||
113 | 1 | return $fault; |
|
114 | } |
||
115 | 6 | throw $fault; |
|
116 | } |
||
117 | |||
118 | 5 | if ($one_way) { |
|
119 | return ''; |
||
120 | } |
||
121 | |||
122 | 5 | return $response; |
|
123 | } |
||
124 | |||
125 | /** |
||
126 | * set CURLOPT_HTTPHEADER. |
||
127 | * |
||
128 | * @param string $action SOAP action |
||
129 | * @param int $version SOAP version |
||
130 | * @return void |
||
131 | */ |
||
132 | 12 | private function ___configHeader($action, $version) |
|
148 | |||
149 | /** |
||
150 | * set CURLOPT_ENCODING. |
||
151 | * |
||
152 | * @return void |
||
153 | */ |
||
154 | 12 | private function ___configCompression() |
|
166 | |||
167 | /** |
||
168 | * set CURLOPT_CONNECTTIMEOUT and CURLOPT_TIMEOUT. |
||
169 | * |
||
170 | * @return void |
||
171 | */ |
||
172 | 12 | private function ___configTimeout() |
|
181 | |||
182 | /** |
||
183 | * set CURLOPT_HTTPAUTH. |
||
184 | * |
||
185 | * @return void |
||
186 | */ |
||
187 | 12 | private function ___configHttpAuthentication() |
|
198 | 12 | ||
199 | /** |
||
200 | * set proxy options. |
||
201 | * |
||
202 | * @return void |
||
203 | */ |
||
204 | private function ___configProxy() |
||
221 | |||
222 | 12 | /** |
|
223 | * Request cURL. |
||
224 | * |
||
225 | * @param[in] string $location SOAP address |
||
226 | * @param string $location |
||
227 | * @throws \SoapFault |
||
228 | * @return mixed response body |
||
229 | */ |
||
230 | private function ___curlCall($location) |
||
316 | |||
317 | |||
318 | /** |
||
319 | * @param string $property |
||
320 | */ |
||
321 | private function ___isNotEmptyExtProperty($property) |
||
325 | } |
||
326 |
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.