Complex classes like SslCertificate 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 SslCertificate, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
8 | class SslCertificate |
||
9 | { |
||
10 | /** @var bool */ |
||
11 | protected $trusted; |
||
12 | |||
13 | /** @var bool */ |
||
14 | protected $revoked; |
||
15 | |||
16 | /** @var string */ |
||
17 | protected $ip; |
||
18 | |||
19 | /** @var BigInteger */ |
||
20 | protected $serial; |
||
21 | |||
22 | /** @var string */ |
||
23 | protected $inputDomain; |
||
24 | |||
25 | /** @var string */ |
||
26 | protected $testedDomain; |
||
27 | |||
28 | /** @var array */ |
||
29 | protected $certificateFields = []; |
||
30 | |||
31 | /** @var array */ |
||
32 | protected $certificateChains = []; |
||
33 | |||
34 | /** @var array */ |
||
35 | protected $connectionMeta = []; |
||
36 | |||
37 | /** @var SslRevocationList */ |
||
38 | protected $crl; |
||
39 | |||
40 | /** @var array */ |
||
41 | protected $crlLinks = []; |
||
42 | |||
43 | /** @var Carbon */ |
||
44 | protected $revokedTime; |
||
45 | |||
46 | 3 | public static function createForHostName(string $url, int $timeout = 30): SslCertificate |
|
52 | |||
53 | 3 | private static function extractCrlLinks($rawCrlPoints): string |
|
60 | |||
61 | 3 | private static function parseCrlLinks($rawCrlInput): array |
|
75 | |||
76 | 3 | private function getRevokedDate() |
|
84 | |||
85 | 3 | private function isClrRevoked() |
|
100 | |||
101 | 24 | private static function parseCertChains(array $chains): array |
|
110 | |||
111 | 24 | public function __construct(array $downloadResults) |
|
129 | |||
130 | 2 | public function hasSslChain(): bool |
|
138 | |||
139 | 1 | public function getCertificateFields(): array |
|
140 | { |
||
141 | 1 | return $this->certificateFields; |
|
142 | } |
||
143 | |||
144 | 1 | public function getCertificateChains(): array |
|
145 | { |
||
146 | 1 | return $this->certificateChains; |
|
147 | } |
||
148 | |||
149 | 1 | public function getSerialNumber(): string |
|
150 | { |
||
151 | 1 | return strtoupper($this->serial->toHex()); |
|
152 | } |
||
153 | |||
154 | 3 | public function hasCrlLink(): bool |
|
155 | { |
||
156 | 3 | return isset($this->certificateFields['extensions']['crlDistributionPoints']); |
|
157 | } |
||
158 | |||
159 | 3 | public function getCrlLinks() |
|
160 | { |
||
161 | 3 | if (! $this->hasCrlLink()) { |
|
162 | return; |
||
163 | } |
||
164 | |||
165 | 3 | return $this->crlLinks; |
|
166 | } |
||
167 | |||
168 | public function getCrl() |
||
169 | { |
||
170 | if (! $this->hasCrlLink()) { |
||
171 | return; |
||
172 | } |
||
173 | |||
174 | return $this->crl; |
||
175 | } |
||
176 | |||
177 | 6 | public function isRevoked() |
|
178 | { |
||
179 | 6 | return $this->revoked; |
|
180 | } |
||
181 | |||
182 | 1 | public function getCrlRevokedTime() |
|
183 | { |
||
184 | 1 | if ($this->isRevoked()) { |
|
185 | 1 | return $this->revokedTime; |
|
186 | } |
||
187 | } |
||
188 | |||
189 | 1 | public function getResolvedIp(): string |
|
190 | { |
||
191 | 1 | return $this->ip; |
|
192 | } |
||
193 | |||
194 | 2 | public function getIssuer(): string |
|
195 | { |
||
196 | 2 | return $this->certificateFields['issuer']['CN']; |
|
197 | } |
||
198 | |||
199 | 4 | public function getDomain(): string |
|
200 | { |
||
201 | 4 | $certDomain = $this->getCertificateDomain(); |
|
202 | 4 | if (str_contains($certDomain, $this->inputDomain) === false) { |
|
203 | return $this->inputDomain; |
||
204 | } |
||
205 | |||
206 | 4 | return $certDomain ?? ''; |
|
207 | } |
||
208 | |||
209 | 1 | public function getTestedDomain(): string |
|
210 | { |
||
211 | 1 | return $this->testedDomain; |
|
212 | } |
||
213 | |||
214 | public function getInputDomain(): string |
||
215 | { |
||
216 | return $this->inputDomain; |
||
217 | } |
||
218 | |||
219 | 9 | public function getCertificateDomain(): string |
|
220 | { |
||
221 | 9 | return $this->certificateFields['subject']['CN']; |
|
222 | } |
||
223 | |||
224 | 8 | public function getAdditionalDomains(): array |
|
232 | |||
233 | 1 | public function getSignatureAlgorithm(): string |
|
234 | { |
||
235 | 1 | return $this->certificateFields['signatureTypeSN'] ?? ''; |
|
236 | } |
||
237 | |||
238 | public function getConnectionMeta(): array |
||
239 | { |
||
240 | return $this->connectionMeta; |
||
241 | } |
||
242 | |||
243 | 6 | public function validFromDate(): Carbon |
|
244 | { |
||
245 | 6 | return Carbon::createFromTimestampUTC($this->certificateFields['validFrom_time_t']); |
|
246 | } |
||
247 | |||
248 | 7 | public function expirationDate(): Carbon |
|
249 | { |
||
252 | |||
253 | 1 | public function isExpired(): bool |
|
257 | |||
258 | 1 | public function isTrusted(): bool |
|
262 | |||
263 | 5 | public function isValid(string $url = null): bool |
|
280 | |||
281 | 1 | public function isValidUntil(Carbon $carbon, string $url = null): bool |
|
289 | |||
290 | 1 | public function isSelfSigned() |
|
313 | |||
314 | 7 | public function appliesToUrl(string $url): bool |
|
335 | |||
336 | 3 | protected function wildcardHostCoversHost(string $wildcardHost, string $host): bool |
|
346 | } |
||
347 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVar
assignment in line 1 and the$higher
assignment in line 2 are dead. The first because$myVar
is never used and the second because$higher
is always overwritten for every possible time line.