datatables-bundle icon indicating copy to clipboard operation
datatables-bundle copied to clipboard

DataTableExporterResponseEvent should contain instance of DataTable

Open MIvanIsten opened this issue 1 year ago • 3 comments

If there are multiple tables on same page with export, each adding own DataTableExporterEvents::PRE_RESPONSE event listener, exporting any of the tables, fires all registered DataTableExporterEvents::PRE_RESPONSE events. The export file name is overwriten by each event. As a result every export file is named by last fired event.

$table1 = $dataTableFactory->create()
    ->setName('dt-1')
    ->add(...)
    ->addEventListener(DataTableExporterEvents::PRE_RESPONSE, function (DataTableExporterResponseEvent $e) {
        $response = $e->getResponse();
        $ext = $response->getFile()->getExtension();
        $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'table-1-export.' . $ext);
    })
    ->handleRequest($request);
$table2 = $dataTableFactory->create()
    ->setName('dt-2')
    ->add(...)
    ->addEventListener(DataTableExporterEvents::PRE_RESPONSE, function (DataTableExporterResponseEvent $e) {
        $response = $e->getResponse();
        $ext = $response->getFile()->getExtension();
        $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'table-2-export.' . $ext);
    })
    ->handleRequest($request);

expected output export from table1 named as table-1-export.xlsx export from table2 named as table-2-export.xlsx

current output export from table1 named as table-2-export.xlsx export from table2 named as table-2-export.xlsx

DataTableExporterResponseEvent should contain instance of DataTable, so we can decide inside event callback to skip it if it belongs to other table.

Or fix DataTableExporterManager to dispatch only events that belong to exported DataTable.

MIvanIsten avatar Jul 23 '24 11:07 MIvanIsten

Stale issue message

github-actions[bot] avatar Sep 21 '24 22:09 github-actions[bot]

Stale issue message

github-actions[bot] avatar Dec 24 '24 22:12 github-actions[bot]

Stale issue message

github-actions[bot] avatar Apr 02 '25 22:04 github-actions[bot]

Stale issue message

github-actions[bot] avatar Jul 02 '25 22:07 github-actions[bot]

Update src/Exporter/Event/DataTableExporterResponseEvent.php to

class DataTableExporterResponseEvent extends Event
{
    /** @var BinaryFileResponse */
    private $response;

    /** @var DataTable */
    private $dataTable;

    /**
     * DataTableExporterResponseEvent constructor.
     */
    public function __construct(BinaryFileResponse $response, DataTable $dataTable)
    {
        $this->response = $response;
        $this->dataTable= $dataTable;
    }

    public function getResponse(): BinaryFileResponse
    {
        return $this->response;
    }

    public function getDataTable(): DataTable
    {
        return $this->dataTable;
    }
}

and replace: https://github.com/omines/datatables-bundle/blob/f346876d17b4f83dcf6025aeaeaf2b36f4ee892f/src/Exporter/DataTableExporterManager.php#L75 with:

        $this->dataTable->getEventDispatcher()->dispatch(new DataTableExporterResponseEvent($response, $this->dataTable), DataTableExporterEvents::PRE_RESPONSE);

this allows to skip event on wrong tables

$table1 = $dataTableFactory->create()
	->setName('dt-1')
	->add(...)
	->addEventListener(DataTableExporterEvents::PRE_RESPONSE, function (DataTableExporterResponseEvent $e) {
		if ($e->getDataTable()->getName() !== 'dt-1') {
			return;
		}
		$response = $e->getResponse();
		$ext = $response->getFile()->getExtension();
		$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'table-1-export.' . $ext);
	})
	->handleRequest($request);
$table2 = $dataTableFactory->create()
	->setName('dt-2')
	->add(...)
	->addEventListener(DataTableExporterEvents::PRE_RESPONSE, function (DataTableExporterResponseEvent $e) {
		if ($e->getDataTable()->getName() !== 'dt-2') {
			return;
		}
		$response = $e->getResponse();
		$ext = $response->getFile()->getExtension();
		$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'table-2-export.' . $ext);
	})
	->handleRequest($request);

MIvanIsten avatar Nov 27 '25 15:11 MIvanIsten