Vtiger_Widget_Model::getInstanceFromValues()   A
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
eloc 8
c 0
b 0
f 0
dl 0
loc 12
ccs 0
cts 2
cp 0
rs 10
cc 4
nc 6
nop 1
crap 20
1
<?php
2
/* +***********************************************************************************
3
 * The contents of this file are subject to the vtiger CRM Public License Version 1.0
4
 * ("License"); You may not use this file except in compliance with the License
5
 * The Original Code is:  vtiger CRM Open Source
6
 * The Initial Developer of the Original Code is vtiger.
7
 * Portions created by vtiger are Copyright (C) vtiger.
8
 * All Rights Reserved.
9
 * Contributor(s): YetiForce S.A.
10
 * *********************************************************************************** */
11
12
use App\Json;
13
14
/**
15
 * Vtiger Widget Model Class.
16
 */
17
class Vtiger_Widget_Model extends \App\Base
18
{
19
	/** @var array Default labels */
20
	const DEFAULT_LABELS = [
21
		'Activities' => 'LBL_ACTIVITIES',
22
		'DetailView' => 'LBL_RECORD_DETAILS',
23
		'GeneralInfo' => 'LBL_RECORD_SUMMARY',
24
	];
25
26
	/**
27
	 * Get ID.
28
	 *
29
	 * @return int
30
	 */
31
	public function getId(): int
32
	{
33
		return (int) $this->get('id');
34
	}
35
36
	public function getWidth()
37
	{
38
		$defaultSize = 4;
39
		$size = $this->get('size');
40
		if ($size) {
41
			$size = Json::decode(App\Purifier::decodeHtml($size));
42
			if (isset($size[App\Session::get('fingerprint')], $size[App\Session::get('fingerprint')]['width'])) {
43
				$defaultSize = (int) $size[App\Session::get('fingerprint')]['width'];
44
			} elseif (!empty($size['width'])) {
45
				$defaultSize = (int) $size['width'];
46
			}
47
		}
48
		return $defaultSize;
49
	}
50
51
	public function getHeight()
52
	{
53
		$defaultSize = 4;
54
		$size = $this->get('size');
55
		if ($size) {
56
			$size = Json::decode(App\Purifier::decodeHtml($size));
57
			if (isset($size[App\Session::get('fingerprint')], $size[App\Session::get('fingerprint')]['height'])) {
58
				$defaultSize = (int) $size[App\Session::get('fingerprint')]['height'];
59
			} elseif (!empty($size['height'])) {
60
				$defaultSize = (int) ($size['height']);
61
			}
62
		}
63
		return $defaultSize;
64
	}
65
66
	/**
67
	 * Function to get the position of the widget.
68
	 *
69
	 * @param int    $defaultPosition
70
	 * @param string $coordinate
71
	 * @param int    $position
72
	 *
73
	 * @throws \App\Exceptions\AppException
74
	 *
75
	 * @return int
76
	 */
77
	public function getPosition(int $position, string $coordinate)
78
	{
79
		if ($positionData = $this->get('position')) {
80
			$positionData = Json::decode(App\Purifier::decodeHtml($positionData));
81
			if (!empty($positionData[App\Session::get('fingerprint')])) {
82
				$position = (int) $positionData[App\Session::get('fingerprint')][$coordinate];
83
			}
84
			if (!empty($positionData[$coordinate])) {
85
				$position = (int) ($positionData[$coordinate]);
86
			}
87
		}
88
		return $position;
89
	}
90
91
	/**
92
	 * Function to get the url of the widget.
93
	 *
94
	 * @return string
95
	 */
96
	public function getUrl()
97
	{
98
		$url = App\Purifier::decodeHtml($this->get('linkurl')) . '&linkid=' . $this->get('linkid');
99
		$widgetid = $this->has('widgetid') ? $this->get('widgetid') : $this->get('id');
100
		return $url . '&widgetid=' . $widgetid . '&active=' . $this->get('active');
101
	}
102
103
	/**
104
	 *  Function to get the Title of the widget.
105
	 */
106
	public function getTitle()
107
	{
108
		$title = $this->get('title');
109
		if (empty($title)) {
110
			$title = $this->get('linklabel');
111
		}
112
		return $title;
113
	}
114
115
	/**
116
	 * Function to get the translated title.
117
	 *
118
	 * @return string
119
	 */
120
	public function getTranslatedTitle(): string
121
	{
122
		$queryParams = parse_url($this->get('linkurl'), PHP_URL_QUERY);
123
		parse_str($queryParams, $output);
124
		return \App\Language::translate($this->getTitle(), $output['module'], null, true, 'Dashboard');
125
	}
126
127
	public function getName()
128
	{
129
		$widgetName = $this->get('name');
130
		if (empty($widgetName)) {
131
			$linkUrl = App\Purifier::decodeHtml($this->getUrl());
132
			preg_match('/name=[a-zA-Z]+/', $linkUrl, $matches);
133
			$matches = explode('=', $matches[0]);
134
			$widgetName = $matches[1];
135
			$this->set('name', $widgetName);
136
		}
137
		return $widgetName;
138
	}
139
140
	/**
141
	 * Function to get the instance of Vtiger Widget Model from the given array of key-value mapping.
142
	 *
143
	 * @param array $valueMap
144
	 *
145
	 * @return \Vtiger_Widget_Model instance
146
	 */
147
	public static function getInstanceFromValues($valueMap)
148
	{
149
		$className = '';
150
		if (!empty($valueMap['handler_class'])) {
151
			$className = $valueMap['handler_class'];
152
		} elseif (!empty($valueMap['linkid'])) {
153
			$className = \vtlib\Link::getLinkData($valueMap['linkid'])['handler_class'] ?? null;
154
		}
155
		$instance = $className ? new $className() : new static();
156
		$instance->setData($valueMap);
157
158
		return $instance;
159
	}
160
161
	public static function getInstance($linkId, $userId)
162
	{
163
		$row = (new \App\Db\Query())->from('vtiger_module_dashboard_widgets')
164
			->innerJoin('vtiger_links', 'vtiger_links.linkid = vtiger_module_dashboard_widgets.linkid')
165
			->where(['linktype' => 'DASHBOARDWIDGET', 'vtiger_links.linkid' => $linkId, 'userid' => $userId])
166
			->one();
167
168
		return $row ? static::getInstanceFromValues($row) : new static();
169
	}
170
171
	/**
172
	 * Get widget instance by id.
173
	 *
174
	 * @param int $widgetId
175
	 * @param int $userId
176
	 *
177
	 * @return \self
0 ignored issues
show
Bug introduced by
The type self was not found. Maybe you did not declare it correctly or list all dependencies?

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:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
178
	 */
179
	public static function getInstanceWithWidgetId($widgetId, $userId)
180
	{
181
		$row = (new \App\Db\Query())->from('vtiger_module_dashboard_widgets')
182
			->innerJoin('vtiger_links', 'vtiger_links.linkid = vtiger_module_dashboard_widgets.linkid')
183
			->where(['linktype' => 'DASHBOARDWIDGET', 'vtiger_module_dashboard_widgets.id' => $widgetId, 'userid' => $userId])
184
			->one();
185
186
		return $row ? static::getInstanceFromValues($row) : new static();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $row ? static::ge...es($row) : new static() returns the type Vtiger_Widget_Model which is incompatible with the documented return type self.
Loading history...
187
	}
188
189
	public static function getInstanceWithTemplateId(int $widgetId)
190
	{
191
		$row = (new \App\Db\Query())->from('vtiger_module_dashboard')
192
			->innerJoin('vtiger_links', 'vtiger_links.linkid = vtiger_module_dashboard.linkid')
193
			->where(['linktype' => 'DASHBOARDWIDGET', 'vtiger_module_dashboard.id' => $widgetId])
194
			->one();
195
196
		return $row ? static::getInstanceFromValues($row) : new static();
197
	}
198
199
	public static function updateWidgetPosition($position, $linkId, $widgetId, $userId)
200
	{
201
		$currentPosition = [];
202
		if (!$linkId && !$widgetId) {
203
			return;
204
		}
205
		if ($linkId) {
206
			$where = ['userid' => $userId, 'linkid' => $linkId];
207
		} elseif ($widgetId) {
208
			$where = ['userid' => $userId, 'id' => $widgetId];
209
		}
210
		$lastSavedPosition = (new \App\Db\Query())->select(['position'])->from('vtiger_module_dashboard_widgets')->where($where)->scalar();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $where does not seem to be defined for all execution paths leading up to this point.
Loading history...
211
		if ($lastSavedPosition && !JSON::isEmpty($lastSavedPosition)) {
212
			$currentPosition = JSON::decode($lastSavedPosition);
213
		}
214
		$currentPosition[App\Session::get('fingerprint')] = $position;
215
		\App\Db::getInstance()->createCommand()
216
			->update('vtiger_module_dashboard_widgets', ['position' => Json::encode($currentPosition)], $where)
217
			->execute();
218
	}
219
220
	/**
221
	 * Update widget size.
222
	 *
223
	 * @param string $size
224
	 * @param int    $linkId
225
	 * @param int    $widgetId
226
	 * @param int    $userId
227
	 */
228
	public static function updateWidgetSize($size, $linkId, $widgetId, $userId)
229
	{
230
		if (!$linkId && !$widgetId) {
231
			return;
232
		}
233
		if ($linkId) {
234
			$where = ['userid' => $userId, 'linkid' => $linkId];
235
		} elseif ($widgetId) {
236
			$where = ['userid' => $userId, 'id' => $widgetId];
237
		}
238
		$lastSize = (new \App\Db\Query())->select(['size'])->from('vtiger_module_dashboard_widgets')->where($where)->scalar();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $where does not seem to be defined for all execution paths leading up to this point.
Loading history...
239
		$currentSize = \App\Json::isEmpty($lastSize) ? [] : Json::decode($lastSize);
240
		$currentSize[App\Session::get('fingerprint')] = $size;
241
		\App\Db::getInstance()->createCommand()
242
			->update('vtiger_module_dashboard_widgets', ['size' => Json::encode($currentSize)], $where)
243
			->execute();
244
	}
245
246
	/**
247
	 * Function to show a widget from the Users Dashboard.
248
	 */
249
	public function show()
250
	{
251
		if (0 == $this->get('active')) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $this->get('active') of type mixed|null to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
252
			App\Db::getInstance()->createCommand()
253
				->update('vtiger_module_dashboard_widgets', ['active' => 1], ['id' => $this->get('widgetid')])
254
				->execute();
255
		}
256
		$this->set('id', $this->get('widgetid'));
257
	}
258
259
	/**
260
	 * Function to remove the widget from the Users Dashboard.
261
	 *
262
	 * @param string $action
263
	 */
264
	public function remove($action = 'hide')
265
	{
266
		$db = App\Db::getInstance();
267
		if ('delete' == $action) {
268
			$db->createCommand()->delete('vtiger_module_dashboard_widgets', ['id' => $this->get('id'), 'blockid' => $this->get('blockid')])
269
				->execute();
270
		} elseif ('hide' == $action) {
271
			$db->createCommand()->update('vtiger_module_dashboard_widgets', ['active' => 0], ['id' => $this->get('id')])
272
				->execute();
273
			$this->set('active', 0);
274
		}
275
	}
276
277
	/**
278
	 * Function returns URL that will remove a widget for a User.
279
	 *
280
	 * @return string
281
	 */
282
	public function getDeleteUrl()
283
	{
284
		$url = 'index.php?module=' . App\Module::getModuleName($this->get('module')) . '&action=Widget&mode=remove&linkid=' . $this->get('linkid');
285
		$widgetid = $this->has('widgetid') ? $this->get('widgetid') : $this->get('id');
286
		if ($widgetid) {
287
			$url .= '&widgetid=' . $widgetid;
288
		}
289
		return $url;
290
	}
291
292
	/**
293
	 * Function to check the Widget is Default widget or not.
294
	 *
295
	 * @return bool
296
	 */
297
	public function isDefault(): bool
298
	{
299
		return 1 == $this->get('isdefault');
300
	}
301
302
	/**
303
	 * Process the UI Widget requested.
304
	 *
305
	 * @param Vtiger_Link_Model   $widgetLink
306
	 * @param Vtiger_Record_Model $recordModel
307
	 */
308
	public function processWidget(Vtiger_Link_Model $widgetLink, Vtiger_Record_Model $recordModel)
309
	{
310
		if (preg_match('/^block:\\/\\/(.*)/', $widgetLink->get('linkurl') ?? '', $matches)) {
311
			[$widgetControllerClass, $widgetControllerClassFile] = explode(':', $matches[1]);
312
			if (!class_exists($widgetControllerClass)) {
313
				\vtlib\Deprecated::checkFileAccessForInclusion($widgetControllerClassFile);
314
				include_once $widgetControllerClassFile;
315
			}
316
			if (class_exists($widgetControllerClass)) {
317
				$widgetControllerInstance = new $widgetControllerClass();
318
				$widgetInstance = $widgetControllerInstance->getWidget($widgetLink);
319
				if ($widgetInstance) {
320
					return $widgetInstance->process($recordModel);
321
				}
322
			}
323
		}
324
	}
325
326
	/**
327
	 * Remove widget from list in dashboard. Removing is possible only for widgets from filters.
328
	 *
329
	 * @param int $id
330
	 */
331
	public static function removeWidgetFromList($id)
332
	{
333
		$dbCommand = \App\Db::getInstance()->createCommand();
334
		$templateId = (new App\Db\Query())->select(['templateid'])->from('vtiger_module_dashboard_widgets')->where(['id' => $id])->scalar();
335
		if ($templateId) {
336
			$dbCommand->delete('vtiger_module_dashboard', ['id' => $templateId])->execute();
337
		}
338
		$dbCommand->delete('vtiger_module_dashboard_widgets', ['id' => $id])->execute();
339
	}
340
341
	/**
342
	 * Function to get the Quick Links in settings view.
343
	 *
344
	 * @return array List of Vtiger_Link_Model instances
345
	 */
346
	public function getSettingsLinks()
347
	{
348
		$links = [];
349
		if (\App\User::getCurrentUserModel()->isAdmin()) {
350
			$links[] = Vtiger_Link_Model::getInstanceFromValues([
351
				'linklabel' => 'LBL_EDIT',
352
				'linkclass' => 'btn btn-success btn-xs js-edit-widget',
353
				'linkicon' => 'yfi yfi-full-editing-view',
354
				'linkdata' => ['url' => "index.php?parent=Settings&module=WidgetsManagement&view=EditWidget&linkId={$this->get('linkid')}&blockId={$this->get('blockid')}&widgetId={$this->getId()}"],
355
			]);
356
		}
357
		if (\App\User::getCurrentUserModel()->isAdmin()) {
358
			$links[] = Vtiger_Link_Model::getInstanceFromValues([
359
				'linklabel' => 'LBL_DELETE',
360
				'linkclass' => 'btn-danger btn-xs js-delete-widget',
361
				'linkicon' => 'fas fa-trash-alt',
362
				'linkdata' => ['id' => $this->getId()],
363
			]);
364
		}
365
366
		return $links;
367
	}
368
369
	/** @var array Custom fields for edit */
370
	public $customFields = [];
371
372
	/** @var array Fields for edit */
373
	public $editFields = [
374
		'isdefault' => ['label' => 'LBL_MANDATORY_WIDGET', 'purifyType' => \App\Purifier::BOOL],
375
		'cache' => ['label' => 'LBL_CACHE_WIDGET', 'purifyType' => \App\Purifier::BOOL],
376
		'width' => ['label' => 'LBL_WIDTH', 'purifyType' => \App\Purifier::INTEGER],
377
		'height' => ['label' => 'LBL_HEIGHT', 'purifyType' => \App\Purifier::INTEGER],
378
	];
379
380
	/**
381
	 * Gets fields for edit view.
382
	 *
383
	 * @return array
384
	 */
385
	public function getEditFields(): array
386
	{
387
		$fields = [];
388
		$widgetsManagementModel = new Settings_WidgetsManagement_Module_Model();
389
		if (\in_array($this->get('linklabel'), $widgetsManagementModel->getWidgetsWithLimit())) {
390
			$fields['limit'] = ['label' => 'LBL_NUMBER_OF_RECORDS_DISPLAYED', 'purifyType' => \App\Purifier::INTEGER];
391
		}
392
		if (\in_array($this->get('linklabel'), $widgetsManagementModel->getWidgetsWithDate())) {
393
			$fields['default_date'] = ['label' => 'LBL_DEFAULT_DATE', 'purifyType' => \App\Purifier::STANDARD];
394
		}
395
		if (\in_array($this->get('linklabel'), $widgetsManagementModel->getWidgetsWithFilterUsers())) {
396
			$fields['default_owner'] = ['label' => 'LBL_DEFAULT_FILTER', 'purifyType' => \App\Purifier::STANDARD];
397
			$fields['owners_all'] = ['label' => 'LBL_FILTERS_AVAILABLE', 'purifyType' => \App\Purifier::STANDARD];
398
		}
399
400
		return $this->editFields + $fields + $this->customFields;
401
	}
402
403
	/**
404
	 * Gets field instance by name.
405
	 *
406
	 * @param string $name
407
	 *
408
	 * @return \Vtiger_Field_Model
409
	 */
410
	public function getFieldInstanceByName($name)
411
	{
412
		$moduleName = 'Settings:WidgetsManagement';
413
		$field = $this->getEditFields()[$name] ?? null;
414
		if (!$field) {
415
			return null;
416
		}
417
		$params = [
418
			'label' => $field['label'],
419
			'tooltip' => $field['tooltip'] ?? '',
420
		];
421
		switch ($name) {
422
			case 'cache':
423
			case 'isdefault':
424
				$params['uitype'] = 56;
425
				$params['typeofdata'] = 'C~O';
426
				$params['fieldvalue'] = (int) $this->get($name);
427
				break;
428
			case 'title':
429
				$params['uitype'] = 1;
430
				$params['typeofdata'] = empty($field['required']) ? 'V~O' : 'V~M';
431
				$params['maximumlength'] = '100';
432
				$params['fieldvalue'] = $this->get($name) ?: '';
433
				break;
434
			case 'width':
435
				$params['uitype'] = 16;
436
				$params['typeofdata'] = 'V~M';
437
				$params['maximumlength'] = '2';
438
				$params['picklistValues'] = [3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10, 11 => 11, 12 => 12];
439
				$params['fieldvalue'] = $this->getWidth();
440
				break;
441
			case 'height':
442
				$params['uitype'] = 16;
443
				$params['typeofdata'] = 'V~M';
444
				$params['maximumlength'] = '2';
445
				$params['picklistValues'] = [3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10, 11 => 11, 12 => 12];
446
				$params['fieldvalue'] = $this->getHeight();
447
				break;
448
			case 'limit':
449
				$params['uitype'] = 7;
450
				$params['typeofdata'] = 'I~M';
451
				$params['maximumlength'] = '127';
452
				$params['fieldvalue'] = $this->get('limit') ?: 10;
453
				break;
454
			case 'default_owner':
455
				$params['uitype'] = 16;
456
				$params['maximumlength'] = '100';
457
				$params['typeofdata'] = 'V~M';
458
				$picklistValue = ['mine' => 'LBL_MINE', 'all' => 'LBL_ALL'];
459
				foreach ($picklistValue as $key => $label) {
460
					$params['picklistValues'][$key] = \App\Language::translate($label, $moduleName);
461
				}
462
				$value = $this->get('owners') ? Json::decode($this->get('owners')) : [];
463
				$params['fieldvalue'] = $value['default'] ?? 'mine';
464
				break;
465
			case 'owners_all':
466
				$params['uitype'] = 33;
467
				$params['maximumlength'] = '100';
468
				$params['typeofdata'] = 'V~M';
469
				$picklistValue = [
470
					'mine' => 'LBL_MINE',
471
					'all' => 'LBL_ALL',
472
					'users' => 'LBL_USERS',
473
					'groups' => 'LBL_GROUPS',
474
				];
475
				foreach ($picklistValue as $key => $label) {
476
					$params['picklistValues'][$key] = \App\Language::translate($label, $moduleName);
477
				}
478
				$owners = $this->get('owners') ? Json::decode($this->get('owners')) : [];
479
				$value = $owners['available'] ?? ['mine'];
480
				$params['fieldvalue'] = implode(' |##| ', $value);
481
				break;
482
			case 'default_date':
483
				$params['uitype'] = 16;
484
				$params['typeofdata'] = 'V~M';
485
				$picklistValue = [
486
					'day' => 'PLL_CURRENT_DAY',
487
					'week' => 'PLL_CURRENT_WEEK',
488
					'month' => 'PLL_CURRENT_MONTH',
489
					'year' => 'PLL_CURRENT_YEAR',
490
				];
491
				foreach ($picklistValue as $key => $label) {
492
					$params['picklistValues'][$key] = \App\Language::translate($label, $moduleName);
493
				}
494
				$params['fieldvalue'] = $this->get('date');
495
				break;
496
			default: break;
497
		}
498
		return \Vtiger_Field_Model::init($moduleName, $params, $name);
499
	}
500
501
	/**
502
	 * Sets data from request.
503
	 *
504
	 * @param App\Request $request
505
	 */
506
	public function setDataFromRequest(App\Request $request)
507
	{
508
		foreach ($this->getEditFields() as $fieldName => $fieldInfo) {
509
			if ($request->has($fieldName) && !isset($this->customFields[$fieldName])) {
510
				$value = $request->getByType($fieldName, $fieldInfo['purifyType']);
511
				$fieldModel = $this->getFieldInstanceByName($fieldName)->getUITypeModel();
512
				$fieldModel->validate($value, true);
513
				$value = $fieldModel->getDBValue($value);
514
515
				switch ($fieldName) {
516
					case 'width':
517
					case 'height':
518
						$size = $this->get('size') ? Json::decode($this->get('size')) : [];
519
						$size[$fieldName] = $value;
520
						$this->set('size', Json::encode($size));
521
						break;
522
					case 'default_owner':
523
						$owners = $this->get('owners') ? Json::decode($this->get('owners')) : [];
524
						$owners['default'] = $value;
525
						$this->set('owners', Json::encode($owners));
526
						break;
527
					case 'owners_all':
528
						$value = $value ? explode(' |##| ', $value) : [];
529
						$owners = $this->get('owners') ? Json::decode($this->get('owners')) : [];
530
						$owners['available'] = $value;
531
						$this->set('owners', Json::encode($owners));
532
						break;
533
					case 'default_date':
534
						$this->set('date', $value);
535
						break;
536
					default:
537
						$this->set($fieldName, $value);
538
						break;
539
				}
540
			}
541
		}
542
		if (!$this->getId() && !$request->isEmpty('blockId')) {
543
			$this->set('blockid', $request->getInteger('blockId'));
544
		}
545
	}
546
547
	/**
548
	 * Function to save.
549
	 *
550
	 * @return bool
551
	 */
552
	public function save(): bool
553
	{
554
		$db = App\Db::getInstance();
555
		$params = array_intersect_key($this->getData(), array_flip(['title', 'data', 'size', 'limit', 'isdefault', 'owners', 'cache', 'date', 'filterid']));
556
		$tableName = 'vtiger_module_dashboard';
557
		if ($this->getId()) {
558
			$result = $db->createCommand()->update($tableName, $params, ['id' => $this->getId()])->execute();
559
			if ($result) {
560
				$db->createCommand()->delete('vtiger_module_dashboard_widgets', ['templateid' => $this->getId()])->execute();
561
			}
562
		} else {
563
			$params['blockid'] = $this->get('blockid');
564
			$params['linkid'] = $this->get('linkid');
565
			$result = $db->createCommand()->insert($tableName, $params)->execute();
566
			$this->set('id', $db->getLastInsertID("{$tableName}_id_seq"));
567
		}
568
569
		return (bool) $result;
570
	}
571
572
	/**
573
	 * Remove widget template.
574
	 *
575
	 * @return bool
576
	 */
577
	public function delete(): bool
578
	{
579
		return (bool) \App\Db::getInstance()->createCommand()
580
			->delete('vtiger_module_dashboard', ['vtiger_module_dashboard.id' => $this->getId()])
581
			->execute();
582
	}
583
584
	/**
585
	 * Gets value from data column.
586
	 *
587
	 * @param string $name
588
	 *
589
	 * @return mixed
590
	 */
591
	public function getDataValue(string $name)
592
	{
593
		$values = $this->get('data') ? Json::decode($this->get('data')) : [];
594
		return $values[$name] ?? null;
595
	}
596
597
	/**
598
	 * Get dashboard id.
599
	 *
600
	 * @param \App\Request $request
601
	 *
602
	 * @return int
603
	 */
604
	public static function getDashboardId(App\Request $request)
605
	{
606
		$dashboardId = false;
607
		if (!$request->isEmpty('dashboardId', true)) {
608
			$dashboardId = $request->getInteger('dashboardId');
609
		} elseif (isset($_SESSION['DashBoard'][$request->getModule()]['LastDashBoardId'])) {
610
			$dashboardId = $_SESSION['DashBoard'][$request->getModule()]['LastDashBoardId'];
611
		}
612
		if (!$dashboardId) {
613
			$dashboardId = Settings_WidgetsManagement_Module_Model::getDefaultDashboard();
614
		}
615
		$request->set('dashboardId', $dashboardId);
616
		return $dashboardId;
617
	}
618
619
	/**
620
	 * Clear configuration of widgets for this device.
621
	 *
622
	 * @param int $dashboardId
623
	 *
624
	 * @return void
625
	 */
626
	public static function clearDeviceConf(int $dashboardId): void
627
	{
628
		$fingerPrint = App\Session::get('fingerprint');
629
		$dataReader = (new \App\Db\Query())->select(['id', 'position', 'size'])->from('vtiger_module_dashboard_widgets')->where([
630
			'userid' => \App\User::getCurrentUserId(),
631
			'dashboardid' => $dashboardId,
632
		])->andWhere([
633
			'or',
634
			['like', 'position', "\"$fingerPrint\""],
635
			['like', 'size', "\"$fingerPrint\""],
636
		], )->createCommand()->query();
637
638
		$createCommand = \App\Db::getInstance()->createCommand();
639
		while (['id' => $id,'position' => $position,'size' => $size] = $dataReader->read()) {
640
			$position = $position ? Json::decode($position) : [];
641
			if (isset($position[$fingerPrint])) {
642
				unset($position[$fingerPrint]);
643
			}
644
			$size = $size ? Json::decode($size) : [];
645
			if (isset($size[$fingerPrint])) {
646
				unset($size[$fingerPrint]);
647
			}
648
			$createCommand->update('vtiger_module_dashboard_widgets', ['position' => Json::encode($position), 'size' => Json::encode($size)], ['id' => $id])->execute();
649
		}
650
	}
651
652
	/**
653
	 * Check if the widget is removable.
654
	 *
655
	 * @return bool
656
	 */
657
	public function isDeletable(): bool
658
	{
659
		return !$this->get('isdefault');
660
	}
661
662
	/**
663
	 * Check if the widget is viewable.
664
	 *
665
	 * @return bool
666
	 */
667
	public function isViewable(): bool
668
	{
669
		$userPrivModel = Users_Privileges_Model::getCurrentUserPrivilegesModel();
670
		$params = vtlib\Functions::getQueryParams($this->get('linkurl'));
671
		$moduleName = $params['module'];
672
		$sourceModulePermission = true;
673
		if (($name = $params['name'] ?? '') && \in_array($name, ['CalendarActivities', 'OverdueActivities'])) {
674
			$sourceModulePermission = $userPrivModel->hasModulePermission('Calendar');
0 ignored issues
show
Bug introduced by
'Calendar' of type string is incompatible with the type integer expected by parameter $mixed of Users_Privileges_Model::hasModulePermission(). ( Ignorable by Annotation )

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

674
			$sourceModulePermission = $userPrivModel->hasModulePermission(/** @scrutinizer ignore-type */ 'Calendar');
Loading history...
675
		}
676
677
		return 'ModTracker' === $moduleName || ($sourceModulePermission && $userPrivModel->hasModulePermission($moduleName));
678
	}
679
680
	/**
681
	 * Check if the widget is creatable.
682
	 *
683
	 * @return bool
684
	 */
685
	public function isCreatable(): bool
686
	{
687
		return false;
688
	}
689
}
690