Skip to content

Commit eab3226

Browse files
committed
Can change grid datamodel
Simple refactoring, just introducing interface for datamodel. This change is without bc break. Now it is possible do to change datamodel with new method setDataModel.
1 parent e7b0ceb commit eab3226

File tree

5 files changed

+173
-7
lines changed

5 files changed

+173
-7
lines changed

src/DataGrid.php

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@
3636
use Ublaboo\DataGrid\Column\MultiAction;
3737
use Ublaboo\DataGrid\Components\DataGridPaginator\DataGridPaginator;
3838
use Ublaboo\DataGrid\DataSource\IDataSource;
39+
use Ublaboo\DataGrid\Exception\CannotChangeDataModelException;
3940
use Ublaboo\DataGrid\Exception\DataGridColumnNotFoundException;
4041
use Ublaboo\DataGrid\Exception\DataGridException;
4142
use Ublaboo\DataGrid\Exception\DataGridFilterNotFoundException;
4243
use Ublaboo\DataGrid\Exception\DataGridHasToBeAttachedToPresenterComponentException;
44+
use Ublaboo\DataGrid\Exception\InitializingDataModelCallbacksException;
4345
use Ublaboo\DataGrid\Export\Export;
4446
use Ublaboo\DataGrid\Export\ExportCsv;
4547
use Ublaboo\DataGrid\Filter\Filter;
@@ -237,7 +239,7 @@ class DataGrid extends Control
237239
protected $toolbarButtons = [];
238240

239241
/**
240-
* @var DataModel|null
242+
* @var DataModelInterface|null
241243
*/
242244
protected $dataModel;
243245

@@ -494,7 +496,7 @@ public function render(): void
494496
/**
495497
* Check whether datagrid has set some columns, initiated data source, etc
496498
*/
497-
if (!($this->dataModel instanceof DataModel)) {
499+
if (!($this->dataModel instanceof DataModelInterface)) {
498500
throw new DataGridException('You have to set a data source first.');
499501
}
500502

@@ -623,7 +625,7 @@ public function setRowCallback(callable $callback): self
623625
*/
624626
public function setPrimaryKey(string $primaryKey): self
625627
{
626-
if ($this->dataModel instanceof DataModel) {
628+
if ($this->dataModel instanceof DataModelInterface) {
627629
throw new DataGridException('Please set datagrid primary key before setting datasource.');
628630
}
629631

@@ -637,14 +639,26 @@ public function setPrimaryKey(string $primaryKey): self
637639
* @param mixed $source
638640
* @return static
639641
* @throws InvalidArgumentException
642+
* @throws InitializingDataModelCallbacksException
640643
*/
641644
public function setDataSource($source): self
642645
{
643646
$this->dataModel = new DataModel($source, $this->primaryKey);
644647

645-
$this->dataModel->onBeforeFilter[] = [$this, 'beforeDataModelFilter'];
646-
$this->dataModel->onAfterFilter[] = [$this, 'afterDataModelFilter'];
647-
$this->dataModel->onAfterPaginated[] = [$this, 'afterDataModelPaginated'];
648+
$this->initializeCallbacks();
649+
650+
return $this;
651+
}
652+
653+
654+
/**
655+
* @throws InitializingDataModelCallbacksException
656+
*/
657+
public function setDataModel(DataModelInterface $dataModel): self
658+
{
659+
$this->dataModel = $dataModel;
660+
661+
$this->initializeCallbacks();
648662

649663
return $this;
650664
}
@@ -3324,4 +3338,16 @@ private function getPresenterInstance(): Presenter
33243338
return $this->getPresenter();
33253339
}
33263340

3341+
3342+
private function initializeCallbacks(): void
3343+
{
3344+
if ($this->dataModel === null) {
3345+
throw new InitializingDataModelCallbacksException();
3346+
}
3347+
3348+
$this->dataModel->onBeforeFilter[] = [$this, 'beforeDataModelFilter'];
3349+
$this->dataModel->onAfterFilter[] = [$this, 'afterDataModelFilter'];
3350+
$this->dataModel->onAfterPaginated[] = [$this, 'afterDataModelPaginated'];
3351+
}
3352+
33273353
}

src/DataModel.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
* @method onAfterFilter(IDataSource $dataSource)
3232
* @method onAfterPaginated(IDataSource $dataSource)
3333
*/
34-
final class DataModel
34+
final class DataModel implements DataModelInterface
3535
{
3636

3737
use SmartObject;

src/DataModelInterface.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php declare(strict_types = 1);
2+
namespace Ublaboo\DataGrid;
3+
4+
5+
use Ublaboo\DataGrid\Components\DataGridPaginator\DataGridPaginator;
6+
use Ublaboo\DataGrid\DataSource\IDataSource;
7+
use Ublaboo\DataGrid\Utils\Sorting;
8+
9+
/**
10+
* @method onBeforeFilter(IDataSource $dataSource)
11+
* @method onAfterFilter(IDataSource $dataSource)
12+
* @method onAfterPaginated(IDataSource $dataSource)
13+
*/
14+
interface DataModelInterface
15+
{
16+
17+
public function getDataSource(): IDataSource;
18+
19+
20+
public function filterData(?DataGridPaginator $paginatorComponent, Sorting $sorting, array $filters): iterable;
21+
22+
23+
/**
24+
* @return mixed
25+
*/
26+
public function filterRow(array $condition);
27+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Ublaboo\DataGrid\Exception;
4+
5+
use Throwable;
6+
7+
class InitializingDataModelCallbacksException extends DataGridException
8+
{
9+
public function __construct(?Throwable $previous = null)
10+
{
11+
parent::__construct("Cannot set callbacks before data model is set.", 0, $previous);
12+
}
13+
}

src/RestBasedDataModel.php

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace Ublaboo\DataGrid;
6+
7+
use Nette\SmartObject;
8+
use Ublaboo\DataGrid\Components\DataGridPaginator\DataGridPaginator;
9+
use Ublaboo\DataGrid\DataSource\IDataSource;
10+
use Ublaboo\DataGrid\Utils\Sorting;
11+
12+
/**
13+
* @method onBeforeFilter(IDataSource $dataSource)
14+
* @method onAfterFilter(IDataSource $dataSource)
15+
* @method onAfterPaginated(IDataSource $dataSource)
16+
*/
17+
final class RestBasedDataModel implements DataModelInterface
18+
{
19+
20+
use SmartObject;
21+
22+
/**
23+
* @var array|callable[]
24+
*/
25+
public $onBeforeFilter = [];
26+
27+
/**
28+
* @var array|callable[]
29+
*/
30+
public $onAfterFilter = [];
31+
32+
/**
33+
* @var array|callable[]
34+
*/
35+
public $onAfterPaginated = [];
36+
37+
/**
38+
* @var IDataSource
39+
*/
40+
private $dataSource;
41+
42+
43+
public function __construct(IDataSource $source)
44+
{
45+
$this->dataSource = $source;
46+
}
47+
48+
49+
public function getDataSource(): IDataSource
50+
{
51+
return $this->dataSource;
52+
}
53+
54+
55+
public function filterData(
56+
?DataGridPaginator $paginatorComponent,
57+
Sorting $sorting,
58+
array $filters
59+
): iterable
60+
{
61+
$this->onBeforeFilter($this->dataSource);
62+
63+
$this->dataSource->filter($filters);
64+
65+
$this->onAfterFilter($this->dataSource);
66+
67+
/**
68+
* Paginator is optional
69+
*/
70+
if ($paginatorComponent !== null) {
71+
$paginator = $paginatorComponent->getPaginator();
72+
73+
$this->dataSource->sort($sorting)->limit(
74+
$paginator->getOffset(),
75+
$paginator->getItemsPerPage()
76+
);
77+
78+
$this->onAfterPaginated($this->dataSource);
79+
80+
$data = $this->dataSource->getData();
81+
$paginator->setItemCount($this->dataSource->getCount());
82+
83+
return $data;
84+
}
85+
86+
return $this->dataSource->sort($sorting)->getData();
87+
}
88+
89+
90+
/**
91+
* @return mixed
92+
*/
93+
public function filterRow(array $condition)
94+
{
95+
$this->onBeforeFilter($this->dataSource);
96+
$this->onAfterFilter($this->dataSource);
97+
98+
return $this->dataSource->filterOne($condition)->getData();
99+
}
100+
}

0 commit comments

Comments
 (0)