Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add casting for Finder. #342

Merged
merged 9 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .phive/phars.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive">
<phar name="phpstan" version="1.10.14" installed="1.10.14" location="./tools/phpstan" copy="false"/>
<phar name="phpstan" version="1.10.59" installed="1.10.59" location="./tools/phpstan" copy="false"/>
<phar name="psalm" version="5.10.0" installed="5.10.0" location="./tools/psalm" copy="false"/>
</phive>
4 changes: 4 additions & 0 deletions docs/filters-and-examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,10 @@ The following options are supported by all filters except `Callback` and `Finder

- `options` (`array`, defaults to `[]`) Additional options to pass to the finder.

- `cast` (`array`, defaults to `[]`) Additional casts to be used on the (mapped
field values. You can use `'int'`, `'bool'`, `'float'`, etc as strings. You can also
use callable functions like `function ($value) { ... }` for more complex scenarios.

## Filtering by `belongsToMany` and `hasMany` associations

If you want to filter values related to a `belongsToMany` or `hasMany` association,
Expand Down
2 changes: 1 addition & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
parameters:
level: 7
level: 8
checkMissingIterableValueType: false
checkGenericClassInNonGenericObjectType: false
paths:
Expand Down
6 changes: 3 additions & 3 deletions src/Model/Filter/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ abstract class Base
/**
* Default configuration.
*
* @var array
* @var array<string, mixed>
*/
protected array $_defaultConfig = [];

Expand Down Expand Up @@ -200,9 +200,9 @@ public function value(): mixed
}

/**
* @return array|string|null
* @return mixed
*/
protected function passedValue(): string|array|null
protected function passedValue(): mixed
{
if (!isset($this->_args[$this->name()])) {
return null;
Expand Down
2 changes: 1 addition & 1 deletion src/Model/Filter/Boolean.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Boolean extends Base
/**
* Default configuration.
*
* @var array
* @var array<string, mixed>
*/
protected array $_defaultConfig = [
'mode' => 'OR',
Expand Down
4 changes: 2 additions & 2 deletions src/Model/Filter/Compare.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Compare extends Base
/**
* Default configuration.
*
* @var array
* @var array<string, mixed>
*/
protected array $_defaultConfig = [
'operator' => '>=',
Expand All @@ -20,7 +20,7 @@ class Compare extends Base
/**
* Allowed operators.
*
* @var array
* @var array<string>
*/
protected array $_operators = [
'>=', '<=', '<', '>',
Expand Down
2 changes: 1 addition & 1 deletion src/Model/Filter/Escaper/DefaultEscaper.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class DefaultEscaper implements EscaperInterface
/**
* Default configuration.
*
* @var array
* @var array<string, mixed>
*/
protected array $_defaultConfig = [
'fromWildCardAny' => '%',
Expand Down
2 changes: 1 addition & 1 deletion src/Model/Filter/Escaper/SqlserverEscaper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class SqlserverEscaper extends DefaultEscaper
/**
* Default configuration.
*
* @var array
* @var array<string, mixed>
*/
protected array $_defaultConfig = [
'fromWildCardAny' => '%',
Expand Down
2 changes: 1 addition & 1 deletion src/Model/Filter/Exists.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Exists extends Base
/**
* Default configuration.
*
* @var array
* @var array<string, mixed>
*/
protected array $_defaultConfig = [
'mode' => 'OR',
Expand Down
18 changes: 17 additions & 1 deletion src/Model/Filter/Finder.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
class Finder extends Base
{
/**
* @var array
* @var array<string, mixed>
*/
protected array $_defaultConfig = [
'map' => [],
'options' => [],
'cast' => [],
];

/**
Expand All @@ -37,6 +38,21 @@ public function process(): bool
foreach ($map as $to => $from) {
$args[$to] = $args[$from] ?? null;
}
$casts = $this->getConfig('cast');
foreach ($casts as $field => $toType) {
$value = $args[$field] ?? null;
if ($value === null) {
continue;
}

if (is_callable($toType)) {
dereuromark marked this conversation as resolved.
Show resolved Hide resolved
dereuromark marked this conversation as resolved.
Show resolved Hide resolved
$value = $toType($value);
} else {
settype($value, $toType);
}

$args[$field] = $value;
}

$options = $this->getConfig('options');
$args += $options;
Expand Down
2 changes: 1 addition & 1 deletion src/Model/Filter/Like.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Like extends Base
/**
* Default configuration.
*
* @var array
* @var array<string, mixed>
*/
protected array $_defaultConfig = [
'before' => false,
Expand Down
2 changes: 1 addition & 1 deletion src/Model/Filter/Value.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Value extends Base
/**
* Default configuration.
*
* @var array
* @var array<string, mixed>
*/
protected array $_defaultConfig = [
'mode' => 'OR',
Expand Down
36 changes: 36 additions & 0 deletions tests/TestApp/Model/Table/FinderArticlesTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,40 @@ public function findSlugged(SelectQuery $query, string $slug): SelectQuery
{
return $query->where(['title' => $slug]);
}

/**
* Requires nullable slug key to be present in $options array.
*
* @param \Cake\ORM\Query\SelectQuery $query
* @param string|null $slug
* @return \Cake\ORM\Query\SelectQuery
*/
public function findSluggedNullable(SelectQuery $query, ?string $slug): SelectQuery
{
return $query->where(['title IS' => $slug]);
}

/**
* Requires uid key to be present in $options array.
*
* @param \Cake\ORM\Query\SelectQuery $query
* @param int $uid
* @return \Cake\ORM\Query\SelectQuery
*/
public function findUser(SelectQuery $query, int $uid): SelectQuery
{
return $query->where(['user_id' => $uid]);
}

/**
* Requires nullable uid key to be present in $options array.
*
* @param \Cake\ORM\Query\SelectQuery $query
* @param int|null $uid
* @return \Cake\ORM\Query\SelectQuery
*/
public function findUserNullable(SelectQuery $query, ?int $uid): SelectQuery
{
return $query->where(['user_id IS' => $uid]);
}
}
8 changes: 4 additions & 4 deletions tests/TestCase/Model/Filter/BaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public function testConstructNonEmptyNameArgument($nonEmptyValue)
$this->Manager,
['fields' => 'fields']
);
$this->assertEquals($filter->name(), $nonEmptyValue);
$this->assertSame($filter->name(), $nonEmptyValue);
}

/**
Expand Down Expand Up @@ -144,13 +144,13 @@ public function testValue()
);

$filter->setArgs(['fields' => 'value']);
$this->assertEquals('value', $filter->value());
$this->assertSame('value', $filter->value());

$filter->setArgs(['other_field' => 'value']);
$this->assertEquals('default', $filter->value());
$this->assertSame('default', $filter->value());

$filter->setArgs(['fields' => ['value1', 'value2']]);
$this->assertEquals('default', $filter->value());
$this->assertSame('default', $filter->value());
}

/**
Expand Down
26 changes: 13 additions & 13 deletions tests/TestCase/Model/Filter/BooleanTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function testProcessWithFlagOn()
'/WHERE Articles\.is_active = \:c0$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
[true],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand All @@ -53,7 +53,7 @@ public function testProcessWithFlagOff()
'/WHERE Articles\.is_active = \:c0$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
[false],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand All @@ -75,7 +75,7 @@ public function testProcessWithStringFlagTrue()
'/WHERE Articles\.is_active = \:c0$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
[true],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand All @@ -97,7 +97,7 @@ public function testProcessWithStringFlagFalse()
'/WHERE Articles\.is_active = \:c0$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
[false],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand All @@ -119,7 +119,7 @@ public function testProcessWithBooleanFlagTrue()
'/WHERE Articles\.is_active = \:c0$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
[true],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand All @@ -141,7 +141,7 @@ public function testProcessWithBooleanFlagFalse()
'/WHERE Articles\.is_active = \:c0$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
[false],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand All @@ -163,7 +163,7 @@ public function testProcessWithStringFlag1()
'/WHERE Articles\.is_active = \:c0$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
[true],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand All @@ -185,7 +185,7 @@ public function testProcessWithStringFlag0()
'/WHERE Articles\.is_active = \:c0$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
[false],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand All @@ -207,7 +207,7 @@ public function testProcessWithIntegerFlag1()
'/WHERE Articles\.is_active = \:c0$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
[true],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand All @@ -226,7 +226,7 @@ public function testProcessWithIntegerFlag0()
'/WHERE Articles\.is_active = \:c0$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
[false],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand Down Expand Up @@ -285,7 +285,7 @@ public function testProcessMultiField()
'/WHERE \(Articles\.is_active = :c0 OR Articles\.other = :c1\)$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
[true, true],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand All @@ -310,7 +310,7 @@ public function testProcessMultiFieldWithAndMode()
'/WHERE \(Articles\.is_active = :c0 AND Articles\.other = :c1\)$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
[true, true],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand All @@ -332,7 +332,7 @@ public function testProcessDefaultFallbackForDisallowedMultiValue()
'/WHERE Articles\.is_active = :c0$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
[true],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand Down
2 changes: 1 addition & 1 deletion tests/TestCase/Model/Filter/CallbackTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function testProcess()
'/WHERE title = \:c0$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
['test'],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand Down
4 changes: 2 additions & 2 deletions tests/TestCase/Model/Filter/ExistsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public function testProcessWithFlagOnNotNullable()
'/WHERE Articles\.number != \:c0$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
[''],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand All @@ -100,7 +100,7 @@ public function testProcessWithFlagOffNotNullable()
'/WHERE Articles\.number = \:c0$/',
$filter->getQuery()->sql()
);
$this->assertEquals(
$this->assertSame(
[''],
Hash::extract($filter->getQuery()->getValueBinder()->bindings(), '{s}.value')
);
Expand Down