Completed
Push — master ( fba9d9...4cd89c )
by Lorenzo
02:36
created

FileHelper   B

Complexity

Total Complexity 49

Size/Duplication

Total Lines 317
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 49
lcom 1
cbo 1
dl 0
loc 317
rs 8.5454
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
B getPathinfoPart() 0 13 9
A getDirname() 0 4 1
A getFilename() 0 4 1
A getFilenameWithoutExtension() 0 4 1
A getFilenameExtension() 0 4 1
A unlinkSafe() 0 12 3
A fileExistsSafe() 0 12 4
C findFiles() 0 43 13
C filePutContentsSafe() 0 29 7
A getMimeType() 0 17 4
A getMimeTypeByFinfo() 0 13 3
A getMimeTypeByMimeContentType() 0 7 2

How to fix   Complexity   

Complex Class

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

1
<?php
2
3
namespace Padosoft\Io;
4
5
/**
6
 * Helper Class FileHelper
7
 * @package Padosoft\Io
8
 */
9
class FileHelper
10
{
11
    public static $arrMimeType = array(
12
13
        'txt' => 'text/plain',
14
        'htm' => 'text/html',
15
        'html' => 'text/html',
16
        'php' => 'text/html',
17
        'css' => 'text/css',
18
        'js' => 'application/javascript',
19
        'json' => 'application/json',
20
        'xml' => 'application/xml',
21
        'swf' => 'application/x-shockwave-flash',
22
        'flv' => 'video/x-flv',
23
24
        // images
25
        'png' => 'image/png',
26
        'jpe' => 'image/jpeg',
27
        'jpeg' => 'image/jpeg',
28
        'jpg' => 'image/jpeg',
29
        'gif' => 'image/gif',
30
        'bmp' => 'image/bmp',
31
        'ico' => 'image/vnd.microsoft.icon',
32
        'tiff' => 'image/tiff',
33
        'tif' => 'image/tiff',
34
        'svg' => 'image/svg+xml',
35
        'svgz' => 'image/svg+xml',
36
37
        // archives
38
        'zip' => 'application/zip',
39
        'rar' => 'application/x-rar-compressed',
40
        'exe' => 'application/x-msdownload',
41
        'msi' => 'application/x-msdownload',
42
        'cab' => 'application/vnd.ms-cab-compressed',
43
44
        // audio/video
45
        'mp3' => 'audio/mpeg',
46
        'qt' => 'video/quicktime',
47
        'mov' => 'video/quicktime',
48
49
        // adobe
50
        'pdf' => 'application/pdf',
51
        'psd' => 'image/vnd.adobe.photoshop',
52
        'ai' => 'application/postscript',
53
        'eps' => 'application/postscript',
54
        'ps' => 'application/postscript',
55
56
        // ms office
57
        'doc' => 'application/msword',
58
        'rtf' => 'application/rtf',
59
        'xls' => 'application/vnd.ms-excel',
60
        'ppt' => 'application/vnd.ms-powerpoint',
61
62
        // open office
63
        'odt' => 'application/vnd.oasis.opendocument.text',
64
        'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
65
    );
66
67
    /**
68
     * Simple pathinfo wrapper.
69
     * @param string $filePath
70
     * @param int $fileInfOoptions
71
     * @return string
72
     * @see http://php.net/manual/en/function.pathinfo.php
73
     */
74
    public static function getPathinfoPart(string $filePath, int $fileInfOoptions) : string
75
    {
76
        if ($filePath === null || $filePath == '' || is_dir($filePath) || DirHelper::endsWithSlash($filePath)) {
77
            return '';
78
        }
79
80
        $info = pathinfo($filePath, $fileInfOoptions);
81
82
        if ($info == '.' && $fileInfOoptions == PATHINFO_DIRNAME) {
83
            return '';
84
        }
85
        return ($info !== null && $info != '') ? $info : '';
86
    }
87
88
    /**
89
     * Return the file name of file (without path and without extension).
90
     * Return empty string if $filePath is null, empty or is a directory.
91
     * Ex.: /public/upload/pippo.txt return '/public/upload'
92
     * @param string $filePath
93
     * @return string
94
     */
95
    public static function getDirname(string $filePath) : string
96
    {
97
        return self::getPathinfoPart($filePath, PATHINFO_DIRNAME);
98
    }
99
100
    /**
101
     * Return the file name of file (without path and with extension).
102
     * Return empty string if $filePath is null, empty or is a directory.
103
     * Ex.: /public/upload/pippo.txt return 'pippo.txt'
104
     * @param string $filePath
105
     * @return string
106
     */
107
    public static function getFilename(string $filePath) : string
108
    {
109
        return self::getPathinfoPart($filePath, PATHINFO_BASENAME);
110
    }
111
112
    /**
113
     * Return the file name of file (without path and without extension).
114
     * Return empty string if $filePath is null, empty or is a directory.
115
     * Ex.: /public/upload/pippo.txt return 'pippo'
116
     * @param string $filePath
117
     * @return string
118
     */
119
    public static function getFilenameWithoutExtension(string $filePath) : string
120
    {
121
        return self::getPathinfoPart($filePath, PATHINFO_FILENAME);
122
    }
123
124
    /**
125
     * Return the file name of file (without path and without extension).
126
     * Return empty string if $filePath is null, empty or is a directory.
127
     * Ex.: /public/upload/pippo.txt return '.txt'
128
     * @param string $filePath
129
     * @return string
130
     */
131
    public static function getFilenameExtension(string $filePath) : string
132
    {
133
        return self::getPathinfoPart($filePath, PATHINFO_EXTENSION);
134
    }
135
136
    /**
137
     * unlink file if exists.
138
     * Return false if exists and unlink fails or if filePath is a dir.
139
     * @param string $filePath
140
     * @return bool
141
     */
142
    public static function unlinkSafe(string $filePath) : bool
143
    {
144
        if (!FileHelper::fileExistsSafe($filePath)) {
145
            return false;
146
        }
147
148
        if (DirHelper::isDirSafe($filePath)) {
149
            return false;
150
        }
151
152
        return unlink($filePath);
153
    }
154
155
    /**
156
     * Check if passed file exists or not.
157
     * If dir passed return false.
158
     * @param string $filePath
159
     * @return bool
160
     */
161
    public static function fileExistsSafe(string $filePath) : bool
162
    {
163
        if ($filePath === null || $filePath == '') {
164
            return false;
165
        }
166
167
        if (DirHelper::isDirSafe($filePath)) {
168
            return false;
169
        }
170
171
        return file_exists($filePath);
172
    }
173
174
    /**
175
     * Find files matching a pattern (recursive with matched files in subdirs).
176
     * Returns an array containing the matched files (full path and not directories),
177
     * an empty array if no file matched or on error.
178
     * @param string $fileNamePattern if is null it set to base_path()/* if exists otherwise __DIR__/* . It support glob() string pattern.
179
     * @param int $flags glob() Valid flags
180
     * @return array of files (full path)
181
     */
182
    public static function findFiles(string $fileNamePattern, int $flags = 0)
183
    {
184
        $fallback = [];
185
186
        if (($fileNamePattern === null || $fileNamePattern == '') && function_exists('base_path')) {
187
            $fileNamePattern = DirHelper::addFinalSlash(base_path()) . '*';
188
        } elseif ($fileNamePattern === null || $fileNamePattern == '') {
189
            $fileNamePattern = __DIR__ . '/*';
190
        }
191
192
        if (DirHelper::endsWithSlash($fileNamePattern)) {
193
            $fileNamePattern .= '*';
194
        }
195
196
        $files = glob($fileNamePattern, $flags);
197
198
        //remove array of empty string
199
        $files = array_filter($files, function ($k) {
200
            return ($k !== null && $k != '');
201
        });
202
203
        if (empty($files)) {
204
            return $fallback;
205
        }
206
207
        foreach (glob(dirname($fileNamePattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
208
209
            if (empty($dir)) {
210
                continue;
211
            }
212
213
            $files = array_merge($files, self::findFiles($dir . '/' . basename($fileNamePattern), $flags));
214
            $files = array_filter($files, function ($k) {
215
                return ($k !== null && $k != '');
216
            });
217
        }
218
219
        $files = array_filter($files, function ($k) {
220
            return (!is_dir($k));
221
        });
222
223
        return $files === false ? $fallback : $files;
224
    }
225
226
    /**
227
     * Equals to file_put_contents but safe, i.e.
228
     * accept empty string and return false without raise an error,
229
     * accept a directory and return false without raise an error,
230
     * and if $forceCreateDirIfNotExists is set to true and path doesn't exists, file_put_contents fails
231
     * so, this class, try to create the complete path before save file.
232
     * @param string $filename file name including folder.
233
     * example :: /path/to/file/filename.ext or filename.ext
234
     * @param string $data The data to write.
235
     * @param bool $forceCreateDirIfNotExists if true and path not exists, try to create it.
236
     * @param string $modeMask The mask applied to dir if need to create some dir.
237
     * @param int $flags same flags used for file_put_contents.
238
     * @see more info: http://php.net/manual/en/function.file-put-contents.php
239
     * @return bool TRUE file created succesfully, return FALSE if failed to create file.
240
     */
241
    public static function filePutContentsSafe(
242
        string $filename,
243
        string $data,
244
        bool $forceCreateDirIfNotExists = true,
245
        string $modeMask = '0755',
246
        int $flags = 0
247
    ) : bool
248
    {
249
        if ($filename === null || $filename == '') {
250
            return false;
251
        }
252
253
        //check if a directory passed ($filename ends with slash)
254
        if (DirHelper::endsWithSlash($filename)) {
255
            return false;
256
        }
257
258
        $dirName = dirname($filename);
259
260
        if (!$forceCreateDirIfNotExists && !DirHelper::isDirSafe($dirName)) {
261
            return false;
262
        }
263
264
        if (!DirHelper::checkDirExistOrCreate(DirHelper::addFinalSlash($dirName), $modeMask)) {
265
            return false;
266
        }
267
268
        return file_put_contents($filename, $data, $flags);
269
    }
270
271
    /**
272
     * Return mime type of a passed file in optimized mode.
273
     * @param string $fullPathFile
274
     * @return string
275
     */
276
    public static function getMimeType(string $fullPathFile) : string
277
    {
278
        $mime_types = self::$arrMimeType;
279
        $ext = strtolower(self::getFilenameExtension($fullPathFile));
280
        if (array_key_exists($ext, $mime_types)) {
281
            return $mime_types[$ext];
282
        }
283
        $mimetype = self::getMimeTypeByMimeContentType($fullPathFile);
284
        if (isNotNullOrEmpty($mimetype)) {
285
            return $mimetype;
286
        }
287
        $mimetype = self::getMimeTypeByFinfo($fullPathFile);
288
        if (isNotNullOrEmpty($mimetype)) {
289
            return $mimetype;
290
        }
291
        return 'application/octet-stream';
292
    }
293
294
    /**
295
     * Return mime type of a passed file using finfo
296
     * @param string $fullPathFile
297
     * @return string return empty string if it fails.
298
     */
299
    public static function getMimeTypeByFinfo(string $fullPathFile) : string
300
    {
301
        if (!function_exists('finfo_open')) {
302
            return '';
303
        }
304
        $finfo = finfo_open(FILEINFO_MIME);
305
        $mimetype = finfo_file($finfo, $fullPathFile);
306
        finfo_close($finfo);
307
        if ($mimetype === false) {
308
            return '';
309
        }
310
        return $mimetype;
311
    }
312
313
    /**
314
     * Return mime type of a passed file using mime_content_type()
315
     * @param string $fullPathFile
316
     * @return string return empty string if it fails.
317
     */
318
    public static function getMimeTypeByMimeContentType(string $fullPathFile) : string
319
    {
320
        if (!function_exists('mime_content_type')) {
321
            return '';
322
        }
323
        return mime_content_type($fullPathFile);
324
    }
325
}
326