mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-12-19 10:42:29 +03:00
Updated setting display to show mulitple number inputs under one heading group. Updated settings to use general number field form view template. Updated translations to match display changes, and to advise on counts. Added page count control for search results. Added setting service method, to get settings as integers, with min/max/default control. Updating sorting group to be names "Lists & Sorting". Added tests to cover.
146 lines
5.0 KiB
PHP
146 lines
5.0 KiB
PHP
<?php
|
|
|
|
namespace BookStack\Search;
|
|
|
|
use BookStack\Entities\Queries\PageQueries;
|
|
use BookStack\Entities\Queries\QueryPopular;
|
|
use BookStack\Entities\Tools\SiblingFetcher;
|
|
use BookStack\Http\Controller;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Pagination\LengthAwarePaginator;
|
|
|
|
class SearchController extends Controller
|
|
{
|
|
public function __construct(
|
|
protected SearchRunner $searchRunner,
|
|
protected PageQueries $pageQueries,
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Searches all entities.
|
|
*/
|
|
public function search(Request $request, SearchResultsFormatter $formatter)
|
|
{
|
|
$searchOpts = SearchOptions::fromRequest($request);
|
|
$fullSearchString = $searchOpts->toString();
|
|
$page = intval($request->get('page', '0')) ?: 1;
|
|
$count = setting()->getInteger('lists-page-count-search', 18, 1, 1000);
|
|
|
|
$results = $this->searchRunner->searchEntities($searchOpts, 'all', $page, $count);
|
|
$formatter->format($results['results']->all(), $searchOpts);
|
|
$paginator = new LengthAwarePaginator($results['results'], $results['total'], $count, $page);
|
|
$paginator->setPath('/search');
|
|
$paginator->appends($request->except('page'));
|
|
|
|
$this->setPageTitle(trans('entities.search_for_term', ['term' => $fullSearchString]));
|
|
|
|
return view('search.all', [
|
|
'entities' => $results['results'],
|
|
'totalResults' => $results['total'],
|
|
'paginator' => $paginator,
|
|
'searchTerm' => $fullSearchString,
|
|
'options' => $searchOpts,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Searches all entities within a book.
|
|
*/
|
|
public function searchBook(Request $request, int $bookId)
|
|
{
|
|
$term = $request->get('term', '');
|
|
$results = $this->searchRunner->searchBook($bookId, $term);
|
|
|
|
return view('entities.list', ['entities' => $results]);
|
|
}
|
|
|
|
/**
|
|
* Searches all entities within a chapter.
|
|
*/
|
|
public function searchChapter(Request $request, int $chapterId)
|
|
{
|
|
$term = $request->get('term', '');
|
|
$results = $this->searchRunner->searchChapter($chapterId, $term);
|
|
|
|
return view('entities.list', ['entities' => $results]);
|
|
}
|
|
|
|
/**
|
|
* Search for a list of entities and return a partial HTML response of matching entities.
|
|
* Returns the most popular entities if no search is provided.
|
|
*/
|
|
public function searchForSelector(Request $request, QueryPopular $queryPopular)
|
|
{
|
|
$entityTypes = $request->filled('types') ? explode(',', $request->get('types')) : ['page', 'chapter', 'book'];
|
|
$searchTerm = $request->get('term', false);
|
|
$permission = $request->get('permission', 'view');
|
|
|
|
// Search for entities otherwise show most popular
|
|
if ($searchTerm !== false) {
|
|
$searchTerm .= ' {type:' . implode('|', $entityTypes) . '}';
|
|
$entities = $this->searchRunner->searchEntities(SearchOptions::fromString($searchTerm), 'all', 1, 20)['results'];
|
|
} else {
|
|
$entities = $queryPopular->run(20, 0, $entityTypes);
|
|
}
|
|
|
|
return view('search.parts.entity-selector-list', ['entities' => $entities, 'permission' => $permission]);
|
|
}
|
|
|
|
/**
|
|
* Search for a list of templates to choose from.
|
|
*/
|
|
public function templatesForSelector(Request $request)
|
|
{
|
|
$searchTerm = $request->get('term', false);
|
|
|
|
if ($searchTerm !== false) {
|
|
$searchOptions = SearchOptions::fromString($searchTerm);
|
|
$searchOptions->setFilter('is_template');
|
|
$entities = $this->searchRunner->searchEntities($searchOptions, 'page', 1, 20)['results'];
|
|
} else {
|
|
$entities = $this->pageQueries->visibleTemplates()
|
|
->where('draft', '=', false)
|
|
->orderBy('updated_at', 'desc')
|
|
->take(20)
|
|
->get();
|
|
}
|
|
|
|
return view('search.parts.entity-selector-list', [
|
|
'entities' => $entities,
|
|
'permission' => 'view'
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Search for a list of entities and return a partial HTML response of matching entities
|
|
* to be used as a result preview suggestion list for global system searches.
|
|
*/
|
|
public function searchSuggestions(Request $request)
|
|
{
|
|
$searchTerm = $request->get('term', '');
|
|
$entities = $this->searchRunner->searchEntities(SearchOptions::fromString($searchTerm), 'all', 1, 5)['results'];
|
|
|
|
foreach ($entities as $entity) {
|
|
$entity->setAttribute('preview_content', '');
|
|
}
|
|
|
|
return view('search.parts.entity-suggestion-list', [
|
|
'entities' => $entities->slice(0, 5)
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Search sibling items in the system.
|
|
*/
|
|
public function searchSiblings(Request $request, SiblingFetcher $siblingFetcher)
|
|
{
|
|
$type = $request->get('entity_type', null);
|
|
$id = $request->get('entity_id', null);
|
|
|
|
$entities = $siblingFetcher->fetch($type, $id);
|
|
|
|
return view('entities.list-basic', ['entities' => $entities, 'style' => 'compact']);
|
|
}
|
|
}
|