| Total Complexity | 101 |
| Total Lines | 543 |
| Duplicated Lines | 0 % |
| Changes | 1 | ||
| Bugs | 1 | Features | 0 |
Complex classes like OSSMail_Mail_Model 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.
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 OSSMail_Mail_Model, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 16 | class OSSMail_Mail_Model extends \App\Base |
||
| 17 | { |
||
| 18 | /** @var string[] Ignored mail addresses */ |
||
| 19 | public const IGNORED_MAILS = ['@', 'undisclosed-recipients', 'Undisclosed-recipients', 'undisclosed-recipients@', 'Undisclosed-recipients@', 'Undisclosed recipients@,@', 'undisclosed recipients@,@']; |
||
| 20 | |||
| 21 | /** @var array Mail account. */ |
||
| 22 | protected $mailAccount = []; |
||
| 23 | |||
| 24 | /** @var string Mail folder. */ |
||
| 25 | protected $mailFolder = ''; |
||
| 26 | |||
| 27 | /** @var bool|int Mail crm id. */ |
||
| 28 | protected $mailCrmId = false; |
||
| 29 | |||
| 30 | /** @var array Action result. */ |
||
| 31 | protected $actionResult = []; |
||
| 32 | |||
| 33 | /** @var int Mail type. */ |
||
| 34 | protected $mailType; |
||
| 35 | |||
| 36 | /** |
||
| 37 | * Set account. |
||
| 38 | * |
||
| 39 | * @param array $account |
||
| 40 | */ |
||
| 41 | public function setAccount($account) |
||
| 42 | { |
||
| 43 | $this->mailAccount = $account; |
||
| 44 | } |
||
| 45 | |||
| 46 | /** |
||
| 47 | * Set folder. |
||
| 48 | * |
||
| 49 | * @param string $folder |
||
| 50 | */ |
||
| 51 | public function setFolder($folder) |
||
| 52 | { |
||
| 53 | $this->mailFolder = $folder; |
||
| 54 | } |
||
| 55 | |||
| 56 | /** |
||
| 57 | * Add action result. |
||
| 58 | * |
||
| 59 | * @param string $type |
||
| 60 | * @param string $result |
||
| 61 | */ |
||
| 62 | public function addActionResult($type, $result) |
||
| 63 | { |
||
| 64 | $this->actionResult[$type] = $result; |
||
| 65 | } |
||
| 66 | |||
| 67 | /** |
||
| 68 | * Get account. |
||
| 69 | * |
||
| 70 | * @return array |
||
| 71 | */ |
||
| 72 | public function getAccount() |
||
| 73 | { |
||
| 74 | return $this->mailAccount; |
||
| 75 | } |
||
| 76 | |||
| 77 | /** |
||
| 78 | * Get folder. |
||
| 79 | * |
||
| 80 | * @return string |
||
| 81 | */ |
||
| 82 | public function getFolder() |
||
| 83 | { |
||
| 84 | return $this->mailFolder; |
||
| 85 | } |
||
| 86 | |||
| 87 | /** |
||
| 88 | * Get action result. |
||
| 89 | * |
||
| 90 | * @param string $action |
||
| 91 | * |
||
| 92 | * @return array |
||
| 93 | */ |
||
| 94 | public function getActionResult($action = false) |
||
| 95 | { |
||
| 96 | if ($action && isset($this->actionResult[$action])) { |
||
| 97 | return $this->actionResult[$action]; |
||
| 98 | } |
||
| 99 | return $this->actionResult; |
||
| 100 | } |
||
| 101 | |||
| 102 | /** |
||
| 103 | * Get type email. |
||
| 104 | * |
||
| 105 | * @param bool $returnText |
||
| 106 | * |
||
| 107 | * @return int|string |
||
| 108 | */ |
||
| 109 | public function getTypeEmail($returnText = false) |
||
| 110 | { |
||
| 111 | if (isset($this->mailType)) { |
||
| 112 | if ($returnText) { |
||
| 113 | $cacheKey = 'Received'; |
||
| 114 | switch ($this->mailType) { |
||
| 115 | case 0: |
||
| 116 | $cacheKey = 'Sent'; |
||
| 117 | break; |
||
| 118 | case 2: |
||
| 119 | $cacheKey = 'Internal'; |
||
| 120 | break; |
||
| 121 | } |
||
| 122 | return $cacheKey; |
||
| 123 | } |
||
| 124 | return $this->mailType; |
||
| 125 | } |
||
| 126 | $account = $this->getAccount(); |
||
| 127 | $fromEmailUser = $this->findEmailUser($this->get('from_email')); |
||
| 128 | $toEmailUser = $this->findEmailUser($this->get('to_email')); |
||
| 129 | $ccEmailUser = $this->findEmailUser($this->get('cc_email')); |
||
| 130 | $bccEmailUser = $this->findEmailUser($this->get('bcc_email')); |
||
| 131 | $existIdentitie = false; |
||
| 132 | foreach (OSSMailScanner_Record_Model::getIdentities($account['user_id']) as $identitie) { |
||
| 133 | if ($identitie['email'] == $this->get('from_email')) { |
||
| 134 | $existIdentitie = true; |
||
| 135 | } |
||
| 136 | } |
||
| 137 | if ($fromEmailUser && ($toEmailUser || $ccEmailUser || $bccEmailUser)) { |
||
| 138 | $key = 2; |
||
| 139 | $cacheKey = 'Internal'; |
||
| 140 | } elseif ($existIdentitie || $fromEmailUser) { |
||
| 141 | $key = 0; |
||
| 142 | $cacheKey = 'Sent'; |
||
| 143 | } else { |
||
| 144 | $key = 1; |
||
| 145 | $cacheKey = 'Received'; |
||
| 146 | } |
||
| 147 | $this->mailType = $key; |
||
| 148 | if ($returnText) { |
||
| 149 | return $cacheKey; |
||
| 150 | } |
||
| 151 | return $key; |
||
| 152 | } |
||
| 153 | |||
| 154 | /** |
||
| 155 | * Find email user. |
||
| 156 | * |
||
| 157 | * @param string $emails |
||
| 158 | * |
||
| 159 | * @return bool |
||
| 160 | */ |
||
| 161 | public static function findEmailUser($emails) |
||
| 162 | { |
||
| 163 | $notFound = 0; |
||
| 164 | if (!empty($emails)) { |
||
| 165 | foreach (explode(',', $emails) as $email) { |
||
| 166 | if (!\Users_Module_Model::checkMailExist($email)) { |
||
| 167 | ++$notFound; |
||
| 168 | } |
||
| 169 | } |
||
| 170 | } |
||
| 171 | return 0 === $notFound; |
||
| 172 | } |
||
| 173 | |||
| 174 | /** |
||
| 175 | * Get account owner. |
||
| 176 | * |
||
| 177 | * @return int |
||
| 178 | */ |
||
| 179 | public function getAccountOwner() |
||
| 180 | { |
||
| 181 | $account = $this->getAccount(); |
||
| 182 | if ($account['crm_user_id']) { |
||
| 183 | return $account['crm_user_id']; |
||
| 184 | } |
||
| 185 | return \App\User::getCurrentUserId(); |
||
| 186 | } |
||
| 187 | |||
| 188 | /** |
||
| 189 | * Generation crm unique id. |
||
| 190 | * |
||
| 191 | * @return string |
||
| 192 | */ |
||
| 193 | public function getUniqueId() |
||
| 194 | { |
||
| 195 | if ($this->has('cid')) { |
||
| 196 | return $this->get('cid'); |
||
| 197 | } |
||
| 198 | $uid = hash('sha256', $this->get('from_email') . '|' . $this->get('date') . '|' . $this->get('subject') . '|' . $this->get('message_id')); |
||
| 199 | $this->set('cid', $uid); |
||
| 200 | return $uid; |
||
| 201 | } |
||
| 202 | |||
| 203 | /** |
||
| 204 | * Get mail crm id. |
||
| 205 | * |
||
| 206 | * @return bool|int |
||
| 207 | */ |
||
| 208 | public function getMailCrmId() |
||
| 209 | { |
||
| 210 | if ($this->mailCrmId) { |
||
| 211 | return $this->mailCrmId; |
||
| 212 | } |
||
| 213 | if (empty($this->get('message_id')) || \Config\Modules\OSSMailScanner::$ONE_MAIL_FOR_MULTIPLE_RECIPIENTS) { |
||
|
|
|||
| 214 | $query = (new \App\Db\Query())->select(['ossmailviewid'])->from('vtiger_ossmailview')->where(['cid' => $this->getUniqueId()])->limit(1); |
||
| 215 | } else { |
||
| 216 | $query = (new \App\Db\Query())->select(['ossmailviewid'])->from('vtiger_ossmailview')->where(['uid' => $this->get('message_id'), 'rc_user' => $this->getAccountOwner()])->limit(1); |
||
| 217 | } |
||
| 218 | return $this->mailCrmId = $query->scalar(); |
||
| 219 | } |
||
| 220 | |||
| 221 | /** |
||
| 222 | * Set mail crm id. |
||
| 223 | * |
||
| 224 | * @param int $id |
||
| 225 | */ |
||
| 226 | public function setMailCrmId($id) |
||
| 227 | { |
||
| 228 | $this->mailCrmId = $id; |
||
| 229 | } |
||
| 230 | |||
| 231 | /** |
||
| 232 | * Get email. |
||
| 233 | * |
||
| 234 | * @param string $cacheKey |
||
| 235 | * |
||
| 236 | * @return string |
||
| 237 | */ |
||
| 238 | public function getEmail($cacheKey) |
||
| 255 | } |
||
| 256 | |||
| 257 | /** |
||
| 258 | * Search crmids by emails. |
||
| 259 | * |
||
| 260 | * @param string $moduleName |
||
| 261 | * @param string $fieldName |
||
| 262 | * @param string[] $emails |
||
| 263 | * |
||
| 264 | * @return array crmids |
||
| 265 | */ |
||
| 266 | public function searchByEmails(string $moduleName, string $fieldName, array $emails) |
||
| 267 | { |
||
| 268 | $return = []; |
||
| 269 | $cacheKey = 'MailSearchByEmails' . $moduleName . '_' . $fieldName; |
||
| 270 | foreach ($emails as $email) { |
||
| 271 | if (empty($email) || \in_array($email, self::IGNORED_MAILS)) { |
||
| 272 | continue; |
||
| 273 | } |
||
| 274 | if (App\Cache::staticHas($cacheKey, $email)) { |
||
| 275 | $cache = App\Cache::staticGet($cacheKey, $email); |
||
| 276 | if (0 != $cache) { |
||
| 277 | $return = array_merge($return, $cache); |
||
| 278 | } |
||
| 279 | } else { |
||
| 280 | $ids = []; |
||
| 281 | $queryGenerator = new \App\QueryGenerator($moduleName); |
||
| 282 | if ($queryGenerator->getModuleField($fieldName)) { |
||
| 283 | $queryGenerator->setFields(['id']); |
||
| 284 | $queryGenerator->addCondition($fieldName, $email, 'e'); |
||
| 285 | $ids = $queryGenerator->createQuery()->column(); |
||
| 286 | $return = array_merge($return, $ids); |
||
| 287 | } |
||
| 288 | if (empty($ids)) { |
||
| 289 | $ids = 0; |
||
| 290 | } |
||
| 291 | App\Cache::staticSave($cacheKey, $email, $ids); |
||
| 292 | } |
||
| 293 | } |
||
| 294 | return $return; |
||
| 295 | } |
||
| 296 | |||
| 297 | /** |
||
| 298 | * Search crmids from domains. |
||
| 299 | * |
||
| 300 | * @param string $moduleName |
||
| 301 | * @param string $fieldName |
||
| 302 | * @param string[] $emails |
||
| 303 | * |
||
| 304 | * @return int[] CRM ids |
||
| 305 | */ |
||
| 306 | public function searchByDomains(string $moduleName, string $fieldName, array $emails) |
||
| 307 | { |
||
| 308 | $cacheKey = 'MailSearchByDomains' . $moduleName . '_' . $fieldName; |
||
| 309 | $crmids = []; |
||
| 310 | foreach ($emails as $email) { |
||
| 311 | if (empty($email) || \in_array($email, self::IGNORED_MAILS)) { |
||
| 312 | continue; |
||
| 313 | } |
||
| 314 | $domain = mb_strtolower(explode('@', $email)[1]); |
||
| 315 | if (!$domain) { |
||
| 316 | continue; |
||
| 317 | } |
||
| 318 | if (App\Cache::staticHas($cacheKey, $domain)) { |
||
| 319 | $cache = App\Cache::staticGet($cacheKey, $domain); |
||
| 320 | if (0 != $cache) { |
||
| 321 | $crmids = array_merge($crmids, $cache); |
||
| 322 | } |
||
| 323 | } else { |
||
| 324 | $crmids = App\Fields\MultiDomain::findIdByDomain($moduleName, $fieldName, $domain); |
||
| 325 | App\Cache::staticSave($cacheKey, $domain, $crmids); |
||
| 326 | } |
||
| 327 | } |
||
| 328 | return $crmids; |
||
| 329 | } |
||
| 330 | |||
| 331 | /** |
||
| 332 | * Find email address. |
||
| 333 | * |
||
| 334 | * @param string $field |
||
| 335 | * @param string $searchModule |
||
| 336 | * @param bool $returnArray |
||
| 337 | * |
||
| 338 | * @return array|string |
||
| 339 | */ |
||
| 340 | public function findEmailAddress($field, $searchModule = false, $returnArray = true) |
||
| 341 | { |
||
| 342 | $return = []; |
||
| 343 | $emails = $this->get($field); |
||
| 344 | if (empty($emails)) { |
||
| 345 | return []; |
||
| 346 | } |
||
| 347 | if (strpos($emails, ',')) { |
||
| 348 | $emails = explode(',', $emails); |
||
| 349 | } else { |
||
| 350 | $emails = (array) $emails; |
||
| 351 | } |
||
| 352 | $emailSearchList = OSSMailScanner_Record_Model::getEmailSearchList(); |
||
| 353 | if (!empty($emailSearchList)) { |
||
| 354 | foreach ($emailSearchList as $field) { |
||
| 355 | $enableFind = true; |
||
| 356 | $row = explode('=', $field); |
||
| 357 | $moduleName = $row[1]; |
||
| 358 | $fieldName = $row[0]; |
||
| 359 | $fieldModel = Vtiger_Module_Model::getInstance($moduleName)->getField($row[0]); |
||
| 360 | if ($searchModule && $searchModule !== $moduleName) { |
||
| 361 | $enableFind = false; |
||
| 362 | } |
||
| 363 | if ($enableFind) { |
||
| 364 | if (319 === $fieldModel->getUIType()) { |
||
| 365 | $return = array_merge($return, $this->searchByDomains($moduleName, $fieldName, $emails)); |
||
| 366 | } else { |
||
| 367 | $return = array_merge($return, $this->searchByEmails($moduleName, $fieldName, $emails)); |
||
| 368 | } |
||
| 369 | } |
||
| 370 | } |
||
| 371 | } |
||
| 372 | if (!$returnArray) { |
||
| 373 | return implode(',', $return); |
||
| 374 | } |
||
| 375 | return $return; |
||
| 376 | } |
||
| 377 | |||
| 378 | /** |
||
| 379 | * Function to saving attachments. |
||
| 380 | */ |
||
| 381 | public function saveAttachments() |
||
| 418 | } |
||
| 419 | |||
| 420 | /** |
||
| 421 | * Treatment mail content with all images and unnecessary trash. |
||
| 422 | * |
||
| 423 | * @return string |
||
| 424 | */ |
||
| 425 | public function getContent(): string |
||
| 485 | } |
||
| 486 | |||
| 487 | /** |
||
| 488 | * Get file from image. |
||
| 489 | * |
||
| 490 | * @param DOMElement $element |
||
| 491 | * @param array $params |
||
| 492 | * @param array $attachments |
||
| 493 | * |
||
| 494 | * @return array |
||
| 495 | */ |
||
| 496 | private function getFileFromImage(DOMElement $element, array $params, array &$attachments): array |
||
| 497 | { |
||
| 498 | $src = trim($element->getAttribute('src'), '\''); |
||
| 499 | $element->removeAttribute('src'); |
||
| 500 | $file = []; |
||
| 501 | if ('data:' === substr($src, 0, 5)) { |
||
| 502 | if ($fileInstance = \App\Fields\File::saveFromString($src, ['validateAllowedFormat' => 'image'])) { |
||
| 503 | $params['titlePrefix'] = 'base64_'; |
||
| 504 | if ($file = \App\Fields\File::saveFromContent($fileInstance, $params)) { |
||
| 505 | $file['srcType'] = 'base64'; |
||
| 506 | } |
||
| 507 | } |
||
| 508 | } elseif (filter_var($src, FILTER_VALIDATE_URL)) { |
||
| 509 | $params['param'] = ['validateAllowedFormat' => 'image']; |
||
| 510 | $params['titlePrefix'] = 'url_'; |
||
| 511 | if (\Config\Modules\OSSMailScanner::$attachMailBodyGraphicUrl ?? true) { |
||
| 512 | if ($file = App\Fields\File::saveFromUrl($src, $params)) { |
||
| 513 | $file['srcType'] = 'image'; |
||
| 514 | } |
||
| 515 | } else { |
||
| 516 | $file = [ |
||
| 517 | 'srcType' => 'url', |
||
| 518 | 'url' => $src, |
||
| 519 | ]; |
||
| 520 | } |
||
| 521 | } elseif ('cid:' === substr($src, 0, 4)) { |
||
| 522 | $src = substr($src, 4); |
||
| 523 | if (isset($attachments[$src])) { |
||
| 524 | $fileInstance = App\Fields\File::loadFromContent($attachments[$src]['attachment'], $attachments[$src]['filename'], ['validateAllowedFormat' => 'image']); |
||
| 525 | if ($fileInstance && $fileInstance->validateAndSecure()) { |
||
| 526 | $params['titlePrefix'] = 'content_'; |
||
| 527 | if ($file = App\Fields\File::saveFromContent($fileInstance, $params)) { |
||
| 528 | $file['srcType'] = 'cid'; |
||
| 529 | } |
||
| 530 | unset($attachments[$src]); |
||
| 531 | } |
||
| 532 | } else { |
||
| 533 | \App\Log::warning("There is no attachment with ID: $src , in mail: {$this->get('date')} | Folder: {$this->getFolder()} | ID: {$this->get('id')}", __CLASS__); |
||
| 534 | } |
||
| 535 | } else { |
||
| 536 | \App\Log::warning("Unsupported photo type, requires verification. ID: $src , in mail: {$this->get('date')} | Folder: {$this->getFolder()} | ID: {$this->get('id')}", __CLASS__); |
||
| 537 | } |
||
| 538 | if ($file) { |
||
| 539 | $yetiforceTag = $element->ownerDocument->createElement('yetiforce'); |
||
| 540 | if ('url' === $file['srcType']) { |
||
| 541 | $yetiforceTag->textContent = $file['url']; |
||
| 542 | } else { |
||
| 543 | $yetiforceTag->setAttribute('type', 'Documents'); |
||
| 544 | $yetiforceTag->setAttribute('crm-id', $file['crmid']); |
||
| 545 | $yetiforceTag->setAttribute('attachment-id', $file['attachmentsId']); |
||
| 546 | } |
||
| 547 | $element->parentNode->replaceChild($yetiforceTag, $element); |
||
| 548 | } else { |
||
| 549 | $file = []; |
||
| 550 | } |
||
| 551 | return $file; |
||
| 552 | } |
||
| 553 | |||
| 554 | /** |
||
| 555 | * Post process function. |
||
| 556 | */ |
||
| 557 | public function postProcess() |
||
| 559 | } |
||
| 560 | } |
||
| 561 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths