diff --git a/composer.json b/composer.json index f65467f..31ccc06 100644 --- a/composer.json +++ b/composer.json @@ -35,6 +35,7 @@ "test": [ "phpunit --debug tests/TestDataObject", "phpunit --debug tests/TestDataPath", + "phpunit --debug tests/TestDataFilters", "phpunit --debug tests/TestValidation" ], "phpstan": "phpstan analyse src tests", diff --git a/src/Data/DataFilters.php b/src/Data/DataFilters.php index 2279de5..699497b 100644 --- a/src/Data/DataFilters.php +++ b/src/Data/DataFilters.php @@ -57,18 +57,23 @@ public function __construct(array $options) public function filter(string $path, $data) { if (!isset($this->options[$path])) { - // TODO: #19 find inclusive path - // $path = $this->findInclusivePaths($path, $this->options); + $path = $this->findInclusivePaths($path, $this->options); - return $data; + if (empty($path)) { + return $data; + } } $filters = $this->options[$path]; if (is_array($data)) { - return array_filter($data, function ($item) use ($filters) { - return $this->filterValue($item, $filters); + array_walk_recursive($data, function (&$item, $key) use ($filters, $path) { + if (!is_array($item) && substr($path, strrpos($path, '/') + 1) === $key) { + $item = $this->filterValue($item, $filters); + } }); + + return $data; } return $this->filterValue($data, $filters); @@ -84,11 +89,11 @@ public function filter(string $path, $data) */ private function filterValue($value, $filters) { - $filterType = $filters['type'] ?? 'string'; - $filterArgs = $filters['args'] ?? []; + $isFiltered = false; + $filterType = $filters['type'] ?? 'string'; + $filterArgs = $filters['args'] ?? []; $filterCallback = $filters['callback'] ?? null; - - $value = $this->castType($value, $filterType); + $value = $this->castType($value, $filterType); if (is_callable($filterCallback) && $filterCallback instanceof Closure) { $args = [$value]; @@ -99,9 +104,9 @@ private function filterValue($value, $filters) $args[] = $filterArgs; } - return call_user_func_array($filterCallback, $args); + $isFiltered = ! call_user_func_array($filterCallback, $args); } - return $value; + return $isFiltered ? false : $value; } } diff --git a/src/Helpers/DataParsers.php b/src/Helpers/DataParsers.php index ed4aab2..94a376d 100644 --- a/src/Helpers/DataParsers.php +++ b/src/Helpers/DataParsers.php @@ -65,4 +65,30 @@ public function findPaths(string $path, array $data, ?Closure $closure = null): return $paths; } + + /** + * Finds the most inclusive path in the options array + * + * @param string $path + * @param array $options + * + * @return string + */ + protected function findInclusivePaths(string $path, array $options): string + { + foreach ($options as $optionPath => $value) { + $asterixIndex = 0; + + while ($asterixPos = strpos($optionPath, '*', $asterixIndex)) { + $asterixIndex = $asterixPos + 1; + $path = substr_replace($path, '*', $asterixPos, strpos($path, '/', $asterixPos) - $asterixPos); + } + + if ($path === $optionPath) { + return $optionPath; + } + } + + return ''; + } } diff --git a/tests/TestDataFilters.php b/tests/TestDataFilters.php index d0f58ad..416111a 100644 --- a/tests/TestDataFilters.php +++ b/tests/TestDataFilters.php @@ -81,5 +81,9 @@ public function testDataFilter() ); $this->assertFalse($test_value_age['persons'][0]['age']); + $this->assertSame(34, $test_value_age['persons'][2]['age']); + + print_r($test_value_name); + print_r($test_value_age); } }