Passed
Push — developer ( dccb56...037909 )
by Radosław
16:39
created

Vtiger_Basic_InventoryField   F

Complexity

Total Complexity 110

Size/Duplication

Total Lines 802
Duplicated Lines 0 %

Test Coverage

Coverage 47.86%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 110
eloc 241
dl 0
loc 802
ccs 67
cts 140
cp 0.4786
rs 2
c 1
b 0
f 0

51 Methods

Rating   Name   Duplication   Size   Complexity  
A isOnlyOne() 0 3 1
A getDBType() 0 15 4
A getBlocks() 0 3 1
A getParamsConfig() 0 3 2
A getModuleName() 0 3 1
A getId() 0 3 1
A getInstance() 0 12 2
A getParams() 0 3 1
A setModuleName() 0 4 1
A getValueForSave() 0 7 3
A getParamConfig() 0 3 1
A getDefaultLabel() 0 3 1
A getColumnName() 0 3 2
A getType() 0 3 1
A displayTypeBase() 0 3 1
A isSummary() 0 3 1
A getColSpan() 0 3 2
A getCustomColumn() 0 19 5
A getDisplayType() 0 3 2
A getEditTemplateName() 0 3 1
A getLabel() 0 3 1
A getRangeValues() 0 3 1
A getTemplateName() 0 20 5
A getFieldInfo() 0 4 1
B setValueToRecord() 0 19 9
A getListViewDisplayValue() 0 3 1
A getConfigField() 0 3 1
A setDefaultDataConfig() 0 12 1
A getDefaultValue() 0 9 4
A getDBValue() 0 3 1
A getEditValue() 0 15 5
B getConfigFields() 0 19 8
A getConfigFieldsData() 0 59 3
A getPreviousValue() 0 3 2
A validate() 0 7 5
A isSync() 0 3 1
A getFieldDataType() 0 3 1
A getMapDetail() 0 10 2
A isVisible() 0 3 1
A getDisplayValue() 0 3 2
A getPurifyType() 0 3 1
A isVisibleInDetail() 0 3 1
A isSummaryEnabled() 0 3 2
A isEditable() 0 3 1
A isMandatory() 0 3 1
A getMaximumLengthByColumn() 0 9 2
A getSummaryValuesFromData() 0 12 5
A compare() 0 3 1
A isRequired() 0 3 1
A isReadOnly() 0 3 1
A set() 0 6 5

How to fix   Complexity   

Complex Class

Complex classes like Vtiger_Basic_InventoryField 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_Basic_InventoryField, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * Inventory Basic Field Class.
5
 *
6
 * @package   InventoryField
7
 *
8
 * @copyright YetiForce S.A.
9
 * @license   YetiForce Public License 5.0 (licenses/LicenseEN.txt or yetiforce.com)
10
 * @author    Mariusz Krzaczkowski <[email protected]>
11
 * @author    Radosław Skrzypczak <[email protected]>
12
 */
13
class Vtiger_Basic_InventoryField extends \App\Base
14
{
15
	/**
16
	 * Field visible everywhere.
17
	 */
18
	private const FIELD_VISIBLE_EVERYWHERE = 0;
19
	/**
20
	 * Field visible in detail view.
21
	 */
22
	private const FIELD_VISIBLE_IN_DETAIL = 2;
23
	/**
24
	 * Field hidden.
25
	 */
26
	private const FIELD_HIDDEN = 5;
27
	/**
28
	 * Field read-only.
29
	 */
30
	private const FIELD_READONLY = 10;
31
32
	protected $columnName = '';
33
	protected $moduleName = '';
34
35
	protected $type;
36
	protected $colSpan = 10;
37
	protected $defaultValue = '';
38
	protected $params = [];
39
	protected $dbType = 'string';
40
	protected $customColumn = [];
41
	protected $summationValue = false;
42
	protected $onlyOne = true;
43
	protected $displayType = self::FIELD_VISIBLE_EVERYWHERE;
44
	protected $displayTypeBase = [
45
		self::FIELD_VISIBLE_EVERYWHERE => 'LBL_DISPLAYTYPE_ALL',
46
		self::FIELD_VISIBLE_IN_DETAIL => 'LBL_DISPLAYTYPE_ONLY_DETAIL',
47
		self::FIELD_HIDDEN => 'LBL_DISPLAYTYPE_HIDDEN',
48
		self::FIELD_READONLY => 'LBL_DISPLAYTYPE_READONLY'
49
	];
50
	protected $blocks = [1];
51
	protected $fieldDataType = 'inventory';
52
	protected $maximumLength = 255;
53
	protected $defaultLabel = '';
54
	protected $purifyType = '';
55
	protected $customPurifyType = [];
56
	protected $customMaximumLength = [];
57
	/** @var array Default values for custom fields */
58
	protected $customDefault = [];
59
	/** @var bool Field is synchronized */
60
	protected $sync = false;
61
	/** @var array List of changes */
62
	protected $changes = [];
63
64
	/**
65
	 * Gets inventory field instance.
66
	 *
67 2
	 * @param string      $moduleName
68
	 * @param string|null $type
69 2
	 *
70 2
	 * @throws \App\Exceptions\AppException
71 2
	 *
72
	 * @return self
73 2
	 */
74 2
	public static function getInstance(string $moduleName, ?string $type = 'Basic')
75 2
	{
76 2
		$cacheName = "$moduleName:$type";
77
		if (\App\Cache::has(__METHOD__, $cacheName)) {
78 2
			$instance = \App\Cache::get(__METHOD__, $cacheName);
79
		} else {
80
			$className = Vtiger_Loader::getComponentClassName('InventoryField', $type, $moduleName);
81
			$instance = new $className();
82
			$instance->setModuleName($moduleName);
83
			\App\Cache::save(__METHOD__, $cacheName, $instance);
84
		}
85
		return clone $instance;
86 2
	}
87
88 2
	/**
89
	 * Function returns module name.
90
	 *
91
	 * @return string
92
	 */
93
	public function getModuleName(): string
94
	{
95
		return $this->moduleName;
96
	}
97
98 2
	/**
99
	 * Function to get the Id.
100 2
	 *
101 2
	 * @return int Field ID
102
	 */
103
	public function getId(): int
104
	{
105
		return (int) $this->get('id');
106
	}
107
108
	/**
109
	 * Sets module name.
110
	 *
111
	 * @param string $moduleName
112
	 *
113
	 * @return \Vtiger_Basic_InventoryField
114
	 */
115
	public function setModuleName(string $moduleName): self
116
	{
117
		$this->moduleName = $moduleName;
118
		return $this;
119
	}
120
121
	/**
122
	 * Getting onlyOne field.
123
	 *
124
	 * @return bool
125
	 */
126
	public function isOnlyOne()
127
	{
128
		return $this->onlyOne;
129
	}
130
131
	public function getBlocks()
132
	{
133
		return $this->blocks;
134
	}
135
136
	/**
137
	 * Getting database-type of field.
138 2
	 *
139
	 * @return string|yii\db\ColumnSchemaBuilder dbType
140 2
	 */
141 2
	public function getDBType()
142
	{
143 2
		$columnCriteria = $this->dbType;
144 2
		if (\is_array($columnCriteria)) {
0 ignored issues
show
introduced by
The condition is_array($columnCriteria) is always false.
Loading history...
145
			[$type, $length, $default, $unsigned] = array_pad($columnCriteria, 4, null);
146
			$columnCriteria = \App\Db::getInstance()->getSchema()->createColumnSchemaBuilder($type, $length);
147
			if (null !== $default) {
148
				$columnCriteria->defaultValue($default);
149
			}
150
			if (null !== $unsigned) {
151
				$columnCriteria->unsigned();
152
			}
153
		}
154
155
		return $columnCriteria;
156
	}
157 2
158
	/**
159 2
	 * Gets value for save.
160
	 *
161
	 * @param array  $item
162
	 * @param bool   $userFormat
163
	 * @param string $column
164
	 *
165
	 * @return mixed
166
	 */
167
	public function getValueForSave(array $item, bool $userFormat = false, string $column = null)
168
	{
169
		if (null === $column) {
170
			$column = $this->getColumnName();
171
		}
172
		$value = $item[$column] ?? null;
173
		return $userFormat ? $this->getDBValue($value) : $value;
174
	}
175
176
	/**
177
	 * Getting all params field.
178
	 *
179
	 * @return array
180
	 */
181
	public function getParams()
182
	{
183
		return $this->params;
184
	}
185
186
	/**
187
	 * Get params value.
188
	 *
189
	 * @return array
190
	 */
191
	public function getParamsConfig()
192
	{
193
		return $this->get('params') ? \App\Json::decode($this->get('params')) : [];
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('param...et('params')) : array() also could return the type string which is incompatible with the documented return type array.
Loading history...
194
	}
195
196
	/**
197
	 * Get the configuration parameter value for the specified key.
198
	 *
199
	 * @param string $key
200
	 *
201
	 * @return mixed
202
	 */
203
	public function getParamConfig(string $key)
204
	{
205
		return $this->getParamsConfig()[$key] ?? null;
206
	}
207
208
	/**
209
	 * Getting all values display Type.
210
	 *
211
	 * @return array
212
	 */
213
	public function displayTypeBase()
214
	{
215
		return $this->displayTypeBase;
216
	}
217
218
	/**
219
	 * Gets display type.
220
	 *
221
	 * @return int
222
	 */
223
	public function getDisplayType(): int
224
	{
225
		return $this->has('displaytype') ? $this->get('displaytype') : $this->displayType;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->has('displ...') : $this->displayType could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
226
	}
227
228
	public function getColSpan()
229
	{
230
		return $this->has('colspan') ? $this->get('colspan') : $this->colSpan;
231
	}
232
233
	public function getRangeValues()
234
	{
235
		return $this->maximumLength;
236
	}
237
238
	/**
239
	 * Get template name for edit.
240
	 *
241
	 * @return string
242
	 */
243
	public function getEditTemplateName()
244
	{
245
		return 'inventoryTypes/Base.tpl';
246
	}
247 1
248
	/**
249 1
	 * Getting template name.
250
	 *
251
	 * @param string $view
252
	 * @param string $moduleName
253
	 *
254
	 * @return string templateName
255
	 */
256
	public function getTemplateName($view, $moduleName)
257 2
	{
258
		$tpl = $view . $this->type . '.tpl';
259 2
		$filename = 'layouts' . DIRECTORY_SEPARATOR . \App\Layout::getActiveLayout() . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . $moduleName . DIRECTORY_SEPARATOR . 'inventoryfields' . DIRECTORY_SEPARATOR . $tpl;
260
		if (is_file($filename)) {
261
			return $tpl;
262
		}
263
		$filename = 'layouts' . DIRECTORY_SEPARATOR . \App\Layout::getActiveLayout() . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . 'Vtiger' . DIRECTORY_SEPARATOR . 'inventoryfields' . DIRECTORY_SEPARATOR . $tpl;
264
		if (is_file($filename)) {
265
			return $tpl;
266
		}
267 2
		$filename = 'layouts' . DIRECTORY_SEPARATOR . Vtiger_Viewer::getDefaultLayoutName() . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . $moduleName . DIRECTORY_SEPARATOR . 'inventoryfields' . DIRECTORY_SEPARATOR . $tpl;
268
		if (is_file($filename)) {
269 2
			return $tpl;
270
		}
271
		$filename = 'layouts' . DIRECTORY_SEPARATOR . Vtiger_Viewer::getDefaultLayoutName() . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . 'Vtiger' . DIRECTORY_SEPARATOR . 'inventoryfields' . DIRECTORY_SEPARATOR . $tpl;
272 2
		if (is_file($filename)) {
273
			return $tpl;
274 2
		}
275
		return $view . 'Base' . '.tpl';
276
	}
277 1
278
	/**
279 1
	 * Getting default label.
280
	 *
281
	 * @return string defaultLabel
282
	 */
283
	public function getDefaultLabel()
284
	{
285
		return $this->defaultLabel;
286
	}
287
288
	/**
289
	 * Getting field type.
290
	 *
291
	 * @return string
292
	 */
293
	public function getType()
294
	{
295
		return $this->type;
296
	}
297
298
	/**
299
	 * Getting column name.
300
	 *
301
	 * @return string columnName
302
	 */
303
	public function getColumnName()
304
	{
305
		return $this->has('columnname') ? $this->get('columnname') : $this->columnName;
306
	}
307
308
	/**
309
	 * Get label.
310
	 *
311
	 * @return string
312
	 */
313
	public function getLabel(): string
314
	{
315
		return $this->get('label');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('label') could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
316
	}
317
318
	/**
319
	 * Getting column name.
320
	 *
321
	 * @return array customColumn
322
	 */
323
	public function getCustomColumn()
324
	{
325
		$columns = [];
326
		$schame = \App\Db::getInstance()->getSchema();
327
		foreach ($this->customColumn as $name => $columnCriteria) {
328
			if (\is_array($columnCriteria)) {
329
				[$type, $length, $default, $unsigned] = array_pad($columnCriteria, 4, null);
330
				$columnCriteria = $schame->createColumnSchemaBuilder($type, $length);
331
				if (null !== $default) {
332
					$columnCriteria->defaultValue($default);
333
				}
334
				if (null !== $unsigned) {
335
					$columnCriteria->unsigned();
336
				}
337
			}
338
			$columns[$name] = $columnCriteria;
339
		}
340
341
		return $columns;
342
	}
343
344
	/**
345
	 * Check if the field is summed up.
346
	 *
347
	 * @return bool
348
	 */
349
	public function isSummary(): bool
350
	{
351
		return $this->summationValue;
352
	}
353
354
	/**
355
	 * Check if summary enabled.
356
	 *
357
	 * @return bool
358
	 */
359
	public function isSummaryEnabled(): bool
360
	{
361
		return $this->isSummary() && 1 === (int) ($this->getParamConfig('summary_enabled') ?? 1);
362
	}
363
364
	/**
365
	 * Gets default value by field.
366
	 *
367
	 * @param string $columnName
368
	 *
369
	 * @return mixed
370
	 */
371
	public function getDefaultValue(string $columnName = '')
372
	{
373
		if (!$columnName || $columnName === $this->getColumnName()) {
374
			$value = $this->has('defaultvalue') ? $this->get('defaultvalue') : $this->defaultValue;
375
		} else {
376
			$value = $this->customDefault[$columnName] ?? '';
377
		}
378
379
		return $value;
380
	}
381
382
	/**
383
	 * Getting value to display.
384
	 *
385
	 * @param mixed $value
386
	 * @param array $rowData
387 2
	 * @param bool  $rawText
388
	 *
389 2
	 * @return string
390 2
	 */
391 2
	public function getDisplayValue($value, array $rowData = [], bool $rawText = false)
392 2
	{
393
		return $value ? \App\Purifier::encodeHtml($value) : '';
394
	}
395 2
396
	/**
397
	 * Function to get the list value in display view.
398
	 *
399
	 * @param mixed $value
400
	 * @param array $rowData
401
	 * @param bool  $rawText
402
	 *
403
	 * @return mixed
404
	 */
405
	public function getListViewDisplayValue($value, array $rowData = [], bool $rawText = false)
406
	{
407 1
		return $this->getDisplayValue($value, $rowData, $rawText);
408
	}
409 1
410 1
	/**
411 1
	 * Get value for Edit view.
412 1
	 *
413 1
	 * @param array  $itemData
414 1
	 * @param string $column
415
	 *
416 1
	 * @return string|int
417
	 */
418
	public function getEditValue(array $itemData, string $column = '')
419
	{
420
		if (!$column) {
421
			$column = $this->getColumnName();
422
		}
423
		$value = '';
424
		if (isset($itemData[$column])) {
425
			$value = $itemData[$column];
426
		} elseif (($default = \App\Config::module($this->getModuleName(), 'defaultInventoryData', [])[$column] ?? null) !== null) {
427
			$value = $default;
428
		} elseif ($column === $this->getColumnName()) {
429
			$value = $this->getDefaultValue();
430
		}
431
432 2
		return $value;
433
	}
434 2
435
	/**
436
	 * Function to check if the current field is mandatory or not.
437
	 *
438
	 * @return bool
439
	 */
440
	public function isMandatory()
441
	{
442
		return true;
443
	}
444
445
	/**
446
	 * Function to check whether the current field is visible.
447 2
	 *
448
	 * @return bool
449 2
	 */
450
	public function isVisible()
451
	{
452 2
		return self::FIELD_HIDDEN !== $this->get('displaytype');
453
	}
454
455 2
	/**
456
	 * Function to check if field is visible in detail view.
457
	 *
458
	 * @return bool
459
	 */
460
	public function isVisibleInDetail()
461
	{
462
		return \in_array($this->get('displaytype'), [self::FIELD_VISIBLE_EVERYWHERE, self::FIELD_READONLY, self::FIELD_VISIBLE_IN_DETAIL]);
463
	}
464
465
	/**
466
	 * Function to check whether the current field is editable.
467
	 *
468
	 * @return bool
469
	 */
470
	public function isEditable(): bool
471
	{
472
		return \in_array($this->get('displaytype'), [self::FIELD_VISIBLE_EVERYWHERE, self::FIELD_READONLY]);
473
	}
474
475
	/**
476
	 * Function checks if the field is read-only.
477
	 *
478
	 * @return bool
479
	 */
480
	public function isReadOnly()
481
	{
482
		return self::FIELD_READONLY === $this->get('displaytype');
483
	}
484
485
	/** {@inheritdoc} */
486
	public function set($key, $value, $register = false)
487
	{
488
		if ($this->getId() && !\in_array($key, ['id']) && (\array_key_exists($key, $this->value) && $this->value[$key] != $value)) {
489
			$this->changes[$key] = $this->get($key);
490
		}
491 2
		return parent::set($key, $value);
492
	}
493 2
494 2
	/**
495 2
	 * Sum the field value for each row.
496 2
	 *
497 2
	 * @param array    $data
498
	 * @param int|null $groupId
499 2
	 *
500 2
	 * @return int|float
501 2
	 */
502 2
	public function getSummaryValuesFromData($data, ?int $groupId = null)
503 2
	{
504 2
		$sum = 0;
505 2
		if (\is_array($data)) {
0 ignored issues
show
introduced by
The condition is_array($data) is always true.
Loading history...
506
			foreach ($data as $row) {
507
				if (null !== $groupId && $groupId !== $row['groupid'] ?? -1) {
508 2
					continue;
509
				}
510
				$sum += $row[$this->getColumnName()];
511
			}
512
		}
513
		return $sum;
514
	}
515 1
516
	/**
517 1
	 * Gets relation field.
518
	 *
519
	 * @param string $related
520
	 *
521
	 * @throws \App\Exceptions\AppException
522
	 *
523
	 * @return bool|\Vtiger_Field_Model
524
	 */
525
	public function getMapDetail(string $related)
526
	{
527
		$inventory = Vtiger_Inventory_Model::getInstance($this->getModuleName());
528
		$fields = $inventory->getAutoCompleteFields();
529
		$field = false;
530
		if ($mapDetail = $fields[$related][$this->getColumnName()] ?? false) {
531
			$moduleModel = Vtiger_Module_Model::getInstance($related);
532
			$field = Vtiger_Field_Model::getInstance($mapDetail['field'], $moduleModel);
533
		}
534
		return $field;
535
	}
536
537
	public function getFieldDataType()
538
	{
539
		return $this->fieldDataType;
540
	}
541
542
	/**
543
	 * Gets database value.
544
	 *
545
	 * @param mixed       $value
546
	 * @param string|null $name
547
	 *
548
	 * @return mixed
549
	 */
550
	public function getDBValue($value, ?string $name = '')
551
	{
552
		return $value;
553
	}
554
555
	/**
556
	 * Verification of data.
557
	 *
558
	 * @param mixed  $value
559
	 * @param string $columnName
560
	 * @param bool   $isUserFormat
561
	 * @param mixed  $originalValue
562
	 *
563
	 * @throws \App\Exceptions\Security
564
	 */
565
	public function validate($value, string $columnName, bool $isUserFormat, $originalValue = null)
566
	{
567
		if (!is_numeric($value) && (\is_string($value) && $value !== strip_tags($value))) {
568
			throw new \App\Exceptions\Security('ERR_ILLEGAL_FIELD_VALUE||' . ($columnName ?? $this->getColumnName()) . '||' . $this->getModuleName() . '||' . $value, 406);
569
		}
570
		if (App\TextUtils::getTextLength($value) > $this->maximumLength) {
571
			throw new \App\Exceptions\Security('ERR_VALUE_IS_TOO_LONG||' . ($columnName ?? $this->getColumnName()) . '||' . $this->getModuleName() . '||' . $value, 406);
572
		}
573
	}
574
575
	/**
576
	 * Sets default data config.
577
	 *
578
	 * @return $this
579
	 */
580
	public function setDefaultDataConfig()
581
	{
582
		$this->set('columnname', $this->columnName)
583
			->set('label', $this->defaultLabel)
584
			->set('presence', 0)
585
			->set('defaultvalue', $this->defaultValue)
586
			->set('displaytype', $this->displayType)
587
			->set('invtype', $this->type)
588
			->set('block', current($this->blocks))
589
			->set('colspan', $this->colSpan);
590
591
		return $this;
592
	}
593
594
	/**
595
	 * Field required to make an entry.
596
	 *
597
	 * @return bool
598
	 */
599
	public function isRequired()
600
	{
601
		return false;
602
	}
603
604
	/**
605
	 * Sets value data.
606
	 *
607
	 * @param \Vtiger_Record_Model $recordModel
608
	 * @param array                $item
609
	 * @param bool                 $userFormat
610
	 *
611
	 * @throws \App\Exceptions\AppException
612
	 * @throws \App\Exceptions\Security
613
	 */
614
	public function setValueToRecord(Vtiger_Record_Model $recordModel, array $item, bool $userFormat)
615
	{
616
		$column = $this->getColumnName();
617
		$baseValue = $item[$column] ?? null;
618
		$value = $this->getValueForSave($item, $userFormat, $column);
619
		if ($userFormat && $baseValue) {
620
			$baseValue = $this->getDBValue($baseValue, $column);
621
		}
622
		$this->validate($value, $column, false, $baseValue);
623
624
		$itemId = $item['id'];
625
		$addToChanges = !$recordModel->isNew() && is_numeric($itemId) && !$this->compare($value, $recordModel->getInventoryData()[$itemId][$column] ?? '', $column);
626
		$recordModel->setInventoryItemPart($itemId, $column, $value, $addToChanges);
627
		if ($customColumn = $this->getCustomColumn()) {
628
			foreach (array_keys($customColumn) as $column) {
629
				$value = $this->getValueForSave($item, $userFormat, $column);
630
				$this->validate($value, $column, false);
631
				$addToChanges = !$recordModel->isNew() && is_numeric($itemId) && !$this->compare($value, $recordModel->getInventoryData()[$itemId][$column] ?? '', $column);
632
				$recordModel->setInventoryItemPart($itemId, $column, $value, $addToChanges);
633
			}
634
		}
635
	}
636
637
	/**
638
	 * Compare two values.
639
	 *
640
	 * @param mixed  $value
641
	 * @param mixed  $prevValue
642
	 * @param string $column
643
	 *
644
	 * @return bool
645
	 */
646
	public function compare($value, $prevValue, string $column): bool
647
	{
648
		return (string) $value === (string) $prevValue;
649
	}
650
651
	/**
652
	 * Gets purify type.
653
	 *
654
	 * @return array
655
	 */
656
	public function getPurifyType()
657
	{
658
		return [$this->getColumnName() => $this->purifyType] + $this->customPurifyType;
659
	}
660
661
	/**
662
	 * Get information about field.
663
	 *
664
	 * @return array
665
	 */
666
	public function getFieldInfo(): array
667
	{
668
		return [
669
			'maximumlength' => $this->maximumLength
670
		];
671
	}
672
673
	/**
674
	 * Get maximum length by column.
675
	 *
676
	 * @param string $columnName
677
	 *
678
	 * @return int|string
679
	 */
680
	public function getMaximumLengthByColumn(string $columnName)
681
	{
682
		if ($columnName === $this->getColumnName()) {
683
			$value = $this->maximumLength;
684
		} else {
685
			$value = $this->customMaximumLength[$columnName] ?? '';
686
		}
687
688
		return $value;
689
	}
690
691
	/**
692
	 * Get pervious value by field.
693
	 *
694
	 * @param string $fieldName
695
	 *
696
	 * @return mixed
697
	 */
698
	public function getPreviousValue(string $fieldName = '')
699
	{
700
		return $fieldName ? ($this->changes[$fieldName] ?? null) : $this->changes;
701
	}
702
703
	/**
704
	 * Check if the field is synchronized.
705
	 *
706
	 * @return bool
707
	 */
708
	public function isSync(): bool
709
	{
710
		return $this->sync;
711
	}
712
713
	/**
714
	 * Gets config fields data.
715
	 *
716
	 * @return array
717
	 */
718
	public function getConfigFieldsData(): array
719
	{
720
		$row = [
721
			'invtype' => [
722
				'name' => 'invtype',
723
				'column' => 'invtype',
724
				'uitype' => 1,
725
				'label' => 'LBL_NAME_FIELD',
726
				'maximumlength' => '30',
727
				'typeofdata' => 'V~M',
728
				'purifyType' => \App\Purifier::STANDARD,
729
				'isEditableReadOnly' => true,
730
			],
731
			'label' => [
732
				'name' => 'label',
733
				'label' => 'LBL_LABEL_NAME',
734
				'uitype' => 1,
735
				'maximumlength' => '50',
736
				'typeofdata' => 'V~M',
737
				'purifyType' => \App\Purifier::TEXT,
738
			],
739
			'displaytype' => [
740
				'name' => 'displaytype',
741
				'label' => 'LBL_DISPLAY_TYPE',
742
				'uitype' => 16,
743
				'maximumlength' => '127',
744
				'typeofdata' => 'V~M',
745
				'purifyType' => \App\Purifier::INTEGER,
746
				'picklistValues' => [],
747
			],
748
			'colspan' => [
749
				'name' => 'colspan',
750
				'label' => 'LBL_COLSPAN',
751
				'uitype' => 7,
752
				'maximumlength' => '0,100',
753
				'typeofdata' => 'N~M',
754
				'purifyType' => \App\Purifier::INTEGER,
755
				'tooltip' => 'LBL_MAX_WIDTH_COLUMN_INFO'
756
			]
757
		];
758
759
		$qualifiedModuleName = 'Settings:LayoutEditor';
760
		foreach ($this->displayTypeBase() as $key => $value) {
761
			$row['displaytype']['picklistValues'][$key] = \App\Language::translate($value, $qualifiedModuleName);
762
		}
763
764
		if ($this->isSummary()) {
765
			$row['summary_enabled'] = [
766
				'name' => 'summary_enabled',
767
				'label' => 'LBL_INV_SUMMARY_ENABLED',
768
				'uitype' => 56,
769
				'maximumlength' => '1',
770
				'typeofdata' => 'C~O',
771
				'purifyType' => \App\Purifier::INTEGER,
772
				'defaultvalue' => 1
773
			];
774
		}
775
776
		return $row;
777
	}
778
779
	/**
780
	 * Gets config fields.
781
	 *
782
	 * @return Vtiger_Field_Model[]
783
	 */
784
	public function getConfigFields(): array
785
	{
786
		$module = 'LayoutEditor';
787
		$fields = [];
788
		foreach ($this->getConfigFieldsData() as $name => $data) {
789
			$fieldModel = \Vtiger_Field_Model::init($module, $data, $name);
790
			if (null !== $this->get($name)) {
791
				$fieldModel->set('fieldvalue', $this->get($name));
792
			} elseif (isset($this->getParamsConfig()[$name])) {
793
				$fieldModel->set('fieldvalue', $this->getParamsConfig()[$name]);
794
			} elseif (property_exists($this, $name) && null !== $this->{$name} && '' !== $this->{$name}) {
795
				$fieldModel->set('fieldvalue', $this->{$name});
796
			} elseif (($default = $fieldModel->get('defaultvalue')) !== null) {
797
				$fieldModel->set('fieldvalue', $default);
798
			}
799
			$fields[$name] = $fieldModel;
800
		}
801
802
		return $fields;
803
	}
804
805
	/**
806
	 * Gets config field.
807
	 *
808
	 * @param string $key
809
	 *
810
	 * @return Vtiger_Field_Model|null
811
	 */
812
	public function getConfigField(string $key): ?Vtiger_Field_Model
813
	{
814
		return $this->getConfigFields()[$key] ?? null;
815
	}
816
}
817