This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
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
![]() |
|||
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
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. ![]() |
|||
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
|
|||
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 |