Skip to content

Commit

Permalink
Improve filter variables
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Jan 30, 2020
1 parent afe1dbe commit 0d89091
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 38 deletions.
81 changes: 45 additions & 36 deletions src/UriTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -251,15 +251,57 @@ private function parseVariableSpecification(array $expression, array $foundVaria
}

/**
* Filter out the value whose key is not a valid variable name for the given template.
* Filters out variables for the given template.
*
* @return array<string|array<string>>
*/
private function filterVariables(array $variables): array
{
$filter = function ($key): bool {
return in_array($key, $this->variableNames, true);
};

return array_filter($variables, $filter, ARRAY_FILTER_USE_KEY);
$result = array_filter($variables, $filter, ARRAY_FILTER_USE_KEY);
foreach ($result as $name => &$value) {
$value = $this->normalizeValue($name, $value, true);
}
unset($value);

return $result;
}

/**
* @param mixed $value the value to be expanded
*
* @throws \TypeError if the type is not supported
* @throws TemplateCanNotBeExpanded if the value contains nested list
*
* @return string|array<string>
*/
private function normalizeValue(string $name, $value, bool $isNestedListAllowed)
{
if (is_array($value)) {
if (!$isNestedListAllowed) {
throw TemplateCanNotBeExpanded::dueToNestedListOfValue($name);
}

foreach ($value as &$var) {
$var = $this->normalizeValue($name, $var, false);
}
unset($var);

return $value;
}

if (is_bool($value)) {
return true === $value ? '1' : '0';
}

if (null === $value || is_scalar($value) || method_exists($value, '__toString')) {
return (string) $value;
}

throw new \TypeError(sprintf('The variable '.$name.' must be NULL, a scalar or a stringable object `%s` given', gettype($value)));
}

/**
Expand Down Expand Up @@ -385,12 +427,7 @@ private function expandExpression(array $foundExpression): string
*/
private function expandVariable(array $variable, string $operator, string $joiner, bool $useQuery): string
{
$expanded = '';
if (!isset($this->variables[$variable['name']])) {
return $expanded;
}

$value = $this->normalizeValue($this->variables[$variable['name']]);
$value = $this->variables[$variable['name']] ?? '';
$arguments = [$value, $variable, $operator];
$method = 'expandString';
$actualQuery = $useQuery;
Expand All @@ -416,30 +453,6 @@ private function expandVariable(array $variable, string $operator, string $joine
return $variable['name'].'='.$expanded;
}

/**
* @param mixed $value the value to be expanded
*
* @throws \TypeError if the type is not supported
*
* @return string|array
*/
private function normalizeValue($value)
{
if (is_array($value)) {
return $value;
}

if (is_bool($value)) {
return true === $value ? '1' : '0';
}

if (is_scalar($value) || method_exists($value, '__toString')) {
return (string) $value;
}

throw new \TypeError(sprintf('The variables must be a scalar or a stringable object `%s` given', gettype($value)));
}

/**
* Expands an expression using a string value.
*/
Expand Down Expand Up @@ -480,10 +493,6 @@ private function expandList(array $value, array $variable, string $operator, str
/** @var string $key */
foreach ($value as $key => $var) {
if ($isAssoc) {
if (is_array($var)) {
throw TemplateCanNotBeExpanded::dueToNestedListOfValue($key);
}

$key = rawurlencode((string) $key);
}

Expand Down
7 changes: 5 additions & 2 deletions tests/UriTemplateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,15 @@ public function testGetTemplate(): void
/**
* @covers ::__construct
* @covers ::filterVariables
* @covers ::normalizeValue
* @covers ::getDefaultVariables
*/
public function testGetDefaultVariables(): void
{
$template = 'http://example.com{+path}{/segments}{?query,more*,foo[]*}';
$variables = [
'path' => '/foo/bar',
'segments' => ['one', 'two'],
'segments' => ['one', 'two', 3, true, 'false', false, null],
'query' => 'test',
'more' => ['fun', 'ice cream'],
'foo[]' => ['fizz', 'buzz'],
Expand All @@ -63,7 +64,7 @@ public function testGetDefaultVariables(): void

$expectedVariables = [
'path' => '/foo/bar',
'segments' => ['one', 'two'],
'segments' => ['one', 'two', '3', '1', 'false', '0', ''],
'query' => 'test',
'more' => ['fun', 'ice cream'],
'foo[]' => ['fizz', 'buzz'],
Expand All @@ -78,6 +79,7 @@ public function testGetDefaultVariables(): void

/**
* @covers ::filterVariables
* @covers ::normalizeValue
* @covers ::withDefaultVariables
*/
public function testWithDefaultVariables(): void
Expand Down Expand Up @@ -163,6 +165,7 @@ public function testExpandAcceptsOnlyStringAndStringableObject(): void
* @covers ::expandList
* @covers ::isAssoc
* @covers ::decodeReserved
* @covers ::normalizeValue
*
* @dataProvider templateExpansionProvider
*/
Expand Down

0 comments on commit 0d89091

Please sign in to comment.