private static function matchPathname($path, $basePath, $pattern, $firstWildcard, $flags)
{
// match with FNM_PATHNAME; the pattern has base implicitly in front of it.
if (isset($pattern[0]) && $pattern[0] === '/') {
$pattern = StringHelper::byteSubstr($pattern, 1, StringHelper::byteLength($pattern));
if ($firstWildcard !== false && $firstWildcard !== 0) {
$firstWildcard--;
}
}
$namelen = StringHelper::byteLength($path) - (empty($basePath) ? 0 : StringHelper::byteLength($basePath) + 1);
$name = StringHelper::byteSubstr($path, -$namelen, $namelen);
if ($firstWildcard !== 0) {
if ($firstWildcard === false) {
$firstWildcard = StringHelper::byteLength($pattern);
}
// if the non-wildcard part is longer than the remaining pathname, surely it cannot match.
if ($firstWildcard > $namelen) {
return false;
}
if (strncmp($pattern, $name, $firstWildcard)) {
return false;
}
$pattern = StringHelper::byteSubstr($pattern, $firstWildcard, StringHelper::byteLength($pattern));
$name = StringHelper::byteSubstr($name, $firstWildcard, $namelen);
// If the whole pattern did not have a wildcard, then our prefix match is all we need; we do not need to call fnmatch at all.
if (empty($pattern) && empty($name)) {
return true;
}
}
$fnmatchFlags = FNM_PATHNAME;
if ($flags & self::PATTERN_CASE_INSENSITIVE) {
$fnmatchFlags |= FNM_CASEFOLD;
}
return fnmatch($pattern, $name, $fnmatchFlags);
}