3 declare(strict_types=1);
5 namespace BookStack\Search;
7 use BookStack\Api\ApiEntityListFormatter;
8 use BookStack\Entities\Models\Entity;
9 use BookStack\Http\ApiController;
10 use Illuminate\Http\JsonResponse;
11 use Illuminate\Http\Request;
13 class SearchApiController extends ApiController
15 protected array $rules = [
17 'query' => ['required'],
18 'page' => ['integer', 'min:1'],
19 'count' => ['integer', 'min:1', 'max:100'],
23 public function __construct(
24 protected SearchRunner $searchRunner,
25 protected SearchResultsFormatter $resultsFormatter
30 * Run a search query against all main content types (shelves, books, chapters & pages)
31 * in the system. Takes the same input as the main search bar within the BookStack
32 * interface as a 'query' parameter. See https://www.bookstackapp.com/docs/user/searching/
33 * for a full list of search term options. Results contain a 'type' property to distinguish
34 * between: bookshelf, book, chapter & page.
36 * The paging parameters and response format emulates a standard listing endpoint
37 * but standard sorting and filtering cannot be done on this endpoint.
39 public function all(Request $request): JsonResponse
41 $this->validate($request, $this->rules['all']);
43 $options = SearchOptions::fromString($request->get('query') ?? '');
44 $page = intval($request->get('page', '0')) ?: 1;
45 $count = min(intval($request->get('count', '0')) ?: 20, 100);
47 $results = $this->searchRunner->searchEntities($options, 'all', $page, $count);
48 $this->resultsFormatter->format($results['results']->all(), $options);
50 $data = (new ApiEntityListFormatter($results['results']->all()))
51 ->withType()->withTags()->withParents()
52 ->withField('preview_html', function (Entity $entity) {
54 'name' => (string) $entity->getAttribute('preview_name'),
55 'content' => (string) $entity->getAttribute('preview_content'),
59 return response()->json([
61 'total' => $results['total'],