Completed
Pull Request — master (#145)
by Vitaly
10:03
created

Path::isAbsolutePath()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 26
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 5.0729

Importance

Changes 0
Metric Value
dl 0
loc 26
ccs 6
cts 7
cp 0.8571
rs 8.439
c 0
b 0
f 0
cc 5
eloc 8
nc 4
nop 1
crap 5.0729
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
    public static function replaceDatePlaceholders($string, $time = null)
26
    {
27 74
        $time = $time === null ? time() : $time;
28
        return preg_replace_callback(
29 74
            '#%([a-zA-Z])#',
30 74
            function($match) use ($time) {
31 74
                return date($match[1], $time);
32 74
            },
33 46
            $string
34 74
        );
35 74
    }
36
37
    /**
38
     * Does a given string contain a date placeholder.
39
     *
40
     * @param  string $string
41
     * @return bool
42
     */
43
    public static function isContainingPlaceholder($string)
44
    {
45 47
        return false !== strpos($string, '%');
46
    }
47 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
    public static function replaceTargetPlaceholders($string, $target)
56
    {
57 4
        $targetDir  = dirname($target);
58
        $search     = ['%TARGET_DIR%', '%TARGET_FILE%'];
59 4
        $replace    = [$targetDir, $target];
60 4
        return str_replace($search, $replace, $string);
61 4
    }
62 4
63
    /**
64
     * Create a regex that matches the raw path considering possible date placeholders.
65
     *
66
     * @param  string $stringWithDatePlaceholders
67
     * @return string
68
     */
69
    public static function datePlaceholdersToRegex($stringWithDatePlaceholders)
70
    {
71 14
        $regex = preg_quote($stringWithDatePlaceholders, '#');
72
        return preg_replace('#%[a-z]#i', '[0-9a-z]+', $regex);
73 14
    }
74 14
75
    /**
76
     * Determine if the path has a trailing slash.
77
     *
78
     * @param  string $string
79
     * @return bool
80
     */
81
    public static function hasTrailingSlash(string $string) : bool
82
    {
83 28
        return substr($string, -1) === '/';
84
    }
85 28
86
    /**
87
     * Adds trailing slash to a string/path if not already there.
88
     *
89
     * @param  string $string
90
     * @return string
91
     */
92
    public static function withTrailingSlash($string)
93
    {
94 21
        return $string . (self::hasTrailingSlash($string) ? '' : '/');
95
    }
96 21
97
    /**
98
     * Removes the trailing slash from a string/path.
99
     *
100
     * @param  string $string
101
     * @return string
102
     */
103
    public static function withoutTrailingSlash($string)
104
    {
105 6
        return strlen($string) > 1 && self::hasTrailingSlash($string) ? substr($string, 0, -1) : $string;
106
    }
107 6
108
    /**
109
     * Determine if the path has a leading slash.
110
     *
111
     * @param  string $string
112
     * @return bool
113
     */
114
    public static function hasLeadingSlash(string $string) : bool
115
    {
116 24
        return substr($string, 0, 1) === '/';
117
    }
118 24
119
    /**
120
     * Adds leading slash to a string/path if not already there.
121
     *
122
     * @param  string $string
123
     * @return string
124
     */
125
    public static function withLeadingSlash($string)
126
    {
127 6
        return (self::hasLeadingSlash($string) ? '' : '/') . $string;
128
    }
129 6
130
    /**
131
     * Removes the leading slash from a string/path.
132
     *
133
     * @param  string $string
134
     * @return string
135
     */
136
    public static function withoutLeadingSlash($string)
137
    {
138 1
        return self::hasLeadingSlash($string) ? substr($string, 1) : $string;
139
    }
140 1
141
    /**
142
     * Is given path absolute.
143
     *
144
     * @param  string $path
145
     * @return bool
146
     */
147
    public static function isAbsolutePath($path) : bool
148
    {
149 49
        // path already absolute?
150
        if ($path[0] === '/') {
151
            return true;
152 49
        }
153 13
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
        if (defined('PHP_WINDOWS_VERSION_BUILD') && self::isAbsoluteWindowsPath($path)) {
163
            return true;
164 36
        }
165
166
        // Stream
167
        if (strpos($path, '://') !== false) {
168
            return true;
169 36
        }
170 1
171
        return false;
172
    }
173 35
174
    /**
175
     * Is given path an absolute windows path.
176
     *
177
     * @param  string $path
178
     * @return bool
179
     */
180
    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 3
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
    public static function toAbsolutePath(string $path, string $base, bool $useIncludePath = false) : string
194
    {
195 46
        if (self::isAbsolutePath($path)) {
196
            return $path;
197 46
        }
198 12
199
        $file = $base . DIRECTORY_SEPARATOR . $path;
200
201 34
        if ($useIncludePath && !file_exists($file)) {
202
            $includePathFile = stream_resolve_include_path($path);
203 34
            if ($includePathFile) {
204 1
                $file = $includePathFile;
205 1
            }
206 1
        }
207
        return $file;
208
    }
209 34
210
    /**
211
     * Return list of directories in a given path without absolute root element
212
     *
213
     * @param string $path
214
     * @return array
215
     */
216
    public static function getDirectoryListFromPath($path): array
217
    {
218 15
        $path = trim($path, '/');
219
        $dirs = explode('/', $path);
220 15
        return array_filter($dirs);
221 15
    }
222 15
223
    /**
224 15
     * Return list of directories in a given path with absolute root element.
225
     *
226
     * @param  string $path
227
     * @return array
228
     */
229
    public static function getDirectoryListFromAbsolutePath(string $path) : array
230
    {
231
        $dirs = static::getDirectoryListFromPath($path);
232
        if (self::hasLeadingSlash($path)) {
233 10
            array_unshift($dirs, '/');
234
        }
235 10
        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
    public static function getPathDepth(string $path) : int
245
    {
246
        return count(self::getDirectoryListFromAbsolutePath($path));
247
    }
248
}
249