]> BookStack Code Mirror - bookstack/blob - app/Http/Controllers/SearchController.php
Started implementation of new search system
[bookstack] / app / Http / Controllers / SearchController.php
1 <?php namespace BookStack\Http\Controllers;
2
3 use BookStack\Repos\EntityRepo;
4 use BookStack\Services\SearchService;
5 use BookStack\Services\ViewService;
6 use Illuminate\Http\Request;
7
8 class SearchController extends Controller
9 {
10     protected $entityRepo;
11     protected $viewService;
12     protected $searchService;
13
14     /**
15      * SearchController constructor.
16      * @param EntityRepo $entityRepo
17      * @param ViewService $viewService
18      * @param SearchService $searchService
19      */
20     public function __construct(EntityRepo $entityRepo, ViewService $viewService, SearchService $searchService)
21     {
22         $this->entityRepo = $entityRepo;
23         $this->viewService = $viewService;
24         $this->searchService = $searchService;
25         parent::__construct();
26     }
27
28     /**
29      * Searches all entities.
30      * @param Request $request
31      * @return \Illuminate\View\View
32      * @internal param string $searchTerm
33      */
34     public function searchAll(Request $request)
35     {
36         if (!$request->has('term')) {
37             return redirect()->back();
38         }
39         $searchTerm = $request->get('term');
40 //        $paginationAppends = $request->only('term'); TODO - Check pagination
41         $this->setPageTitle(trans('entities.search_for_term', ['term' => $searchTerm]));
42
43         $entities = $this->searchService->searchEntities($searchTerm);
44
45         return view('search/all', [
46             'entities'   => $entities,
47             'searchTerm' => $searchTerm
48         ]);
49     }
50
51     /**
52      * Search only the pages in the system.
53      * @param Request $request
54      * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
55      */
56     public function searchPages(Request $request)
57     {
58         if (!$request->has('term')) return redirect()->back();
59
60         $searchTerm = $request->get('term');
61         $paginationAppends = $request->only('term');
62         $pages = $this->entityRepo->getBySearch('page', $searchTerm, [], 20, $paginationAppends);
63         $this->setPageTitle(trans('entities.search_page_for_term', ['term' => $searchTerm]));
64         return view('search/entity-search-list', [
65             'entities'   => $pages,
66             'title'      => trans('entities.search_results_page'),
67             'searchTerm' => $searchTerm
68         ]);
69     }
70
71     /**
72      * Search only the chapters in the system.
73      * @param Request $request
74      * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
75      */
76     public function searchChapters(Request $request)
77     {
78         if (!$request->has('term')) return redirect()->back();
79
80         $searchTerm = $request->get('term');
81         $paginationAppends = $request->only('term');
82         $chapters = $this->entityRepo->getBySearch('chapter', $searchTerm, [], 20, $paginationAppends);
83         $this->setPageTitle(trans('entities.search_chapter_for_term', ['term' => $searchTerm]));
84         return view('search/entity-search-list', [
85             'entities'   => $chapters,
86             'title'      => trans('entities.search_results_chapter'),
87             'searchTerm' => $searchTerm
88         ]);
89     }
90
91     /**
92      * Search only the books in the system.
93      * @param Request $request
94      * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
95      */
96     public function searchBooks(Request $request)
97     {
98         if (!$request->has('term')) return redirect()->back();
99
100         $searchTerm = $request->get('term');
101         $paginationAppends = $request->only('term');
102         $books = $this->entityRepo->getBySearch('book', $searchTerm, [], 20, $paginationAppends);
103         $this->setPageTitle(trans('entities.search_book_for_term', ['term' => $searchTerm]));
104         return view('search/entity-search-list', [
105             'entities'   => $books,
106             'title'      => trans('entities.search_results_book'),
107             'searchTerm' => $searchTerm
108         ]);
109     }
110
111     /**
112      * Searches all entities within a book.
113      * @param Request $request
114      * @param integer $bookId
115      * @return \Illuminate\View\View
116      * @internal param string $searchTerm
117      */
118     public function searchBook(Request $request, $bookId)
119     {
120         if (!$request->has('term')) {
121             return redirect()->back();
122         }
123         $searchTerm = $request->get('term');
124         $searchWhereTerms = [['book_id', '=', $bookId]];
125         $pages = $this->entityRepo->getBySearch('page', $searchTerm, $searchWhereTerms);
126         $chapters = $this->entityRepo->getBySearch('chapter', $searchTerm, $searchWhereTerms);
127         return view('search/book', ['pages' => $pages, 'chapters' => $chapters, 'searchTerm' => $searchTerm]);
128     }
129
130
131     /**
132      * Search for a list of entities and return a partial HTML response of matching entities.
133      * Returns the most popular entities if no search is provided.
134      * @param Request $request
135      * @return mixed
136      */
137     public function searchEntitiesAjax(Request $request)
138     {
139         $entities = collect();
140         $entityTypes = $request->has('types') ? collect(explode(',', $request->get('types'))) : collect(['page', 'chapter', 'book']);
141         $searchTerm = ($request->has('term') && trim($request->get('term')) !== '') ? $request->get('term') : false;
142
143         // Search for entities otherwise show most popular
144         if ($searchTerm !== false) {
145             foreach (['page', 'chapter', 'book'] as $entityType) {
146                 if ($entityTypes->contains($entityType)) {
147                     $entities = $entities->merge($this->entityRepo->getBySearch($entityType, $searchTerm)->items());
148                 }
149             }
150             $entities = $entities->sortByDesc('title_relevance');
151         } else {
152             $entityNames = $entityTypes->map(function ($type) {
153                 return 'BookStack\\' . ucfirst($type);
154             })->toArray();
155             $entities = $this->viewService->getPopular(20, 0, $entityNames);
156         }
157
158         return view('search/entity-ajax-list', ['entities' => $entities]);
159     }
160
161 }
162
163