Completed
Push — master ( edab46...759e1c )
by Lorenzo
01:54
created

DirHelper::checkDirExistOrCreate()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.2
c 0
b 0
f 0
cc 4
eloc 6
nc 4
nop 2
1
<?php
2
3
namespace Padosoft\Io;
4
5
/**
6
 * Helper Class DirHelper
7
 * @package Padosoft\Io
8
 */
9
class DirHelper
10
{
11
    /**
12
     * Check if passed path exists or not.
13
     * @param string $filePath
14
     * @return bool
15
     */
16
    public static function isDirSafe(string $filePath) : bool
17
    {
18
        if (!$filePath) {
19
            return false;
20
        }
21
22
        return is_dir($filePath);
23
    }
24
25
    /**
26
     * Check if passed path exists or try to create it.
27
     * Return false if it fails to create it or if a file (and not a dir) passed as argument.
28
     * @param string $filePath
29
     * @param string $modeMask default '0755'
30
     * @return bool
31
     */
32
    public static function checkDirExistOrCreate(string $filePath, string $modeMask = '0755') : bool
33
    {
34
        if (self::isDirSafe($filePath)) {
35
            return true;
36
        }
37
38
        //controllo adesso che non sia un file
39
        if (FileHelper::fileExistsSafe($filePath)) {
40
            return false;
41
        }
42
43
        return mkdir($filePath, $modeMask, true) && self::isDirSafe($filePath);
44
    }
45
46
    /**
47
     * If dir passed, check if finishes with '/' otherwise append a slash to path.
48
     * If wrong or empty string passed, return '/'.
49
     * @param string $path
50
     * @return string
51
     */
52
    public static function addFinalSlash(string $path) : string
53
    {
54
        if ($path === null || $path == '') {
55
            return '/';
56
        }
57
58
        $quoted = preg_quote('/', '/');
59
        $path = preg_replace('/(?:' . $quoted . ')+$/', '', $path) . '/';
60
61
        return $path;
62
    }
63
64
    /**
65
     * for each dir passed in array, check if it finishes with '/' otherwise append a slash to path.
66
     * If not dir, leave the element untouched.
67
     * @param array $paths
68
     * @return array
69
     */
70
    public static function addFinalSlashToAllPaths(array $paths) : array
71
    {
72
        if (empty($paths)) {
73
            return [];
74
        }
75
76
        return array_map('self::addFinalSlash', $paths);
77
    }
78
79
    /**
80
     * Check if path ends with slash '/'
81
     * @param string $paths
82
     * @return bool
83
     */
84
    public static function endsWithSlash(string $paths) : bool
85
    {
86
        return self::endsWith($paths, '/');
87
    }
88
89
    /**
90
     * Check if path ends with star '*'
91
     * @param string $paths
92
     * @return bool
93
     */
94
    public static function endsWithStar(string $paths) : bool
95
    {
96
        return self::endsWith($paths, '*');
97
    }
98
99
    /**
100
     * Check if path ends with $needle
101
     * @param string $paths
102
     * @param string $needle
103
     * @return bool
104
     */
105
    public static function endsWith(string $paths, string $needle) : bool
106
    {
107
        if ($paths === null || $paths == '') {
108
            return false;
109
        }
110
        if ($needle === null || $needle == '') {
111
            return false;
112
        }
113
114
        // search forward starting from end minus needle length characters
115
        // see: http://stackoverflow.com/questions/834303/startswith-and-endswith-functions-in-php
116
        return (($temp = strlen($paths) - strlen($needle)) >= 0 && strpos($paths, $needle, $temp) !== false);
117
    }
118
119
    /**
120
     * Check if path starts with slash '/'
121
     * @param string $paths
122
     * @return bool
123
     */
124
    public static function startsWithSlash(string $paths) : bool
125
    {
126
        return self::startsWith($paths, '/');
127
    }
128
129
    /**
130
     * Check if path starts with slash $needle
131
     * @param string $paths
132
     * @param string $needle
133
     * @return bool
134
     */
135
    public static function startsWith(string $paths, string $needle) : bool
136
    {
137
        if ($paths === null || $paths == '') {
138
            return false;
139
        }
140
        if ($needle === null || $needle == '') {
141
            return false;
142
        }
143
144
        // search backwards starting from haystack length characters from the end
145
        // see: http://stackoverflow.com/questions/834303/startswith-and-endswith-functions-in-php
146
        return strrpos($paths, $needle, -strlen($paths)) !== false;
147
    }
148
149
    /**
150
     * Find dirs matching a pattern (recursive with subdirs).
151
     * Returns an array containing the matched dirs (full path and not files),
152
     * an empty array if no dir matched or on error.
153
     * @param string $pathPattern if is null it set to base_path()/* if exists otherwise __DIR__/*. It support glob() string pattern.
154
     * @return array of dirs
155
     */
156
    public static function findDirs(string $pathPattern)
157
    {
158
        if (($pathPattern === null || $pathPattern == '') && function_exists('base_path')) {
159
            $pathPattern = base_path() . '/*';
160
        } elseif ($pathPattern === null || $pathPattern == '') {
161
            $pathPattern = __DIR__ . '/*';
162
        } elseif (!self::endsWithStar($pathPattern)) {
163
            $pathPattern = DirHelper::addFinalSlash($pathPattern);
164
        }
165
166
        $files = glob($pathPattern, GLOB_ONLYDIR);
167
168
        foreach (glob(dirname($pathPattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
169
            $files = array_merge($files, self::findDirs($dir . '/' . basename($pathPattern)));
170
        }
171
172
        return $files;
173
    }
174
175
    /**
176
     * Dir::Delete()
177
     * get a dir path and remove all files and subdir in this dir.
178
     * if $not_remove_dir==TRUE then when finish DO NOT REMOVE THE $directory dir.
179
     * @param string $directory directory to empty
180
     * @param bool $not_remove_dir TRUE if DO NOT REMOVE THE $directory dir but only files.
181
     * @return bool TRUE if success, otherwise FALSE
182
     **/
183
    public static function delete($directory, bool $not_remove_dir = false) : bool
184
    {
185
        $directory = self::removeFinalSlash($directory);
186
187
        if (!self::isDirSafe($directory) || !is_readable($directory)) {
188
            return false;
189
        }
190
191
        $directoryHandle = opendir($directory);
192
        while ($contents = readdir($directoryHandle)) {
193
            if ($contents == '.' || $contents == '..') {
194
                continue;
195
            }
196
            $path = $directory . "/" . $contents;
197
198
            if (is_dir($path)) {
199
                self::delete($path, $not_remove_dir);
200
            } else {
201
                unlink($path);
202
            }
203
        }
204
        closedir($directoryHandle);
205
206
        if (!$not_remove_dir) {
207
            return true;
208
        }
209
        return rmdir($directory);
210
    }
211
212
    /**
213
     * Remove final slash ('/') char in dir if ends with slash.
214
     * @param $directory
215
     * @return string
216
     */
217
    public static function removeFinalSlash($directory) : string
218
    {
219
        if (self::endsWithSlash($directory)) {
220
            $directory = substr($directory, 0, -1);
221
        }
222
        return $directory;
223
    }
224
}
225