Skip to content

Commit

Permalink
Allow to filter relationships using Operator::OPERATOR_EMPTY
Browse files Browse the repository at this point in the history
  • Loading branch information
nohponex committed Feb 13, 2016
1 parent 08b5841 commit 6bdb816
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 24 deletions.
53 changes: 36 additions & 17 deletions src/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,11 @@ public function __construct(
}

foreach ($relationships as $relationshipKey => $relationshipValue) {
if (!is_array($relationshipValue)) {
if (!is_array($relationshipValue) && $relationshipValue !== Operator::OPERATOR_EMPTY) {
throw new \Exception(sprintf(
'Values for relationship filter "%s" MUST be an array',
$relationshipKey
'Values for relationship filter "%s" MUST be an array or Operator::"%s"',
$relationshipKey,
Operator::OPERATOR_EMPTY
));
}
}
Expand Down Expand Up @@ -168,19 +169,23 @@ public function validate($modelClass)
*/

if ($this->relationships !== null) {
foreach ($this->relationships as $relationshipKey => $value) {
foreach ($this->relationships as $relationshipKey => $relationshipValue) {
if (!$modelClass::relationshipExists($relationshipKey)) {
throw new RequestException(sprintf(
'Not a valid relationship for filter relationship "%"',
$relationshipKey
));
}

if ($relationshipValue === Operator::OPERATOR_EMPTY) {
continue;
}

//@TODO add relationship validator
$relationshipValidator = [UnsignedIntegerValidator::class, 'parseStatic'];

//Run validator, if any value is incorrect IncorrectParametersException will be thrown
foreach ($value as $id) {
foreach ($relationshipValue as $id) {
call_user_func($relationshipValidator, $id);
}
}
Expand Down Expand Up @@ -296,6 +301,16 @@ public function validate($modelClass)
* Article::class
* );
* ```
* @example
* ```php
* $filter = Filter::parseFromParameters(
* (object) [
* 'filter' => [
* 'tag' => Operator::OPERATOR_EMPTY
* ]
* ],
* Article::class
* );
* @throws RequestException
* @throws \Exception
* @throws IncorrectParametersException
Expand Down Expand Up @@ -352,18 +367,22 @@ public static function parseFromParameters($parameters, $modelClass)
));
}

//Todo use filterValidation model
//$function = 'intval';

//Split multiples and trim additional spaces and force string
$values = array_map(
'strval',
//array_map(
// $function,
// array_map('trim', explode(',', trim($filterValue)))
//)
array_map('trim', explode(',', trim($filterValue)))
);
if ($filterValue === Operator::OPERATOR_EMPTY) {
$values = Operator::OPERATOR_EMPTY;
} else {
//Todo use filterValidation model
//$function = 'intval';

//Split multiples and trim additional spaces and force string
$values = array_map(
'strval',
//array_map(
// $function,
// array_map('trim', explode(',', trim($filterValue)))
//)
array_map('trim', explode(',', trim($filterValue)))
);
}

$filterRelationships->{$filterKey} = $values;
} else {
Expand Down
22 changes: 15 additions & 7 deletions src/Model/Directives.php
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,21 @@ protected static function handleFilter(
$relationship = $relationships->{$relationshipKey};

if ($relationship->type === Relationship::TYPE_TO_ONE) {
$additionalQuery[] = sprintf(
'%s "%s"."%s" IN (%s)',
($hasWhere ? 'AND' : 'WHERE'),
static::$table,
$relationship->recordDataAttribute,
self::handleFilterParseIn($relationshipFilterValue)
);
if ($relationshipFilterValue === Operator::OPERATOR_EMPTY) {
$additionalQuery[] = sprintf(
'%s "%s"."%s" IS NULL',
($hasWhere ? 'AND' : 'WHERE'),
$relationship->recordDataAttribute
);
} else {
$additionalQuery[] = sprintf(
'%s "%s"."%s" IN (%s)',
($hasWhere ? 'AND' : 'WHERE'),
static::$table,
$relationship->recordDataAttribute,
self::handleFilterParseIn($relationshipFilterValue)
);
}
$hasWhere = true;
} else {
throw new NotImplementedException(
Expand Down
21 changes: 21 additions & 0 deletions tests/src/FilterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,27 @@ public function testParseFromParametersPrimaryUsingIntval()
$this->assertEquals([4], $filter->primary);
}

/**
* @covers ::parseFromParameters
*/
public function testParseFromParametersRelationshipEmpty()
{
$parameters = (object) [
'filter' => (object) [ //Will accept both arrays and object
'tag' => Operator::OPERATOR_EMPTY
]
];

$filter = Filter::parseFromParameters(
$parameters,
Article::class //Use article resource model's filters
);

$this->assertInstanceOf(Filter::class, $filter);

$this->assertEquals(Operator::OPERATOR_EMPTY, $filter->relationships->tag);
}

/**
* @covers ::parseFromParameters
*/
Expand Down

0 comments on commit 6bdb816

Please sign in to comment.