Added chapter search

Migrated book search to vue-based system.
Updated old tag seached.
Made chapter page layout widths same as book page.
Closes #344
This commit is contained in:
Dan Brown
2017-04-15 19:16:07 +01:00
parent 0e0945ef84
commit dcde599709
12 changed files with 179 additions and 99 deletions

View File

@ -61,16 +61,24 @@ class SearchController extends Controller
*/
public function searchBook(Request $request, $bookId)
{
if (!$request->has('term')) {
return redirect()->back();
}
$searchTerm = $request->get('term');
$searchWhereTerms = [['book_id', '=', $bookId]];
$pages = $this->entityRepo->getBySearch('page', $searchTerm, $searchWhereTerms);
$chapters = $this->entityRepo->getBySearch('chapter', $searchTerm, $searchWhereTerms);
return view('search/book', ['pages' => $pages, 'chapters' => $chapters, 'searchTerm' => $searchTerm]);
$term = $request->get('term', '');
$results = $this->searchService->searchBook($bookId, $term);
return view('partials/entity-list', ['entities' => $results]);
}
/**
* Searches all entities within a chapter.
* @param Request $request
* @param integer $chapterId
* @return \Illuminate\View\View
* @internal param string $searchTerm
*/
public function searchChapter(Request $request, $chapterId)
{
$term = $request->get('term', '');
$results = $this->searchService->searchChapter($chapterId, $term);
return view('partials/entity-list', ['entities' => $results]);
}
/**
* Search for a list of entities and return a partial HTML response of matching entities.
@ -80,19 +88,13 @@ class SearchController extends Controller
*/
public function searchEntitiesAjax(Request $request)
{
$entities = collect();
$entityTypes = $request->has('types') ? collect(explode(',', $request->get('types'))) : collect(['page', 'chapter', 'book']);
$searchTerm = ($request->has('term') && trim($request->get('term')) !== '') ? $request->get('term') : false;
// Search for entities otherwise show most popular
if ($searchTerm !== false) {
foreach (['page', 'chapter', 'book'] as $entityType) {
if ($entityTypes->contains($entityType)) {
// TODO - Update to new system
$entities = $entities->merge($this->entityRepo->getBySearch($entityType, $searchTerm)->items());
}
}
$entities = $entities->sortByDesc('title_relevance');
$searchTerm .= ' {type:'. implode('|', $entityTypes->toArray()) .'}';
$entities = $this->searchService->searchEntities($searchTerm)['results'];
} else {
$entityNames = $entityTypes->map(function ($type) {
return 'BookStack\\' . ucfirst($type);

View File

@ -569,7 +569,7 @@ class EntityRepo
$draftPage->save();
$this->savePageRevision($draftPage, trans('entities.pages_initial_revision'));
$this->searchService->indexEntity($draftPage);
return $draftPage;
}

View File

@ -8,6 +8,7 @@ use BookStack\SearchTerm;
use Illuminate\Database\Connection;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Collection;
class SearchService
{
@ -86,6 +87,35 @@ class SearchService
];
}
/**
* Search a book for entities
* @param integer $bookId
* @param string $searchString
* @return Collection
*/
public function searchBook($bookId, $searchString)
{
$terms = $this->parseSearchString($searchString);
$results = collect();
$pages = $this->buildEntitySearchQuery($terms, 'page')->where('book_id', '=', $bookId)->take(20)->get();
$chapters = $this->buildEntitySearchQuery($terms, 'chapter')->where('book_id', '=', $bookId)->take(20)->get();
return $results->merge($pages)->merge($chapters)->sortByDesc('score')->take(20);
}
/**
* Search a book for entities
* @param integer $chapterId
* @param string $searchString
* @return Collection
*/
public function searchChapter($chapterId, $searchString)
{
$terms = $this->parseSearchString($searchString);
$pages = $this->buildEntitySearchQuery($terms, 'page')->where('chapter_id', '=', $chapterId)->take(20)->get();
return $pages->sortByDesc('score');
}
/**
* Search across a particular entity type.
* @param array $terms
@ -96,6 +126,21 @@ class SearchService
* @return \Illuminate\Database\Eloquent\Collection|int|static[]
*/
public function searchEntityTable($terms, $entityType = 'page', $page = 1, $count = 20, $getCount = false)
{
$query = $this->buildEntitySearchQuery($terms, $entityType);
if ($getCount) return $query->count();
$query = $query->skip(($page-1) * $count)->take($count);
return $query->get();
}
/**
* Create a search query for an entity
* @param array $terms
* @param string $entityType
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function buildEntitySearchQuery($terms, $entityType = 'page')
{
$entity = $this->getEntity($entityType);
$entitySelect = $entity->newQuery();
@ -137,11 +182,7 @@ class SearchService
if (method_exists($this, $functionName)) $this->$functionName($entitySelect, $entity, $filterValue);
}
$query = $this->permissionService->enforceEntityRestrictions($entityType, $entitySelect, 'view');
if ($getCount) return $query->count();
$query = $query->skip(($page-1) * $count)->take($count);
return $query->get();
return $this->permissionService->enforceEntityRestrictions($entityType, $entitySelect, 'view');
}