Passed
Push — developer ( 5f736c...9195d5 )
by Mariusz
18:14
created

Calendar_Calendar_Model::getEntityCount()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 55
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
eloc 45
c 0
b 0
f 0
dl 0
loc 55
rs 8.5777
ccs 0
cts 44
cp 0
cc 6
nc 5
nop 0
crap 42

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Calendar Model Class.
5
 *
6
 * @copyright YetiForce S.A.
7
 * @license   YetiForce Public License 5.0 (licenses/LicenseEN.txt or yetiforce.com)
8
 * @author    YetiForce S.A.
9
 */
10
class Calendar_Calendar_Model extends Vtiger_Calendar_Model
11
{
12
	public $moduleName = 'Calendar';
13
	public $module;
14
	public $relationAcounts = [
15
		'Contacts' => ['vtiger_contactdetails', 'contactid', 'parentid'],
16
		'Project' => ['vtiger_project', 'projectid', 'linktoaccountscontacts'],
17
		'HelpDesk' => ['vtiger_troubletickets', 'ticketid', 'parent_id'],
18
		'ServiceContracts' => ['vtiger_servicecontracts', 'servicecontractsid', 'sc_related_to'],
19
	];
20
21
	/** {@inheritdoc} */
22
	public function getCalendarTypes(): array
23
	{
24
		$calendarTypes = [];
25
		$moduleField = $this->getModule()->getFieldByName('activitytype');
26
		if ($moduleField && $moduleField->isActiveField()) {
27
			$calendarTypes = $moduleField->getPicklistValues();
28
		}
29
		return $calendarTypes;
30
	}
31
32
	/**
33
	 * Get query.
34
	 *
35
	 * @return \App\Db\Query
36
	 */
37
	public function getQuery(): App\Db\Query
38
	{
39
		$queryGenerator = new App\QueryGenerator($this->getModuleName());
40
		if ($this->has('customFilter')) {
41
			$queryGenerator->initForCustomViewById($this->get('customFilter'));
42
		}
43
		$queryGenerator->setFields(array_keys($queryGenerator->getModuleFields()));
44
		$queryGenerator->setField('id');
45
		if ($types = $this->get('types')) {
46
			$queryGenerator->addCondition('activitytype', implode('##', $types), 'e');
47
		}
48
		switch ($this->get('time')) {
49
			case 'current':
50
				$queryGenerator->addCondition('activitystatus', implode('##', Calendar_Module_Model::getComponentActivityStateLabel('current')), 'e');
51
				break;
52
			case 'history':
53
				$queryGenerator->addCondition('activitystatus', implode('##', Calendar_Module_Model::getComponentActivityStateLabel('history')), 'e');
54
				break;
55
			default:
56
				break;
57
		}
58
		if (!empty($this->get('activitystatus'))) {
59
			$queryGenerator->addNativeCondition(['vtiger_activity.status' => $this->get('activitystatus')]);
60
		}
61
		if ($this->get('start') && $this->get('end')) {
62
			$dbStartDateOject = DateTimeField::convertToDBTimeZone($this->get('start'));
63
			$dbStartDateTime = $dbStartDateOject->format('Y-m-d H:i:s');
64
			$dbStartDate = $dbStartDateOject->format('Y-m-d');
65
			$dbEndDateObject = DateTimeField::convertToDBTimeZone($this->get('end'));
66
			$dbEndDateTime = $dbEndDateObject->format('Y-m-d H:i:s');
67
			$dbEndDate = $dbEndDateObject->format('Y-m-d');
68
			$queryGenerator->addNativeCondition([
69
				'or',
70
				[
71
					'and',
72
					['>=', new \yii\db\Expression("CONCAT(date_start, ' ', time_start)"), $dbStartDateTime],
73
					['<=', new \yii\db\Expression("CONCAT(date_start, ' ', time_start)"), $dbEndDateTime],
74
				],
75
				[
76
					'and',
77
					['>=', new \yii\db\Expression("CONCAT(due_date, ' ', time_end)"), $dbStartDateTime],
78
					['<=', new \yii\db\Expression("CONCAT(due_date, ' ', time_end)"), $dbEndDateTime],
79
				],
80
				[
81
					'and',
82
					['<', 'date_start', $dbStartDate],
83
					['>', 'due_date', $dbEndDate],
84
				],
85
			]);
86
		}
87
		$query = $queryGenerator->createQuery();
88
		if ($this->has('filters')) {
89
			foreach ($this->get('filters') as $filter) {
90
				$filterClassName = Vtiger_Loader::getComponentClassName('CalendarFilter', $filter['name'], 'Calendar');
91
				$filterInstance = new $filterClassName();
92
				if ($filterInstance->checkPermissions() && $conditions = $filterInstance->getCondition($filter['value'])) {
93
					$query->andWhere($conditions);
94
				}
95
			}
96
		}
97
		$conditions = [];
98
		if (!empty($this->get('user')) && isset($this->get('user')['selectedIds'][0])) {
99
			$selectedUsers = $this->get('user');
100
			$selectedIds = $selectedUsers['selectedIds'];
101
			if ('all' !== $selectedIds[0]) {
102
				$conditions[] = ['vtiger_crmentity.smownerid' => $selectedIds];
103
				$subQuery = (new \App\Db\Query())->select(['crmid'])->from('u_#__crmentity_showners')->where(['userid' => $selectedIds]);
104
				$conditions[] = ['vtiger_crmentity.crmid' => $subQuery];
105
			}
106
			if (isset($selectedUsers['excludedIds']) && 'all' === $selectedIds[0]) {
107
				$conditions[] = ['not in', 'vtiger_crmentity.smownerid', $selectedUsers['excludedIds']];
108
			}
109
		}
110
		if ($conditions) {
111
			$query->andWhere(array_merge(['or'], $conditions));
112
		}
113
		$query->orderBy('vtiger_activity.date_start,vtiger_activity.time_start');
114
		return $query;
115
	}
116
117
	/**
118
	 * Gets entity data.
119
	 *
120
	 * @throws \App\Exceptions\NoPermittedToRecord
121
	 *
122
	 * @return array
123
	 */
124
	public function getEntity()
125
	{
126
		$return = [];
127
		$currentUser = \App\User::getCurrentUserModel();
128
		$moduleModel = Vtiger_Module_Model::getInstance($this->getModuleName());
129
		$editForm = \App\Config::module('Calendar', 'SHOW_EDIT_FORM');
130
		$dataReader = $this->getQuery()->createCommand()->query();
131
		$colors = \App\Fields\Picklist::getColors('activitytype', false);
132
		while ($row = $dataReader->read()) {
133
			$item = [];
134
			if ($editForm && $moduleModel->getRecordFromArray($row)->setId($row['id'])->isEditable()) {
135
				$item['url'] = 'index.php?module=' . $this->getModuleName() . '&view=EventForm&record=' . $row['id'];
136
			} else {
137
				$item['url'] = 'index.php?module=' . $this->getModuleName() . '&view=ActivityState&record=' . $row['id'];
138
			}
139
			$item['module'] = $this->getModuleName();
140
			$item['title'] = \App\Purifier::encodeHtml($row['subject']);
141
			$item['id'] = $row['id'];
142
			$item['set'] = 'Task' == $row['activitytype'] ? 'Task' : 'Event';
143
			$dateTimeFieldInstance = new DateTimeField($row['date_start'] . ' ' . $row['time_start']);
0 ignored issues
show
Bug introduced by
$row['date_start'] . ' ' . $row['time_start'] of type string is incompatible with the type type expected by parameter $value of DateTimeField::__construct(). ( Ignorable by Annotation )

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

143
			$dateTimeFieldInstance = new DateTimeField(/** @scrutinizer ignore-type */ $row['date_start'] . ' ' . $row['time_start']);
Loading history...
144
			$userDateTimeString = $dateTimeFieldInstance->getFullcalenderDateTimevalue();
145
			$startDateTimeDisplay = $dateTimeFieldInstance->getDisplayDateTimeValue();
146
			$startTimeDisplay = $dateTimeFieldInstance->getDisplayTime();
147
			$dateTimeComponents = explode(' ', $userDateTimeString);
148
			$dateComponent = $dateTimeComponents[0];
149
			$startTimeFormated = $dateTimeComponents[1];
150
			//Conveting the date format in to Y-m-d . since full calendar expects in the same format
151
			$startDateFormated = DateTimeField::__convertToDBFormat($dateComponent, $currentUser->getDetail('date_format'));
152
153
			$dateTimeFieldInstance = new DateTimeField($row['due_date'] . ' ' . $row['time_end']);
154
			$userDateTimeString = $dateTimeFieldInstance->getFullcalenderDateTimevalue();
155
			$endDateTimeDisplay = $dateTimeFieldInstance->getDisplayDateTimeValue();
156
			$dateTimeComponents = explode(' ', $userDateTimeString);
157
			$dateComponent = $dateTimeComponents[0];
158
			$endTimeFormated = $dateTimeComponents[1];
159
			//Conveting the date format in to Y-m-d . since full calendar expects in the same format
160
			$endDateFormated = DateTimeField::__convertToDBFormat($dateComponent, $currentUser->getDetail('date_format'));
161
162
			$item['allDay'] = 1 == $row['allday'];
163
			$item['start_date'] = $row['date_start'];
164
			if ($item['allDay']) {
165
				$item['start'] = $startDateFormated;
166
				$item['end'] = $endDateFormated;
167
			} else {
168
				$item['start'] = $startDateFormated . ' ' . $startTimeFormated;
169
				$item['end'] = $endDateFormated . ' ' . $endTimeFormated;
170
			}
171
172
			$item['start_display'] = $startDateTimeDisplay;
173
			$item['end_display'] = $endDateTimeDisplay;
174
			$item['hour_start'] = $startTimeDisplay;
175
			$item['borderColor'] = $colors[$row['activitytype']] ?? '';
176
			$item['className'] = 'js-popover-tooltip--record ownerCBg_' . $row['assigned_user_id'];
177
			$return[] = $item;
178
		}
179
		$dataReader->close();
180
		return $return;
181
	}
182
183
	/**
184
	 * Gets number of events.
185
	 *
186
	 * @return array
187
	 */
188
	public function getEntityCount(): array
189
	{
190
		$colors = \App\Fields\Picklist::getColors('activitytype', false);
191
		$currentUser = Users_Record_Model::getCurrentUserModel();
192
		$startDate = DateTimeField::convertToDBTimeZone($this->get('start'));
193
		$startDate = strtotime($startDate->format('Y-m-d H:i:s'));
194
		$endDate = DateTimeField::convertToDBTimeZone($this->get('end'));
195
		$endDate = strtotime($endDate->format('Y-m-d H:i:s'));
196
		$dataReader = $this->getQuery()
197
			->createCommand()
198
			->query();
199
		$return = [];
200
		while ($record = $dataReader->read()) {
201
			$activityType = $record['activitytype'];
202
203
			$dateTimeFieldInstance = new DateTimeField($record['date_start'] . ' ' . $record['time_start']);
0 ignored issues
show
Bug introduced by
$record['date_start'] . .... $record['time_start'] of type string is incompatible with the type type expected by parameter $value of DateTimeField::__construct(). ( Ignorable by Annotation )

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

203
			$dateTimeFieldInstance = new DateTimeField(/** @scrutinizer ignore-type */ $record['date_start'] . ' ' . $record['time_start']);
Loading history...
204
			$userDateTimeString = $dateTimeFieldInstance->getDisplayDateTimeValue($currentUser);
205
			$dateTimeComponents = explode(' ', $userDateTimeString);
206
			$dateComponent = $dateTimeComponents[0];
207
			$startDateFormated = DateTimeField::__convertToDBFormat($dateComponent, $currentUser->get('date_format'));
208
209
			$dateTimeFieldInstance = new DateTimeField($record['due_date'] . ' ' . $record['time_end']);
210
			$userDateTimeString = $dateTimeFieldInstance->getDisplayDateTimeValue($currentUser);
211
			$dateTimeComponents = explode(' ', $userDateTimeString);
212
			$dateComponent = $dateTimeComponents[0];
213
			$endDateFormated = DateTimeField::__convertToDBFormat($dateComponent, $currentUser->get('date_format'));
214
215
			$begin = new DateTime($startDateFormated);
216
			$end = new DateTime($endDateFormated);
217
			$end->modify('+1 day');
218
			$interval = DateInterval::createFromDateString('1 day');
219
			foreach (new DatePeriod($begin, $interval, $end) as $dt) {
220
				$date = strtotime($dt->format('Y-m-d'));
221
				if ($date >= $startDate && $date <= $endDate) {
222
					$date = date('Y-m-d', $date);
223
					$dateKey = $date . '__' . $activityType;
224
225
					$return[$dateKey]['allDay'] = true;
226
					$return[$dateKey]['start'] = $date;
227
					if (isset($return[$dateKey]['title'])) {
228
						++$return[$dateKey]['title'];
229
					} else {
230
						$return[$dateKey]['title'] = 1;
231
					}
232
					$return[$dateKey]['label'] = \App\Language::translate($activityType, $this->getModuleName());
233
					$return[$dateKey]['className'] = 'fc-draggable picklistCBg_Calendar_activitytype_' . $activityType;
234
					$return[$dateKey]['borderColor'] = $colors[$record['activitytype']] ?? '';
235
					$return[$dateKey]['type'] = 'widget';
236
					$return[$dateKey]['activityType'] = $activityType;
237
					$return[$dateKey]['url'] = 'index.php?module=' . $this->getModuleName() . '&view=List&entityState=Active';
238
				}
239
			}
240
		}
241
		$dataReader->close();
242
		return array_values($return);
243
	}
244
245
	/**
246
	 * Static Function to get the instance of Vtiger Module Model for the given id or name.
247
	 *
248
	 * @param mixed id or name of the module
249
	 */
250
	public static function getCleanInstance()
251
	{
252
		$instance = Vtiger_Cache::get('calendarModels', 'Calendar');
253
		if (false === $instance) {
254
			$instance = new self();
255
			Vtiger_Cache::set('calendarModels', 'Calendar', clone $instance);
256
257
			return $instance;
258
		}
259
		return clone $instance;
260
	}
261
262
	/** {@inheritdoc} */
263
	public function updateEvent(int $recordId, string $start, string $end, App\Request $request): bool
264
	{
265
		try {
266
			$recordModel = Vtiger_Record_Model::getInstanceById($recordId, $this->getModuleName());
267
			if ($success = $recordModel->isEditable()) {
268
				$start = DateTimeField::convertToDBTimeZone($start);
269
				$recordModel->set('date_start', $start->format('Y-m-d'));
270
				$end = DateTimeField::convertToDBTimeZone($end);
271
				$recordModel->set('due_date', $end->format('Y-m-d'));
272
				if ($request->getBoolean('allDay')) {
273
					$recordModel->set('allday', 1);
274
				} else {
275
					$recordModel->set('time_start', $start->format('H:i:s'));
276
					$recordModel->set('time_end', $end->format('H:i:s'));
277
					$recordModel->set('allday', 0);
278
				}
279
				$recordModel->save();
280
				$success = true;
281
			}
282
		} catch (Exception $e) {
283
			\App\Log::error($e->__toString());
284
			$success = false;
285
		}
286
		return $success;
287
	}
288
}
289