Skip to content

Commit 537d931

Browse files
committed
added export support
1 parent 0a45ef3 commit 537d931

25 files changed

+485
-109
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"symfony/config": "^4.0",
2727
"symfony/dependency-injection": "^4.0",
2828
"symfony/property-access": "^4.0",
29+
"symfony/serializer": "^4.2",
2930
"symfony/templating": "^4.0",
3031
"symfony/yaml": "^4.0",
3132
"twig/twig": "^2.0"

src/Column/Column.php

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use FreezyBee\DataGridBundle\Filter\DateRangeFilter;
88
use FreezyBee\DataGridBundle\Filter\Filter;
99
use FreezyBee\DataGridBundle\Filter\NumberRangeFilter;
10+
use FreezyBee\DataGridBundle\Filter\SelectBooleanFilter;
1011
use FreezyBee\DataGridBundle\Filter\SelectEntityFilter;
1112
use FreezyBee\DataGridBundle\Filter\SelectFilter;
1213
use Symfony\Component\Templating\EngineInterface;
@@ -43,9 +44,15 @@ abstract class Column
4344
/** @var string|null */
4445
protected $customTemplate;
4546

47+
/** @var bool */
48+
protected $allowExport = true;
49+
50+
/** @var bool */
51+
protected $allowRender = true;
52+
4653
/**
4754
* @var callable|null
48-
* callable(mixed $value)
55+
* callable(mixed $value, array $params)
4956
*/
5057
protected $customRendererCallback;
5158

@@ -138,7 +145,7 @@ public function setSelectFilter(array $options): self
138145
*/
139146
public function setSelectBooleanFilter(): self
140147
{
141-
$this->filter = new SelectFilter(['Ano' => 1, 'Ne' => 0]);
148+
$this->filter = new SelectBooleanFilter();
142149
return $this->setFilterable();
143150
}
144151

@@ -236,6 +243,42 @@ public function setCustomTemplate(string $customTemplate): self
236243
return $this;
237244
}
238245

246+
/**
247+
* @return bool
248+
*/
249+
public function isAllowExport(): bool
250+
{
251+
return $this->allowExport;
252+
}
253+
254+
/**
255+
* @param bool $allowExport
256+
* @return Column
257+
*/
258+
public function setAllowExport(bool $allowExport): self
259+
{
260+
$this->allowExport = $allowExport;
261+
return $this;
262+
}
263+
264+
/**
265+
* @return bool
266+
*/
267+
public function isAllowRender(): bool
268+
{
269+
return $this->allowRender;
270+
}
271+
272+
/**
273+
* @param bool $allowRender
274+
* @return Column
275+
*/
276+
public function setAllowRender(bool $allowRender): self
277+
{
278+
$this->allowRender = $allowRender;
279+
return $this;
280+
}
281+
239282
/**
240283
* @param callable $customRendererCallback
241284
*/
@@ -283,16 +326,17 @@ public function setCustomSortCallback(callable $customSortCallback): self
283326
/**
284327
* @param mixed $row
285328
* @param EngineInterface $engine
329+
* @param array $params
286330
* @return string|null
287331
*/
288-
public function renderContent($row, EngineInterface $engine): ?string
332+
public function renderContent($row, EngineInterface $engine, array $params = []): ?string
289333
{
290334
if ($this->customTemplate !== null) {
291-
return $engine->render($this->customTemplate, ['item' => $row]);
335+
return $engine->render($this->customTemplate, $params + ['item' => $row]);
292336
}
293337

294338
if (is_callable($this->customRendererCallback)) {
295-
return call_user_func($this->customRendererCallback, $row);
339+
return call_user_func($this->customRendererCallback, $row, $params);
296340
}
297341

298342
return null;

src/Column/DateTimeColumn.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,17 @@ public function __construct(string $name, string $label, string $format)
2828
/**
2929
* {@inheritdoc}
3030
*/
31-
public function renderContent($row, EngineInterface $engine): ?string
31+
public function renderContent($row, EngineInterface $engine, array $params = []): ?string
3232
{
33-
$content = parent::renderContent($row, $engine);
33+
$content = parent::renderContent($row, $engine, $params);
3434
if ($content !== null) {
3535
return $content;
3636
}
3737

3838
return $engine->render('@FreezyBeeDataGrid/column/datetime.html.twig', [
39-
'item' => $row,
40-
'propertyName' => $this->contentColumnName,
41-
'format' => $this->format,
42-
]);
39+
'item' => $row,
40+
'propertyName' => $this->contentColumnName,
41+
'format' => $this->format,
42+
] + $params);
4343
}
4444
}

src/Column/LinkColumn.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,18 @@ public function __construct(string $name, string $label, string $route, ?string
2929
/**
3030
* {@inheritdoc}
3131
*/
32-
public function renderContent($row, EngineInterface $engine): ?string
32+
public function renderContent($row, EngineInterface $engine, array $params = []): ?string
3333
{
34-
$content = parent::renderContent($row, $engine);
34+
$content = parent::renderContent($row, $engine, $params);
3535
if ($content !== null) {
3636
return $content;
3737
}
3838

3939
return $engine->render('@FreezyBeeDataGrid/column/link.html.twig', [
40-
'item' => $row,
41-
'linkIdPropertyName' => "{$this->name}.id",
42-
'propertyName' => $this->contentColumnName,
43-
'route' => $this->route,
44-
]);
40+
'item' => $row,
41+
'linkIdPropertyName' => "{$this->name}.id",
42+
'propertyName' => $this->contentColumnName,
43+
'route' => $this->route,
44+
] + $params);
4545
}
4646
}

src/Column/TextColumn.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ class TextColumn extends Column
1414
/**
1515
* {@inheritdoc}
1616
*/
17-
public function renderContent($row, EngineInterface $engine): ?string
17+
public function renderContent($row, EngineInterface $engine, array $params = []): ?string
1818
{
19-
$content = parent::renderContent($row, $engine);
19+
$content = parent::renderContent($row, $engine, $params);
2020
if ($content !== null) {
2121
return $content;
2222
}
2323

2424
return $engine->render('@FreezyBeeDataGrid/column/text.html.twig', [
25-
'item' => $row,
26-
'propertyName' => $this->contentColumnName,
27-
]);
25+
'item' => $row,
26+
'propertyName' => $this->contentColumnName,
27+
] + $params);
2828
}
2929
}

src/Controller/DataGridController.php

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use FreezyBee\DataGridBundle\DataGridFactory;
88
use Symfony\Component\HttpFoundation\JsonResponse;
99
use Symfony\Component\HttpFoundation\Request;
10+
use Symfony\Component\HttpFoundation\Response;
1011

1112
/**
1213
* @author Jakub Janata <[email protected]>
@@ -29,9 +30,27 @@ public function __construct(DataGridFactory $dataGridFactory)
2930
* @param Request $request
3031
* @return JsonResponse
3132
*/
32-
public function handle(string $name, Request $request): JsonResponse
33+
public function ajax(string $name, Request $request): JsonResponse
3334
{
34-
$name = preg_replace('/\//', '\\', $name) ?? '';
35-
return $this->dataGridFactory->create($name)->ajax($request);
35+
return $this->dataGridFactory->create(self::processName($name))->ajax($request);
36+
}
37+
38+
/**
39+
* @param string $name
40+
* @param Request $request
41+
* @return Response
42+
*/
43+
public function export(string $name, Request $request): Response
44+
{
45+
return $this->dataGridFactory->create(self::processName($name))->export($request);
46+
}
47+
48+
/**
49+
* @param string $name
50+
* @return string
51+
*/
52+
private static function processName(string $name): string
53+
{
54+
return preg_replace('/\//', '\\', $name) ?? '';
3655
}
3756
}

src/DataGrid.php

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44

55
namespace FreezyBee\DataGridBundle;
66

7-
use FreezyBee\DataGridBundle\Column\ActionColumn;
87
use FreezyBee\DataGridBundle\DataSource\DataSourceInterface;
8+
use FreezyBee\DataGridBundle\Export\DataGridExporterInterface;
99
use Symfony\Component\HttpFoundation\JsonResponse;
1010
use Symfony\Component\HttpFoundation\Request;
11+
use Symfony\Component\HttpFoundation\Response;
1112
use Symfony\Component\Templating\EngineInterface;
1213

1314
/**
@@ -18,6 +19,9 @@ class DataGrid
1819
/** @var EngineInterface */
1920
private $engine;
2021

22+
/** @var DataGridExporterInterface */
23+
private $exporter;
24+
2125
/** @var DataSourceInterface */
2226
private $dataSource;
2327

@@ -29,17 +33,20 @@ class DataGrid
2933

3034
/**
3135
* @param EngineInterface $engine
36+
* @param DataGridExporterInterface $exporter
3237
* @param DataSourceInterface $dataSource
3338
* @param DataGridConfig $config
3439
* @param string $name
3540
*/
3641
public function __construct(
3742
EngineInterface $engine,
43+
DataGridExporterInterface $exporter,
3844
DataSourceInterface $dataSource,
3945
DataGridConfig $config,
4046
string $name
4147
) {
4248
$this->engine = $engine;
49+
$this->exporter = $exporter;
4350
$this->dataSource = $dataSource;
4451
$this->config = $config;
4552
$this->name = $name;
@@ -50,6 +57,33 @@ public function __construct(
5057
* @return JsonResponse
5158
*/
5259
public function ajax(Request $request): JsonResponse
60+
{
61+
$result = $this->processData($request, false);
62+
63+
return (new JsonResponse([
64+
'draw' => $request->query->getInt('draw'),
65+
'recordsTotal' => $result['totalCount'],
66+
'recordsFiltered' => $result['filteredCount'],
67+
'data' => $result['data'],
68+
]))->setEncodingOptions(JSON_UNESCAPED_UNICODE);
69+
}
70+
71+
72+
/**
73+
* @param Request $request
74+
* @return Response
75+
*/
76+
public function export(Request $request): Response
77+
{
78+
return $this->exporter->export($this->processData($request, true)['data']);
79+
}
80+
81+
/**
82+
* @param Request $request
83+
* @param bool $export
84+
* @return array
85+
*/
86+
private function processData(Request $request, bool $export): array
5387
{
5488
$totalCount = $this->dataSource->getTotalCount();
5589

@@ -63,7 +97,7 @@ public function ajax(Request $request): JsonResponse
6397

6498
// filters
6599
foreach ($query['columns'] as $index => $ajaxColumn) {
66-
$value = $ajaxColumn['search']['value'];
100+
$value = $ajaxColumn['search']['value'] ?? '';
67101
$column = $this->config->getColumns()[$index] ?? null;
68102

69103
if ($value !== '' && $column !== null && $column->isFilterable()) {
@@ -73,22 +107,27 @@ public function ajax(Request $request): JsonResponse
73107

74108
$filteredCount = $this->dataSource->getFilteredCount();
75109

76-
// limit and offset
77-
$this->dataSource->applyLimitAndOffset((int) $query['length'], (int) $query['start']);
78-
79-
$items = $this->dataSource->getData();
110+
if (!$export) {
111+
// limit and offset
112+
$this->dataSource->applyLimitAndOffset((int) $query['length'], (int) $query['start']);
113+
}
80114

81115
$data = [];
82-
foreach ($items as $item) {
116+
foreach ($this->dataSource->getData() as $item) {
117+
// custom export
118+
if ($export && $this->config->getCustomExportCallback() !== null) {
119+
$data[] = $this->config->getCustomExportCallback()($item);
120+
continue;
121+
}
122+
83123
$row = [];
84124
foreach ($this->config->getColumns() as $column) {
85-
if ($column instanceof ActionColumn) {
86-
continue;
125+
if (($export && $column->isAllowExport()) || (!$export && $column->isAllowRender())) {
126+
$row[] = $column->renderContent($item, $this->engine, ['export' => $export]);
87127
}
88-
$row[] = $column->renderContent($item, $this->engine);
89128
}
90129

91-
if ($this->config->getActionColumn()->hasActions()) {
130+
if (!$export && $this->config->getActionColumn()->hasActions()) {
92131
$row[] = $this->engine->render('@FreezyBeeDataGrid/action.html.twig', [
93132
'item' => $item,
94133
'actions' => $this->config->getActionColumn()->getActions()
@@ -97,14 +136,14 @@ public function ajax(Request $request): JsonResponse
97136
$data[] = $row;
98137
}
99138

100-
return (new JsonResponse([
101-
'draw' => $request->query->getInt('draw'),
102-
'recordsTotal' => $totalCount,
103-
'recordsFiltered' => $filteredCount,
139+
return [
104140
'data' => $data,
105-
]))->setEncodingOptions(JSON_UNESCAPED_UNICODE);
141+
'totalCount' => $totalCount,
142+
'filteredCount' => $filteredCount,
143+
];
106144
}
107145

146+
108147
/**
109148
* @return string
110149
*/
@@ -123,7 +162,8 @@ public function render(): string
123162
'perPage' => $this->config->getDefaultPerPage(), $this->config->getColumns(),
124163
'sortIndex' => $sortIndex,
125164
'sortDir' => $this->config->getDefaultSortColumnDirection() ?? 'desc',
126-
]
165+
],
166+
'allowExport' => $this->config->isAllowExport(),
127167
]);
128168
}
129169
}

0 commit comments

Comments
 (0)