aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag
diff options
context:
space:
mode:
authorNicolas LÅ“uillet <nicolas@loeuillet.org>2016-11-04 23:24:43 +0100
committerNicolas LÅ“uillet <nicolas@loeuillet.org>2016-11-19 19:17:30 +0100
commitee122a7528f55dfb5f02e351c509d00b756fedaa (patch)
treeb4b134dc00dda3394a1ab01408369803c8b0b889 /src/Wallabag
parent27dce581caba158a8ffffa5bc30648a21f47da12 (diff)
downloadwallabag-ee122a7528f55dfb5f02e351c509d00b756fedaa.tar.gz
wallabag-ee122a7528f55dfb5f02e351c509d00b756fedaa.tar.zst
wallabag-ee122a7528f55dfb5f02e351c509d00b756fedaa.zip
Added a simple search engine
Fix #18
Diffstat (limited to 'src/Wallabag')
-rw-r--r--src/Wallabag/CoreBundle/Controller/EntryController.php33
-rw-r--r--src/Wallabag/CoreBundle/Controller/ExportController.php2
-rw-r--r--src/Wallabag/CoreBundle/Form/Type/SearchEntryType.php29
-rw-r--r--src/Wallabag/CoreBundle/Repository/EntryRepository.php19
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.en.yml3
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig4
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig9
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/search_form.html.twig14
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig16
9 files changed, 113 insertions, 16 deletions
diff --git a/src/Wallabag/CoreBundle/Controller/EntryController.php b/src/Wallabag/CoreBundle/Controller/EntryController.php
index 3f4eb17d..fc1697be 100644
--- a/src/Wallabag/CoreBundle/Controller/EntryController.php
+++ b/src/Wallabag/CoreBundle/Controller/EntryController.php
@@ -15,10 +15,34 @@ use Wallabag\CoreBundle\Form\Type\NewEntryType;
15use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache; 15use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
16use Wallabag\CoreBundle\Event\EntrySavedEvent; 16use Wallabag\CoreBundle\Event\EntrySavedEvent;
17use Wallabag\CoreBundle\Event\EntryDeletedEvent; 17use Wallabag\CoreBundle\Event\EntryDeletedEvent;
18use Wallabag\CoreBundle\Form\Type\SearchEntryType;
18 19
19class EntryController extends Controller 20class EntryController extends Controller
20{ 21{
21 /** 22 /**
23 * @param Request $request
24 * @param int $page
25 *
26 * @Route("/search/{page}", name="search", defaults={"page" = "1"})
27 *
28 * @return \Symfony\Component\HttpFoundation\Response
29 */
30 public function searchFormAction(Request $request, $page)
31 {
32 $form = $this->createForm(SearchEntryType::class);
33
34 $form->handleRequest($request);
35
36 if ($form->isValid()) {
37 return $this->showEntries('search', $request, $page);
38 }
39
40 return $this->render('WallabagCoreBundle:Entry:search_form.html.twig', [
41 'form' => $form->createView(),
42 ]);
43 }
44
45 /**
22 * Fetch content and update entry. 46 * Fetch content and update entry.
23 * In case it fails, entry will return to avod loosing the data. 47 * In case it fails, entry will return to avod loosing the data.
24 * 48 *
@@ -244,8 +268,13 @@ class EntryController extends Controller
244 private function showEntries($type, Request $request, $page) 268 private function showEntries($type, Request $request, $page)
245 { 269 {
246 $repository = $this->get('wallabag_core.entry_repository'); 270 $repository = $this->get('wallabag_core.entry_repository');
271 $searchTerm = (isset($request->get('search_entry')['term']) ? $request->get('search_entry')['term'] : '');
247 272
248 switch ($type) { 273 switch ($type) {
274 case 'search':
275 $qb = $repository->getBuilderForSearchByUser($this->getUser()->getId(), $searchTerm);
276
277 break;
249 case 'untagged': 278 case 'untagged':
250 $qb = $repository->getBuilderForUntaggedByUser($this->getUser()->getId()); 279 $qb = $repository->getBuilderForUntaggedByUser($this->getUser()->getId());
251 280
@@ -294,11 +323,11 @@ class EntryController extends Controller
294 } 323 }
295 324
296 return $this->render( 325 return $this->render(
297 'WallabagCoreBundle:Entry:entries.html.twig', 326 'WallabagCoreBundle:Entry:entries.html.twig', [
298 [
299 'form' => $form->createView(), 327 'form' => $form->createView(),
300 'entries' => $entries, 328 'entries' => $entries,
301 'currentPage' => $page, 329 'currentPage' => $page,
330 'searchTerm' => $searchTerm,
302 ] 331 ]
303 ); 332 );
304 } 333 }
diff --git a/src/Wallabag/CoreBundle/Controller/ExportController.php b/src/Wallabag/CoreBundle/Controller/ExportController.php
index 79653cfe..abc3336a 100644
--- a/src/Wallabag/CoreBundle/Controller/ExportController.php
+++ b/src/Wallabag/CoreBundle/Controller/ExportController.php
@@ -48,7 +48,7 @@ class ExportController extends Controller
48 * 48 *
49 * @Route("/export/{category}.{format}", name="export_entries", requirements={ 49 * @Route("/export/{category}.{format}", name="export_entries", requirements={
50 * "format": "epub|mobi|pdf|json|xml|txt|csv", 50 * "format": "epub|mobi|pdf|json|xml|txt|csv",
51 * "category": "all|unread|starred|archive|tag_entries|untagged" 51 * "category": "all|unread|starred|archive|tag_entries|untagged|search"
52 * }) 52 * })
53 * 53 *
54 * @return \Symfony\Component\HttpFoundation\Response 54 * @return \Symfony\Component\HttpFoundation\Response
diff --git a/src/Wallabag/CoreBundle/Form/Type/SearchEntryType.php b/src/Wallabag/CoreBundle/Form/Type/SearchEntryType.php
new file mode 100644
index 00000000..b56cae8e
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Form/Type/SearchEntryType.php
@@ -0,0 +1,29 @@
1<?php
2
3namespace Wallabag\CoreBundle\Form\Type;
4
5use Symfony\Component\Form\AbstractType;
6use Symfony\Component\Form\Extension\Core\Type\TextType;
7use Symfony\Component\Form\FormBuilderInterface;
8use Symfony\Component\OptionsResolver\OptionsResolver;
9
10class SearchEntryType extends AbstractType
11{
12 public function buildForm(FormBuilderInterface $builder, array $options)
13 {
14 $builder
15 ->setMethod('GET')
16 ->add('term', TextType::class, [
17 'required' => true,
18 'label' => 'entry.new.form_search.term_label',
19 ])
20 ;
21 }
22
23 public function configureOptions(OptionsResolver $resolver)
24 {
25 $resolver->setDefaults([
26 'csrf_protection' => false,
27 ]);
28 }
29}
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
index 61be5220..8f23164f 100644
--- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
@@ -86,6 +86,25 @@ class EntryRepository extends EntityRepository
86 } 86 }
87 87
88 /** 88 /**
89 * Retrieves entries filtered with a search term for a user.
90 *
91 * @param int $userId
92 * @param string $term
93 *
94 * @return QueryBuilder
95 */
96 public function getBuilderForSearchByUser($userId, $term)
97 {
98 return $this
99 ->getBuilderByUser($userId)
100 ->andWhere('e.content LIKE :term')->setParameter('term', '%'.$term.'%')
101 ->orWhere('e.title LIKE :term')->setParameter('term', '%'.$term.'%')
102 ->leftJoin('e.tags', 't')
103 ->groupBy('e.id')
104 ->having('count(t.id) = 0');
105 }
106
107 /**
89 * Retrieves untagged entries for a user. 108 * Retrieves untagged entries for a user.
90 * 109 *
91 * @param int $userId 110 * @param int $userId
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
index 20e83a07..63216a0f 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
@@ -162,6 +162,7 @@ entry:
162 archived: 'Archived entries' 162 archived: 'Archived entries'
163 filtered: 'Filtered entries' 163 filtered: 'Filtered entries'
164 filtered_tags: 'Filtered by tags:' 164 filtered_tags: 'Filtered by tags:'
165 filtered_search: 'Filtered by search:'
165 untagged: 'Untagged entries' 166 untagged: 'Untagged entries'
166 list: 167 list:
167 number_on_the_page: '{0} There are no entries.|{1} There is one entry.|]1,Inf[ There are %count% entries.' 168 number_on_the_page: '{0} There are no entries.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
@@ -227,6 +228,8 @@ entry:
227 placeholder: 'http://website.com' 228 placeholder: 'http://website.com'
228 form_new: 229 form_new:
229 url_label: Url 230 url_label: Url
231 search:
232 placeholder: 'What are you looking for?'
230 edit: 233 edit:
231 page_title: 'Edit an entry' 234 page_title: 'Edit an entry'
232 title_label: 'Title' 235 title_label: 'Title'
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig
index 92cabdd9..654c1d2d 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig
@@ -6,8 +6,10 @@
6 {{ 'entry.page_titles.archived'|trans }} 6 {{ 'entry.page_titles.archived'|trans }}
7{% elseif currentRoute == 'all' %} 7{% elseif currentRoute == 'all' %}
8 {{ 'entry.page_titles.filtered'|trans }} 8 {{ 'entry.page_titles.filtered'|trans }}
9{% elseif currentRoute == 'search' %}
10 {{ 'entry.page_titles.filtered_search'|trans }} {{ filter }}
9{% elseif currentRoute == 'tag_entries' %} 11{% elseif currentRoute == 'tag_entries' %}
10 {{ 'entry.page_titles.filtered_tags'|trans }} {{ currentTag }} 12 {{ 'entry.page_titles.filtered_tags'|trans }} {{ filter }}
11{% elseif currentRoute == 'untagged' %} 13{% elseif currentRoute == 'untagged' %}
12 {{ 'entry.page_titles.untagged'|trans }} 14 {{ 'entry.page_titles.untagged'|trans }}
13{% else %} 15{% else %}
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 160dbf3d..ff555055 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
@@ -1,11 +1,14 @@
1{% extends "WallabagCoreBundle::layout.html.twig" %} 1{% extends "WallabagCoreBundle::layout.html.twig" %}
2 2
3{% block title %} 3{% block title %}
4 {% set currentTag = '' %} 4 {% set filter = '' %}
5 {% if tag is defined %} 5 {% if tag is defined %}
6 {% set currentTag = tag %} 6 {% set filter = tag %}
7 {% endif %}
8 {% if searchTerm is not empty %}
9 {% set filter = searchTerm %}
7 {% endif %} 10 {% endif %}
8 {% include "@WallabagCore/themes/common/Entry/_title.html.twig" with {'currentTag': currentTag} %} 11 {% include "@WallabagCore/themes/common/Entry/_title.html.twig" with {'filter': filter} %}
9{% endblock %} 12{% endblock %}
10 13
11{% block content %} 14{% block content %}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/search_form.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/search_form.html.twig
new file mode 100644
index 00000000..9b8ac86d
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/search_form.html.twig
@@ -0,0 +1,14 @@
1<form name="search
2" method="GET" action="{{ path('search')}}">
3 {% if form_errors(form) %}
4 <span class="black-text">{{ form_errors(form) }}</span>
5 {% endif %}
6
7 {% if form_errors(form.term) %}
8 <span class="black-text">{{ form_errors(form.term) }}</span>
9 {% endif %}
10
11 {{ form_widget(form.term, { 'attr': {'autocomplete': 'off', 'placeholder': 'entry.search.placeholder'} }) }}
12
13 {{ form_rest(form) }}
14</form>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
index f1ef01df..9437a2a8 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
@@ -89,11 +89,11 @@
89 <i class="material-icons">add</i> 89 <i class="material-icons">add</i>
90 </a> 90 </a>
91 </li> 91 </li>
92 <!--<li> 92 <li>
93 <a title="{{ 'menu.top.search'|trans }}" class="waves-effect" href="javascript: void(null);" id="nav-btn-search"> 93 <a title="{{ 'menu.top.search'|trans }}" class="waves-effect" href="javascript: void(null);" id="nav-btn-search">
94 <i class="material-icons">search</i> 94 <i class="material-icons">search</i>
95 </a> 95 </a>
96 </li>--> 96 </li>
97 <li id="button_filters"> 97 <li id="button_filters">
98 <a class="nav-panel-menu button-collapse-right tooltipped" data-position="bottom" data-delay="50" data-tooltip="{{ 'menu.top.filter_entries'|trans }}" href="#" data-activates="filters"> 98 <a class="nav-panel-menu button-collapse-right tooltipped" data-position="bottom" data-delay="50" data-tooltip="{{ 'menu.top.filter_entries'|trans }}" href="#" data-activates="filters">
99 <i class="material-icons">filter_list</i> 99 <i class="material-icons">filter_list</i>
@@ -106,13 +106,11 @@
106 </li> 106 </li>
107 </ul> 107 </ul>
108 </div> 108 </div>
109 <form method="get" action="index.php"> 109 <div class="input-field nav-panel-search" style="display: none">
110 <div class="input-field nav-panel-search" style="display: none"> 110 {{ render(controller("WallabagCoreBundle:Entry:searchForm")) }}
111 <input name="search" id="searchfield" type="search" required placeholder="{{ 'menu.search_form.input_label'|trans }}"> 111 <label for="search" class="active"><i class="material-icons search">search</i></label>
112 <label for="search"><i class="material-icons search">search</i></label> 112 <i class="material-icons close">clear</i>
113 <i class="material-icons close">clear</i> 113 </div>
114 </div>
115 </form>
116 <div class="input-field nav-panel-add" style="display: none"> 114 <div class="input-field nav-panel-add" style="display: none">
117 {{ render(controller("WallabagCoreBundle:Entry:addEntryForm")) }} 115 {{ render(controller("WallabagCoreBundle:Entry:addEntryForm")) }}
118 <label for="add" class="active"><i class="material-icons add">add</i></label> 116 <label for="add" class="active"><i class="material-icons add">add</i></label>