Skip to content

Commit 410ca34

Browse files
authored
Merge pull request #2778 from yajra/p1
[10.x] Fix set total & filtered records count
2 parents d13de45 + a81f9f5 commit 410ca34

File tree

6 files changed

+156
-161
lines changed

6 files changed

+156
-161
lines changed

.github/workflows/continuous-integration.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
with:
4040
timeout_minutes: 5
4141
max_attempts: 5
42-
command: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress
42+
command: COMPOSER_ROOT_VERSION=dev-master composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress
4343

4444
- name: Execute tests
4545
run: vendor/bin/phpunit --verbose

.github/workflows/static-analysis.yml

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,33 @@ on:
2222

2323
jobs:
2424
static-analysis-phpstan:
25+
2526
name: "Static Analysis with PHPStan"
2627
runs-on: ubuntu-latest
2728

2829
strategy:
30+
fail-fast: true
2931
matrix:
30-
php-version:
31-
- "8.1"
32+
php: [8.1]
33+
stability: [prefer-stable]
3234

3335
steps:
34-
- name: "Checkout code"
35-
uses: "actions/checkout@v2"
36+
- name: Checkout code
37+
uses: actions/checkout@v2
3638

37-
- name: "Install PHP"
38-
uses: "shivammathur/setup-php@v2"
39+
- name: Setup PHP
40+
uses: shivammathur/setup-php@v2
3941
with:
40-
coverage: "none"
41-
php-version: "${{ matrix.php-version }}"
42-
tools: "cs2pr"
42+
php-version: ${{ matrix.php }}
43+
tools: composer:v2
44+
coverage: none
4345

44-
- name: "Install dependencies with Composer"
45-
uses: "ramsey/composer-install@v1"
46+
- name: Install dependencies
47+
uses: nick-invision/retry@v1
48+
with:
49+
timeout_minutes: 5
50+
max_attempts: 5
51+
command: COMPOSER_ROOT_VERSION=dev-master composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress
4652

4753
- name: "Run a static analysis with phpstan/phpstan"
48-
run: "vendor/bin/phpstan --error-format=checkstyle | cs2pr"
54+
run: "vendor/bin/phpstan --error-format=checkstyle"

src/CollectionDataTable.php

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public static function create($source)
9191
*/
9292
public function count(): int
9393
{
94-
return ($this->collection->count() > $this->totalRecords) ? $this->totalRecords : $this->collection->count();
94+
return $this->collection->count();
9595
}
9696

9797
/**
@@ -112,8 +112,6 @@ public function columnSearch(): void
112112
continue;
113113
}
114114

115-
$this->isFilterApplied = true;
116-
117115
$regex = $this->request->isRegex($i);
118116
$keyword = $this->request->columnKeyword($i);
119117

@@ -187,16 +185,6 @@ public function make($mDataSupport = true): JsonResponse
187185
}
188186
}
189187

190-
/**
191-
* Count total items.
192-
*
193-
* @return int
194-
*/
195-
public function totalCount(): int
196-
{
197-
return $this->totalRecords ?: $this->collection->count();
198-
}
199-
200188
/**
201189
* Get results.
202190
*
@@ -254,8 +242,6 @@ protected function globalSearch(string $keyword): void
254242
$keyword = $this->config->isCaseInsensitive() ? Str::lower($keyword) : $keyword;
255243

256244
$this->collection = $this->collection->filter(function ($row) use ($keyword) {
257-
$this->isFilterApplied = true;
258-
259245
$data = $this->serialize($row);
260246
foreach ($this->request->searchableColumnIndex() as $index) {
261247
$column = $this->getColumnName($index);

src/DataTableAbstract.php

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,16 @@ abstract class DataTableAbstract implements DataTable
7272
/**
7373
* Total records.
7474
*
75-
* @var int
75+
* @var int|null
7676
*/
77-
protected int $totalRecords = 0;
77+
protected ?int $totalRecords = null;
7878

7979
/**
8080
* Total filtered records.
8181
*
82-
* @var int
82+
* @var int|null
8383
*/
84-
protected int $filteredRecords = 0;
84+
protected ?int $filteredRecords = null;
8585

8686
/**
8787
* Auto-filter flag.
@@ -109,17 +109,10 @@ abstract class DataTableAbstract implements DataTable
109109
'DT_RowAttr' => [],
110110
];
111111

112-
/**
113-
* [internal] Track if any filter was applied for at least one column.
114-
*
115-
* @var bool
116-
*/
117-
protected bool $isFilterApplied = false;
118-
119112
/**
120113
* Custom ordering callback.
121114
*
122-
* @var ?callable
115+
* @var callable|null
123116
*/
124117
protected $orderCallback = null;
125118

@@ -453,7 +446,7 @@ public function with($key, $value = ''): static
453446
* @param callable $value
454447
* @return $this
455448
*/
456-
public function withQuery($key, callable $value): static
449+
public function withQuery(string $key, callable $value): static
457450
{
458451
$this->appends[$key] = $value;
459452

@@ -492,7 +485,7 @@ public function blacklist(array $blacklist): static
492485
* @param string|array $whitelist
493486
* @return $this
494487
*/
495-
public function whitelist($whitelist = '*'): static
488+
public function whitelist(array|string $whitelist = '*'): static
496489
{
497490
$this->columnDef['whitelist'] = $whitelist;
498491

@@ -505,7 +498,7 @@ public function whitelist($whitelist = '*'): static
505498
* @param bool $state
506499
* @return $this
507500
*/
508-
public function smart($state = true): static
501+
public function smart(bool $state = true): static
509502
{
510503
$this->config->set('datatables.search.smart', $state);
511504

@@ -518,7 +511,7 @@ public function smart($state = true): static
518511
* @param bool $state
519512
* @return $this
520513
*/
521-
public function startsWithSearch($state = true): static
514+
public function startsWithSearch(bool $state = true): static
522515
{
523516
$this->config->set('datatables.search.starts_with', $state);
524517

@@ -531,7 +524,7 @@ public function startsWithSearch($state = true): static
531524
* @param bool $multiTerm
532525
* @return $this
533526
*/
534-
public function setMultiTerm($multiTerm = true): static
527+
public function setMultiTerm(bool $multiTerm = true): static
535528
{
536529
$this->config->set('datatables.search.multi_term', $multiTerm);
537530

@@ -544,20 +537,36 @@ public function setMultiTerm($multiTerm = true): static
544537
* @param int $total
545538
* @return $this
546539
*/
547-
public function setTotalRecords($total): static
540+
public function setTotalRecords(int $total): static
548541
{
542+
$this->skipTotalRecords();
549543
$this->totalRecords = $total;
550544

551545
return $this;
552546
}
553547

548+
/**
549+
* Skip total records and set the recordsTotal equals to recordsFiltered.
550+
* This will improve the performance by skipping the total count query.
551+
*
552+
* @return $this
553+
*
554+
* @deprecated Just use setTotalRecords instead.
555+
*/
556+
public function skipTotalRecords(): static
557+
{
558+
$this->totalRecords = 0;
559+
560+
return $this;
561+
}
562+
554563
/**
555564
* Set filtered records manually.
556565
*
557566
* @param int $total
558567
* @return $this
559568
*/
560-
public function setFilteredRecords($total): static
569+
public function setFilteredRecords(int $total): static
561570
{
562571
$this->filteredRecords = $total;
563572

@@ -651,7 +660,6 @@ abstract protected function defaultOrdering(): void;
651660
public function filter(callable $callback, $globalSearch = false): static
652661
{
653662
$this->autoFilter = $globalSearch;
654-
$this->isFilterApplied = true;
655663
$this->filterCallback = $callback;
656664

657665
return $this;
@@ -721,7 +729,7 @@ protected function filterRecords(): void
721729

722730
$this->columnSearch();
723731
$this->searchPanesSearch();
724-
$this->filteredRecords = $this->isFilterApplied ? $this->filteredCount() : $this->totalRecords;
732+
$this->filteredCount();
725733
}
726734

727735
/**
@@ -778,14 +786,24 @@ protected function searchPanesSearch(): void
778786
// Add support for search pane.
779787
}
780788

789+
/**
790+
* Count total items.
791+
*
792+
* @return int
793+
*/
794+
public function totalCount(): int
795+
{
796+
return $this->totalRecords ??= $this->count();
797+
}
798+
781799
/**
782800
* Count filtered items.
783801
*
784802
* @return int
785803
*/
786804
protected function filteredCount(): int
787805
{
788-
return $this->filteredRecords ?: $this->count();
806+
return $this->filteredRecords ??= $this->count();
789807
}
790808

791809
/**

src/QueryDataTable.php

Lines changed: 5 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,6 @@ class QueryDataTable extends DataTableAbstract
4141
*/
4242
protected $limitCallback = null;
4343

44-
/**
45-
* Flag to skip total records count query.
46-
*
47-
* @var bool
48-
*/
49-
protected bool $skipTotalRecords = false;
50-
5144
/**
5245
* Flag to keep the select bindings.
5346
*
@@ -103,9 +96,7 @@ public static function canCreate($source): bool
10396
public function make($mDataSupport = true): JsonResponse
10497
{
10598
try {
106-
$this->prepareQuery();
107-
108-
$results = $this->results();
99+
$results = $this->prepareQuery()->results();
109100
$processed = $this->processResults($results, $mDataSupport);
110101
$data = $this->transform($results, $processed);
111102

@@ -117,8 +108,10 @@ public function make($mDataSupport = true): JsonResponse
117108

118109
/**
119110
* Prepare query by executing count, filter, order and paginate.
111+
*
112+
* @return $this
120113
*/
121-
protected function prepareQuery(): void
114+
protected function prepareQuery(): static
122115
{
123116
if (! $this->prepared) {
124117
$this->totalRecords = $this->totalCount();
@@ -131,22 +124,8 @@ protected function prepareQuery(): void
131124
}
132125

133126
$this->prepared = true;
134-
}
135127

136-
/**
137-
* Count total items.
138-
*
139-
* @return int
140-
*/
141-
public function totalCount(): int
142-
{
143-
if ($this->skipTotalRecords) {
144-
$this->isFilterApplied = true;
145-
146-
return 1;
147-
}
148-
149-
return $this->totalRecords ?: $this->count();
128+
return $this;
150129
}
151130

152131
/**
@@ -215,19 +194,6 @@ public function results(): Collection
215194
return $this->query->get();
216195
}
217196

218-
/**
219-
* Skip total records and set the recordsTotal equals to recordsFiltered.
220-
* This will improve the performance by skipping the total count query.
221-
*
222-
* @return $this
223-
*/
224-
public function skipTotalRecords(): static
225-
{
226-
$this->skipTotalRecords = true;
227-
228-
return $this;
229-
}
230-
231197
/**
232198
* Keep the select bindings.
233199
*
@@ -268,8 +234,6 @@ public function columnSearch(): void
268234
$keyword = $this->getColumnSearchKeyword($index);
269235
$this->compileColumnSearch($index, $column, $keyword);
270236
}
271-
272-
$this->isFilterApplied = true;
273237
}
274238
}
275239

@@ -628,26 +592,9 @@ protected function searchPanesSearch(): void
628592
} else {
629593
$this->query->whereIn($column, $values);
630594
}
631-
632-
$this->isFilterApplied = true;
633595
}
634596
}
635597

636-
/**
637-
* Count filtered items.
638-
*
639-
* @return int
640-
*/
641-
protected function filteredCount(): int
642-
{
643-
$this->filteredRecords = $this->filteredRecords ?: $this->count();
644-
if ($this->skipTotalRecords) {
645-
$this->totalRecords = $this->filteredRecords;
646-
}
647-
648-
return $this->filteredRecords;
649-
}
650-
651598
/**
652599
* Resolve callback parameter instance.
653600
*
@@ -769,8 +716,6 @@ protected function globalSearch(string $keyword): void
769716
} else {
770717
$this->compileQuerySearch($query, $column, $keyword);
771718
}
772-
773-
$this->isFilterApplied = true;
774719
});
775720
});
776721
}

0 commit comments

Comments
 (0)