Passed
Push — developer ( b6ebe7...0bf5e9 )
by Mariusz
47:54 queued 29:05
created

ProductGroup::findTree()   C

Complexity

Conditions 12
Paths 17

Size

Total Lines 36
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 24
dl 0
loc 36
rs 6.9666
c 1
b 0
f 0
cc 12
nc 17
nop 1

How to fix   Complexity   

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
 * Comarch product group synchronization file.
5
 *
6
 * The file is part of the paid functionality. Using the file is allowed only after purchasing a subscription.
7
 * File modification allowed only with the consent of the system producer.
8
 *
9
 * @package Integration
10
 *
11
 * @copyright YetiForce S.A.
12
 * @license   YetiForce Public License 5.0 (licenses/LicenseEN.txt or yetiforce.com)
13
 * @author    Mariusz Krzaczkowski <[email protected]>
14
 */
15
16
namespace App\Integrations\Comarch\Xl\Synchronizer;
17
18
/**
19
 * Comarch product group synchronization class.
20
 */
21
class ProductGroup extends \App\Integrations\Comarch\Synchronizer
22
{
23
	/** @var array Cache for data from the API */
24
	private $cache;
25
	/** @var array ID by name cache from the API */
26
	private $cacheList = [];
27
	/** @var array ID by name cache from the API */
28
	private $parentTree = [];
29
	/** @var array Field values */
30
	private $fieldValues = [];
31
	/** @var \Settings_Picklist_Field_Model */
32
	private $fieldModel;
33
34
	/** {@inheritdoc} */
35
	public function process(): void
36
	{
37
		$this->fieldModel = \Vtiger_Field_Model::getInstance(
0 ignored issues
show
Documentation Bug introduced by
It seems like Vtiger_Field_Model::getI...etInstance('Products')) of type false is incompatible with the declared type Settings_Picklist_Field_Model of property $fieldModel.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
38
			'pscategory',
39
			\Vtiger_Module_Model::getInstance('Products')
40
		);
41
		if ($this->fieldModel->isActiveField()) {
42
			$this->getAllFromApi();
43
			if (null !== $this->cache) {
44
				$this->import();
45
			} else {
46
				$this->controller->log('Skip import ' . $this->name, []);
47
			}
48
		}
49
	}
50
51
	/**
52
	 * Import account type from API.
53
	 *
54
	 * @return void
55
	 */
56
	public function import(): void
57
	{
58
		if ($this->config->get('log_all')) {
59
			$this->controller->log('Start import ' . $this->name, []);
60
		}
61
		$recordModel = \Settings_TreesManager_Record_Model::getInstanceById($this->fieldModel->getFieldParams());
0 ignored issues
show
Bug introduced by
$this->fieldModel->getFieldParams() of type array is incompatible with the type integer expected by parameter $record of Settings_TreesManager_Re...odel::getInstanceById(). ( Ignorable by Annotation )

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

61
		$recordModel = \Settings_TreesManager_Record_Model::getInstanceById(/** @scrutinizer ignore-type */ $this->fieldModel->getFieldParams());
Loading history...
62
		$this->loadTreeValues();
63
		$i = 0;
64
		foreach ($this->cache as $id => $value) {
65
			$key = $this->findTree($id);
66
			if (empty($key)) {
67
				try {
68
					if (empty($value['parent'])) {
69
						$newId = $recordModel->addValue($value['label']);
70
					} else {
71
						$newId = $recordModel->addValue($value['label'], $this->findTree($value['parent']));
72
					}
73
					$this->cacheList[$id] = $newId;
74
					++$i;
75
				} catch (\Throwable $ex) {
76
					$this->controller->log('Import ' . $this->name, ['API' => $value], $ex);
77
					\App\Log::error("Error during import {$this->name}: \n{$ex->__toString()}", self::LOG_CATEGORY);
78
				}
79
			}
80
		}
81
		if ($this->config->get('log_all')) {
82
			$this->controller->log('End import ' . $this->name, ['imported' => $i]);
83
		}
84
	}
85
86
	/**
87
	 * Get tree values.
88
	 */
89
	private function loadTreeValues(): void
90
	{
91
		$moduleName = $this->fieldModel->getModuleName();
92
		$values = [];
93
		foreach (\App\Fields\Tree::getValuesById($this->fieldModel->getFieldParams()) as $value) {
0 ignored issues
show
Bug introduced by
$this->fieldModel->getFieldParams() of type array is incompatible with the type integer expected by parameter $templateId of App\Fields\Tree::getValuesById(). ( Ignorable by Annotation )

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

93
		foreach (\App\Fields\Tree::getValuesById(/** @scrutinizer ignore-type */ $this->fieldModel->getFieldParams()) as $value) {
Loading history...
94
			$this->parentTree[$value['tree']] = \App\Fields\Tree::getParentIdx($value);
95
			$label = mb_strtolower($value['label']);
96
			$translated = mb_strtolower(\App\Language::translate($value['label'], $moduleName));
97
			if (isset($values[$label])) {
98
				$values[$label][] = $value['tree'];
99
			} else {
100
				$values[$label] = [$value['tree']];
101
			}
102
			if ($translated !== $label) {
103
				if (isset($values[$translated])) {
104
					$values[$translated][] = $value['tree'];
105
				} else {
106
					$values[$translated] = [$value['tree']];
107
				}
108
			}
109
		}
110
		$this->fieldValues = $values;
111
	}
112
113
	/**
114
	 * Find tree key.
115
	 *
116
	 * @param int $id
117
	 *
118
	 * @return string|null
119
	 */
120
	private function findTree(int $id): ?string
121
	{
122
		if (!isset($this->cache[$id])) {
123
			return null;
124
		}
125
		if (!empty($this->cacheList[$id])) {
126
			return $this->cacheList[$id];
127
		}
128
		$return = '';
129
		$value = $this->cache[$id];
130
		$name = mb_strtolower($value['label']);
131
		$create = empty($this->fieldValues[$name]);
132
		if (!$create) {
133
			if (empty($value['parent'])) {
134
				$create = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $create is dead and can be removed.
Loading history...
135
				foreach ($this->fieldValues[$name] as $parent) {
136
					if (empty($this->parentTree[$parent])) {
137
						$return = $parent;
138
						break;
139
					}
140
				}
141
			} else {
142
				foreach ($this->fieldValues[$name] as $tree) {
143
					if (!empty($this->parentTree[$tree]) && ($parentTree = $this->parentTree[$tree])) {
144
						if ($parentTree === $this->findTree($value['parent'])) {
145
							$return = $tree;
146
							break;
147
						}
148
					}
149
				}
150
			}
151
			if ($return) {
152
				$this->cacheList[$id] = $return;
153
			}
154
		}
155
		return $return;
156
	}
157
158
	/**
159
	 * Get all unit measure from API.
160
	 *
161
	 * @return array|null
162
	 */
163
	private function getAllFromApi(): ?array
164
	{
165
		if (null === $this->cache) {
166
			$this->cache = [];
167
			try {
168
				foreach ($this->getFromApi('Product/GetChildrenGroup/0') as $row) {
169
					$this->cache[$row['tgD_GidNumer']] = [
170
						'label' => $row['tgD_Kod']
171
					];
172
				}
173
			} catch (\Throwable $ex) {
174
				$this->controller->log('Get ' . $this->name, null, $ex);
175
				\App\Log::error("Error during getAllFromApi {$this->name}: \n{$ex->__toString()}", self::LOG_CATEGORY);
176
			}
177
			foreach ($this->cache as $id => $row) {
178
				try {
179
					if ($childrens = $this->getFromApi('Product/GetChildrenGroup/' . $id)) {
180
						foreach ($childrens as $children) {
181
							$this->cache[$children['tgD_GidNumer']] = [
182
								'label' => $children['tgD_Kod'],
183
								'parent' => $id,
184
							];
185
						}
186
					}
187
				} catch (\Throwable $ex) {
188
					$this->controller->log('Get ' . $this->name, null, $ex);
189
					\App\Log::error("Error during getAllFromApi {$this->name}: \n{$ex->__toString()}", self::LOG_CATEGORY);
190
				}
191
			}
192
		}
193
		return $this->cache;
194
	}
195
196
	/** {@inheritdoc} */
197
	public function getYfValue($apiValue, array $field)
198
	{
199
		$this->loadCacheList();
200
		return $this->cacheList[$apiValue] ?? null;
201
	}
202
203
	/** {@inheritdoc} */
204
	public function getApiValue($yfValue, array $field)
205
	{
206
		$this->loadCacheList();
207
		$key = array_search($yfValue, $this->cacheList);
208
		return $key ?? null;
209
	}
210
211
	/**
212
	 * Load cache list.
213
	 *
214
	 * @return void
215
	 */
216
	private function loadCacheList(): void
217
	{
218
		if (empty($this->cacheList)) {
219
			$this->process();
220
		}
221
	}
222
}
223