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 MimeParser 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 MimeParser, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
8 | class MimeParser |
||
9 | { |
||
10 | protected $removeHeaders = array("Received", "From", "X-Original-To", "MIME-Version", "Received-SPF", "Delivered-To"); |
||
11 | protected $allowedHeaders = array("return-path", "subject"); |
||
12 | private $cache; |
||
13 | private $grammar; |
||
14 | private $contentDecoder; |
||
15 | private $headerDecoder; |
||
16 | |||
17 | 5 | public function __construct(array $allowedHeaders = array(), array $removeHeaders = array()) |
|
27 | |||
28 | 1 | public function parseString($string, $fillHeaders = false, \Swift_Mime_MimeEntity $message = null) |
|
37 | |||
38 | /** |
||
39 | * |
||
40 | * @param stream $stream |
||
41 | * @param boolean $fillHeaders (default to false) |
||
42 | * @param \Swift_Mime_MimeEntity $message (default to null) |
||
43 | * @return Swift_Mime_MimeEntity|\Swift_Message |
||
44 | */ |
||
45 | 5 | public function parseStream($stream, $fillHeaders = false, \Swift_Mime_MimeEntity $message = null) |
|
68 | |||
69 | 5 | protected function extractHeaders($stream) |
|
95 | |||
96 | 5 | private function filterHeaders(array $headers) |
|
105 | |||
106 | 5 | protected function parseParts($stream, $partHeaders) |
|
163 | |||
164 | 5 | private function extractValueHeader($header) |
|
173 | |||
174 | 5 | private function getContentType(array $partHeaders) |
|
182 | |||
183 | 5 | private function extractHeaderParts($header) |
|
202 | 5 | protected function extractPart($stream, $boundary, $encoding) |
|
203 | { |
||
204 | 5 | $rows = array(); |
|
205 | 5 | while (!feof($stream)) { |
|
206 | 5 | $row = fgets($stream); |
|
207 | |||
208 | 5 | if ($boundary !== null) { |
|
209 | 3 | View Code Duplication | if (strpos($row, "--$boundary--") === 0) { |
210 | 3 | throw new Exception\EndOfMultiPartReachedException ($this->contentDecoder->decode(implode("", $rows), $encoding)); |
|
211 | } |
||
212 | 3 | View Code Duplication | if (strpos($row, "--$boundary") === 0) { |
213 | 3 | throw new Exception\EndOfPartReachedException ($this->contentDecoder->decode(implode("", $rows), $encoding)); |
|
214 | } |
||
215 | 3 | } |
|
216 | 5 | $rows [] = $row; |
|
217 | 5 | } |
|
218 | 2 | throw new Exception\EndOfMultiPartReachedException ($this->contentDecoder->decode(implode("", $rows), $encoding)); |
|
219 | } |
||
220 | |||
221 | 5 | private function getTransferEncoding(array $partHeaders) |
|
222 | { |
||
223 | 5 | if (array_key_exists('content-transfer-encoding', $partHeaders)) { |
|
224 | 1 | return $partHeaders ['content-transfer-encoding']; |
|
225 | } |
||
226 | |||
227 | 4 | return ''; |
|
228 | } |
||
229 | |||
230 | /** |
||
231 | * |
||
232 | * @param array $headersRaw |
||
233 | * @return \Swift_Mime_HeaderSet |
||
234 | */ |
||
235 | 5 | protected function createHeadersSet(array $headersRaw) |
|
236 | { |
||
237 | 5 | $headers = \Swift_DependencyContainer::getInstance()->lookup('mime.headerset'); |
|
238 | |||
239 | 5 | foreach ($headersRaw as $name => $value) { |
|
240 | 5 | switch (strtolower($name)) { |
|
241 | 5 | case "content-type": |
|
242 | 5 | $parts = $this->extractHeaderParts($value); |
|
243 | 5 | unset ($parts ["boundary"]); |
|
244 | 5 | $headers->addParameterizedHeader($name, $this->extractValueHeader($value), $parts); |
|
245 | 5 | break; |
|
246 | 5 | case "return-path" : |
|
247 | 1 | if (preg_match_all('/([a-z][a-z0-9_\-\.]*@[a-z0-9\.\-]*\.[a-z]{2,5})/i', $value, $mch)) { |
|
248 | 1 | foreach ($mch [0] as $k => $mails) { |
|
249 | 1 | $headers->addPathHeader($name, $mch [1] [$k]); |
|
250 | 1 | } |
|
251 | 1 | } |
|
252 | 1 | break; |
|
253 | 5 | case "date": |
|
254 | 1 | $headers->addDateHeader($name, strtotime($value)); |
|
255 | 1 | break; |
|
256 | 5 | case "to": |
|
257 | 5 | case "from": |
|
258 | 5 | case "bcc" : |
|
259 | 5 | case "reply-to": |
|
260 | 5 | case "cc": |
|
261 | 5 | $adresses = array(); |
|
262 | 5 | if (preg_match_all('/(.*?)<([a-z][a-z0-9_\-\.]*@[a-z0-9\.\-]*\.[a-z]{2,5})>\s*[;,]*/i', $value, $mch)) { |
|
263 | 5 | foreach ($mch [0] as $k => $mail) { |
|
264 | 5 | if (!$mch [1] [$k]) { |
|
265 | $adresses [$mch [2] [$k]] = trim($mch [2] [$k]); |
||
266 | } else { |
||
267 | 5 | $adresses [$mch [2] [$k]] = trim($mch [1] [$k]); |
|
268 | } |
||
269 | 5 | } |
|
270 | 5 | } elseif (preg_match_all('/([a-z][a-z0-9_\-\.]*@[a-z0-9\.\-]*\.[a-z]{2,5})/i', $value, $mch)) { |
|
271 | foreach ($mch [0] as $k => $mails) { |
||
272 | $adresses [$mch [1] [$k]] = trim($mch [1] [$k]); |
||
273 | } |
||
274 | } |
||
275 | 5 | $headers->addMailboxHeader($name, $adresses); |
|
276 | 5 | break; |
|
277 | 5 | default: |
|
278 | 5 | $headers->addTextHeader($name, $value); |
|
279 | 5 | break; |
|
280 | 5 | } |
|
281 | 5 | } |
|
282 | 5 | return $headers; |
|
283 | } |
||
284 | |||
285 | 5 | protected function createMessage(array $message, \Swift_Mime_MimeEntity $entity) |
|
325 | |||
326 | /** |
||
327 | * |
||
328 | * @param string $type |
||
329 | * @return \Swift_Mime_ContentEncoder |
||
330 | */ |
||
331 | 3 | protected function getEncoder($type) |
|
348 | |||
349 | /** |
||
350 | * |
||
351 | * @param string $path |
||
352 | * The file containg a MIME message |
||
353 | * @return \Swift_Message |
||
354 | */ |
||
355 | 1 | public function parseFile($path, $fillHeaders = false, \Swift_Mime_MimeEntity $message = null) |
|
362 | } |
||
363 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: