Passed
Push — developer ( f60fa3...82f58d )
by Radosław
32:52
created

Module::isQuickCreateSupported()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
/**
3
 * Basic module model class.
4
 *
5
 * @package Model
6
 *
7
 * @copyright YetiForce Sp. z o.o.
8
 * @license   YetiForce Public License 3.0 (licenses/LicenseEN.txt or yetiforce.com)
9
 * @author    Mariusz Krzaczkowski <[email protected]>
10
 * @author    Radosław Skrzypczak <[email protected]>
11
 */
12
13
namespace YF\Modules\Base\Model;
14
15
use App;
16
use App\Api;
17
18
class Module
19
{
20
	/** @var YF\Modules\Base\Model\Module[] Module model cache. */
21
	protected static $cache;
22
23
	/** @var string Module name. */
24
	protected $moduleName;
25
26
	/** @var array Fields. */
27
	protected $fields = [];
28
29
	/** @var array Fields. */
30
	protected $fieldsForm;
31
32
	/** @var array Data from API fields. */
33
	protected $apiFields;
34
35
	/** @var array Fields models. */
36
	protected $fieldsModels;
37
38
	protected $defaultView = 'ListView';
39
40
	/**
41
	 * Get module model instance.
42
	 *
43
	 * @param string $moduleName
44
	 *
45
	 * @return self
0 ignored issues
show
Documentation introduced by
Should the return type not be \self?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
46
	 */
47
	public static function getInstance(string $moduleName): self
48
	{
49
		if (isset(self::$cache[$moduleName])) {
50
			return self::$cache[$moduleName];
51
		}
52
		$handlerModule = App\Loader::getModuleClassName($moduleName, 'Model', 'Module');
53
		return self::$cache[$moduleName] = new $handlerModule($moduleName);
54
	}
55
56
	/**
57
	 * Constructor  function.
58
	 *
59
	 * @param string $moduleName
60
	 */
61
	public function __construct(string $moduleName)
62
	{
63
		$this->moduleName = $moduleName;
64
	}
65
66
	/**
67
	 * Function to check permission for a Module/Action.
68
	 *
69
	 * @param string $module
70
	 * @param string $action
71
	 *
72
	 * @return bool
73
	 */
74
	public static function isPermittedByModule(string $module, string $action)
75
	{
76
		if (!\App\Session::has('modulePermissions')) {
77
			\App\Session::set('modulePermissions', []);
78
		}
79
		$data = \App\Session::get('modulePermissions');
80
		if (!isset($data[$module])) {
81
			$data[$module] = Api::getInstance()->call($module . '/Privileges');
82
			\App\Session::set('modulePermissions', $data);
83
		}
84
		if (isset($data[$module][$action]) && !empty($data[$module][$action])) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return isset($data[$modu...ata[$module][$action]);.
Loading history...
85
			return true;
86
		}
87
		return false;
88
	}
89
90
	/**
91
	 * unction to check permission for a Module/Action.
92
	 *
93
	 * @param string $action
94
	 *
95
	 * @return bool
96
	 */
97
	public function isPermitted(string $action): bool
98
	{
99
		return self::isPermittedByModule($this->moduleName, $action);
100
	}
101
102
	/**
103
	 * Get fields and blocks.
104
	 *
105
	 * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
106
	 */
107
	public function loadFieldsFromApi(): void
108
	{
109 View Code Duplication
		if (\App\Cache::has('moduleFields', $this->moduleName)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
110
			$data = \App\Cache::get('moduleFields', $this->moduleName);
111
		} else {
112
			$data = Api::getInstance()->call($this->moduleName . '/Fields');
113
			\App\Cache::save('moduleFields', $this->moduleName, $data);
114
		}
115
		$this->apiFields = $data;
116
	}
117
118
	/**
119
	 * Get all blocks.
120
	 *
121
	 * @return array
122
	 */
123
	public function getBlocks(): array
124
	{
125
		if (!isset($this->apiFields['blocks'])) {
126
			$this->loadFieldsFromApi();
127
		}
128
		return $this->apiFields['blocks'];
129
	}
130
131
	/**
132
	 * Get all fields.
133
	 *
134
	 * @return array
135
	 */
136
	public function getFields(): array
137
	{
138
		if (!isset($this->apiFields['fields'])) {
139
			$this->loadFieldsFromApi();
140
		}
141
		return $this->apiFields['fields'];
142
	}
143
144
	/**
145
	 * Get inventory fields.
146
	 *
147
	 * @return array
148
	 */
149
	public function getInventoryFields(): array
150
	{
151
		if (!isset($this->apiFields['inventory'])) {
152
			$this->loadFieldsFromApi();
153
		}
154
		return $this->apiFields['inventory'] ?? [];
155
	}
156
157
	/**
158
	 * Get field by name.
159
	 *
160
	 * @param string $name
161
	 *
162
	 * @return array
163
	 */
164
	public function getField(string $name): array
165
	{
166
		if (!isset($this->apiFields['fields'])) {
167
			$this->loadFieldsFromApi();
168
		}
169
		if (empty($this->apiFields['fields'][$name])) {
170
			throw new \App\Exceptions\AppException("Field not found: {$name}");
171
		}
172
		return $this->apiFields['fields'][$name];
173
	}
174
175
	/**
176
	 * Get field model by name.
177
	 *
178
	 * @param string $name
179
	 *
180
	 * @return \YF\Modules\Base\FieldTypes\BaseField
181
	 */
182
	public function getFieldModel(string $name): \YF\Modules\Base\FieldTypes\BaseField
183
	{
184
		if (!isset($this->fieldsModels[$name])) {
185
			$this->fieldsModels[$name] = Field::getInstance($this->moduleName, $this->getField($name));
186
		}
187
		return $this->fieldsModels[$name];
188
	}
189
190
	/**
191
	 * Get all field names.
192
	 *
193
	 * @return string[]
194
	 */
195
	public function getFieldNames(): array
196
	{
197
		if (!isset($this->apiFields['fields'])) {
198
			$this->loadFieldsFromApi();
199
		}
200
		return array_keys($this->apiFields['fields']);
201
	}
202
203
	/**
204
	 * Get form fields models.
205
	 *
206
	 * @return \YF\Modules\Base\FieldTypes\BaseField[]
207
	 */
208
	public function getFormFields(): array
209
	{
210
		if (empty($this->fieldsForm)) {
211
			$this->loadFieldsModels();
212
		}
213
		return $this->fieldsForm;
214
	}
215
216
	/**
217
	 * Get fields models.
218
	 *
219
	 * @return \YF\Modules\Base\FieldTypes\BaseField[]
220
	 */
221
	public function getFieldsModels(): array
222
	{
223
		if (empty($this->fieldsForm)) {
224
			$this->loadFieldsModels();
225
		}
226
		return $this->fieldsModels;
227
	}
228
229
	/**
230
	 * Load all fields models.
231
	 *
232
	 * @return void
233
	 */
234
	public function loadFieldsModels(): void
235
	{
236
		if (!isset($this->apiFields['fields'])) {
237
			$this->loadFieldsFromApi();
238
		}
239
		$fields = $fieldsForm = [];
240
		foreach ($this->apiFields['fields'] as $fieldName => $field) {
241
			$this->fieldsModels[$fieldName] = $fieldInstance = Field::getInstance($this->moduleName, $field);
242
			if ($field['isEditable']) {
243
				$fieldsForm[$field['blockId']][$fieldName] = $fieldInstance;
244
			}
245
			$fields[$fieldName] = $fieldInstance;
246
		}
247
		$this->fieldsModels = $fields;
248
		$this->fieldsForm = $fieldsForm;
249
	}
250
251
	/**
252
	 * Get tabs.
253
	 *
254
	 * @param int $record
255
	 *
256
	 * @return array
257
	 */
258
	public function getTabsFromApi(int $record): array
259
	{
260
		if (\App\Cache::has('moduleTabs', $this->moduleName)) {
261
			$data = \App\Cache::get('moduleTabs', $this->moduleName);
262
		} else {
263
			$data = Api::getInstance()->call($this->moduleName . '/RelatedModules');
264
			\App\Cache::save('moduleTabs', $this->moduleName, $data, \App\Cache::LONG);
265
		}
266
		$url = "index.php?module={$this->moduleName}&view=DetailView&record={$record}";
267
		foreach ($data['base'] as &$row) {
268
			$row['tabId'] = $row['type'];
269
			$row['url'] = "{$url}&tabId={$row['tabId']}&mode={$row['type']}";
270
		}
271
		foreach ($data['related'] as &$row) {
272
			$row['tabId'] = 'rel' . $row['relationId'];
273
			$row['url'] = "{$url}&tabId={$row['tabId']}&mode=relatedList&relationId={$row['relationId']}&relatedModuleName={$row['relatedModuleName']}";
274
		}
275
		return $data;
276
	}
277
278
	/**
279
	 * Returns default view for module.
280
	 *
281
	 * @return string
282
	 */
283
	public function getDefaultView(): string
284
	{
285
		return $this->defaultView;
286
	}
287
288
	/**
289
	 * Returns default address url.
290
	 *
291
	 * @return string
292
	 */
293
	public function getDefaultUrl(): string
294
	{
295
		return "index.php?module={$this->moduleName}&view={$this->getDefaultView()}";
296
	}
297
298
	/**
299
	 * Function to check is quick create supported.
300
	 *
301
	 * @return bool
302
	 */
303
	public function isQuickCreateSupported(): bool
304
	{
305
		return true;
306
	}
307
}
308