3 namespace BookStack\Http\Controllers\Api;
5 use BookStack\Entities\Models\Entity;
6 use BookStack\Search\SearchOptions;
7 use BookStack\Search\SearchResultsFormatter;
8 use BookStack\Search\SearchRunner;
9 use Illuminate\Http\Request;
11 class SearchApiController extends ApiController
13 protected $searchRunner;
14 protected $resultsFormatter;
18 'query' => ['required'],
19 'page' => ['integer', 'min:1'],
20 'count' => ['integer', 'min:1', 'max:100'],
24 public function __construct(SearchRunner $searchRunner, SearchResultsFormatter $resultsFormatter)
26 $this->searchRunner = $searchRunner;
27 $this->resultsFormatter = $resultsFormatter;
31 * Run a search query against all main content types (shelves, books, chapters & pages)
32 * in the system. Takes the same input as the main search bar within the BookStack
33 * interface as a 'query' parameter. See https://www.bookstackapp.com/docs/user/searching/
34 * for a full list of search term options. Results contain a 'type' property to distinguish
35 * between: bookshelf, book, chapter & page.
37 * The paging parameters and response format emulates a standard listing endpoint
38 * but standard sorting and filtering cannot be done on this endpoint. If a count value
39 * is provided this will only be taken as a suggestion. The results in the response
40 * may currently be up to 4x this value.
42 public function all(Request $request)
44 $this->validate($request, $this->rules['all']);
46 $options = SearchOptions::fromString($request->get('query') ?? '');
47 $page = intval($request->get('page', '0')) ?: 1;
48 $count = min(intval($request->get('count', '0')) ?: 20, 100);
50 $results = $this->searchRunner->searchEntities($options, 'all', $page, $count);
51 $this->resultsFormatter->format($results['results']->all(), $options);
53 /** @var Entity $result */
54 foreach ($results['results'] as $result) {
56 'id', 'name', 'slug', 'book_id',
57 'chapter_id', 'draft', 'template',
58 'created_at', 'updated_at',
59 'tags', 'type', 'preview_html', 'url',
61 $result->setAttribute('type', $result->getType());
62 $result->setAttribute('url', $result->getUrl());
63 $result->setAttribute('preview_html', [
64 'name' => (string) $result->getAttribute('preview_name'),
65 'content' => (string) $result->getAttribute('preview_content'),
69 return response()->json([
70 'data' => $results['results'],
71 'total' => $results['total'],