-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathUtil.php
109 lines (103 loc) · 3.76 KB
/
Util.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<?php
/**
* @license Apache 2.0
*/
namespace In\Blueprint;
use InvalidArgumentException;
use Symfony\Component\Finder\Finder;
/**
* Convenient utility functions that don't neatly fit anywhere else
*/
class Util
{
/**
* Turns the given $fullPath into a relative path based on $basePaths, which can either
* be a single string path, or a list of possible paths. If a list is given, the first
* matching basePath in the list will be used to compute the relative path. If no
* relative path could be computed, the original string will be returned because there
* is always a chance it was a valid relative path to begin with.
*
* It should be noted that these are "relative paths" primarily in Finder's sense of them,
* and conform specifically to what is expected by functions like `exclude()` and `notPath()`.
* In particular, leading and trailing slashes are removed.
*
* @param string $fullPath
* @param string|array $basePaths
* @return string
*/
public static function getRelativePath($fullPath, $basePaths)
{
$relativePath = null;
if (is_string($basePaths)) { // just a single path, not an array of possible paths
$relativePath = self::removePrefix($fullPath, $basePaths);
} else { // an array of paths
foreach ($basePaths as $basePath) {
$relativePath = self::removePrefix($fullPath, $basePath);
if (!empty($relativePath)) {
break;
}
}
}
return !empty($relativePath) ? trim($relativePath, '/') : $fullPath;
}
/**
* Removes a prefix from the start of a string if it exists, or null otherwise.
*
* @param string $str
* @param string $prefix
* @return null|string
*/
private static function removePrefix($str, $prefix)
{
if (substr($str, 0, strlen($prefix)) == $prefix) {
return substr($str, strlen($prefix));
}
return null;
}
/**
* Build a Symfony Finder object that scans the given $directory.
*
* @param string|array|Finder $directory The directory(s) or filename(s)
* @param null|string|array $exclude The directory(s) or filename(s) to exclude (as absolute or relative paths)
* @throws InvalidArgumentException
*/
public static function finder($directory, $exclude = null)
{
if ($directory instanceof Finder) {
return $directory;
} else {
$finder = new Finder();
$finder->sortByName();
}
$finder->files()->followLinks()->name('*.php');
if (is_string($directory)) {
if (is_file($directory)) { // Scan a single file?
$finder->append([$directory]);
} else { // Scan a directory
$finder->in($directory);
}
} elseif (is_array($directory)) {
foreach ($directory as $path) {
if (is_file($path)) { // Scan a file?
$finder->append([$path]);
} else {
$finder->in($path);
}
}
} else {
throw new InvalidArgumentException('Unexpected $directory value:' . gettype($directory));
}
if ($exclude !== null) {
if (is_string($exclude)) {
$finder->notPath(Util::getRelativePath($exclude, $directory));
} elseif (is_array($exclude)) {
foreach ($exclude as $path) {
$finder->notPath(Util::getRelativePath($path, $directory));
}
} else {
throw new InvalidArgumentException('Unexpected $exclude value:' . gettype($exclude));
}
}
return $finder;
}
}