Skip to content

Commit

Permalink
Add "smallint" and "bigint" support to FilterModel (#2211)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Voříšek <[email protected]>
  • Loading branch information
mkrecek234 and mvorisek authored Jun 18, 2024
1 parent 12b9e3d commit 2e27a15
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 58 deletions.
3 changes: 3 additions & 0 deletions demos/collection/tablefilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Atk4\Ui\App;
use Atk4\Ui\Grid;
use Atk4\Ui\Table\Column\FilterModel;
use Atk4\Ui\View;

/** @var App $app */
Expand All @@ -16,6 +17,8 @@
$grid = Grid::addTo($view, ['menu' => ['class' => ['atk-grid-menu']]]); // menu class added for Behat testing

$model = new Country($app->db);
$model->getIdField()->system = false;
$model->getIdField()->ui['filterModel'] = FilterModel\TypeNumber::class;
$model->addExpression('is_uk', [
'expr' => $model->expr('case when [atk_fp_country__iso] = [country] THEN [t] ELSE [f] END', ['country' => 'GB', 't' => true, 'f' => false]),
'type' => 'boolean',
Expand Down
6 changes: 3 additions & 3 deletions src/Table/Column/FilterModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ public static function factoryType(App $app, Field $field): self
Types::TEXT => FilterModel\TypeString::class,

Types::BOOLEAN => FilterModel\TypeBoolean::class,
Types::SMALLINT => FilterModel\TypeNumber::class,
Types::INTEGER => FilterModel\TypeNumber::class,
Types::BIGINT => FilterModel\TypeNumber::class,
Types::FLOAT => FilterModel\TypeNumber::class,
CustomTypes::MONEY => FilterModel\TypeNumber::class,

Expand All @@ -68,7 +70,7 @@ public static function factoryType(App $app, Field $field): self
Types::JSON => FilterModel\TypeString::class,

'TODO we do not support enum type, any type can be enum' => FilterModel\TypeEnum::class,
][$field->type];
][$field->type] ?? null;

// you can set your own filter model class
if (isset($field->ui['filterModel'])) {
Expand Down Expand Up @@ -99,8 +101,6 @@ protected function init(): void

public function afterInit(): void
{
$this->addField('name', ['default' => $this->lookupField->shortName, 'system' => true]);

// create a name for our filter model to save as session data
$this->name = 'filter_model_' . $this->lookupField->shortName;

Expand Down
9 changes: 5 additions & 4 deletions src/Table/Column/FilterModel/TypeBoolean.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@ protected function init(): void
{
parent::init();

$this->op->type = 'smallint';
$this->op->values = [
'true' => 'Is Yes',
'false' => 'Is No',
0 => 'Is No',
1 => 'Is Yes',
];
$this->op->default = 'true';
$this->op->default = 1;
}

#[\Override]
public function setConditionForModel(Model $model): void
{
$filter = $this->recallData();
if ($filter !== null) {
$model->addCondition($filter['name'], $filter['op'] === 'true');
$model->addCondition($this->lookupField, $filter['op'] === 1);
}
}
}
18 changes: 8 additions & 10 deletions src/Table/Column/FilterModel/TypeDate.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ public function setConditionForModel(Model $model): void
if ($filter !== null) {
switch ($filter['op']) {
case 'empty':
$model->addCondition($filter['name'], '=', null);
$model->addCondition($this->lookupField, '=', null);

break;
case 'not empty':
$model->addCondition($filter['name'], '!=', null);
$model->addCondition($this->lookupField, '!=', null);

break;
case 'within':
Expand All @@ -85,14 +85,14 @@ public function setConditionForModel(Model $model): void
[$d1, $d2] = [$d2, $d1];
}
$model->addCondition($model->expr('[field] between [value] and [value2]', [
'field' => $model->getField($filter['name']),
'value' => $model->getPersistence()->typecastSaveField($model->getField($filter['name']), $d1),
'value2' => $model->getPersistence()->typecastSaveField($model->getField($filter['name']), $d2),
'field' => $this->lookupField,
'value' => $model->getPersistence()->typecastSaveField($this->lookupField, $d1),
'value2' => $model->getPersistence()->typecastSaveField($this->lookupField, $d2),
]));

break;
default:
$model->addCondition($filter['name'], $filter['op'], $this->getDate($filter['value']));
$model->addCondition($this->lookupField, $filter['op'], $this->getDate($filter['value']));
}
}
}
Expand All @@ -102,10 +102,8 @@ public function setConditionForModel(Model $model): void
* Will construct and return a date object base on constructor string.
*
* @param string $dateModifier the string to pass to generated a date from
*
* @return \DateTime
*/
public function getDate($dateModifier)
public function getDate(string $dateModifier): ?\DateTime
{
switch ($dateModifier) {
case 'exact':
Expand All @@ -123,7 +121,7 @@ public function getDate($dateModifier)

break;
default:
$date = $dateModifier ? new \DateTime($dateModifier) : null;
$date = null;
}

return $date;
Expand Down
28 changes: 13 additions & 15 deletions src/Table/Column/FilterModel/TypeDatetime.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ public function setConditionForModel(Model $model): void
if ($filter !== null) {
switch ($filter['op']) {
case 'empty':
$model->addCondition($filter['name'], '=', null);
$model->addCondition($this->lookupField, '=', null);

break;
case 'not empty':
$model->addCondition($filter['name'], '!=', null);
$model->addCondition($this->lookupField, '!=', null);

break;
case 'within':
Expand All @@ -85,9 +85,9 @@ public function setConditionForModel(Model $model): void
[$d1, $d2] = [$d2, $d1];
}
$model->addCondition($model->expr('[field] between [value] and [value2]', [
'field' => $model->getField($filter['name']),
'value' => $model->getPersistence()->typecastSaveField($model->getField($filter['name']), $d1),
'value2' => $model->getPersistence()->typecastSaveField($model->getField($filter['name']), $d2),
'field' => $this->lookupField,
'value' => $model->getPersistence()->typecastSaveField($this->lookupField, $d1),
'value2' => $model->getPersistence()->typecastSaveField($this->lookupField, $d2),
]));

break;
Expand All @@ -100,24 +100,24 @@ public function setConditionForModel(Model $model): void
}
$betweenOperator = $filter['op'] === '!=' ? 'not between' : 'between';
$model->addCondition($model->expr('[field] ' . $betweenOperator . ' [value] and [value2]', [
'field' => $model->getField($filter['name']),
'value' => $model->getPersistence()->typecastSaveField($model->getField($filter['name']), $d1),
'value2' => $model->getPersistence()->typecastSaveField($model->getField($filter['name']), $d2),
'field' => $this->lookupField,
'value' => $model->getPersistence()->typecastSaveField($this->lookupField, $d1),
'value2' => $model->getPersistence()->typecastSaveField($this->lookupField, $d2),
]));

break;
case '>':
case '<=':
$model->addCondition($filter['name'], $filter['op'], $this->getDatetime($filter['value'])->setTime(23, 59, 59, 999_999));
$model->addCondition($this->lookupField, $filter['op'], $this->getDatetime($filter['value'])->setTime(23, 59, 59, 999_999));

break;
case '<':
case '>=':
$model->addCondition($filter['name'], $filter['op'], $this->getDatetime($filter['value'])->setTime(0, 0, 0));
$model->addCondition($this->lookupField, $filter['op'], $this->getDatetime($filter['value'])->setTime(0, 0, 0));

break;
default:
$model->addCondition($filter['name'], $filter['op'], $this->getDatetime($filter['value']));
$model->addCondition($this->lookupField, $filter['op'], $this->getDatetime($filter['value']));
}
}
}
Expand All @@ -127,10 +127,8 @@ public function setConditionForModel(Model $model): void
* Will construct and return a date object base on constructor string.
*
* @param string $dateModifier the string to pass to generated a date from
*
* @return \DateTime
*/
public function getDatetime($dateModifier)
public function getDatetime(string $dateModifier): ?\DateTime
{
switch ($dateModifier) {
case 'exact':
Expand All @@ -148,7 +146,7 @@ public function getDatetime($dateModifier)

break;
default:
$date = $dateModifier ? new \DateTime($dateModifier) : null;
$date = null;
}

return $date;
Expand Down
2 changes: 1 addition & 1 deletion src/Table/Column/FilterModel/TypeEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function setConditionForModel(Model $model): void
}
}
if ($values !== []) {
$model->addCondition($filter['name'], 'in', $values);
$model->addCondition($this->lookupField, 'in', $values);
}
}
}
Expand Down
11 changes: 6 additions & 5 deletions src/Table/Column/FilterModel/TypeNumber.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ protected function init(): void
];
$this->op->default = '=';

$this->value->type = $this->lookupField->type;
$this->value->ui['form'] = [Form\Control\Line::class];
$this->addField('range', ['ui' => ['caption' => '', 'form' => [Form\Control\Line::class]]]);
}
Expand All @@ -38,16 +39,16 @@ public function setConditionForModel(Model $model): void
switch ($filter['op']) {
case 'between':
$model->addCondition(
$model->expr('[field] between [value] and [range]', [
'field' => $model->getField($filter['name']),
'value' => $filter['value'],
'range' => $filter['range'],
$model->expr('[field] between [value] and [value2]', [
'field' => $this->lookupField,
'value' => $model->getPersistence()->typecastSaveField($this->lookupField, $filter['value']),
'value2' => $model->getPersistence()->typecastSaveField($this->lookupField, $filter['range']),
])
);

break;
default:
$model->addCondition($filter['name'], $filter['op'], $filter['value']);
$model->addCondition($this->lookupField, $filter['op'], $filter['value']);
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/Table/Column/FilterModel/TypeString.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,23 @@ public function setConditionForModel(Model $model): void
if ($filter !== null) {
switch ($filter['op']) {
case 'is':
$model->addCondition($filter['name'], $filter['value']);
$model->addCondition($this->lookupField, $filter['value']);

break;
case 'is not':
$model->addCondition($filter['name'], '!=', $filter['value']);
$model->addCondition($this->lookupField, '!=', $filter['value']);

break;
case 'contains':
$model->addCondition($filter['name'], 'like', '%' . $filter['value'] . '%');
$model->addCondition($this->lookupField, 'like', '%' . $filter['value'] . '%');

break;
case 'start':
$model->addCondition($filter['name'], 'like', $filter['value'] . '%');
$model->addCondition($this->lookupField, 'like', $filter['value'] . '%');

break;
case 'end':
$model->addCondition($filter['name'], 'like', '%' . $filter['value']);
$model->addCondition($this->lookupField, 'like', '%' . $filter['value']);

break;
}
Expand Down
8 changes: 4 additions & 4 deletions src/Table/Column/FilterModel/TypeTime.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ public function setConditionForModel(Model $model): void
[$d1, $d2] = [$d2, $d1];
}
$model->addCondition($model->expr('[field] between [value] and [value2]', [
'field' => $model->getField($filter['name']),
'value' => $model->getPersistence()->typecastSaveField($model->getField($filter['name']), $d1),
'value2' => $model->getPersistence()->typecastSaveField($model->getField($filter['name']), $d2),
'field' => $this->lookupField,
'value' => $model->getPersistence()->typecastSaveField($this->lookupField, $d1),
'value2' => $model->getPersistence()->typecastSaveField($this->lookupField, $d2),
]));

break;
default:
$model->addCondition($filter['name'], $filter['op'], $filter['value']);
$model->addCondition($this->lookupField, $filter['op'], $filter['value']);
}
}
}
Expand Down
37 changes: 26 additions & 11 deletions tests-behat/filter.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,46 @@ Feature: Table Filter
Given I am on "collection/tablefilter.php"
Then I should see "Australia"
Then I click filter column name "atk_fp_country__name"
When I fill in "value" with "united kingdom"
Then I press button "Set"
When I fill field using "//div.popup[2]//input[@name='value']" with "united kingdom"
When I click using selector "//div.popup[2]//div[text()='Set']"
Then I should not see "Australia"
Then I should see "United Kingdom"
Then I click filter column name "atk_fp_country__phonecode"
When I fill field using "//div.popup[5]//input[@name='value']" with "44"
When I click using selector "//div.popup[5]//div[text()='Set']"
When I fill field using "//div.popup[6]//input[@name='value']" with "44"
When I click using selector "//div.popup[6]//div[text()='Set']"
Then I should see "United Kingdom"
Then I click filter column name "atk_fp_country__phonecode"
When I fill field using "//div.popup[5]//input[@name='value']" with "4"
When I click using selector "//div.popup[5]//div[text()='Set']"
When I fill field using "//div.popup[6]//input[@name='value']" with "4"
When I click using selector "//div.popup[6]//div[text()='Set']"
Then I should not see "United Kingdom"
Then I should see "No records"
Then I click filter column name "atk_fp_country__phonecode"
When I click using selector "//div.popup[5]//div[text()='Clear']"
When I click using selector "//div.popup[6]//div[text()='Clear']"
Then I should not see "No records"
Then I should see "United Kingdom"
Then I click filter column name "is_uk"
Then I select value "Is No" in lookup "//div.popup[6]//input[@name='op']"
When I click using selector "//div.popup[6]//div[text()='Set']"
Then I select value "Is No" in lookup "//div.popup[7]//input[@name='op']"
When I click using selector "//div.popup[7]//div[text()='Set']"
Then I should see "No records"
Then I click filter column name "is_uk"
Then I select value "Is Yes" in lookup "//div.popup[6]//input[@name='op']"
When I click using selector "//div.popup[6]//div[text()='Set']"
Then I select value "Is Yes" in lookup "//div.popup[7]//input[@name='op']"
When I click using selector "//div.popup[7]//div[text()='Set']"
Then I should see "United Kingdom"
Then I press button "Clear Filters"
Then I should not see "United Kingdom"
Then I should see "Australia"
Then I should see "Argentina"
Then I should see "Austria"
Then I click filter column name "atk_fp_country__id"
When I select value "=" in lookup "//div.popup[1]//input[@name='op']"
When I fill field using "//div.popup[1]//input[@name='value']" with "13"
When I click using selector "//div.popup[1]//div[text()='Set']"
Then I should see "Australia"
Then I should not see "Argentina"
Then I should not see "Austria"
Then I click filter column name "atk_fp_country__id"
When I select value "< or equal" in lookup "//div.popup[1]//input[@name='op']"
When I click using selector "//div.popup[1]//div[text()='Set']"
Then I should see "Australia"
Then I should see "Argentina"
Then I should not see "Austria"

0 comments on commit 2e27a15

Please sign in to comment.