Completed
Pull Request — master (#274)
by Victor
02:16
created

FilesystemHelper   B

Complexity

Total Complexity 40

Size/Duplication

Total Lines 183
Duplicated Lines 3.28 %

Coupling/Cohesion

Components 0
Dependencies 1

Test Coverage

Coverage 0%

Importance

Changes 6
Bugs 1 Features 1
Metric Value
wmc 40
c 6
b 1
f 1
lcom 0
cbo 1
dl 6
loc 183
ccs 0
cts 88
cp 0
rs 8.2608

13 Methods

Rating   Name   Duplication   Size   Complexity  
A filemtime() 0 3 1
A scandir() 0 3 1
A fileExists() 0 3 1
A isWritable() 0 3 1
A isDir() 0 3 1
A md5File() 0 3 1
A mkdir() 0 5 2
C copyr() 0 23 10
A move() 0 5 2
B checkr() 0 19 7
A removeIfExists() 0 11 3
B rmdirr() 0 18 7
A tripleMove() 6 8 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

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

1
<?php
2
/**
3
 * @author Victor Dubiniuk <[email protected]>
4
 *
5
 * @copyright Copyright (c) 2015, ownCloud, Inc.
6
 * @license AGPL-3.0
7
 *
8
 * This code is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License, version 3,
10
 * as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License, version 3,
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
19
 *
20
 */
21
22
namespace Owncloud\Updater\Utils;
23
24
class FilesystemHelper {
25
26
	/**
27
	 * Wrapper for filemtime function
28
	 * @param string $path
29
	 * @return array
30
	 */
31
	public function filemtime($path){
32
		return filemtime($path);
33
	}
34
35
	/**
36
	 * Wrapper for scandir function
37
	 * @param string $path
38
	 * @return array
39
	 */
40
	public function scandir($path){
41
		return scandir($path);
42
	}
43
44
	/**
45
	 * Wrapper for file_exists function
46
	 * @param string $path
47
	 * @return bool
48
	 */
49
	public function fileExists($path){
50
		return file_exists($path);
51
	}
52
53
	/**
54
	 * Wrapper for is_writable function
55
	 * @param string $path
56
	 * @return bool
57
	 */
58
	public function isWritable($path){
59
		return is_writable($path);
60
	}
61
62
	/**
63
	 * Wrapper for is_dir function
64
	 * @param string $path
65
	 * @return bool
66
	 */
67
	public function isDir($path){
68
		return is_dir($path);
69
	}
70
71
	/**
72
	 * Wrapper for md5_file function
73
	 * @param string $path
74
	 * @return string
75
	 */
76
	public function md5File($path){
77
		return md5_file($path);
78
	}
79
80
	/**
81
	 * Wrapper for mkdir
82
	 * @param string $path
83
	 * @param bool $isRecursive
84
	 * @throws \Exception on error
85
	 */
86
	public function mkdir($path, $isRecursive = false){
87
		if (!mkdir($path, 0755, $isRecursive)){
88
			throw new \Exception("Unable to create $path");
89
		}
90
	}
91
92
	/**
93
	 * Copy recursive
94
	 * @param string $src  - source path
95
	 * @param string $dest - destination path
96
	 * @throws \Exception on error
97
	 */
98
	public function copyr($src, $dest, $stopOnError = true){
99
		if (is_dir($src)){
100
			if (!is_dir($dest)){
101
				try{
102
					$this->mkdir($dest);
103
				} catch (\Exception $e){
104
					if ($stopOnError){
105
						throw $e;
106
					}
107
				}
108
			}
109
			$files = scandir($src);
110
			foreach ($files as $file){
111
				if (!in_array($file, [".", ".."])){
112
					$this->copyr("$src/$file", "$dest/$file", $stopOnError);
113
				}
114
			}
115
		} elseif (file_exists($src)){
116
			if (!copy($src, $dest) && $stopOnError){
117
				throw new \Exception("Unable to copy $src to $dest");
118
			}
119
		}
120
	}
121
122
	/**
123
	 * Moves file/directory
124
	 * @param string $src  - source path
125
	 * @param string $dest - destination path
126
	 * @throws \Exception on error
127
	 */
128
	public function move($src, $dest){
129
		if (!rename($src, $dest)){
130
			throw new \Exception("Unable to move $src to $dest");
131
		}
132
	}
133
134
	/**
135
	 * Check permissions recursive
136
	 * @param string $src  - path to check
137
	 * @param Collection $collection - object to store incorrect permissions
138
	 */
139
	public function checkr($src, $collection){
140
		if (!file_exists($src)){
141
			return;
142
		}
143
		if (!is_writable($src)){
144
			$collection->addNotWritable($src);
145
		}
146
		if (!is_readable($src)){
147
			$collection->addNotReadable($src);
148
		}
149
		if (is_dir($src)){
150
			$files = scandir($src);
151
			foreach ($files as $file){
152
				if (!in_array($file, [".", ".."])){
153
					$this->checkr("$src/$file", $collection);
154
				}
155
			}
156
		}
157
	}
158
159
	public function removeIfExists($path) {
160
		if (!file_exists($path)) {
161
			return;
162
		}
163
164
		if (is_dir($path)) {
165
			$this->rmdirr($path);
166
		} else {
167
			@unlink($path);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
168
		}
169
	}
170
171
	protected function rmdirr($dir) {
172
		if(is_dir($dir)) {
173
			$files = scandir($dir);
174
			foreach($files as $file) {
175
				if ($file != "." && $file != "..") {
176
					$this->rmdirr("$dir/$file");
177
				}
178
			}
179
			@rmdir($dir);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
180
		}elseif(file_exists($dir)) {
181
			@unlink($dir);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
182
		}
183
		if(file_exists($dir)) {
184
			return false;
185
		}else{
186
			return true;
187
		}
188
	}
189
190
	/**
191
	 *
192
	 * @param string $old
193
	 * @param string $new
194
	 * @param string $temp
195
	 * @param string $dirName
196
	 */
197
	public function tripleMove($old, $new, $temp, $dirName){
198 View Code Duplication
		if ($this->fileExists($old . '/' . $dirName)){
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...
199
			$this->move($old . '/' . $dirName, $temp . '/' . $dirName);
200
		}
201 View Code Duplication
		if ($this->fileExists($new . '/' . $dirName)){
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...
202
			$this->move($new . '/' . $dirName, $old . '/' . $dirName);
203
		}
204
	}
205
206
}
207