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: