Completed
Push — master ( 61f3b2...32110c )
by Jean-Christophe
02:56
created

UFileSystem   C

Complexity

Total Complexity 57

Size/Duplication

Total Lines 193
Duplicated Lines 4.15 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 57
c 2
b 1
f 0
lcom 1
cbo 1
dl 8
loc 193
rs 6.433

18 Methods

Rating   Name   Duplication   Size   Complexity  
A glob_recursive() 0 7 2
A deleteAllFilesFromFolder() 0 7 3
A deleteFile() 0 5 2
A safeMkdir() 0 5 2
A cleanPathname() 4 13 4
A cleanFilePathname() 4 10 3
A openReplaceInTemplateFile() 0 7 2
A openReplaceWriteFromTemplateFile() 0 6 2
A replaceFromTemplate() 0 8 2
A replaceWriteFromContent() 0 3 1
A tryToRequire() 0 7 2
A lastModified() 0 3 1
A load() 0 6 2
A save() 0 3 1
A getDirFromNamespace() 0 3 1
B xcopy() 0 20 7
A delTree() 0 7 3
C getLines() 0 53 17

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

1
<?php
2
3
namespace Ubiquity\utils\base;
4
5
/**
6
 * File system utilities
7
 * @author jc
8
 * @version 1.0.0.2
9
 */
10
class UFileSystem {
11
12
	public static function glob_recursive($pattern, $flags=0) {
13
		$files=\glob($pattern, $flags);
14
		foreach ( \glob(\dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir ) {
15
			$files=\array_merge($files, self::glob_recursive($dir . '/' . \basename($pattern), $flags));
16
		}
17
		return $files;
18
	}
19
20
	public static function deleteAllFilesFromFolder($folder) {
21
		$files=\glob($folder . '/*');
22
		foreach ( $files as $file ) {
23
			if (\is_file($file))
24
				\unlink($file);
25
		}
26
	}
27
28
	public static function deleteFile($filename){
29
		if (\file_exists($filename))
30
			return \unlink($filename);
31
		return false;
32
	}
33
34
	public static function safeMkdir($dir) {
35
		if (!\is_dir($dir))
36
			return \mkdir($dir, 0777, true);
37
		return true;
38
	}
39
40
	public static function cleanPathname($path) {
41
		if (UString::isNotNull($path)) {
42 View Code Duplication
			if (DS === "/")
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...
43
				$path=\str_replace("\\", DS, $path);
44
			else
45
				$path=\str_replace("/", DS, $path);
46
			$path=\str_replace(DS . DS, DS, $path);
47
			if (!UString::endswith($path, DS)) {
48
				$path=$path . DS;
49
			}
50
		}
51
		return $path;
52
	}
53
	
54
	public static function cleanFilePathname($path) {
55
		if (UString::isNotNull($path)) {
56 View Code Duplication
			if (DS === "/")
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...
57
				$path=\str_replace("\\", DS, $path);
58
			else
59
				$path=\str_replace("/", DS, $path);
60
			$path=\str_replace(DS . DS, DS, $path);
61
		}
62
		return $path;
63
	}
64
65
	public static function openReplaceInTemplateFile($source, $keyAndValues) {
66
		if (\file_exists($source)) {
67
			$str=\file_get_contents($source);
68
			return self::replaceFromTemplate($str, $keyAndValues);
69
		}
70
		return false;
71
	}
72
73
	public static function openReplaceWriteFromTemplateFile($source, $destination, $keyAndValues) {
74
		if (($str=self::openReplaceInTemplateFile($source, $keyAndValues))) {
75
			return \file_put_contents($destination, $str, LOCK_EX);
76
		}
77
		return false;
78
	}
79
80
	public static function replaceFromTemplate($content, $keyAndValues) {
81
		array_walk($keyAndValues, function (&$item) {
82
			if (\is_array($item))
83
				$item=\implode("\n", $item);
84
		});
85
		$str=\str_replace(array_keys($keyAndValues), array_values($keyAndValues), $content);
86
		return $str;
87
	}
88
89
	public static function replaceWriteFromContent($content, $destination, $keyAndValues) {
90
		return \file_put_contents($destination, self::replaceFromTemplate($content, $keyAndValues), LOCK_EX);
91
	}
92
93
	public static function tryToRequire($file) {
94
		if (\file_exists($file)) {
95
			require_once ($file);
96
			return true;
97
		}
98
		return false;
99
	}
100
101
	public static function lastModified($filename) {
102
		return \filemtime($filename);
103
	}
104
105
	public static function load($filename){
106
		if (\file_exists($filename)) {
107
			return \file_get_contents($filename);
108
		}
109
		return false;
110
	}
111
112
	public static function save($filename,$content,$flags=LOCK_EX){
113
		return \file_put_contents($filename, $content, $flags);
114
	}
115
	
116
	public static function getDirFromNamespace($ns){
117
		return ROOT . DS . str_replace ( "\\", DS, $ns );
118
	}
119
	
120
	public static function xcopy($source, $dest, $permissions = 0755){
121
		if (is_link($source)) {
122
			return symlink(readlink($source), $dest);
123
		}
124
		if (is_file($source)) {
125
			return copy($source, $dest);
126
		}
127
		if (!is_dir($dest)) {
128
			mkdir($dest, $permissions,true);
129
		}
130
		$dir = dir($source);
131
		while (false !== $entry = $dir->read()) {
132
			if ($entry == '.' || $entry == '..') {
133
				continue;
134
			}
135
			self::xcopy("$source/$entry", "$dest/$entry", $permissions);
136
		}
137
		$dir->close();
138
		return true;
139
	}
140
	
141
	public static function delTree($dir) {
142
		$files = array_diff(scandir($dir), array('.','..'));
143
		foreach ($files as $file) {
144
			(is_dir("$dir/$file")) ? self::delTree("$dir/$file") : unlink("$dir/$file");
145
		}
146
		return rmdir($dir);
147
	}
148
	
149
	public static function getLines($filename,$reverse=false,$maxLines=null,$lineCallback=null){
150
		if(file_exists($filename)){
151
			$result=[];
152
			if($reverse && isset($maxLines)){
153
				$fl = fopen($filename, "r");
154
				 for($x_pos = 0, $ln = 0,$lines=[]; fseek($fl, $x_pos, SEEK_END) !== -1; $x_pos--) {
155
					 $char = fgetc($fl);
156
					 if ($char === "\n") {
157
					 	if(is_callable($lineCallback)){
158
					 		$lineCallback($result,$lines[$ln]);
159
					 	}else{
160
					 		$result[]=$lines[$ln];
161
					 	}
162
					 	if(isset($maxLines) && sizeof($result)>=$maxLines){
163
					 		fclose($fl);
164
					 		return $result;
165
					 	}
166
					 $ln++;
167
					 continue;
168
					 }
169
					 $lines[$ln] = $char . ((array_key_exists($ln, $lines)) ? $lines[$ln] : '');
170
				 }
171
				 fclose($fl);
172
				 return $result;
173
			 }else{
174
				$handle = fopen($filename, "r");
175
				if ($handle) {
176
					while (($line = fgets($handle)) !== false) {
177
						if(is_callable($lineCallback)){
178
							$lineCallback($result,$line);
179
						}else{
180
							$result[]=$line;
181
						}
182
						if(isset($maxLines) && sizeof($result)>=$maxLines){
183
							fclose($handle);
184
							if($result){
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
185
								$result=array_reverse($result);
186
							}
187
							return $result;
188
						}
189
					}
190
					fclose($handle);
191
				} else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
192
					// error opening the file.
193
				}
194
				if($reverse){
195
					$result=array_reverse($result);
196
				}
197
				return $result;
198
			}
199
		}
200
		return [];
201
	}
202
}
203