Completed
Push — master ( 72cf29...ecec76 )
by Sebastian
03:13
created

Path::hasTrailingSlash()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
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 73
    public static function replaceDatePlaceholders($string, $time = null)
26
    {
27 73
        $time = $time === null ? time() : $time;
28 73
        return preg_replace_callback(
29 73
            '#%([a-zA-Z])#',
30 73
            function($match) use ($time) {
31 46
                return date($match[1], $time);
32 73
            },
33 73
            $string
34
        );
35
    }
36
37
    /**
38
     * Does a given string contain a date placeholder.
39
     *
40
     * @param  string $string
41
     * @return bool
42
     */
43 54
    public static function isContainingPlaceholder($string)
44
    {
45 54
        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 69
    public static function hasTrailingSlash(string $string) : bool
82
    {
83 69
        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 15
    public static function withTrailingSlash($string)
93
    {
94 15
        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 61
    public static function withoutTrailingSlash($string)
104
    {
105 61
        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 57
    public static function hasLeadingSlash(string $string) : bool
115
    {
116 57
        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 $string) : 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 8
    public static function withoutLeadingSlash(string $string) : string
137
    {
138 8
        return ltrim($string, '/');
139
    }
140
141
    /**
142
     * Removes trailing and leading sl
143
     * @param string $string
144
     * @return string
145
     */
146 5
    public static function withoutLeadingOrTrailingSlash(string $string) : string
147
    {
148 5
        return trim($string, '/');
149
    }
150
151
    /**
152
     * Is given path absolute.
153
     *
154
     * @param  string $path
155
     * @return bool
156
     */
157 51
    public static function isAbsolutePath($path) : bool
158
    {
159
        // path already absolute?
160 51
        if ($path[0] === '/') {
161 15
            return true;
162
        }
163
164
        // Matches the following on Windows:
165
        //  - \\NetworkComputer\Path
166
        //  - \\.\D:
167
        //  - \\.\c:
168
        //  - C:\Windows
169
        //  - C:\windows
170
        //  - C:/windows
171
        //  - c:/windows
172 36
        if (defined('PHP_WINDOWS_VERSION_BUILD') && self::isAbsoluteWindowsPath($path)) {
173
            return true;
174
        }
175
176
        // Stream
177 36
        if (strpos($path, '://') !== false) {
178 1
            return true;
179
        }
180
181 35
        return false;
182
    }
183
184
    /**
185
     * Is given path an absolute windows path.
186
     *
187
     * @param  string $path
188
     * @return bool
189
     */
190 3
    public static function isAbsoluteWindowsPath($path) : bool
191
    {
192 3
        return ($path[0] === '\\' || (strlen($path) >= 3 && preg_match('#^[A-Z]\:[/\\\]#i', substr($path, 0, 3))));
193
    }
194
195
    /**
196
     * Converts a path to an absolute one if necessary relative to a given base path.
197
     *
198
     * @param  string  $path
199
     * @param  string  $base
200
     * @param  boolean $useIncludePath
201
     * @return string
202
     */
203 48
    public static function toAbsolutePath(string $path, string $base, bool $useIncludePath = false) : string
204
    {
205 48
        if (self::isAbsolutePath($path)) {
206 14
            return $path;
207
        }
208
209 34
        $file = $base . DIRECTORY_SEPARATOR . $path;
210
211 34
        if ($useIncludePath && !file_exists($file)) {
212 1
            $includePathFile = stream_resolve_include_path($path);
213 1
            if ($includePathFile) {
214 1
                $file = $includePathFile;
215
            }
216
        }
217 34
        return $file;
218
    }
219
220
    /**
221
     * Return list of directories in a given path without absolute root element
222
     *
223
     * @param string $path
224
     * @return array
225
     */
226 17
    public static function getDirectoryListFromPath($path): array
227
    {
228 17
        $path = trim($path, '/');
229 17
        $dirs = explode('/', $path);
230 17
        return array_filter($dirs);
231
    }
232
233
    /**
234
     * Return list of directories in a given path with absolute root element.
235
     *
236
     * @param  string $path
237
     * @return array
238
     */
239 17
    public static function getDirectoryListFromAbsolutePath(string $path) : array
240
    {
241 17
        $dirs = static::getDirectoryListFromPath($path);
242 17
        if (self::hasLeadingSlash($path)) {
243 17
            array_unshift($dirs, '/');
244
        }
245 17
        return $dirs;
246
    }
247
248
    /**
249
     * Returns directory depth of a given path.
250
     *
251
     * @param  string $path
252
     * @return int
253
     */
254 11
    public static function getPathDepth(string $path) : int
255
    {
256 11
        return count(self::getDirectoryListFromAbsolutePath($path));
257
    }
258
}
259