diff options
author | Nicolas LÅ“uillet <nicolas@loeuillet.org> | 2016-11-04 23:24:43 +0100 |
---|---|---|
committer | Nicolas LÅ“uillet <nicolas@loeuillet.org> | 2016-11-19 19:17:30 +0100 |
commit | ee122a7528f55dfb5f02e351c509d00b756fedaa (patch) | |
tree | b4b134dc00dda3394a1ab01408369803c8b0b889 /src | |
parent | 27dce581caba158a8ffffa5bc30648a21f47da12 (diff) | |
download | wallabag-ee122a7528f55dfb5f02e351c509d00b756fedaa.tar.gz wallabag-ee122a7528f55dfb5f02e351c509d00b756fedaa.tar.zst wallabag-ee122a7528f55dfb5f02e351c509d00b756fedaa.zip |
Added a simple search engine
Fix #18
Diffstat (limited to 'src')
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; | |||
15 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache; | 15 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache; |
16 | use Wallabag\CoreBundle\Event\EntrySavedEvent; | 16 | use Wallabag\CoreBundle\Event\EntrySavedEvent; |
17 | use Wallabag\CoreBundle\Event\EntryDeletedEvent; | 17 | use Wallabag\CoreBundle\Event\EntryDeletedEvent; |
18 | use Wallabag\CoreBundle\Form\Type\SearchEntryType; | ||
18 | 19 | ||
19 | class EntryController extends Controller | 20 | class 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 | |||
3 | namespace Wallabag\CoreBundle\Form\Type; | ||
4 | |||
5 | use Symfony\Component\Form\AbstractType; | ||
6 | use Symfony\Component\Form\Extension\Core\Type\TextType; | ||
7 | use Symfony\Component\Form\FormBuilderInterface; | ||
8 | use Symfony\Component\OptionsResolver\OptionsResolver; | ||
9 | |||
10 | class 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> |