Completed
Push — master ( 236d2e...a95984 )
by Sebastian
03:12
created

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