Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add keyMatch4()
  • Loading branch information
leeqvip committed May 25, 2020
1 parent e2ce186 commit c3781e0
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
60 changes: 60 additions & 0 deletions src/Util/BuiltinOperations.php
Expand Up @@ -131,6 +131,66 @@ public static function keyMatch3Func(...$args): bool
return self::keyMatch3($name1, $name2);
}

/**
* determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *.
* Besides what KeyMatch3 does, KeyMatch4 can also match repeated patterns:
* "/parent/123/child/123" matches "/parent/{id}/child/{id}"
* "/parent/123/child/456" does not match "/parent/{id}/child/{id}"
* But KeyMatch3 will match both.
*
* @param string $key1
* @param string $key2
*
* @return bool
*/
public static function keyMatch4(string $key1, string $key2): bool
{
$key2 = str_replace(['/*'], ['/.*'], $key2);

$tokens = [];
$pattern = '/\{([^\/]+)\}/';
$key2 = preg_replace_callback(
$pattern,
function ($m) use (&$tokens) {
$tokens[] = $m[1];
return '([^\/]+)';
},
$key2
);

$matched = preg_match_all('~^' . $key2 . '$~', $key1, $matches);
if (!$matched) {
return false;
}

$values = [];
foreach ($tokens as $key => $token) {
if (!isset($values[$token])) {
$values[$token] = $matches[$key + 1];
}
if ($values[$token] != $matches[$key + 1]) {
return false;
}
}

return true;
}

/**
* the wrapper for KeyMatch4.
*
* @param mixed ...$args
*
* @return bool
*/
public static function keyMatch4Func(...$args): bool
{
$name1 = $args[0];
$name2 = $args[1];

return self::keyMatch4($name1, $name2);
}

/**
* determines whether key1 matches the pattern of key2 in regular expression.
*
Expand Down
22 changes: 22 additions & 0 deletions tests/Unit/Util/BuiltinOperationsTest.php
Expand Up @@ -27,6 +27,11 @@ private function keyMatch3Func($name1, $name2)
return (bool) BuiltinOperations::keyMatch3Func($name1, $name2);
}

private function keyMatch4Func($name1, $name2)
{
return (bool) BuiltinOperations::keyMatch4Func($name1, $name2);
}

public function testKeyMatchFunc()
{
$this->assertTrue($this->keyMatchFunc('/foo', '/foo'));
Expand Down Expand Up @@ -98,4 +103,21 @@ public function testKeyMatch3Func()

$this->assertFalse($this->keyMatch3Func('/myid/using/myresid', '/{id/using/{resId}'));
}

public function testKeyMatch4Func()
{
$this->assertTrue($this->keyMatch4Func('/parent/123/child/123', '/parent/{id}/child/{id}'));
$this->assertFalse($this->keyMatch4Func('/parent/123/child/456', '/parent/{id}/child/{id}'));

$this->assertTrue($this->keyMatch4Func('/parent/123/child/123', '/parent/{id}/child/{another_id}'));
$this->assertTrue($this->keyMatch4Func('/parent/123/child/456', '/parent/{id}/child/{another_id}'));

$this->assertTrue($this->keyMatch4Func('/parent/123/child/123/book/123', '/parent/{id}/child/{id}/book/{id}'));
$this->assertFalse($this->keyMatch4Func('/parent/123/child/123/book/456', '/parent/{id}/child/{id}/book/{id}'));
$this->assertFalse($this->keyMatch4Func('/parent/123/child/456/book/123', '/parent/{id}/child/{id}/book/{id}'));
$this->assertFalse($this->keyMatch4Func('/parent/123/child/456/book/', '/parent/{id}/child/{id}/book/{id}'));
$this->assertFalse($this->keyMatch4Func('/parent/123/child/456', '/parent/{id}/child/{id}/book/{id}'));

$this->assertFalse($this->keyMatch4Func('/parent/123/child/123', '/parent/{i/d}/child/{i/d}'));
}
}

0 comments on commit c3781e0

Please sign in to comment.