diff options
5 files changed, 104 insertions, 17 deletions
diff --git a/.travis.yml b/.travis.yml index 229e3e0e..c09bcd22 100644 --- a/.travis.yml +++ b/.travis.yml | |||
@@ -16,12 +16,15 @@ cache: | |||
16 | - $HOME/.npm | 16 | - $HOME/.npm |
17 | - $HOME/.yarn-cache | 17 | - $HOME/.yarn-cache |
18 | 18 | ||
19 | if: | | ||
20 | type = pull_request OR \ | ||
21 | branch = master | ||
22 | |||
19 | php: | 23 | php: |
20 | - 7.1 | 24 | - 7.1 |
21 | - 7.2 | 25 | - 7.2 |
22 | - 7.3 | 26 | - 7.3 |
23 | - 7.4 | 27 | - 7.4 |
24 | - nightly | ||
25 | 28 | ||
26 | node_js: | 29 | node_js: |
27 | - "5" | 30 | - "5" |
@@ -34,11 +37,10 @@ env: | |||
34 | matrix: | 37 | matrix: |
35 | fast_finish: true | 38 | fast_finish: true |
36 | include: | 39 | include: |
37 | - php: 7.2 | 40 | - php: 7.3 |
38 | env: CS_FIXER=run VALIDATE_TRANSLATION_FILE=run ASSETS=build DB=sqlite | 41 | env: CS_FIXER=run VALIDATE_TRANSLATION_FILE=run ASSETS=build DB=sqlite |
39 | allow_failures: | 42 | allow_failures: |
40 | - php: 7.4 | 43 | - php: 7.4 |
41 | - php: nightly | ||
42 | 44 | ||
43 | # exclude v1 branches | 45 | # exclude v1 branches |
44 | branches: | 46 | branches: |
diff --git a/src/Wallabag/CoreBundle/Controller/ExportController.php b/src/Wallabag/CoreBundle/Controller/ExportController.php index 282fd733..cec8d499 100644 --- a/src/Wallabag/CoreBundle/Controller/ExportController.php +++ b/src/Wallabag/CoreBundle/Controller/ExportController.php | |||
@@ -68,6 +68,18 @@ class ExportController extends Controller | |||
68 | ); | 68 | ); |
69 | 69 | ||
70 | $title = 'Tag ' . $tag->getLabel(); | 70 | $title = 'Tag ' . $tag->getLabel(); |
71 | } elseif ('search' === $category) { | ||
72 | $searchTerm = (isset($request->get('search_entry')['term']) ? $request->get('search_entry')['term'] : ''); | ||
73 | $currentRoute = (null !== $request->query->get('currentRoute') ? $request->query->get('currentRoute') : ''); | ||
74 | |||
75 | $entries = $repository->getBuilderForSearchByUser( | ||
76 | $this->getUser()->getId(), | ||
77 | $searchTerm, | ||
78 | $currentRoute | ||
79 | )->getQuery() | ||
80 | ->getResult(); | ||
81 | |||
82 | $title = 'Search ' . $searchTerm; | ||
71 | } else { | 83 | } else { |
72 | $entries = $repository | 84 | $entries = $repository |
73 | ->$methodBuilder($this->getUser()->getId()) | 85 | ->$methodBuilder($this->getUser()->getId()) |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig index b747ed84..4182628f 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig | |||
@@ -96,16 +96,21 @@ | |||
96 | {% if tag is defined %} | 96 | {% if tag is defined %} |
97 | {% set currentTag = tag %} | 97 | {% set currentTag = tag %} |
98 | {% endif %} | 98 | {% endif %} |
99 | {% set exportSearchTerm = null %} | ||
100 | {% if searchTerm is defined %} | ||
101 | {% set exportSearchTerm = searchTerm %} | ||
102 | {% endif %} | ||
103 | {% set previousRoute = app.request.attributes.get('currentRoute') %} | ||
99 | <h2>{{ 'entry.list.export_title'|trans }}</h2> | 104 | <h2>{{ 'entry.list.export_title'|trans }}</h2> |
100 | <a href="javascript: void(null);" id="download-form-close" class="close-button--popup close-button">×</a> | 105 | <a href="javascript: void(null);" id="download-form-close" class="close-button--popup close-button">×</a> |
101 | <ul> | 106 | <ul> |
102 | {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub', 'tag' : currentTag }) }}">EPUB</a></li>{% endif %} | 107 | {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">EPUB</a></li>{% endif %} |
103 | {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi', 'tag' : currentTag }) }}">MOBI</a></li>{% endif %} | 108 | {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">MOBI</a></li>{% endif %} |
104 | {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf', 'tag' : currentTag }) }}">PDF</a></li>{% endif %} | 109 | {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">PDF</a></li>{% endif %} |
105 | {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json', 'tag' : currentTag }) }}">JSON</a></li>{% endif %} | 110 | {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">JSON</a></li>{% endif %} |
106 | {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv', 'tag' : currentTag }) }}">CSV</a></li>{% endif %} | 111 | {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">CSV</a></li>{% endif %} |
107 | {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt', 'tag' : currentTag }) }}">TXT</a></li>{% endif %} | 112 | {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">TXT</a></li>{% endif %} |
108 | {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml', 'tag' : currentTag }) }}">XML</a></li>{% endif %} | 113 | {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">XML</a></li>{% endif %} |
109 | </ul> | 114 | </ul> |
110 | </aside> | 115 | </aside> |
111 | 116 | ||
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 3906e1e0..0c21dc5d 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 | |||
@@ -63,15 +63,20 @@ | |||
63 | {% if tag is defined %} | 63 | {% if tag is defined %} |
64 | {% set currentTag = tag.slug %} | 64 | {% set currentTag = tag.slug %} |
65 | {% endif %} | 65 | {% endif %} |
66 | {% set exportSearchTerm = null %} | ||
67 | {% if searchTerm is defined %} | ||
68 | {% set exportSearchTerm = searchTerm %} | ||
69 | {% endif %} | ||
70 | {% set previousRoute = app.request.attributes.get('currentRoute') %} | ||
66 | <h4 class="center">{{ 'entry.list.export_title'|trans }}</h4> | 71 | <h4 class="center">{{ 'entry.list.export_title'|trans }}</h4> |
67 | <ul> | 72 | <ul> |
68 | {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub', 'tag' : currentTag }) }}">EPUB</a></li>{% endif %} | 73 | {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">EPUB</a></li>{% endif %} |
69 | {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi', 'tag' : currentTag }) }}">MOBI</a></li>{% endif %} | 74 | {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">MOBI</a></li>{% endif %} |
70 | {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf', 'tag' : currentTag }) }}">PDF</a></li>{% endif %} | 75 | {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">PDF</a></li>{% endif %} |
71 | {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json', 'tag' : currentTag }) }}">JSON</a></li>{% endif %} | 76 | {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">JSON</a></li>{% endif %} |
72 | {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv', 'tag' : currentTag }) }}">CSV</a></li>{% endif %} | 77 | {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">CSV</a></li>{% endif %} |
73 | {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt', 'tag' : currentTag }) }}">TXT</a></li>{% endif %} | 78 | {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">TXT</a></li>{% endif %} |
74 | {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml', 'tag' : currentTag }) }}">XML</a></li>{% endif %} | 79 | {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">XML</a></li>{% endif %} |
75 | </ul> | 80 | </ul> |
76 | </div> | 81 | </div> |
77 | 82 | ||
diff --git a/tests/Wallabag/CoreBundle/Controller/ExportControllerTest.php b/tests/Wallabag/CoreBundle/Controller/ExportControllerTest.php index d7ce7c45..36822ab3 100644 --- a/tests/Wallabag/CoreBundle/Controller/ExportControllerTest.php +++ b/tests/Wallabag/CoreBundle/Controller/ExportControllerTest.php | |||
@@ -3,9 +3,13 @@ | |||
3 | namespace Tests\Wallabag\CoreBundle\Controller; | 3 | namespace Tests\Wallabag\CoreBundle\Controller; |
4 | 4 | ||
5 | use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; | 5 | use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; |
6 | use Wallabag\CoreBundle\Entity\Entry; | ||
6 | 7 | ||
7 | class ExportControllerTest extends WallabagCoreTestCase | 8 | class ExportControllerTest extends WallabagCoreTestCase |
8 | { | 9 | { |
10 | private $adminEntry; | ||
11 | private $bobEntry; | ||
12 | |||
9 | public function testLogin() | 13 | public function testLogin() |
10 | { | 14 | { |
11 | $client = $this->getClient(); | 15 | $client = $this->getClient(); |
@@ -243,6 +247,30 @@ class ExportControllerTest extends WallabagCoreTestCase | |||
243 | $this->assertContains('foo', $content[0]['tags']); | 247 | $this->assertContains('foo', $content[0]['tags']); |
244 | } | 248 | } |
245 | 249 | ||
250 | public function testJsonExportFromSearch() | ||
251 | { | ||
252 | $this->setUpForJsonExportFromSearch(); | ||
253 | |||
254 | $this->logInAs('admin'); | ||
255 | $client = $this->getClient(); | ||
256 | |||
257 | ob_start(); | ||
258 | $crawler = $client->request('GET', '/export/search.json?search_entry[term]=entry+search¤tRoute=homepage'); | ||
259 | ob_end_clean(); | ||
260 | |||
261 | $this->assertSame(200, $client->getResponse()->getStatusCode()); | ||
262 | |||
263 | $headers = $client->getResponse()->headers; | ||
264 | $this->assertSame('application/json', $headers->get('content-type')); | ||
265 | $this->assertSame('attachment; filename="Search entry search articles.json"', $headers->get('content-disposition')); | ||
266 | $this->assertSame('UTF-8', $headers->get('content-transfer-encoding')); | ||
267 | |||
268 | $content = json_decode($client->getResponse()->getContent(), true); | ||
269 | $this->assertCount(1, $content); | ||
270 | |||
271 | $this->tearDownForJsonExportFromSearch(); | ||
272 | } | ||
273 | |||
246 | public function testXmlExport() | 274 | public function testXmlExport() |
247 | { | 275 | { |
248 | $this->logInAs('admin'); | 276 | $this->logInAs('admin'); |
@@ -282,6 +310,41 @@ class ExportControllerTest extends WallabagCoreTestCase | |||
282 | $this->assertNotEmpty('updated_at', (string) $content->entry[0]->updated_at); | 310 | $this->assertNotEmpty('updated_at', (string) $content->entry[0]->updated_at); |
283 | } | 311 | } |
284 | 312 | ||
313 | private function setUpForJsonExportFromSearch() | ||
314 | { | ||
315 | $client = $this->getClient(); | ||
316 | $em = $this->getEntityManager(); | ||
317 | |||
318 | $userRepository = $client->getContainer() | ||
319 | ->get('wallabag_user.user_repository.test'); | ||
320 | |||
321 | $user = $userRepository->findOneByUserName('admin'); | ||
322 | $this->adminEntry = new Entry($user); | ||
323 | $this->adminEntry->setUrl('http://0.0.0.0/entry-search-admin'); | ||
324 | $this->adminEntry->setTitle('test title entry search admin'); | ||
325 | $this->adminEntry->setContent('this is my content /o/'); | ||
326 | $em->persist($this->adminEntry); | ||
327 | |||
328 | $user = $userRepository->findOneByUserName('bob'); | ||
329 | $this->bobEntry = new Entry($user); | ||
330 | $this->bobEntry->setUrl('http://0.0.0.0/entry-search-bob'); | ||
331 | $this->bobEntry->setTitle('test title entry search bob'); | ||
332 | $this->bobEntry->setContent('this is my content /o/'); | ||
333 | $em->persist($this->bobEntry); | ||
334 | |||
335 | $em->flush(); | ||
336 | } | ||
337 | |||
338 | private function tearDownForJsonExportFromSearch() | ||
339 | { | ||
340 | $em = $this->getEntityManager(); | ||
341 | |||
342 | $em->remove($this->adminEntry); | ||
343 | $em->remove($this->bobEntry); | ||
344 | |||
345 | $em->flush(); | ||
346 | } | ||
347 | |||
285 | private function getSanitizedFilename($title) | 348 | private function getSanitizedFilename($title) |
286 | { | 349 | { |
287 | return preg_replace('/[^A-Za-z0-9\- \']/', '', iconv('utf-8', 'us-ascii//TRANSLIT', $title)); | 350 | return preg_replace('/[^A-Za-z0-9\- \']/', '', iconv('utf-8', 'us-ascii//TRANSLIT', $title)); |