Entity   C
last analyzed

Complexity

Total Complexity 55

Size/Duplication

Total Lines 332
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 332
rs 6.8
c 0
b 0
f 0
wmc 55
lcom 1
cbo 2

23 Methods

Rating   Name   Duplication   Size   Complexity  
B getPrototype() 0 14 6
A __construct() 0 4 1
A init() 0 20 4
A check() 0 10 4
C create() 0 22 7
B rename() 0 16 5
A remove() 0 18 4
A getExtension() 0 6 2
A getCreated() 0 6 2
A getAccessed() 0 6 2
A getModified() 0 6 2
A getPermissions() 0 6 2
A getSize() 0 6 2
A getContents() 0 6 2
A putContents() 0 6 2
A isInited() 0 4 1
A isDir() 0 4 1
A isFile() 0 4 1
A getParent() 0 4 1
A getName() 0 4 1
A getPath() 0 4 1
A getPathFull() 0 4 1
A getType() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like Entity 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 Entity, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * @package Cadmium\System\Modules\Filemanager
5
 * @author Anton Romanov
6
 * @copyright Copyright (c) 2015-2017, Anton Romanov
7
 * @link http://cadmium-cms.com
8
 */
9
10
namespace Modules\Filemanager\Utils {
11
12
	use Explorer;
13
14
	class Entity {
15
16
		private $parent = null, $name = '', $path = '', $path_full = '', $type = '';
17
18
		/**
19
		 * Get entity prototype data
20
		 *
21
		 * @return array|false : the data array or false if the name is invalid
22
		 */
23
24
		private function getPrototype(string $name) {
25
26
			if (('' === $name) || preg_match('/[\/\\\\]/', $name)) return false;
27
28
			if ($this->parent->isIgnoreHidden() && preg_match('/^\./', $name)) return false;
29
30
			$path = (($this->parent->getPath() ? ($this->parent->getPath() . '/') : '') . $name);
31
32
			$path_full = ($this->parent->getPathFull() . $name);
33
34
			# ------------------------
35
36
			return ['name' => $name, 'path' => $path, 'path_full' => $path_full];
37
		}
38
39
		/**
40
		 * Constructor
41
		 */
42
43
		public function __construct(Container $parent, string $name = '') {
44
45
			$this->parent = $parent; $this->init($name);
46
		}
47
48
		/**
49
		 * Initialize the entity by a directory/file name
50
		 *
51
		 * @return bool : true on success or false if a corresponding directory/file does not exist
52
		 */
53
54
		public function init(string $name) : bool {
55
56
			if (false === ($prototype = $this->getPrototype($name))) return false;
57
58
			# Check type
59
60
			$type = Explorer::getType($prototype['path_full']);
61
62
			if (!in_array($type, ['dir', 'file'], true)) return false;
63
64
			# Set data
65
66
			foreach ($prototype as $var => $value) $this->$var = $value;
67
68
			$this->type = $type;
0 ignored issues
show
Documentation Bug introduced by
It seems like $type can also be of type false. However, the property $type is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
69
70
			# ------------------------
71
72
			return true;
73
		}
74
75
		/**
76
		 * Check whether another entity with a given name exists in the same parent directory.
77
		 * This method is useful to find out is it possible to create or rename the entity
78
		 *
79
		 * @return bool : true if the check has been successful and no other items with the given name found, otherwise false
80
		 */
81
82
		public function check(string $name) : bool {
83
84
			if (false === ($prototype = $this->getPrototype($name))) return false;
85
86
			if (($name !== $this->name) && Explorer::exists($prototype['path_full'])) return false;
87
88
			# ------------------------
89
90
			return true;
91
		}
92
93
		/**
94
		 * Create the entity
95
		 *
96
		 * @return bool : true on success or false on failure
97
		 */
98
99
		public function create(string $name, string $type) : bool {
100
101
			if (('' !== $this->name) || (false === ($prototype = $this->getPrototype($name)))) return false;
102
103
			if (!in_array($type, ['dir', 'file'], true)) return false;
104
105
			# Create entity
106
107
			$create = (($type === 'dir') ? 'createDir' : 'createFile');
108
109
			if (!Explorer::$create($prototype['path_full'])) return false;
110
111
			# Set data
112
113
			foreach ($prototype as $var => $value) $this->$var = $value;
114
115
			$this->type = $type;
116
117
			# ------------------------
118
119
			return true;
120
		}
121
122
		/**
123
		 * Rename the entity
124
		 *
125
		 * @return bool : true on success or false on failure
126
		 */
127
128
		public function rename(string $name) : bool {
129
130
			if (('' === $this->name) || (false === ($prototype = $this->getPrototype($name)))) return false;
131
132
			# Rename entity
133
134
			if (!Explorer::rename($this->path_full, $prototype['path_full'])) return false;
135
136
			# Set data
137
138
			foreach ($prototype as $var => $value) $this->$var = $value;
139
140
			# ------------------------
141
142
			return true;
143
		}
144
145
		/**
146
		 * Remove the entity
147
		 *
148
		 * @return bool : true on success or false on failure
149
		 */
150
151
		public function remove() : bool {
152
153
			if ('' === $this->name) return false;
154
155
			# Remove entity
156
157
			$remove = (($this->type === 'dir') ? 'removeDir' : 'removeFile');
158
159
			if (!Explorer::$remove($this->path_full, true)) return false;
160
161
			# Reset data
162
163
			$this->name = ''; $this->path = ''; $this->path_full = ''; $this->type = '';
164
165
			# ------------------------
166
167
			return true;
168
		}
169
170
		/**
171
		 * Get the entity extension in lower case
172
		 *
173
		 * @return string|false : the extension or false on failure
174
		 */
175
176
		public function getExtension() {
177
178
			if ('' === $this->name) return false;
179
180
			return strtolower(Explorer::getExtension($this->name, false));
181
		}
182
183
		/**
184
		 * Get the entity creation time
185
		 *
186
		 * @return int|false : the time or false on failure
187
		 */
188
189
		public function getCreated() {
190
191
			if ('' === $this->name) return false;
192
193
			return Explorer::getCreated($this->path_full);
194
		}
195
196
		/**
197
		 * Get the entity access time
198
		 *
199
		 * @return int|false : the time or false on failure
200
		 */
201
202
		public function getAccessed() {
203
204
			if ('' === $this->name) return false;
205
206
			return Explorer::getAccessed($this->path_full);
207
		}
208
209
		/**
210
		 * Get the entity modification time
211
		 *
212
		 * @return int|false : the time or false on failure
213
		 */
214
215
		public function getModified() {
216
217
			if ('' === $this->name) return false;
218
219
			return Explorer::getModified($this->path_full);
220
		}
221
222
		/**
223
		 * Get the entity permissions
224
		 *
225
		 * @return int|false : the permissions or false on failure
226
		 */
227
228
		public function getPermissions() {
229
230
			if ('' === $this->name) return false;
231
232
			return Explorer::getPermissions($this->path_full);
233
		}
234
235
		/**
236
		 * Get the entity size
237
		 *
238
		 * @return int|false : the size or false on failure
239
		 */
240
241
		public function getSize() {
242
243
			if ('' === $this->name) return false;
244
245
			return Explorer::getSize($this->path_full);
246
		}
247
248
		/**
249
		 * Get the file contents
250
		 *
251
		 * @return string|false : the read data or false on failure
252
		 */
253
254
		public function getContents() {
255
256
			if ('' === $this->name) return false;
257
258
			return Explorer::getContents($this->path_full);
259
		}
260
261
		/**
262
		 * Save data into the file
263
		 *
264
		 * @return int|false : the number of bytes that were written to the file or false on failure
265
		 */
266
267
		public function putContents(string $contents) {
268
269
			if ('' === $this->name) return false;
270
271
			return Explorer::putContents($this->path_full, $contents);
272
		}
273
274
		/**
275
		 * Check if the entity has been successfully initialized
276
		 */
277
278
		public function isInited() : bool {
279
280
			return ('' !== $this->name);
281
		}
282
283
		/**
284
		 * Check if the entity is a directory
285
		 */
286
287
		public function isDir() : bool {
288
289
			return ($this->type === 'dir');
290
		}
291
292
		/**
293
		 * Check if the entity is a file
294
		 */
295
296
		public function isFile() : bool {
297
298
			return ($this->type === 'file');
299
		}
300
301
		/**
302
		 * Get the entity parent
303
		 */
304
305
		public function getParent() : Container {
306
307
			return $this->parent;
308
		}
309
310
		/**
311
		 * Get the entity name
312
		 */
313
314
		public function getName() : string {
315
316
			return $this->name;
317
		}
318
319
		/**
320
		 * Get the entity relative path
321
		 */
322
323
		public function getPath() : string {
324
325
			return $this->path;
326
		}
327
328
		/**
329
		 * Get the entity full path
330
		 */
331
332
		public function getPathFull() : string {
333
334
			return $this->path_full;
335
		}
336
337
		/**
338
		 * Get the entity type
339
		 */
340
341
		public function getType() : string {
342
343
			return $this->type;
344
		}
345
	}
346
}
347