Completed
Pull Request — master (#145)
by Vitaly
02:41
created

Path::getDirectoryListFromPath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
crap 1
1
<?php
2
namespace phpbu\App\Util;
3
4
/**
5
 * Path utility class.
6
 *
7
 * @package    phpbu
8
 * @subpackage Util
9
 * @author     Sebastian Feldmann <[email protected]>
10
 * @copyright  Sebastian Feldmann <[email protected]>
11
 * @license    https://opensource.org/licenses/MIT The MIT License (MIT)
12
 * @link       http://phpbu.de/
13
 * @since      Class available since Release 5.1.0
14
 */
15
class Path
16
{
17
    /**
18
     * Date placeholder replacement.
19
     * Replaces %{somevalue} with date({somevalue}).
20
     *
21
     * @param  string               $string
22
     * @param  mixed <integer|null> $time
23
     * @return string
24
     */
25 74
    public static function replaceDatePlaceholders($string, $time = null)
26
    {
27 74
        $time = $time === null ? time() : $time;
28 74
        return preg_replace_callback(
29 74
            '#%([a-zA-Z])#',
30 74
            function($match) use ($time) {
31 46
                return date($match[1], $time);
32 74
            },
33 74
            $string
34
        );
35
    }
36
37
    /**
38
     * Does a given string contain a date placeholder.
39
     *
40
     * @param  string $string
41
     * @return bool
42
     */
43 47
    public static function isContainingPlaceholder($string)
44
    {
45 47
        return false !== strpos($string, '%');
46
    }
47
48
    /**
49
     * Replaces %TARGET_DIR% and %TARGET_FILE% in given string.
50
     *
51
     * @param  string $string
52
     * @param  string $target
53
     * @return string
54
     */
55 4
    public static function replaceTargetPlaceholders($string, $target)
56
    {
57 4
        $targetDir  = dirname($target);
58 4
        $search     = ['%TARGET_DIR%', '%TARGET_FILE%'];
59 4
        $replace    = [$targetDir, $target];
60 4
        return str_replace($search, $replace, $string);
61
    }
62
63
    /**
64
     * Create a regex that matches the raw path considering possible date placeholders.
65
     *
66
     * @param  string $stringWithDatePlaceholders
67
     * @return string
68
     */
69 14
    public static function datePlaceholdersToRegex($stringWithDatePlaceholders)
70
    {
71 14
        $regex = preg_quote($stringWithDatePlaceholders, '#');
72 14
        return preg_replace('#%[a-z]#i', '[0-9a-z]+', $regex);
73
    }
74
75
    /**
76
     * Determine if the path has a trailing slash.
77
     *
78
     * @param  string $string
79
     * @return bool
80
     */
81 28
    public static function hasTrailingSlash(string $string) : bool
82
    {
83 28
        return substr($string, -1) === '/';
84
    }
85
86
    /**
87
     * Adds trailing slash to a string/path if not already there.
88
     *
89
     * @param  string $string
90
     * @return string
91
     */
92 21
    public static function withTrailingSlash($string)
93
    {
94 21
        return $string . (self::hasTrailingSlash($string) ? '' : '/');
95
    }
96
97
    /**
98
     * Removes the trailing slash from a string/path.
99
     *
100
     * @param  string $string
101
     * @return string
102
     */
103 6
    public static function withoutTrailingSlash($string)
104
    {
105 6
        return strlen($string) > 1 && self::hasTrailingSlash($string) ? substr($string, 0, -1) : $string;
106
    }
107
108
    /**
109
     * Determine if the path has a leading slash.
110
     *
111
     * @param  string $string
112
     * @return bool
113
     */
114 25
    public static function hasLeadingSlash(string $string) : bool
115
    {
116 25
        return substr($string, 0, 1) === '/';
117
    }
118
119
    /**
120
     * Adds leading slash to a string/path if not already there.
121
     *
122
     * @param  string $string
123
     * @return string
124
     */
125 6
    public static function withLeadingSlash($string)
126
    {
127 6
        return (self::hasLeadingSlash($string) ? '' : '/') . $string;
128
    }
129
130
    /**
131
     * Removes the leading slash from a string/path.
132
     *
133
     * @param  string $string
134
     * @return string
135
     */
136 2
    public static function withoutLeadingSlash($string)
137
    {
138 2
        return self::hasLeadingSlash($string) ? substr($string, 1) : $string;
139
    }
140
141
    /**
142
     * Is given path absolute.
143
     *
144
     * @param  string $path
145
     * @return bool
146
     */
147 49
    public static function isAbsolutePath($path) : bool
148
    {
149
        // path already absolute?
150 49
        if ($path[0] === '/') {
151 13
            return true;
152
        }
153
154
        // Matches the following on Windows:
155
        //  - \\NetworkComputer\Path
156
        //  - \\.\D:
157
        //  - \\.\c:
158
        //  - C:\Windows
159
        //  - C:\windows
160
        //  - C:/windows
161
        //  - c:/windows
162 36
        if (defined('PHP_WINDOWS_VERSION_BUILD') && self::isAbsoluteWindowsPath($path)) {
163
            return true;
164
        }
165
166
        // Stream
167 36
        if (strpos($path, '://') !== false) {
168 1
            return true;
169
        }
170
171 35
        return false;
172
    }
173
174
    /**
175
     * Is given path an absolute windows path.
176
     *
177
     * @param  string $path
178
     * @return bool
179
     */
180 3
    public static function isAbsoluteWindowsPath($path) : bool
181
    {
182 3
        return ($path[0] === '\\' || (strlen($path) >= 3 && preg_match('#^[A-Z]\:[/\\\]#i', substr($path, 0, 3))));
183
    }
184
185
    /**
186
     * Converts a path to an absolute one if necessary relative to a given base path.
187
     *
188
     * @param  string  $path
189
     * @param  string  $base
190
     * @param  boolean $useIncludePath
191
     * @return string
192
     */
193 46
    public static function toAbsolutePath(string $path, string $base, bool $useIncludePath = false) : string
194
    {
195 46
        if (self::isAbsolutePath($path)) {
196 12
            return $path;
197
        }
198
199 34
        $file = $base . DIRECTORY_SEPARATOR . $path;
200
201 34
        if ($useIncludePath && !file_exists($file)) {
202 1
            $includePathFile = stream_resolve_include_path($path);
203 1
            if ($includePathFile) {
204 1
                $file = $includePathFile;
205
            }
206
        }
207 34
        return $file;
208
    }
209
210
    /**
211
     * Return list of directories in a given path without absolute root element
212
     *
213
     * @param string $path
214
     * @return array
215
     */
216 16
    public static function getDirectoryListFromPath($path): array
217
    {
218 16
        $path = trim($path, '/');
219 16
        $dirs = explode('/', $path);
220 16
        return array_filter($dirs);
221
    }
222
223
    /**
224
     * Return list of directories in a given path with absolute root element.
225
     *
226
     * @param  string $path
227
     * @return array
228
     */
229 16
    public static function getDirectoryListFromAbsolutePath(string $path) : array
230
    {
231 16
        $dirs = static::getDirectoryListFromPath($path);
232 16
        if (self::hasLeadingSlash($path)) {
233 16
            array_unshift($dirs, '/');
234
        }
235 16
        return array_filter($dirs);
236
    }
237
238
    /**
239
     * Returns directory depth of a given path.
240
     *
241
     * @param  string $path
242
     * @return int
243
     */
244 10
    public static function getPathDepth(string $path) : int
245
    {
246 10
        return count(self::getDirectoryListFromAbsolutePath($path));
247
    }
248
}
249