Skip to content

Commit 68d5793

Browse files
committed
Unify grid / list view filters
1 parent c4b417b commit 68d5793

File tree

7 files changed

+512
-1
lines changed

7 files changed

+512
-1
lines changed

wcfsetup/install/files/lib/system/gridView/filter/SelectFilter.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class SelectFilter extends AbstractFilter
2323
public function __construct(
2424
private readonly array $options,
2525
string $databaseColumn = '',
26-
private readonly bool $labelLanguageItems = true
26+
protected readonly bool $labelLanguageItems = true
2727
) {
2828
parent::__construct($databaseColumn);
2929
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace wcf\system\listView\filter;
4+
5+
use wcf\data\DatabaseObjectList;
6+
use wcf\system\category\CategoryHandler;
7+
use wcf\system\form\builder\field\AbstractFormField;
8+
use wcf\system\form\builder\field\SelectFormField;
9+
10+
/**
11+
* Allows a column to be filtered on the basis of a select category.
12+
*
13+
* @author Olaf Braun
14+
* @copyright 2001-2025 WoltLab GmbH
15+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
16+
* @since 6.2
17+
*/
18+
class CategoryFilter extends AbstractFilter
19+
{
20+
/**
21+
* @param \Traversable<mixed> $options
22+
*/
23+
public function __construct(
24+
private readonly \Traversable $options,
25+
string $id,
26+
string $languageItem = 'wcf.global.category',
27+
string $databaseColumn = ''
28+
29+
) {
30+
parent::__construct($id, $languageItem, $databaseColumn);
31+
}
32+
33+
#[\Override]
34+
public function getFormField(): AbstractFormField
35+
{
36+
return SelectFormField::create($this->id)
37+
->label($this->languageItem)
38+
->options($this->options, true);
39+
}
40+
41+
#[\Override]
42+
public function applyFilter(DatabaseObjectList $list, string $value): void
43+
{
44+
$columnName = $this->getDatabaseColumnName($list);
45+
46+
$list->getConditionBuilder()->add("{$columnName} = ?", [$value]);
47+
}
48+
49+
#[\Override]
50+
public function renderValue(string $value): string
51+
{
52+
return CategoryHandler::getInstance()->getCategory((int)$value)->getTitle();
53+
}
54+
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
<?php
2+
3+
namespace wcf\system\listView\filter;
4+
5+
use wcf\data\DatabaseObjectList;
6+
use wcf\system\form\builder\field\AbstractFormField;
7+
use wcf\system\form\builder\field\DateRangeFormField;
8+
use wcf\system\WCF;
9+
10+
/**
11+
* Filter for columns that contain unix timestamps.
12+
*
13+
* @author Marcel Werk
14+
* @copyright 2001-2024 WoltLab GmbH
15+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
16+
* @since 6.2
17+
*/
18+
class DateFilter extends AbstractFilter
19+
{
20+
#[\Override]
21+
public function getFormField(): AbstractFormField
22+
{
23+
return DateRangeFormField::create($this->id)
24+
->label($this->languageItem)
25+
->nullable();
26+
}
27+
28+
#[\Override]
29+
public function applyFilter(DatabaseObjectList $list, string $value): void
30+
{
31+
$columnName = $this->getDatabaseColumnName($list);
32+
$timestamps = $this->getTimestamps($value);
33+
34+
if (!$timestamps['from'] && !$timestamps['to']) {
35+
return;
36+
}
37+
38+
if (!$timestamps['to']) {
39+
$list->getConditionBuilder()->add("{$columnName} >= ?", [$timestamps['from']]);
40+
} else {
41+
$list->getConditionBuilder()->add("{$columnName} BETWEEN ? AND ?", [$timestamps['from'], $timestamps['to']]);
42+
}
43+
}
44+
45+
#[\Override]
46+
public function renderValue(string $value): string
47+
{
48+
$values = explode(';', $value);
49+
if (\count($values) !== 2) {
50+
return '';
51+
}
52+
53+
$locale = WCF::getLanguage()->getLocale();
54+
$fromString = $toString = '';
55+
if ($values[0] !== '') {
56+
$fromDateTime = \DateTime::createFromFormat(
57+
'Y-m-d',
58+
$values[0],
59+
WCF::getUser()->getTimeZone()
60+
);
61+
if ($fromDateTime !== false) {
62+
$fromString = \IntlDateFormatter::formatObject(
63+
$fromDateTime,
64+
[
65+
\IntlDateFormatter::LONG,
66+
\IntlDateFormatter::NONE,
67+
],
68+
$locale
69+
);
70+
}
71+
}
72+
if ($values[1] !== '') {
73+
$toDateTime = \DateTime::createFromFormat(
74+
'Y-m-d',
75+
$values[1],
76+
WCF::getUser()->getTimeZone()
77+
);
78+
if ($toDateTime !== false) {
79+
$toString = \IntlDateFormatter::formatObject(
80+
$toDateTime,
81+
[
82+
\IntlDateFormatter::LONG,
83+
\IntlDateFormatter::NONE,
84+
],
85+
$locale
86+
);
87+
}
88+
}
89+
90+
if ($fromString && $toString) {
91+
return $fromString . '' . $toString;
92+
} else if ($fromString) {
93+
return '>= ' . $fromString;
94+
} else if ($toString) {
95+
return '<= ' . $toString;
96+
}
97+
98+
return '';
99+
}
100+
101+
/**
102+
* @return array{from: int, to: int}
103+
*/
104+
private function getTimestamps(string $value): array
105+
{
106+
$from = 0;
107+
$to = 0;
108+
109+
$values = explode(';', $value);
110+
if (\count($values) === 2) {
111+
$fromDateTime = \DateTime::createFromFormat(
112+
'Y-m-d',
113+
$values[0]
114+
);
115+
if ($fromDateTime !== false) {
116+
$fromDateTime->setTime(0, 0);
117+
$from = $fromDateTime->getTimestamp();
118+
}
119+
120+
$toDateTime = \DateTime::createFromFormat(
121+
'Y-m-d',
122+
$values[1]
123+
);
124+
if ($toDateTime !== false) {
125+
$toDateTime->setTime(23, 59, 59);
126+
$to = $toDateTime->getTimestamp();
127+
}
128+
}
129+
130+
return [
131+
'from' => $from,
132+
'to' => $to,
133+
];
134+
}
135+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
namespace wcf\system\listView\filter;
4+
5+
use wcf\data\DatabaseObjectList;
6+
use wcf\system\form\builder\field\AbstractFormField;
7+
use wcf\system\form\builder\field\NumericRangeFormField;
8+
9+
/**
10+
* Filter for columns that contain numerics.
11+
*
12+
* @author Marcel Werk
13+
* @copyright 2001-2025 WoltLab GmbH
14+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
15+
* @since 6.2
16+
*/
17+
class NumericFilter extends AbstractFilter
18+
{
19+
public function __construct(
20+
string $id,
21+
string $languageItem,
22+
string $databaseColumn = '',
23+
protected readonly bool $integerValues = false
24+
) {
25+
parent::__construct($id, $languageItem, $databaseColumn);
26+
}
27+
28+
#[\Override]
29+
public function getFormField(): AbstractFormField
30+
{
31+
return NumericRangeFormField::create($this->id)
32+
->label($this->languageItem)
33+
->nullable()
34+
->integerValues($this->integerValues);
35+
}
36+
37+
#[\Override]
38+
public function applyFilter(DatabaseObjectList $list, string $value): void
39+
{
40+
$columnName = $this->getDatabaseColumnName($list);
41+
$values = $this->parseValue($value);
42+
43+
if (!$values['from'] && !$values['to']) {
44+
return;
45+
}
46+
47+
if (!$values['to']) {
48+
$list->getConditionBuilder()->add("{$columnName} >= ?", [$values['from']]);
49+
} else {
50+
$list->getConditionBuilder()->add("{$columnName} BETWEEN ? AND ?", [$values['from'], $values['to']]);
51+
}
52+
}
53+
54+
#[\Override]
55+
public function renderValue(string $value): string
56+
{
57+
$values = $this->parseValue($value);
58+
59+
if ($values['from'] && $values['to']) {
60+
return $values['from'] . '' . $values['to'];
61+
} else if ($values['from']) {
62+
return '>= ' . $values['from'];
63+
} else if ($values['to']) {
64+
return '<= ' . $values['to'];
65+
}
66+
67+
return '';
68+
}
69+
70+
/**
71+
* @return array{from: int, to: int}
72+
*/
73+
private function parseValue(string $value): array
74+
{
75+
$from = 0;
76+
$to = 0;
77+
78+
$values = explode(';', $value);
79+
if (\count($values) === 2) {
80+
$from = $values[0];
81+
$to = $values[1];
82+
}
83+
84+
return [
85+
'from' => $from,
86+
'to' => $to,
87+
];
88+
}
89+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace wcf\system\listView\filter;
4+
5+
use wcf\data\DatabaseObjectList;
6+
use wcf\system\form\builder\field\AbstractFormField;
7+
use wcf\system\form\builder\field\SelectFormField;
8+
use wcf\system\WCF;
9+
10+
/**
11+
* Allows a column to be filtered on the basis of a select dropdown.
12+
*
13+
* @author Marcel Werk
14+
* @copyright 2001-2024 WoltLab GmbH
15+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
16+
* @since 6.2
17+
*/
18+
class SelectFilter extends AbstractFilter
19+
{
20+
/**
21+
* @param array<string|int, mixed> $options
22+
*/
23+
public function __construct(
24+
private readonly array $options,
25+
string $id,
26+
string $languageItem,
27+
string $databaseColumn = '',
28+
protected readonly bool $labelLanguageItems = true
29+
) {
30+
parent::__construct($id, $languageItem, $databaseColumn);
31+
}
32+
33+
#[\Override]
34+
public function getFormField(): AbstractFormField
35+
{
36+
return SelectFormField::create($this->id)
37+
->label($this->languageItem)
38+
->options($this->options, labelLanguageItems: $this->labelLanguageItems);
39+
}
40+
41+
#[\Override]
42+
public function applyFilter(DatabaseObjectList $list, string $value): void
43+
{
44+
$columnName = $this->getDatabaseColumnName($list);
45+
46+
$list->getConditionBuilder()->add("{$columnName} = ?", [$value]);
47+
}
48+
49+
#[\Override]
50+
public function renderValue(string $value): string
51+
{
52+
return WCF::getLanguage()->get($this->options[$value]);
53+
}
54+
}

0 commit comments

Comments
 (0)