Passed
Push — developer ( 6b5868...bed0f9 )
by Radosław
22:42 queued 03:39
created

Outlook   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 178
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 44
eloc 88
dl 0
loc 178
rs 8.8798
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A getExceptions() 0 3 1
A findRelatedRecordsBySubject() 0 6 2
A getUserId() 0 3 1
B initFromRequest() 0 18 7
B getEmailsFields() 0 19 7
A getMailCrmId() 0 8 2
B getMailType() 0 22 8
B getNumberFields() 0 19 7
A findRelatedRecords() 0 16 4
A getActions() 0 3 1
A findRelatedRecordsByEmail() 0 14 4

How to fix   Complexity   

Complex Class

Complex classes like Outlook 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 Outlook, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Mail outlook message file.
4
 *
5
 * @package App
6
 *
7
 * @copyright YetiForce S.A.
8
 * @license   YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com)
9
 * @author    Mariusz Krzaczkowski <[email protected]>
10
 */
11
12
namespace App\Mail\ScannerEngine;
13
14
/**
15
 * Mail outlook message class.
16
 */
17
class Outlook extends Base
18
{
19
	/**
20
	 * Scanner engine name.
21
	 *
22
	 * @var string
23
	 */
24
	public $name = 'Outlook';
25
26
	/** {@inheritdoc} */
27
	public function getActions(): array
28
	{
29
		return array_filter(explode(',', \App\User::getCurrentUserModel()->getDetail('mail_scanner_actions')));
30
	}
31
32
	/** {@inheritdoc} */
33
	public function getMailCrmId()
34
	{
35
		if ($this->has('mailCrmId')) {
36
			return $this->get('mailCrmId');
37
		}
38
		$mailCrmId = \App\Mail\Message::findByCid($this->getCid());
39
		$this->set('mailCrmId', $mailCrmId);
40
		return $mailCrmId;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $mailCrmId returns the type boolean|integer which is incompatible with the return type mandated by App\Mail\ScannerEngine\Base::getMailCrmId() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
41
	}
42
43
	/** {@inheritdoc} */
44
	public function getMailType(): int
45
	{
46
		if ($this->has('mailType')) {
47
			return $this->get('mailType');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('mailType') could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
48
		}
49
		$to = false;
50
		$from = (bool) \App\Mail\RecordFinder::findUserEmail([$this->get('from_email')]);
51
		if ($this->has('to_email')) {
52
			$to = (bool) \App\Mail\RecordFinder::findUserEmail($this->get('to_email'));
53
		} elseif ($this->has('cc_email')) {
54
			$to = (bool) \App\Mail\RecordFinder::findUserEmail($this->get('cc_email'));
55
		} elseif ($this->has('bcc_email')) {
56
			$to = (bool) \App\Mail\RecordFinder::findUserEmail($this->get('bcc_email'));
57
		}
58
		$key = self::MAIL_TYPE_RECEIVED;
59
		if ($from && $to) {
60
			$key = self::MAIL_TYPE_INTERNAL;
61
		} elseif ($from) {
62
			$key = self::MAIL_TYPE_SENT;
63
		}
64
		$this->set('mailType', $key);
65
		return $key;
66
	}
67
68
	/** {@inheritdoc} */
69
	public function getUserId(): int
70
	{
71
		return \App\User::getCurrentUserRealId();
72
	}
73
74
	/**
75
	 * Initialize with request data.
76
	 *
77
	 * @param \App\Request $request
78
	 *
79
	 * @return void
80
	 */
81
	public function initFromRequest(\App\Request $request)
82
	{
83
		$this->set('subject', $request->isEmpty('mailSubject') ? '-' : \App\TextUtils::textTruncate($request->getByType('mailSubject', 'Text'), 65535, false));
84
		$this->set('headers', $request->isEmpty('mailHeaders') ? '' : \App\TextUtils::textTruncate($request->getRaw('mailHeaders'), 16777215, false));
85
		$this->set('from_email', $request->getByType('mailFrom', 'Email'));
86
		$this->set('date', $request->getByType('mailDateTimeCreated', 'DateTimeInIsoFormat'));
87
		$this->set('message_id', $request->getByType('mailMessageId', 'MailId'));
88
		if (!$request->isEmpty('mailTo')) {
89
			$this->set('to_email', $request->getArray('mailTo', 'Email'));
90
		}
91
		if (!$request->isEmpty('mailCc', true)) {
92
			$this->set('cc_email', $request->getArray('mailCc', 'Email'));
93
		}
94
		if (!$request->isEmpty('mailBcc', true)) {
95
			$this->set('bcc_email', $request->getArray('mailBcc', 'Email'));
96
		}
97
		if (!$request->isEmpty('mailBody', true)) {
98
			$this->set('body', $request->getForHtml('mailBody'));
99
		}
100
	}
101
102
	/** {@inheritdoc} */
103
	public function findRelatedRecords(bool $onlyId = false): array
104
	{
105
		$ids = $this->findRelatedRecordsByEmail();
106
		if ($idsBySubject = $this->findRelatedRecordsBySubject()) {
107
			$ids[] = current($idsBySubject);
108
		}
109
		if (!$onlyId) {
110
			foreach ($ids as &$id) {
111
				$id = [
112
					'id' => $id,
113
					'module' => \App\Record::getType($id),
114
					'label' => \App\Record::getLabel($id),
115
				];
116
			}
117
		}
118
		return $ids;
119
	}
120
121
	/** {@inheritdoc} */
122
	public function findRelatedRecordsByEmail(): array
123
	{
124
		if (isset($this->processData['findByEmail'])) {
125
			return $this->processData['findByEmail'];
126
		}
127
		$emails = $this->get('to_email');
128
		$emails[] = $this->get('from_email');
129
		if ($this->has('cc_email')) {
130
			$emails = array_merge($emails, $this->get('cc_email'));
131
		}
132
		if ($this->has('bcc_email')) {
133
			$emails = array_merge($emails, $this->get('bcc_email'));
134
		}
135
		return $this->processData['findByEmail'] = \App\Utils::flatten(\App\Mail\RecordFinder::findByEmail($emails, $this->getEmailsFields()));
136
	}
137
138
	/** {@inheritdoc} */
139
	public function findRelatedRecordsBySubject(): array
140
	{
141
		if (isset($this->processData['findBySubject'])) {
142
			return $this->processData['findBySubject'];
143
		}
144
		return $this->processData['findBySubject'] = \App\Mail\RecordFinder::findBySubject($this->get('subject'), $this->getNumberFields());
145
	}
146
147
	/** {@inheritdoc} */
148
	public function getEmailsFields(?string $searchModuleName = null): array
149
	{
150
		$cacheKey = $searchModuleName ?? '-';
151
		if (isset($this->emailsFieldsCache[$cacheKey])) {
152
			return $this->emailsFieldsCache[$cacheKey];
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->emailsFieldsCache[$cacheKey] returns the type string which is incompatible with the type-hinted return array.
Loading history...
153
		}
154
		$user = \App\User::getCurrentUserModel();
155
		$fields = [];
156
		if ($mailScannerFields = $user->getDetail('mail_scanner_fields')) {
157
			foreach (explode(',', trim($mailScannerFields, ',')) as $field) {
158
				$field = explode('|', $field);
159
				if (($searchModuleName && $searchModuleName !== $field[1]) || !\in_array($field[3], [13, 319])) {
160
					continue;
161
				}
162
				$fields[$field[1]][$field[3]][] = $field[2];
163
			}
164
		}
165
		$this->emailsFieldsCache[$cacheKey] = $fields;
166
		return $fields;
167
	}
168
169
	/** {@inheritdoc} */
170
	public function getNumberFields(?string $searchModuleName = null): array
171
	{
172
		$cacheKey = $searchModuleName ?? '-';
173
		if (isset($this->numberFieldsCache[$cacheKey])) {
174
			return $this->numberFieldsCache[$cacheKey];
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->numberFieldsCache[$cacheKey] returns the type string which is incompatible with the type-hinted return array.
Loading history...
175
		}
176
		$user = \App\User::getCurrentUserModel();
177
		$fields = [];
178
		if ($mailScannerFields = $user->getDetail('mail_scanner_fields')) {
179
			foreach (explode(',', trim($mailScannerFields, ',')) as $field) {
180
				$field = explode('|', $field);
181
				if (($searchModuleName && $searchModuleName !== $field[1]) || 4 !== (int) $field[3]) {
182
					continue;
183
				}
184
				$fields[$field[1]][$field[3]][] = $field[2];
185
			}
186
		}
187
		$this->numberFieldsCache[$cacheKey] = $fields;
188
		return $fields;
189
	}
190
191
	/** {@inheritdoc} */
192
	public function getExceptions(): array
193
	{
194
		return [];
195
	}
196
}
197