Skip to content

Commit 878929c

Browse files
authored
Merge pull request #60 from MortalFlesh/feature/add-declare-function
Add declare function
2 parents 576f652 + 41e6c35 commit 878929c

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

src/ApiFilter.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Lmc\ApiFilter\Filters\FiltersInterface;
1212
use Lmc\ApiFilter\Service\FilterApplicator;
1313
use Lmc\ApiFilter\Service\FilterFactory;
14+
use Lmc\ApiFilter\Service\FunctionCreator;
1415
use Lmc\ApiFilter\Service\Functions;
1516
use Lmc\ApiFilter\Service\QueryParametersParser;
1617

@@ -22,13 +23,16 @@ class ApiFilter
2223
private $parser;
2324
/** @var FilterApplicator */
2425
private $applicator;
26+
/** @var FunctionCreator */
27+
private $functionCreator;
2528

2629
public function __construct()
2730
{
2831
$filterFactory = new FilterFactory();
2932
$this->functions = new Functions();
3033
$this->parser = new QueryParametersParser($filterFactory, $this->functions);
3134
$this->applicator = new FilterApplicator();
35+
$this->functionCreator = new FunctionCreator($filterFactory);
3236

3337
if (class_exists('Doctrine\ORM\QueryBuilder')) {
3438
$this->registerApplicator(new QueryBuilderApplicator(), Priority::MEDIUM);
@@ -168,6 +172,44 @@ public function registerApplicator(ApplicatorInterface $applicator, int $priorit
168172
return $this;
169173
}
170174

175+
/**
176+
* Declare a function to specify a name for several parameters which must be given together.
177+
*
178+
* ApiFilter::applyFilters() method will be used with all declared parameters.
179+
* If you want to have a custom callback, not just abstract a name for few parameters, use registerFunction method instead
180+
*
181+
* Note:
182+
* It is not allowed to register more functions with same parameter (not matter of their order).
183+
*
184+
* @example
185+
* How to abstract first and last name into a fullName function and still benefit from ApiFilter features
186+
* $apiFilter->declareFunction('fullName', ['first', 'last']);
187+
*
188+
* @see ApiFilter::registerFunction()
189+
* @see ApiFilter::executeFunction()
190+
*
191+
* Parameters might be defined as
192+
* - array of single values (names)
193+
* - array of array values (definitions)
194+
* - array of ParameterDefinition
195+
*
196+
* @param array $parameters names or definition of needed parameters (parameters will be passed to function in given order)
197+
* @throws ApiFilterExceptionInterface
198+
*/
199+
public function declareFunction(string $functionName, array $parameters)
200+
{
201+
$parameters = $this->functionCreator->normalizeParameters($parameters);
202+
203+
$this->functions->register(
204+
$functionName,
205+
$this->functionCreator->getParameterNames($parameters),
206+
$this->functionCreator->createByParameters($this->applicator, $parameters),
207+
$this->functionCreator->getParameterDefinitions($parameters)
208+
);
209+
210+
return $this;
211+
}
212+
171213
/**
172214
* Add a custom function to express any intention you can have
173215
*

tests/ApiFilterRegisterFunctionTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,19 @@ protected function setUp(): void
2222
$this->apiFilter->registerApplicator(new SqlApplicator(), Priority::HIGHEST);
2323
}
2424

25+
/**
26+
* @test
27+
*/
28+
public function shouldNotAllowToDeclareFunctionsWithSameParameters(): void
29+
{
30+
$this->expectException(ApiFilterExceptionInterface::class);
31+
$this->expectExceptionMessage('There is already a function "person1" with parameter "name" registered. Parameters must be unique.');
32+
33+
$this->apiFilter
34+
->declareFunction('person1', ['name', 'age'])
35+
->declareFunction('person2', ['name', 'ageTo', 'ageFrom']);
36+
}
37+
2538
/**
2639
* @test
2740
*/

0 commit comments

Comments
 (0)