Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add server side export #83

Merged
merged 62 commits into from
Apr 28, 2020
Merged

Add server side export #83

merged 62 commits into from
Apr 28, 2020

Conversation

MaximePinot
Copy link
Contributor

This Bundle only allows server side processing. This raises an issue when it comes to use the HTML5 export buttons. These buttons only export the current page (as the DOM is only aware of the current page).

This pull request aims to fix this limitation.

Usage

I suggest you look at the ExporterController and the exporter.html.twig file for a complete usage example.

How it works

Front-end

https://github.com/MaximePinot/datatables-bundle/blob/10e586c98cb3c4f2f167828a932ef9180551e33d/tests/Fixtures/AppBundle/Resources/views/exporter.html.twig#L11-L26

Adding an export button must be handled by the front-end developer as it is not the Bundle's concern to manage/render anything. As the Bundle still needs some specific parameters to be sent, I created a function that generates the function needed by the action option.

Back-end

Everything is handled automatically by the Bundle and its current structure (isCallback / getResponse) is not changed (see this piece of code).

To trigger an "export state", the request must be sent with a _exporter parameter (along with the usual _dt parameter) whose value is the name of the DataTable exporter (defined by the getName() method).

At the moment, I only created an Excel exporter. I think the Bundle should be shipped with a few common exporters such as PDF, CSV and HTML. I plan to add these three, but I want to be sure that my implementation is correct before.

Anyone can add a DataTable exporter to its project by creating a service class that implements the Omines\DataTablesBundle\Exporter\DataTableExporterInterface. The service must be tagged with datatables.exporter.

Documentation

I did not write any documentation yet. I first want to be sure that my implementation is correct. When this pull request is ready to be merged. I will add a commit that adds a Server side export section to the documentation.

To maintain BC, it is not possible to type hint with the
TranslatorInterface as older versions of Symfony inject "Symfony\Component\Translation\TranslatorInterface"
while newer versions of Symfony inject "Symfony\Contracts\Translation\TranslatorInterface".
The 'render' column option is usually use to inject HTML.
Tests were passing using "Symfony\Component\Translation\DataCollectorTranslator" as type-hint but Symfony may inject "Symfony\Bundle\FrameworkBundle\Translation\Translator".
* Using a Generator makes the code more readable.
* Avoid creating an array (iterator_to_array) may be sligtly faster?
@curry684
Copy link
Member

curry684 commented Aug 9, 2019

@shades684 changes make sense afaics, your opinion?

@MaximePinot
Copy link
Contributor Author

Hi @curry684, thank you for reviewing my pull request.

I think some things should be improved. For example, it would be better to automatically tag classes that implement Omines\DataTablesBundle\Exporter\DataTableExporterInterface.

I need to add more tests. I'm using my fork in production and a "Cannot traverse an already closed generator" error is raised when one tries to export an empty DataTable. Apart from that, it's working fine.

However, exported data can be confusing depending of the render callback. Is there a way I can get the raw value from the database before the render callback is called?

@curry684
Copy link
Member

curry684 commented Aug 9, 2019

AbstractColumn::transform converts the raw value pre-rendering.

https://github.com/omines/datatables-bundle/blob/94777da/src/Column/AbstractColumn.php#L68-L77

…-export

# Conflicts:
#	composer.json
#	src/DataTable.php
#	src/DataTableFactory.php
#	tests/Fixtures/services.yml
Export the entire table but keep current sort and filtering
@MaximePinot
Copy link
Contributor Author

Hi @curry684 ,

I've been using my server-side-export branch for more than 6 months now on a big project. Everything is working as expected.

Could you also test it on one of your project?

As soon as you tell me everything is fine and my implementation is correct, I will add :

  • A HTML exporter
  • A PDF exporter
  • An "Export" section to the documentation

Then, I believe this PR will be ready to be merged!

MaximePinot and others added 9 commits January 15, 2020 15:11
Will not fix #122 but should prevent similar issues.
* Symfony 3 is not supported, according to the readme.md

Symfony 3 is not supported, according to the readme.md. 
This updates the documentation to reflect that only Symfony 4.1+ is supported by this bundle

* Update index.html.md
This is actually obsolete since Symfony Flex, as you can now run Symfony 4.1 with more recent components.
To maintain BC, it is not possible to type hint with the
TranslatorInterface as older versions of Symfony inject "Symfony\Component\Translation\TranslatorInterface"
while newer versions of Symfony inject "Symfony\Contracts\Translation\TranslatorInterface".
The 'render' column option is usually use to inject HTML.
Tests were passing using "Symfony\Component\Translation\DataCollectorTranslator" as type-hint but Symfony may inject "Symfony\Bundle\FrameworkBundle\Translation\Translator".
* Using a Generator makes the code more readable.
* Avoid creating an array (iterator_to_array) may be sligtly faster?
Export the entire table but keep current sort and filtering
@MaximePinot
Copy link
Contributor Author

Wow, maybe I should have git merge instead of git rebase 😅 Sorry for all the duplicates... But at least, tests are passing!

@MaximePinot MaximePinot requested a review from curry684 April 23, 2020 09:52
@curry684
Copy link
Member

I have no good way to test at the moment and the PR is unreviewable due to the rebase, so I'll just merge it and we'll see how the community likes it :P

@curry684 curry684 merged commit f3a35b3 into omines:master Apr 28, 2020
@MaximePinot
Copy link
Contributor Author

Thanks @curry684! I'm watching this repository so I'll be responsive if someone opens an issue about this feature. 😉

@curry684
Copy link
Member

curry684 commented Jun 30, 2020

It would seem something in Symfony 5 broke it:

https://travis-ci.org/github/omines/datatables-bundle/jobs/703172222

There were 5 errors:
1) Tests\Functional\Exporter\Csv\CsvExporterTest::testExport
Error: Call to undefined method Symfony\Component\HttpFoundation\Response::getFile()
/home/travis/build/omines/datatables-bundle/tests/Functional/Exporter/Csv/CsvExporterTest.php:34
2) Tests\Functional\Exporter\Event\DataTableExporterResponseEventTest::testPreResponseEvent with data set #0 ('excel', 'xlsx')
TypeError: Argument 1 passed to PHPUnit\Framework\Assert::assertStringContainsString() must be of the type string, null given, called in /home/travis/build/omines/datatables-bundle/tests/Functional/Exporter/Event/DataTableExporterResponseEventTest.php on line 43
/home/travis/build/omines/datatables-bundle/tests/Functional/Exporter/Event/DataTableExporterResponseEventTest.php:43
3) Tests\Functional\Exporter\Event\DataTableExporterResponseEventTest::testPreResponseEvent with data set #1 ('txt', 'txt')
TypeError: Argument 1 passed to PHPUnit\Framework\Assert::assertStringContainsString() must be of the type string, null given, called in /home/travis/build/omines/datatables-bundle/tests/Functional/Exporter/Event/DataTableExporterResponseEventTest.php on line 43
/home/travis/build/omines/datatables-bundle/tests/Functional/Exporter/Event/DataTableExporterResponseEventTest.php:43
4) Tests\Functional\Exporter\Excel\ExcelExporterTest::testExport
Error: Call to undefined method Symfony\Component\HttpFoundation\Response::getFile()
/home/travis/build/omines/datatables-bundle/tests/Functional/Exporter/Excel/ExcelExporterTest.php:45
5) Tests\Functional\Exporter\Excel\ExcelExporterTest::testWithSearch
Error: Call to undefined method Symfony\Component\HttpFoundation\Response::getFile()
/home/travis/build/omines/datatables-bundle/tests/Functional/Exporter/Excel/ExcelExporterTest.php:103

Also a fatal:

1) Tests\Functional\Exporter\Excel\ExcelExporterTest::testEmptyDataTable
Failed asserting that false is true.
/home/travis/build/omines/datatables-bundle/tests/Functional/Exporter/Excel/ExcelExporterTest.php:77

Not really sure what's behind this. Could you have a look?

I'm holding off 0.5.0 until this is fixed (currently at rc1).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants