Skip to content

Instantly share code, notes, and snippets.

@amatzen
Created February 17, 2021 09:53
Show Gist options
  • Save amatzen/6ab568f74c67caddae31c66be22a8b15 to your computer and use it in GitHub Desktop.
Save amatzen/6ab568f74c67caddae31c66be22a8b15 to your computer and use it in GitHub Desktop.
OpenApiReader
public function getPathFromUri(string $uri, string $method, array &$parameters = []) : ?string
{
$parsed = parse_url($uri);
$templatePaths = [];
$exact = null;
foreach ($this->reader->get('paths') as $path => $pathObject) {
if (isset($pathObject[$method])) {
if (false !== mb_strpos($path, '{')) {
$templatePaths[] = $path;
} elseif (self::strEndsWith($parsed['path'], $path)
&& (null === $exact || mb_strlen($path) < mb_strlen($exact))) {
$exact = $path;
}
}
}
$found = [];
foreach ($templatePaths as $path) {
$pattern = preg_replace_callback('/\/\{(.+?)\}/', function ($matches) {
return '/(?<'.$matches[1].'>[^/}]+?)';
}, $path);
$pattern = '/'.str_replace('/', '\/', $pattern).'$/';
if (preg_match_all($pattern, $parsed['path'], $matches)) {
$params = [];
foreach ($matches as $key => $values) {
if (!is_numeric($key)) {
$params[$key] = is_numeric($values[0]) ? intval($values[0]) : $values[0];
}
}
$found[$path] = $params;
}
}
// If there is an exact path and template path matches, find out which one
// has the most / chars, i.e. is the longest match
$maxLength = mb_substr_count($exact ?? '', '/');
$retPath = $exact;
foreach ($found as $path => $pathParameters) {
$length = mb_substr_count($path, '/');
if ($length > $maxLength) {
$maxLength = $length;
$retPath = $path;
$parameters = $pathParameters;
}
}
return $retPath;
}
private static function strEndsWith($haystack, $needle)
{
$length = mb_strlen($needle);
if (0 == $length) {
return true;
}
return mb_substr($haystack, -$length) === $needle;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment