Module::getModuleMeta()   A
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 25
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 4

Importance

Changes 0
Metric Value
eloc 19
dl 0
loc 25
rs 9.6333
c 0
b 0
f 0
ccs 18
cts 18
cp 1
cc 4
nc 6
nop 0
crap 4
1
<?php
2
3
namespace App;
4
5
/**
6
 * Modules basic class.
7
 *
8
 * @package App
9
 *
10
 * @copyright YetiForce S.A.
11
 * @license   YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com)
12
 * @author    Mariusz Krzaczkowski <[email protected]>
13
 * @author    Radosław Skrzypczak <[email protected]>
14
 */
15
class Module
16
{
17
	/**
18
	 * Cache for tabdata.php.
19
	 *
20
	 * @var array
21
	 */
22
	protected static $tabdataCache;
23
24
	/**
25
	 * Init tabdata from file.
26
	 */
27
	public static function init()
28
	{
29
		static::$tabdataCache = require ROOT_DIRECTORY . '/user_privileges/tabdata.php';
30
		static::$tabdataCache['tabName'] = array_flip(static::$tabdataCache['tabId']);
31
	}
32
33
	/**
34
	 * Init tabdata form db.
35 7
	 */
36
	public static function initFromDb()
37 7
	{
38 7
		static::$tabdataCache = static::getModuleMeta();
39 7
		static::$tabdataCache['tabName'] = array_flip(static::$tabdataCache['tabId']);
40
	}
41 5868
42
	/**
43 5868
	 * Gets entity info.
44 5868
	 *
45 5868
	 * @param string $moduleName
46
	 *
47
	 * @return array|null
48
	 */
49
	public static function getEntityInfo(string $moduleName = null): ?array
50 5868
	{
51 5844
		return self::getEntitiesInfo()[$moduleName] ?? null;
52
	}
53
54
	/**
55 62
	 * Gets all entities data.
56 62
	 *
57 62
	 * @param array
58 62
	 */
59 62
	public static function getEntitiesInfo(): array
60 62
	{
61 62
		$cacheName = 'ModuleEntityInfo';
62 62
		if (!Cache::has($cacheName, '')) {
63 62
			$entityInfos = [];
64
			$dataReader = (new \App\Db\Query())->from('vtiger_entityname')->createCommand()->query();
65 62
			while ($row = $dataReader->read()) {
66 62
				$row['fieldnameArr'] = $row['fieldname'] ? explode(',', $row['fieldname']) : [];
67
				$row['searchcolumnArr'] = $row['searchcolumn'] ? explode(',', $row['searchcolumn']) : [];
68
				$entityInfos[$row['modulename']] = $row;
69 62
			}
70
			return Cache::save($cacheName, '', $entityInfos);
0 ignored issues
show
Bug Best Practice introduced by
The expression return App\Cache::save($...Name, '', $entityInfos) returns the type boolean which is incompatible with the type-hinted return array.
Loading history...
71
		}
72
		return Cache::get($cacheName, '');
73
	}
74
75
	public static function getAllEntityModuleInfo($sort = false)
76
	{
77
		$entity = static::getEntitiesInfo();
78
		if ($sort) {
79
			usort($entity, function ($a, $b) {
80
				return $a['sequence'] < $b['sequence'] ? -1 : 1;
81
			});
82
		}
83
		return $entity;
84
	}
85
86
	protected static $isModuleActiveCache = [];
87
88
	/**
89
	 * Function to check whether the module is active.
90
	 *
91
	 * @param string $moduleName
92
	 *
93
	 * @return bool
94 15
	 */
95
	public static function isModuleActive(string $moduleName): bool
96 15
	{
97 15
		if (isset(static::$isModuleActiveCache[$moduleName])) {
98
			return static::$isModuleActiveCache[$moduleName];
99 3
		}
100 1
		if (\in_array($moduleName, ['CustomView', 'Users', 'Import', 'com_vtiger_workflow', 'PickList'])) {
101
			static::$isModuleActiveCache[$moduleName] = true;
102 1
			return true;
103
		}
104 2
		$moduleId = static::getModuleId($moduleName);
105 2
		$isActive = (isset(static::$tabdataCache['tabPresence'][$moduleId]) && 0 == static::$tabdataCache['tabPresence'][$moduleId]);
106 2
		static::$isModuleActiveCache[$moduleName] = $isActive;
107
		return $isActive;
108 2
	}
109
110
	/**
111
	 * Get module id by module name.
112
	 *
113
	 * @param string $moduleName
114
	 *
115
	 * @return bool|int
116
	 */
117
	public static function getModuleId($moduleName)
118 127
	{
119
		return static::$tabdataCache['tabId'][$moduleName] ?? false;
120 127
	}
121
122
	/**
123
	 * Get module nane by module id.
124
	 *
125
	 * @param int $tabId
126
	 *
127
	 * @return bool|string
128
	 */
129
	public static function getModuleName($tabId)
130 446
	{
131
		return static::$tabdataCache['tabName'][$tabId] ?? false;
132 446
	}
133
134
	/**
135
	 * Get module owner by module id.
136
	 *
137
	 * @param int $tabId
138
	 *
139
	 * @return int
140
	 */
141
	public static function getModuleOwner($tabId)
142
	{
143
		return static::$tabdataCache['tabOwnedby'][$tabId] ?? false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return static::tabdataCa...edby'][$tabId] ?? false could also return false which is incompatible with the documented return type integer. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
144
	}
145
146
	/**
147
	 * Get all module names.
148
	 *
149
	 * @return string[]
150
	 */
151
	public static function getAllModuleNames()
152
	{
153
		return static::$tabdataCache['tabName'];
154
	}
155
156
	/**
157
	 * Function to get the list of module for which the user defined sharing rules can be defined.
158
	 *
159
	 * @param array $eliminateModules
160
	 *
161
	 * @return array
162
	 */
163
	public static function getSharingModuleList($eliminateModules = false)
164 2
	{
165
		$modules = \vtlib\Functions::getAllModules(true, true, 0, false, 0);
166 2
		$sharingModules = [];
167 2
		foreach ($modules as $row) {
168 2
			if (!$eliminateModules || !\in_array($row['name'], $eliminateModules)) {
169 2
				$sharingModules[] = $row['name'];
170 2
			}
171
		}
172
		return $sharingModules;
173 2
	}
174
175
	/**
176
	 * Get sql for name in display format.
177
	 *
178
	 * @param string $moduleName
179
	 *
180
	 * @return string
181
	 */
182
	public static function getSqlForNameInDisplayFormat($moduleName)
183
	{
184
		$db = \App\Db::getInstance();
185
		$entityFieldInfo = static::getEntityInfo($moduleName);
186
		$fieldsName = $entityFieldInfo['fieldnameArr'];
187
		if (\count($fieldsName) > 1) {
188
			$sqlString = 'CONCAT(';
189
			foreach ($fieldsName as &$column) {
190
				$sqlString .= "{$db->quoteTableName($entityFieldInfo['tablename'])}.{$db->quoteColumnName($column)},' ',";
191
			}
192
			$formattedName = new \yii\db\Expression(rtrim($sqlString, ',\' \',') . ')');
193
		} else {
194
			$fieldsName = array_pop($fieldsName);
195
			$formattedName = "{$db->quoteTableName($entityFieldInfo['tablename'])}.{$db->quoteColumnName($fieldsName)}";
196
		}
197
		return $formattedName;
198
	}
199
200
	/**
201
	 * Function to get a action id for a given action name.
202
	 *
203
	 * @param string $action
204
	 *
205
	 * @return int|null
206
	 */
207
	public static function getActionId($action)
208 16
	{
209
		if (empty($action)) {
210 16
			return null;
211 6
		}
212
		if (Cache::has('getActionId', $action)) {
213 12
			return Cache::get('getActionId', $action);
214 6
		}
215
		$actionIds = static::$tabdataCache['actionId'];
216 7
		if (isset($actionIds[$action])) {
217 7
			$actionId = $actionIds[$action];
218 7
		}
219
		if (empty($actionId)) {
220 7
			$actionId = (new Db\Query())->select(['actionid'])->from('vtiger_actionmapping')->where(['actionname' => $action])->scalar();
221
		}
222
		if (is_numeric($actionId)) {
223 7
			$actionId = (int) $actionId;
224 7
		}
225
		Cache::save('getActionId', $action, $actionId, Cache::LONG);
226 7
		return $actionId;
227 7
	}
228
229
	/**
230
	 * Get module meta data.
231
	 *
232
	 * @return array
233
	 */
234
	public static function getModuleMeta()
235 7
	{
236
		$tabNames = $tabPresence = $tabOwned = [];
237 7
		$allModules = \vtlib\Functions::getAllModules(false, true);
238 7
		foreach ($allModules as $moduleInfo) {
239 7
			$tabNames[$moduleInfo['name']] = $tabId = (int) $moduleInfo['tabid'];
240 7
			$tabPresence[$tabId] = $moduleInfo['presence'];
241 7
			$tabOwned[$tabId] = $moduleInfo['ownedby'];
242 7
		}
243
		//Constructing the actionname=>actionid array
244
		$actionAll = [];
245 7
		$dataReader = (new Db\Query())->from(['vtiger_actionmapping'])->createCommand()->query();
246 7
		while ($row = $dataReader->read()) {
247 7
			$actionname = $row['actionname'];
248 7
			$actionAll[$actionname] = $actionid = (int) $row['actionid'];
249 7
			if (0 === (int) $row['securitycheck']) {
250 7
				$actionSecure[$actionid] = $actionname;
251 7
			}
252
		}
253
		return [
254
			'tabId' => $tabNames,
255 7
			'tabPresence' => $tabPresence,
256 7
			'tabOwnedby' => $tabOwned,
257 7
			'actionId' => $actionAll,
258 7
			'actionName' => $actionSecure,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $actionSecure does not seem to be defined for all execution paths leading up to this point.
Loading history...
259 7
		];
260
	}
261
262
	/**
263
	 * Function to create file about modules.
264
	 *
265
	 * @throws \App\Exceptions\NoPermitted
266
	 */
267
	public static function createModuleMetaFile()
268 7
	{
269
		Cache::delete('moduleTabs', 'all');
270 7
		Cache::delete('getTrackingModules', 'all');
271 7
		$filename = ROOT_DIRECTORY . '/user_privileges/tabdata.php';
272 7
		if (file_exists($filename)) {
273 7
			if (is_writable($filename)) {
274 7
				$moduleMeta = static::getModuleMeta();
275 7
				$content = '$tab_seq_array=' . Utils::varExport($moduleMeta['tabPresence']) . ";\n";
276 7
				$content .= 'return ' . Utils::varExport($moduleMeta) . ";\n";
277 7
				if (!Utils::saveToFile($filename, $content)) {
278
					throw new Exceptions\NoPermitted("Cannot write file ($filename)");
279
				}
280
			} else {
281
				Log::error("The file $filename is not writable");
282
			}
283
		} else {
284
			Log::error("The file $filename does not exist");
285
		}
286 7
		static::initFromDb();
287
	}
288
289 7
	/**
290 7
	 * Function changes the module type.
291
	 *
292
	 * @param string $moduleName
293
	 * @param int    $type
294
	 */
295
	public static function changeType(string $moduleName, int $type)
296
	{
297
		$moduleModel = \Vtiger_Module_Model::getInstance($moduleName);
298
		if ($moduleModel && $moduleModel->changeType($type) && PrivilegeUtil::modifyPermissions($moduleName, ['RecordPdfInventory'], \Vtiger_Module_Model::ADVANCED_TYPE === $type)) {
299
			UserPrivilegesFile::recalculateAll();
300
		}
301
	}
302
303
	/**
304
	 * Get all module names by filter.
305
	 *
306
	 * @param bool     $isEntityType
307
	 * @param bool     $showRestricted
308
	 * @param bool|int $presence
309
	 *
310
	 * @return string[]
311
	 */
312
	public static function getAllModuleNamesFilter($isEntityType = true, $showRestricted = false, $presence = false): array
313
	{
314
		$modules = [];
315
		foreach (\vtlib\Functions::getAllModules($isEntityType, $showRestricted, $presence) as $value) {
316
			$modules[$value['name']] = Language::translate($value['name'], $value['name']);
317
		}
318
		return $modules;
319
	}
320
321
	/**
322
	 * Function to get the list of all accessible modules for Quick Create.
323
	 *
324
	 * @param bool $restrictList
325
	 * @param bool $tree
326
	 *
327
	 * @return array List of Vtiger_Module_Model instances
328
	 */
329
	public static function getQuickCreateModules($restrictList = false, $tree = false): array
330
	{
331
		$restrictListString = $restrictList ? 1 : 0;
332
		if ($tree) {
333
			$userModel = \App\User::getCurrentUserModel();
334
			$quickCreateModulesTreeCache = \App\Cache::get('getQuickCreateModules', 'tree' . $restrictListString . $userModel->getDetail('roleid'));
335
			if (false !== $quickCreateModulesTreeCache) {
336
				return $quickCreateModulesTreeCache;
337
			}
338
		} else {
339
			$quickCreateModules = \App\Cache::get('getQuickCreateModules', $restrictListString);
340
			if (false !== $quickCreateModules) {
341
				return $quickCreateModules;
342
			}
343
		}
344
345
		$userPrivModel = \Users_Privileges_Model::getCurrentUserPrivilegesModel();
346
347
		$query = new \App\Db\Query();
348
		$query->select(['vtiger_tab.*'])->from('vtiger_field')
349
			->innerJoin('vtiger_tab', 'vtiger_tab.tabid = vtiger_field.tabid')
350
			->where(['<>', 'vtiger_tab.presence', 1]);
351
		if ($tree) {
352
			$query->andWhere(['<>', 'vtiger_tab.name', 'Users']);
353
		} else {
354
			$query->andWhere(['quickcreate' => [0, 2]])
355
				->andWhere(['<>', 'vtiger_tab.type', 1]);
356
		}
357
		if ($restrictList) {
358
			$query->andWhere(['not in', 'vtiger_tab.name', ['ModComments', 'PriceBooks', 'CallHistory', 'OSSMailView']]);
359
		}
360
		$quickCreateModules = [];
361
		$dataReader = $query->distinct()->createCommand()->query();
362
		while ($row = $dataReader->read()) {
363
			if ($userPrivModel->hasModuleActionPermission($row['tabid'], 'CreateView')) {
364
				$moduleModel = \Vtiger_Module_Model::getInstanceFromArray($row);
365
				$quickCreateModules[$row['name']] = $moduleModel;
366
			}
367
		}
368
		if ($tree) {
369
			$menu = \Vtiger_Menu_Model::getAll();
370
			$quickCreateModulesTree = [];
371
			foreach ($menu as $parent) {
372
				if (!empty($parent['childs'])) {
373
					$items = [];
374
					foreach ($parent['childs'] as $child) {
375
						if (isset($quickCreateModules[$child['mod']])) {
376
							$items[$quickCreateModules[$child['mod']]->name] = $quickCreateModules[$child['mod']];
377
							unset($quickCreateModules[$child['mod']]);
378
						}
379
					}
380
					if (!empty($items)) {
381
						$quickCreateModulesTree[] = ['name' => $parent['name'], 'icon' => $parent['icon'], 'modules' => $items];
382
					}
383
				}
384
			}
385
			if (!empty($quickCreateModules)) {
386
				$quickCreateModulesTree[] = ['name' => 'LBL_OTHER', 'icon' => 'yfm-Other', 'modules' => $quickCreateModules];
387
			}
388
			\App\Cache::save('getQuickCreateModules', 'tree' . $restrictListString . $userPrivModel->get('roleid'), $quickCreateModulesTree);
389
			return $quickCreateModulesTree;
390
		}
391
		\App\Cache::save('getQuickCreateModules', $restrictListString, $quickCreateModules);
392
		return $quickCreateModules;
393
	}
394
}
395
396
Module::init();
397