Skip to content

Commit 56c3f34

Browse files
authored
Add events before and after creating the response (#373)
1 parent 15974fc commit 56c3f34

File tree

9 files changed

+226
-1
lines changed

9 files changed

+226
-1
lines changed

docs/source/index.html.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,39 @@ Of course you can modify the base type to fit the controller's specific needs be
545545
`handleRequest`. Secondly, the `createDataTableFromType` function accepts an array as a second
546546
argument which is passed to the type class for parametrized instantiation.
547547

548+
# Events
549+
550+
A few events are available that allow you to hook into the DataTables lifecycle. These are dispatched
551+
by the `DataTable` instance, and can be listened to by adding event listeners to the table.
552+
553+
## DataTableEvents::PRE_RESPONSE
554+
555+
This event is dispatched just before the response is created, allowing you to modify the table
556+
one last time while the table state is already known. This could, for instance, be useful for
557+
adding or removing columns when in the server-side exporting context.
558+
559+
```php?start_inline=1
560+
$table->addEventListener(DataTableEvents::PRE_RESPONSE, function (DataTablePreResponseEvent $event) {
561+
$table = $event->getTable();
562+
563+
$table
564+
->add('extraColumn', TextColumn::class)
565+
->remove('obsoleteColumn')
566+
;
567+
});
568+
```
569+
570+
## DataTableEvents::POST_RESPONSE
571+
572+
This event is dispatched just after the response is created but before it is returned to the client.
573+
This is useful for logging, or other post-processing tasks.
574+
575+
```php?start_inline=1
576+
$table->addEventListener(DataTableEvents::POST_RESPONSE, function (DataTablePreResponseEvent $event) use ($logger) {
577+
$logger->info('Table rendered', ['table' => $event->getTable()]);
578+
});
579+
```
580+
548581
# Javascript
549582

550583
```javascript

src/DataTable.php

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
use Omines\DataTablesBundle\Adapter\ResultSetInterface;
1717
use Omines\DataTablesBundle\Column\AbstractColumn;
1818
use Omines\DataTablesBundle\DependencyInjection\Instantiator;
19+
use Omines\DataTablesBundle\Event\DataTablePostResponseEvent;
20+
use Omines\DataTablesBundle\Event\DataTablePreResponseEvent;
1921
use Omines\DataTablesBundle\Exception\InvalidArgumentException;
2022
use Omines\DataTablesBundle\Exception\InvalidConfigurationException;
2123
use Omines\DataTablesBundle\Exception\InvalidStateException;
@@ -123,6 +125,28 @@ public function add(string $name, string $type, array $options = []): static
123125
return $this;
124126
}
125127

128+
public function remove(string $name): static
129+
{
130+
if (!isset($this->columnsByName[$name])) {
131+
throw new InvalidArgumentException(sprintf("There is no column with name '%s'", $name));
132+
}
133+
134+
$column = $this->columnsByName[$name];
135+
unset($this->columnsByName[$name]);
136+
$index = array_search($column, $this->columns, true);
137+
unset($this->columns[$index]);
138+
139+
return $this;
140+
}
141+
142+
public function clearColumns(): static
143+
{
144+
$this->columns = [];
145+
$this->columnsByName = [];
146+
147+
return $this;
148+
}
149+
126150
/**
127151
* Adds an event listener to an event on this DataTable.
128152
*
@@ -263,14 +287,19 @@ public function handleRequest(Request $request): static
263287

264288
public function getResponse(): Response
265289
{
290+
$this->eventDispatcher->dispatch(new DataTablePreResponseEvent($this), DataTableEvents::PRE_RESPONSE);
291+
266292
$state = $this->getState();
267293

268294
// Server side export
269295
if (null !== $state->getExporterName()) {
270-
return $this->exporterManager
296+
$response = $this->exporterManager
271297
->setDataTable($this)
272298
->setExporterName($state->getExporterName())
273299
->getResponse();
300+
$this->eventDispatcher->dispatch(new DataTablePostResponseEvent($this), DataTableEvents::POST_RESPONSE);
301+
302+
return $response;
274303
}
275304

276305
$resultSet = $this->getResultSet();
@@ -285,6 +314,8 @@ public function getResponse(): Response
285314
$response['template'] = $this->renderer->renderDataTable($this, $this->template, $this->templateParams);
286315
}
287316

317+
$this->eventDispatcher->dispatch(new DataTablePostResponseEvent($this), DataTableEvents::POST_RESPONSE);
318+
288319
return new JsonResponse($response);
289320
}
290321

src/DataTableEvents.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
/*
4+
* Symfony DataTables Bundle
5+
* (c) Omines Internetbureau B.V. - https://omines.nl/
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
declare(strict_types=1);
12+
13+
namespace Omines\DataTablesBundle;
14+
15+
/**
16+
* Available events.
17+
*
18+
* @author Jeroen van den Broek <[email protected]>
19+
*/
20+
final class DataTableEvents
21+
{
22+
/**
23+
* The PRE_RESPONSE event is dispatched right before the response
24+
* is generated to allow any last-minute changes based on the table state.
25+
*
26+
* @Event("Omines\DataTablesBundle\Event\DataTablePreResponseEvent")
27+
*/
28+
public const PRE_RESPONSE = 'omines_datatables.pre_response';
29+
30+
/**
31+
* The POST_RESPONSE event is dispatched right after the response
32+
* is generated but before it is returned.
33+
*
34+
* @Event("Omines\DataTablesBundle\Event\DataTablePostResponseEvent")
35+
*/
36+
public const POST_RESPONSE = 'omines_datatables.post_response';
37+
}

src/Event/DataTableEvent.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
/*
4+
* Symfony DataTables Bundle
5+
* (c) Omines Internetbureau B.V. - https://omines.nl/
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
declare(strict_types=1);
12+
13+
namespace Omines\DataTablesBundle\Event;
14+
15+
use Omines\DataTablesBundle\DataTable;
16+
use Symfony\Contracts\EventDispatcher\Event;
17+
18+
/**
19+
* DataTableEvent.
20+
*
21+
* @author Jeroen van den Broek <[email protected]>
22+
*/
23+
abstract class DataTableEvent extends Event
24+
{
25+
/**
26+
* DataTableEvent constructor.
27+
*/
28+
public function __construct(
29+
protected readonly DataTable $table,
30+
) {
31+
}
32+
33+
public function getTable(): DataTable
34+
{
35+
return $this->table;
36+
}
37+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/*
4+
* Symfony DataTables Bundle
5+
* (c) Omines Internetbureau B.V. - https://omines.nl/
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
declare(strict_types=1);
12+
13+
namespace Omines\DataTablesBundle\Event;
14+
15+
/**
16+
* DataTablePostResponseEvent.
17+
*
18+
* @author Jeroen van den Broek <[email protected]>
19+
*/
20+
class DataTablePostResponseEvent extends DataTableResponseEvent
21+
{
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/*
4+
* Symfony DataTables Bundle
5+
* (c) Omines Internetbureau B.V. - https://omines.nl/
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
declare(strict_types=1);
12+
13+
namespace Omines\DataTablesBundle\Event;
14+
15+
/**
16+
* DataTablePreResponseEvent.
17+
*
18+
* @author Jeroen van den Broek <[email protected]>
19+
*/
20+
class DataTablePreResponseEvent extends DataTableResponseEvent
21+
{
22+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/*
4+
* Symfony DataTables Bundle
5+
* (c) Omines Internetbureau B.V. - https://omines.nl/
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
declare(strict_types=1);
12+
13+
namespace Omines\DataTablesBundle\Event;
14+
15+
use Symfony\Component\HttpFoundation\Response;
16+
17+
/**
18+
* DataTableResponseEvent.
19+
*
20+
* @author Jeroen van den Broek <[email protected]>
21+
*/
22+
abstract class DataTableResponseEvent extends DataTableEvent
23+
{
24+
public function getResponse(): Response
25+
{
26+
return $this->table->getResponse();
27+
}
28+
}

tests/Fixtures/AppBundle/DataTable/Type/RegularPersonTableType.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
use Omines\DataTablesBundle\Column\DateTimeColumn;
1717
use Omines\DataTablesBundle\Column\TextColumn;
1818
use Omines\DataTablesBundle\DataTable;
19+
use Omines\DataTablesBundle\DataTableEvents;
1920
use Omines\DataTablesBundle\DataTableTypeInterface;
21+
use Omines\DataTablesBundle\Event\DataTablePreResponseEvent;
2022

2123
/**
2224
* RegularPersonTableType.
@@ -36,6 +38,7 @@ public function configure(DataTable $dataTable, array $options): void
3638
},
3739
'format' => 'd-m-Y',
3840
])
41+
->add('dummy', TextColumn::class, ['data' => fn () => ''])
3942
->createAdapter(ArrayAdapter::class, [
4043
['firstName' => 'Donald', 'lastName' => 'Trump'],
4144
['firstName' => 'Barack', 'lastName' => 'Obama'],
@@ -49,6 +52,16 @@ public function configure(DataTable $dataTable, array $options): void
4952

5053
return $row;
5154
})
55+
->addEventListener(DataTableEvents::PRE_RESPONSE, function (DataTablePreResponseEvent $event) {
56+
$table = $event->getTable();
57+
58+
$table
59+
->add('email', TextColumn::class, [
60+
'data' => fn ($context) => mb_strtolower($context['lastName']) . '@example.org',
61+
])
62+
->remove('dummy')
63+
;
64+
})
5265
;
5366
}
5467
}

tests/Functional/FunctionalTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ public function testTypeDataTable(): void
8181
$this->assertSame('George W.', $json->data[0]->firstName);
8282
$this->assertSame('BUSH', $json->data[0]->lastName);
8383
$this->assertSame('01-01-2017', $json->data[0]->lastActivity);
84+
$this->assertSame('[email protected]', $json->data[0]->email);
85+
$this->assertObjectNotHasProperty('dummy', $json->data[0]);
8486

8587
$json = $this->callDataTableUrl('/type?_dt=persons&draw=1&search[value]=Bush');
8688

0 commit comments

Comments
 (0)