diff options
Diffstat (limited to 'src/Wallabag')
4 files changed, 102 insertions, 11 deletions
diff --git a/src/Wallabag/CoreBundle/Helper/EntriesExport.php b/src/Wallabag/CoreBundle/Helper/EntriesExport.php index 806319b1..33ff6311 100644 --- a/src/Wallabag/CoreBundle/Helper/EntriesExport.php +++ b/src/Wallabag/CoreBundle/Helper/EntriesExport.php | |||
@@ -5,6 +5,10 @@ namespace Wallabag\CoreBundle\Helper; | |||
5 | use PHPePub\Core\EPub; | 5 | use PHPePub\Core\EPub; |
6 | use PHPePub\Core\Structure\OPF\DublinCore; | 6 | use PHPePub\Core\Structure\OPF\DublinCore; |
7 | use Symfony\Component\HttpFoundation\Response; | 7 | use Symfony\Component\HttpFoundation\Response; |
8 | use Symfony\Component\Serializer\Serializer; | ||
9 | use Symfony\Component\Serializer\Encoder\XmlEncoder; | ||
10 | use Symfony\Component\Serializer\Encoder\JsonEncoder; | ||
11 | use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; | ||
8 | 12 | ||
9 | class EntriesExport | 13 | class EntriesExport |
10 | { | 14 | { |
@@ -86,6 +90,12 @@ class EntriesExport | |||
86 | 90 | ||
87 | case 'csv': | 91 | case 'csv': |
88 | return $this->produceCSV(); | 92 | return $this->produceCSV(); |
93 | |||
94 | case 'json': | ||
95 | return $this->produceJSON(); | ||
96 | |||
97 | case 'xml': | ||
98 | return $this->produceXML(); | ||
89 | } | 99 | } |
90 | 100 | ||
91 | throw new \InvalidArgumentException(sprintf('The format "%s" is not yet supported.', $format)); | 101 | throw new \InvalidArgumentException(sprintf('The format "%s" is not yet supported.', $format)); |
@@ -319,6 +329,51 @@ class EntriesExport | |||
319 | )->send(); | 329 | )->send(); |
320 | } | 330 | } |
321 | 331 | ||
332 | private function produceJSON() | ||
333 | { | ||
334 | $serializer = $this->prepareSerializingContent(); | ||
335 | $jsonContent = $serializer->serialize($this->entries, 'json'); | ||
336 | |||
337 | return Response::create( | ||
338 | $jsonContent, | ||
339 | 200, | ||
340 | array( | ||
341 | 'Content-type' => 'application/json', | ||
342 | 'Content-Disposition' => 'attachment; filename="'.$this->title.'.json"', | ||
343 | 'Content-Transfer-Encoding' => 'UTF-8', | ||
344 | ) | ||
345 | )->send(); | ||
346 | } | ||
347 | |||
348 | private function produceXML() | ||
349 | { | ||
350 | $serializer = $this->prepareSerializingContent(); | ||
351 | $xmlContent = $serializer->serialize($this->entries, 'xml'); | ||
352 | |||
353 | return Response::create( | ||
354 | $xmlContent, | ||
355 | 200, | ||
356 | array( | ||
357 | 'Content-type' => 'application/xml', | ||
358 | 'Content-Disposition' => 'attachment; filename="'.$this->title.'.xml"', | ||
359 | 'Content-Transfer-Encoding' => 'UTF-8', | ||
360 | ) | ||
361 | )->send(); | ||
362 | } | ||
363 | /** | ||
364 | * Return a Serializer object for producing processes that need it (JSON & XML). | ||
365 | * | ||
366 | * @return Serializer | ||
367 | */ | ||
368 | private function prepareSerializingContent() | ||
369 | { | ||
370 | $encoders = array(new XmlEncoder(), new JsonEncoder()); | ||
371 | $normalizers = array(new ObjectNormalizer()); | ||
372 | $normalizers[0]->setIgnoredAttributes(array('user', 'createdAt', 'updatedAt')); | ||
373 | |||
374 | return new Serializer($normalizers, $encoders); | ||
375 | } | ||
376 | |||
322 | /** | 377 | /** |
323 | * Return a kind of footer / information for the epub. | 378 | * Return a kind of footer / information for the epub. |
324 | * | 379 | * |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig index 5a231c86..bf38bff8 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig | |||
@@ -99,13 +99,13 @@ | |||
99 | {% endif %} | 99 | {% endif %} |
100 | <h4 class="center">{% trans %}Export{% endtrans %}</h4> | 100 | <h4 class="center">{% trans %}Export{% endtrans %}</h4> |
101 | <ul> | 101 | <ul> |
102 | <li class="bold"><a class="waves-effect" href="{{ path('ebook', { 'category': currentRoute, 'format': 'epub' }) }}">{% trans %}EPUB{% endtrans %}</a></li> | 102 | <li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub' }) }}">{% trans %}EPUB{% endtrans %}</a></li> |
103 | <li class="bold"><a class="waves-effect" href="{{ path('ebook', { 'category': currentRoute, 'format': 'mobi' }) }}">{% trans %}MOBI{% endtrans %}</a></li> | 103 | <li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi' }) }}">{% trans %}MOBI{% endtrans %}</a></li> |
104 | <li class="bold"><a class="waves-effect" href="{{ path('ebook', { 'category': currentRoute, 'format': 'pdf' }) }}">{% trans %}PDF{% endtrans %}</a></li> | 104 | <li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf' }) }}">{% trans %}PDF{% endtrans %}</a></li> |
105 | <li class="bold"><del><a class="waves-effect" href="{{ path('ebook', { 'category': currentRoute, 'format': 'xml' }) }}">{% trans %}XML{% endtrans %}</a></del></li> | 105 | <li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml' }) }}">{% trans %}XML{% endtrans %}</a></li> |
106 | <li class="bold"><del><a class="waves-effect" href="{{ path('ebook', { 'category': currentRoute, 'format': 'json' }) }}">{% trans %}JSON{% endtrans %}</a></del></li> | 106 | <li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json' }) }}">{% trans %}JSON{% endtrans %}</a></li> |
107 | <li class="bold"><a class="waves-effect" href="{{ path('ebook', { 'category': currentRoute, 'format': 'csv' }) }}">{% trans %}CSV{% endtrans %}</a></li> | 107 | <li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv' }) }}">{% trans %}CSV{% endtrans %}</a></li> |
108 | <li class="bold"><del><a class="waves-effect" href="{{ path('ebook', { 'category': currentRoute, 'format': 'txt' }) }}">{% trans %}TXT{% endtrans %}</a></del></li> | 108 | <li class="bold"><del><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt' }) }}">{% trans %}TXT{% endtrans %}</a></del></li> |
109 | </ul> | 109 | </ul> |
110 | </div> | 110 | </div> |
111 | 111 | ||
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig index bece099a..fd84d984 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig | |||
@@ -106,10 +106,12 @@ | |||
106 | </a> | 106 | </a> |
107 | <div class="collapsible-body"> | 107 | <div class="collapsible-body"> |
108 | <ul> | 108 | <ul> |
109 | {% if export_epub %}<li><a href="{{ path('ebook_entry', { 'id': entry.id, 'format': 'epub' }) }}" title="Generate ePub file">EPUB</a></li>{% endif %} | 109 | {% if export_epub %}<li><a href="{{ path('export_entry', { 'id': entry.id, 'format': 'epub' }) }}" title="Generate ePub file">EPUB</a></li>{% endif %} |
110 | {% if export_mobi %}<li><a href="{{ path('ebook_entry', { 'id': entry.id, 'format': 'mobi' }) }}" title="Generate Mobi file">MOBI</a></li>{% endif %} | 110 | {% if export_mobi %}<li><a href="{{ path('export_entry', { 'id': entry.id, 'format': 'mobi' }) }}" title="Generate Mobi file">MOBI</a></li>{% endif %} |
111 | {% if export_pdf %}<li><a href="{{ path('ebook_entry', { 'id': entry.id, 'format': 'pdf' }) }}" title="Generate PDF file">PDF</a></li>{% endif %} | 111 | {% if export_pdf %}<li><a href="{{ path('export_entry', { 'id': entry.id, 'format': 'pdf' }) }}" title="Generate PDF file">PDF</a></li>{% endif %} |
112 | <li><a href="{{ path('ebook_entry', { 'id': entry.id, 'format': 'csv' }) }}" title="Generate CSV file">CSV</a></li> | 112 | <li><a href="{{ path('export_entry', { 'id': entry.id, 'format': 'csv' }) }}" title="Generate CSV file">CSV</a></li> |
113 | <li><a href="{{ path('export_entry', { 'id': entry.id, 'format': 'json' }) }}" title="Generate JSON file">JSON</a></li> | ||
114 | <li><a href="{{ path('export_entry', { 'id': entry.id, 'format': 'xml' }) }}" title="Generate XML file">XML</a></li> | ||
113 | </ul> | 115 | </ul> |
114 | </div> | 116 | </div> |
115 | </li> | 117 | </li> |
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/ExportControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/ExportControllerTest.php index 3f749aae..febdf4d4 100644 --- a/src/Wallabag/CoreBundle/Tests/Controller/ExportControllerTest.php +++ b/src/Wallabag/CoreBundle/Tests/Controller/ExportControllerTest.php | |||
@@ -113,4 +113,38 @@ class ExportControllerTest extends WallabagCoreTestCase | |||
113 | $this->assertGreaterThan(1, $csv); | 113 | $this->assertGreaterThan(1, $csv); |
114 | $this->assertEquals('Title;URL;Content;Tags;"MIME Type";Language', $csv[0]); | 114 | $this->assertEquals('Title;URL;Content;Tags;"MIME Type";Language', $csv[0]); |
115 | } | 115 | } |
116 | |||
117 | public function testJsonExport() | ||
118 | { | ||
119 | $this->logInAs('admin'); | ||
120 | $client = $this->getClient(); | ||
121 | |||
122 | ob_start(); | ||
123 | $crawler = $client->request('GET', '/export/all.json'); | ||
124 | ob_end_clean(); | ||
125 | |||
126 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
127 | |||
128 | $headers = $client->getResponse()->headers; | ||
129 | $this->assertEquals('application/json', $headers->get('content-type')); | ||
130 | $this->assertEquals('attachment; filename="All articles.json"', $headers->get('content-disposition')); | ||
131 | $this->assertEquals('UTF-8', $headers->get('content-transfer-encoding')); | ||
132 | } | ||
133 | |||
134 | public function testXmlExport() | ||
135 | { | ||
136 | $this->logInAs('admin'); | ||
137 | $client = $this->getClient(); | ||
138 | |||
139 | ob_start(); | ||
140 | $crawler = $client->request('GET', '/export/unread.xml'); | ||
141 | ob_end_clean(); | ||
142 | |||
143 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
144 | |||
145 | $headers = $client->getResponse()->headers; | ||
146 | $this->assertEquals('application/xml', $headers->get('content-type')); | ||
147 | $this->assertEquals('attachment; filename="Unread articles.xml"', $headers->get('content-disposition')); | ||
148 | $this->assertEquals('UTF-8', $headers->get('content-transfer-encoding')); | ||
149 | } | ||
116 | } | 150 | } |