Total Complexity | 52 |
Total Lines | 422 |
Duplicated Lines | 0 % |
Changes | 2 | ||
Bugs | 0 | Features | 0 |
Complex classes like Vtiger_CalendarExtSource_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 Vtiger_CalendarExtSource_Model, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
15 | class Vtiger_CalendarExtSource_Model extends App\Base |
||
16 | { |
||
17 | /** @var string[] Extra source details */ |
||
18 | const EXTRA_SOURCE_TYPES = [ |
||
19 | 1 => 'LBL_SOURCE_TYPE_1', |
||
20 | 2 => 'LBL_SOURCE_TYPE_2', |
||
21 | 3 => 'LBL_SOURCE_TYPE_3', |
||
22 | 4 => 'LBL_SOURCE_TYPE_4', |
||
23 | ]; |
||
24 | /** @var string Extra source table name */ |
||
25 | const EXTRA_SOURCE_TABLE = 's_#__calendar_sources'; |
||
26 | |||
27 | /** @var string Base module name */ |
||
28 | protected $baseModuleName; |
||
29 | /** @var string Target module name */ |
||
30 | protected $targetModuleName; |
||
31 | /** @var \Vtiger_Module_Model Target module model */ |
||
32 | protected $targetModuleModel; |
||
33 | /** @var \App\QueryGenerator Query generator instance */ |
||
34 | protected $queryGenerator; |
||
35 | /** @var string[] Name record fields */ |
||
36 | protected $nameFields; |
||
37 | |||
38 | /** |
||
39 | * Get calendar extra sources list. |
||
40 | * |
||
41 | * @param int $moduleId |
||
42 | * |
||
43 | * @return array |
||
44 | */ |
||
45 | public static function getByModule(int $moduleId): array |
||
46 | { |
||
47 | $user = \App\User::getCurrentUserModel(); |
||
48 | $query = (new \App\Db\Query())->from(self::EXTRA_SOURCE_TABLE) |
||
49 | ->where(['base_module' => $moduleId]); |
||
50 | if (!$user->isAdmin()) { |
||
51 | $query->andWhere(['or', ['public' => 1], ['user_id' => $user->getId()]]); |
||
52 | } |
||
53 | return $query->createCommand(\App\Db::getInstance('admin'))->queryAllByGroup(1); |
||
54 | } |
||
55 | |||
56 | /** |
||
57 | * Get calendar extra source instance by id. |
||
58 | * |
||
59 | * @param int $id |
||
60 | * |
||
61 | * @return $this |
||
62 | */ |
||
63 | public static function getInstanceById(int $id) |
||
78 | } |
||
79 | |||
80 | /** |
||
81 | * Get calendar extra source clean instance by module name. |
||
82 | * |
||
83 | * @param string $moduleName |
||
84 | * |
||
85 | * @return $this |
||
86 | */ |
||
87 | public static function getCleanInstance(string $moduleName) |
||
88 | { |
||
89 | $className = Vtiger_Loader::getComponentClassName('Model', 'CalendarExtSource', $moduleName); |
||
90 | $handler = new $className(); |
||
91 | $handler->baseModuleName = $moduleName; |
||
92 | return $handler; |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * Get calendar extra sources data by id. |
||
97 | * |
||
98 | * @param int $id |
||
99 | * |
||
100 | * @return string[] |
||
101 | */ |
||
102 | public static function getById(int $id): array |
||
103 | { |
||
104 | if (\App\Cache::has('Calendar-GetExtraSourceById', $id)) { |
||
105 | return \App\Cache::get('Calendar-GetExtraSourceById', $id); |
||
106 | } |
||
107 | $row = (new \App\Db\Query())->from(self::EXTRA_SOURCE_TABLE) |
||
108 | ->where(['id' => $id]) |
||
109 | ->one(\App\Db::getInstance('admin')); |
||
110 | \App\Cache::save('Calendar-GetExtraSourceById', $id, $row, \App\Cache::LONG); |
||
111 | return $row; |
||
112 | } |
||
113 | |||
114 | /** |
||
115 | * Save calendar extra sources. |
||
116 | * |
||
117 | * @return int |
||
118 | */ |
||
119 | public function save(): int |
||
120 | { |
||
121 | $dbCommand = \App\Db::getInstance('admin')->createCommand(); |
||
122 | if ($id = $this->get('id')) { |
||
123 | $dbCommand->update(self::EXTRA_SOURCE_TABLE, $this->getData(), [ |
||
124 | 'id' => $id |
||
125 | ])->execute(); |
||
126 | \App\Cache::save('Calendar-GetExtraSourceById', $id, $this->getData(), \App\Cache::LONG); |
||
127 | } else { |
||
128 | $params = $this->getData(); |
||
129 | $params['user_id'] = \App\User::getCurrentUserId(); |
||
130 | $dbCommand->insert(self::EXTRA_SOURCE_TABLE, $params) |
||
131 | ->execute(); |
||
132 | $id = \App\Db::getInstance('admin')->getLastInsertID(self::EXTRA_SOURCE_TABLE . '_id_seq'); |
||
133 | } |
||
134 | \App\Cache::delete('Calendar-GetExtraSourcesList', $this->get('base_module')); |
||
135 | return $id; |
||
136 | } |
||
137 | |||
138 | /** |
||
139 | * Delete calendar extra sources. |
||
140 | * |
||
141 | * @return bool |
||
142 | */ |
||
143 | public function delete(): bool |
||
144 | { |
||
145 | $dbCommand = \App\Db::getInstance('admin')->createCommand(); |
||
146 | $status = $dbCommand->delete(self::EXTRA_SOURCE_TABLE, ['id' => $this->get('id')])->execute(); |
||
147 | \App\Cache::delete('Calendar-GetExtraSourceById', $this->get('id')); |
||
148 | \App\Cache::delete('Calendar-GetExtraSourcesList', $this->get('base_module')); |
||
149 | return (bool) $status; |
||
150 | } |
||
151 | |||
152 | /** |
||
153 | * Get module model. |
||
154 | * |
||
155 | * @return Vtiger_Module_Model |
||
156 | */ |
||
157 | public function getModule(): Vtiger_Module_Model |
||
158 | { |
||
159 | if (!$this->targetModuleModel) { |
||
160 | $this->targetModuleModel = \Vtiger_Module_Model::getInstance($this->targetModuleName); |
||
161 | } |
||
162 | return $this->targetModuleModel; |
||
163 | } |
||
164 | |||
165 | /** |
||
166 | * Get extra sources query. |
||
167 | * |
||
168 | * @return \App\Db\Query |
||
169 | */ |
||
170 | protected function getExtraSourcesQuery(): ?App\Db\Query |
||
171 | { |
||
172 | if ( |
||
173 | !\App\Privilege::isPermitted($this->targetModuleName) |
||
174 | || !\App\CustomView::getCustomViewById($this->get('custom_view')) |
||
175 | ) { |
||
176 | return null; |
||
177 | } |
||
178 | $this->queryGenerator = new App\QueryGenerator($this->targetModuleName); |
||
179 | $this->queryGenerator->initForCustomViewById($this->get('custom_view')); |
||
180 | $this->targetModuleModel = $this->queryGenerator->getModuleModel(); |
||
181 | if ($this->get('include_filters')) { |
||
182 | $this->loadExtraSourcesQueryFilter(); |
||
183 | } |
||
184 | $this->queryGenerator->clearFields(); |
||
185 | $this->queryGenerator->setField('assigned_user_id'); |
||
186 | if ($this->get('field_label')) { |
||
187 | $this->nameFields = [$this->getModule()->getField($this->get('field_label'))->getName()]; |
||
188 | } else { |
||
189 | $this->nameFields = $this->getModule()->getNameFields(); |
||
190 | } |
||
191 | foreach ($this->nameFields as $field) { |
||
192 | $this->queryGenerator->setField($field); |
||
193 | } |
||
194 | $this->loadExtraSourcesQueryType(); |
||
195 | return $this->queryGenerator->createQuery(); |
||
196 | } |
||
197 | |||
198 | /** |
||
199 | * Load extra sources query condition by type. |
||
200 | * |
||
201 | * @return void |
||
202 | */ |
||
203 | protected function loadExtraSourcesQueryType(): void |
||
280 | } |
||
281 | } |
||
282 | |||
283 | /** |
||
284 | * Load extra sources query condition by type. |
||
285 | * |
||
286 | * @return void |
||
287 | */ |
||
288 | protected function loadExtraSourcesQueryFilter(): void |
||
289 | { |
||
290 | $conditions = []; |
||
291 | if (!empty($this->get('user')) && isset($this->get('user')['selectedIds'][0])) { |
||
292 | $selectedUsers = $this->get('user'); |
||
293 | $selectedIds = $selectedUsers['selectedIds']; |
||
294 | if ('all' !== $selectedIds[0]) { |
||
295 | $conditions[] = ['vtiger_crmentity.smownerid' => $selectedIds]; |
||
296 | $subQuery = (new \App\Db\Query())->select(['crmid']) |
||
297 | ->from('u_#__crmentity_showners') |
||
298 | ->where(['userid' => $selectedIds]); |
||
299 | $conditions[] = ['vtiger_crmentity.crmid' => $subQuery]; |
||
300 | } |
||
301 | if (isset($selectedUsers['excludedIds']) && 'all' === $selectedIds[0]) { |
||
302 | $conditions[] = ['not in', 'vtiger_crmentity.smownerid', $selectedUsers['excludedIds']]; |
||
303 | } |
||
304 | } |
||
305 | if ($conditions) { |
||
306 | $this->queryGenerator->addNativeCondition(array_merge(['or'], $conditions)); |
||
307 | } |
||
308 | } |
||
309 | |||
310 | /** |
||
311 | * Get calendar extra source counter. |
||
312 | * |
||
313 | * @return int |
||
314 | */ |
||
315 | public function getExtraSourcesCount(): int |
||
316 | { |
||
317 | $privileges = Users_Privileges_Model::getCurrentUserPrivilegesModel(); |
||
318 | if ($privileges->hasModuleActionPermission($this->baseModuleName, 'CalendarExtraSources')) { |
||
319 | if ($query = $this->getExtraSourcesQuery()) { |
||
320 | return $query->count(); |
||
321 | } |
||
322 | } |
||
323 | return 0; |
||
324 | } |
||
325 | |||
326 | /** |
||
327 | * Get calendar extra source rows. |
||
328 | * |
||
329 | * @return array |
||
330 | */ |
||
331 | public function getRows(): array |
||
332 | { |
||
333 | $query = $this->getExtraSourcesQuery(); |
||
334 | $privileges = Users_Privileges_Model::getCurrentUserPrivilegesModel(); |
||
335 | if (!$query || !$privileges->hasModuleActionPermission($this->baseModuleName, 'CalendarExtraSources')) { |
||
336 | return []; |
||
337 | } |
||
338 | $dataReader = $query->createCommand()->query(); |
||
339 | $result = []; |
||
340 | while ($row = $dataReader->read()) { |
||
341 | $result[] = $this->formatRow($row); |
||
342 | } |
||
343 | $dataReader->close(); |
||
344 | return $result; |
||
345 | } |
||
346 | |||
347 | /** |
||
348 | * Format record data. |
||
349 | * |
||
350 | * @param array $row |
||
351 | * |
||
352 | * @return array |
||
353 | */ |
||
354 | protected function formatRow(array $row): array |
||
355 | { |
||
356 | $item = [ |
||
357 | 'id' => $row['id'], |
||
358 | 'editable' => false, |
||
359 | ]; |
||
360 | $this->formatDate($row, $item); |
||
361 | $title = ''; |
||
362 | foreach ($this->nameFields as $field) { |
||
363 | $title .= ' ' . \App\Purifier::encodeHtml($row[$field]); |
||
364 | } |
||
365 | $item['title'] = trim($title); |
||
366 | $item['backgroundColor'] = $this->get('color'); |
||
367 | $item['textColor'] = $this->get('textColor'); |
||
368 | $item['className'] = 'js-show-modal js-quick-detail-modal js-popover-tooltip--record ownerCBr_' . $row['assigned_user_id']; |
||
369 | $item['url'] = 'index.php?module=' . $this->targetModuleName . '&view=Detail&record=' . $row['id']; |
||
370 | return $item; |
||
371 | } |
||
372 | |||
373 | /** |
||
374 | * Format dates. |
||
375 | * |
||
376 | * @param array $row |
||
377 | * @param array $item |
||
378 | * |
||
379 | * @return void |
||
380 | */ |
||
381 | protected function formatDate(array $row, array &$item): void |
||
437 | } |
||
438 | } |
||
439 | } |
||
440 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.