OSSMail_Module_Model   F
last analyzed

Complexity

Total Complexity 84

Size/Duplication

Total Lines 334
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 84
eloc 200
c 1
b 0
f 0
dl 0
loc 334
rs 2

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getDefaultViewName() 0 3 1
A getComposeUrl() 0 16 5
A getDefaultMailAccount() 0 3 3
A getSettingLinks() 0 13 2
D getExternalUrl() 0 33 10
A getComposeParameters() 0 9 3
A getModalRecordsListSourceFields() 0 6 2
D getExternalUrlForWidget() 0 83 16
F getComposeParam() 0 111 42

How to fix   Complexity   

Complex Class

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

1
<?php
2
3
/**
4
 * @copyright YetiForce S.A.
5
 * @license   YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com)
6
 * @author    Radosław Skrzypczak <[email protected]>
7
 * @author    Mariusz Krzaczkowski <[email protected]>
8
 */
9
class OSSMail_Module_Model extends Vtiger_Module_Model
10
{
11
	public function getDefaultViewName()
12
	{
13
		return 'Index';
14
	}
15
16
	/** {@inheritdoc} */
17
	public function getSettingLinks(): array
18
	{
19
		Vtiger_Loader::includeOnce('~~modules/com_vtiger_workflow/VTWorkflowUtils.php');
20
		$settingsLinks = [];
21
		if ($menu = Settings_Vtiger_MenuItem_Model::getInstance('Mail')) {
22
			$settingsLinks[] = [
23
				'linktype' => 'LISTVIEWSETTING',
24
				'linklabel' => 'LBL_MODULE_CONFIGURATION',
25
				'linkurl' => 'index.php?module=OSSMail&parent=Settings&view=Index&block=' . $menu->get('blockid') . '&fieldid=' . $menu->get('fieldid'),
26
				'linkicon' => 'adminIcon-mail-download-history',
27
			];
28
		}
29
		return $settingsLinks;
0 ignored issues
show
introduced by
The expression return $settingsLinks returns an array which contains values of type array<string,string> which are incompatible with the return type string mandated by Vtiger_Module_Model::getSettingLinks().
Loading history...
30
	}
31
32
	public static function getDefaultMailAccount($accounts)
33
	{
34
		return (isset($_SESSION['AutoLoginUser']) && \array_key_exists($_SESSION['AutoLoginUser'], $accounts)) ? $accounts[$_SESSION['AutoLoginUser']] : reset($accounts);
35
	}
36
37
	/**
38
	 * URL generation for internal mail clients.
39
	 *
40
	 * @param mixed $moduleName
41
	 * @param mixed $record
42
	 * @param mixed $view
43
	 * @param mixed $type
44
	 *
45
	 * @return string
46
	 */
47
	public static function getComposeUrl($moduleName = false, $record = false, $view = false, $type = false): string
48
	{
49
		$url = 'index.php?module=OSSMail&view=Compose';
50
		if ($moduleName) {
51
			$url .= '&crmModule=' . $moduleName;
52
		}
53
		if ($record) {
54
			$url .= '&crmRecord=' . $record;
55
		}
56
		if ($view) {
57
			$url .= '&crmView=' . $view;
58
		}
59
		if ($type) {
60
			$url .= '&type=' . $type;
61
		}
62
		return $url;
63
	}
64
65
	public static function getComposeParam(App\Request $request)
66
	{
67
		$moduleName = $request->getByType('crmModule');
68
		$record = $request->getInteger('crmRecord');
69
		$type = $request->getByType('type');
70
		$return = [];
71
		if (('Users' === $moduleName && $record === \App\User::getCurrentUserRealId()) || ('Users' !== $moduleName && !empty($record) && \App\Record::isExists($record) && \App\Privilege::isPermitted($moduleName, 'DetailView', $record))) {
72
			$recordModel = Vtiger_Record_Model::getInstanceById($record, $moduleName);
73
			$eventHandler = new App\EventHandler();
74
			$eventHandler->setRecordModel($recordModel)->setModuleName($moduleName)->setParams($return);
75
			$eventHandler->trigger('MailComposeParamBefore');
76
			$return = $eventHandler->getParams();
77
78
			$recordModel_OSSMailView = OSSMailView_Record_Model::getCleanInstance('OSSMailView');
79
			if ($request->isEmpty('to') && ($email = $recordModel_OSSMailView->findEmail($record, $moduleName))) {
80
				$return['to'] = $email;
81
			}
82
			foreach (['_to', '_cc'] as $name) {
83
				$content = $request->has($name) ? $request->getRaw($name) : ($return[$name] ?? '');
84
				if ($content) {
85
					$emailParser = \App\EmailParser::getInstanceByModel($recordModel);
86
					$emailParser->emailoptout = false;
87
					$fromEmailDetails = $emailParser->setContent($content)->parse()->getContent();
88
					if ($fromEmailDetails) {
89
						$return[substr($name, -2)] = $fromEmailDetails;
90
					}
91
					if (isset($return[$name])) {
92
						unset($return[$name]);
93
					}
94
				}
95
			}
96
			if (!\in_array($moduleName, array_keys(array_merge(\App\ModuleHierarchy::getModulesByLevel(0), \App\ModuleHierarchy::getModulesByLevel(3)))) || 'Campaigns' === $moduleName) {
97
				$subject = '';
98
				if ('new' === $type || 'Campaigns' === $moduleName) {
99
					$return['title'] = $recordModel->getName();
100
					$subject .= $recordModel->getName();
101
				}
102
				$recordNumber = $recordModel->getRecordNumber();
103
				if (!empty($recordNumber)) {
104
					$return['recordNumber'] = $recordNumber;
105
					$subject = "[$recordNumber] $subject";
106
				}
107
				if (($templateId = $request->getInteger('template', 0)) && \App\Record::isExists($templateId, 'EmailTemplates')) {
108
					$params = $request->getArray('templateParams', \App\Purifier::TEXT, [], App\Purifier::ALNUM);
109
					$templateModel = \Vtiger_Record_Model::getInstanceById($templateId, 'EmailTemplates');
110
					$textParser = \App\TextParser::getInstanceByModel($recordModel);
111
					foreach ($params as $key => $value) {
112
						$textParser->setParam($key, $value);
113
					}
114
					if ('Calendar' === $moduleName && !$recordModel->isEmpty('meeting_url') && !\array_key_exists('meetingUrl', $params) ) {
115
						$textParser->setParam('meetingUrl', $recordModel->get('meeting_url'));
116
					}
117
					$subject = $textParser->setContent($templateModel->get('subject'))->parse()->getContent();
118
					$return['html'] = true;
119
					$return['body'] = $textParser->setContent($templateModel->get('content'))->parse()->getContent();
120
				}
121
				$return['subject'] = $subject;
122
				if ('Calendar' === $moduleName && $request->getBoolean('ics')) {
123
					$filePath = \App\Config::main('tmp_dir');
124
					$tmpFileName = tempnam($filePath, 'ics');
125
					$filePath .= basename($tmpFileName);
126
					if (false !== file_put_contents($filePath, $recordModel->getICal())) {
0 ignored issues
show
Bug introduced by
The method getICal() does not exist on Vtiger_Record_Model. It seems like you code against a sub-type of Vtiger_Record_Model such as Calendar_Record_Model. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

126
					if (false !== file_put_contents($filePath, $recordModel->/** @scrutinizer ignore-call */ getICal())) {
Loading history...
127
						$fileName = \App\Fields\File::sanitizeUploadFileName($recordModel->getName()) . '.ics';
128
						$return['filePath'] = [['path' => $filePath, 'name' => $fileName]];
129
					}
130
				}
131
			}
132
133
			$eventHandler->setParams($return);
134
			$eventHandler->trigger('MailComposeParamAfter');
135
			$return = $eventHandler->getParams();
136
		}
137
		if (!empty($moduleName)) {
138
			$return['crmmodule'] = $moduleName;
139
		}
140
		if (!empty($record)) {
141
			$return['crmrecord'] = $record;
142
		}
143
		if (!$request->isEmpty('crmView')) {
144
			$return['crmview'] = $request->getByType('crmView');
145
		}
146
		if (!$request->isEmpty('mid') && !empty($type)) {
147
			$return['mailId'] = (int) $request->getInteger('mid');
148
			$return['type'] = $type;
149
		}
150
		if (!$request->isEmpty('pdf_path')) {
151
			$return['filePath'] = $request->get('pdf_path');
152
		}
153
		if (!empty($moduleName)) {
154
			$currentUser = Users_Record_Model::getCurrentUserModel();
155
			$moduleConfig = App\Config::module($moduleName);
156
			if ($moduleConfig && isset($moduleConfig['SEND_IDENTITY'][$currentUser->get('roleid')])) {
157
				$return['from'] = $moduleConfig['SEND_IDENTITY'][$currentUser->get('roleid')];
158
			}
159
		}
160
		if (!$request->isEmpty('to')) {
161
			$return['to'] = $request->get('to');
162
		}
163
		if (!$request->isEmpty('cc')) {
164
			$return['cc'] = $request->get('cc');
165
		}
166
		if (!$request->isEmpty('bcc')) {
167
			$return['bcc'] = $request->get('bcc');
168
		}
169
		if (!$request->isEmpty('subject')) {
170
			$return['subject'] = $request->get('subject');
171
		}
172
		if (!$request->isEmpty('emails')) {
173
			$return['bcc'] = implode(',', $request->get('emails'));
174
		}
175
		return $return;
176
	}
177
178
	protected static $composeParam = false;
179
180
	/**
181
	 * Function get compose parameters.
182
	 *
183
	 * @return array
184
	 */
185
	public static function getComposeParameters()
186
	{
187
		if (!self::$composeParam) {
188
			$config = (new \App\Db\Query())->select(['parameter', 'value'])->from('vtiger_ossmailscanner_config')
189
				->where(['conf_type' => 'email_list'])->createCommand()->queryAllByGroup(0);
190
			$config['popup'] = '_blank' == $config['target'] ? true : false;
191
			self::$composeParam = $config;
192
		}
193
		return self::$composeParam;
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::composeParam also could return the type true which is incompatible with the documented return type array.
Loading history...
194
	}
195
196
	/**
197
	 * URL generation for external mail clients.
198
	 *
199
	 * @param mixed $moduleName
200
	 * @param mixed $record
201
	 * @param mixed $view
202
	 * @param mixed $type
203
	 *
204
	 * @return string
205
	 */
206
	public static function getExternalUrl($moduleName = false, $record = false, $view = false, $type = false): string
207
	{
208
		$url = 'mailto:';
209
		$request = new App\Request([]);
210
		if ($moduleName) {
211
			$request->set('crmModule', $moduleName);
212
		}
213
		if ($record) {
214
			$request->set('crmRecord', $record);
215
		}
216
		if ($view) {
217
			$request->set('crmView', $view);
218
		}
219
		if ($type) {
220
			$request->set('type', $type);
221
		}
222
		$param = self::getComposeParam($request);
223
		if (isset($param['to'])) {
224
			$url .= str_replace(',', ';', $param['to']);
225
		}
226
		$url .= '?';
227
		foreach (['cc', 'bcc'] as $value) {
228
			if (isset($param[$value])) {
229
				$url .= $value . '=' . str_replace(',', ';', $param[$value]) . '&';
230
			}
231
		}
232
		if (isset($param['subject'])) {
233
			$url .= 'subject=' . \App\Purifier::encodeHtml($param['subject']) . '&';
234
		}
235
		if (isset($param['body'])) {
236
			$url .= 'body=' . \App\Purifier::encodeHtml($param['body']) . '&';
237
		}
238
		return $url;
239
	}
240
241
	/**
242
	 * Get mail url for widget.
243
	 *
244
	 * @param int    $record
245
	 * @param string $type
246
	 * @param int    $srecord
247
	 * @param string $smoduleName
248
	 *
249
	 * @return string
250
	 */
251
	public static function getExternalUrlForWidget($record, $type, $srecord = false, $smoduleName = false)
252
	{
253
		if (\is_object($record)) {
0 ignored issues
show
introduced by
The condition is_object($record) is always false.
Loading history...
254
			$body = $record->get('content');
255
			$subject = $record->get('subject');
256
			$from = $record->get('from_email');
257
			$to = $record->get('to_email');
258
			$cc = $record->get('cc_email');
259
			$date = $record->get('date');
260
		} else {
261
			$body = $record['bodyRaw'];
262
			$subject = $record['subjectRaw'];
263
			$from = $record['fromRaw'];
264
			$to = $record['toRaw'];
265
			$cc = $record['ccRaw'];
266
			$date = $record['date'];
267
		}
268
269
		if (!empty($srecord) && !empty($smoduleName)) {
270
			$recordModel = Vtiger_Record_Model::getInstanceById($srecord);
271
			$moduleModel = $recordModel->getModule();
272
			if (!\in_array($smoduleName, array_keys(array_merge(\App\ModuleHierarchy::getModulesByLevel(0), \App\ModuleHierarchy::getModulesByLevel(3))))) {
273
				$fieldName = $moduleModel->getSequenceNumberFieldName();
274
				if ($fieldName) {
275
					$subject = "[$fieldName] $subject";
276
				}
277
			}
278
		}
279
		if ('forward' == $type) {
280
			$url = 'mailto:';
281
			$subject = 'Fwd: ' . $subject;
282
		} else {
283
			$url = 'mailto:' . $from;
284
			$subject = 'Re: ' . $subject;
285
		}
286
		$url .= '?subject=' . $subject;
287
		if ('replyAll' == $type && !empty($cc)) {
288
			$url .= '&cc=' . $cc;
289
		}
290
		include_once 'vendor/ezyang/htmlpurifier/library/HTMLPurifier.auto.php';
291
		$config = HTMLPurifier_Config::createDefault();
292
		$config->set('Core.Encoding', \App\Config::main('default_charset'));
293
		$config->set('Cache.SerializerPath', ROOT_DIRECTORY . '/cache/vtlib');
294
		$config->set('CSS.AllowTricky', false);
295
		$config->set('HTML.AllowedElements', 'div,p,br');
296
		$config->set('HTML.AllowedAttributes', '');
297
		$purifier = new HTMLPurifier($config);
298
		$body = $purifier->purify($body);
299
		$body = str_replace(['<p> </p>', '<p></p>', '</p>', '<br />', '<p>', '<div>', '</div>', PHP_EOL . PHP_EOL, PHP_EOL . PHP_EOL], ['', '', PHP_EOL, PHP_EOL, '', '', PHP_EOL, PHP_EOL, PHP_EOL], nl2br($body));
300
301
		$content = '';
302
		$mailtoLimit = \App\Config::component('Mail', 'MAILTO_LIMIT');
303
304
		if ('forward' == $type) {
305
			$content .= \App\Language::translate('LBL_MAIL_FORWARD_INTRO', 'OSSMailView') . PHP_EOL;
306
			$content .= \App\Language::translate('Subject', 'OSSMailView') . ': ' . $subject . PHP_EOL;
307
			$content .= \App\Language::translate('Date', 'OSSMailView') . ': ' . $date . PHP_EOL;
308
			$content .= \App\Language::translate('From', 'OSSMailView') . ': ' . $from . PHP_EOL;
309
			$content .= \App\Language::translate('To', 'OSSMailView') . ': ' . $to . PHP_EOL;
310
			foreach (explode(PHP_EOL, $body) as $line) {
311
				$line = trim($line);
312
				if (!empty($line)) {
313
					$line = '> ' . $line . PHP_EOL;
314
					if (\strlen($url . '&body=' . rawurlencode($content . $line)) > $mailtoLimit) {
315
						break;
316
					}
317
					$content .= $line;
318
				}
319
			}
320
		} else {
321
			$content .= \App\Language::translateArgs('LBL_MAIL_REPLY_INTRO', 'OSSMailView', $date, $from) . PHP_EOL;
322
			foreach (explode(PHP_EOL, $body) as $line) {
323
				$line = trim($line);
324
				if (!empty($line)) {
325
					$line = '> ' . $line . PHP_EOL;
326
					if (\strlen($url . '&body=' . rawurlencode($content . $line)) > $mailtoLimit) {
327
						break;
328
					}
329
					$content .= $line;
330
				}
331
			}
332
		}
333
		return $url . '&body=' . rawurlencode($content);
334
	}
335
336
	/** {@inheritdoc} */
337
	public function getModalRecordsListSourceFields(App\QueryGenerator $queryGenerator, Vtiger_Module_Model $baseModule, $popupFields)
338
	{
339
		foreach ($baseModule->getFieldsByType('email') as $item) {
340
			$popupFields[$item->getName()] = $item->getName();
341
		}
342
		return $popupFields;
343
	}
344
}
345