1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-07-31 15:24:31 +03:00

respective book and chapter structure added.

This commit is contained in:
Rashad
2024-10-27 22:50:20 +05:30
parent 90a8070518
commit f606711463
5 changed files with 103 additions and 246 deletions

View File

@ -17,20 +17,9 @@ class SearchApiController extends ApiController
'query' => ['required'],
'page' => ['integer', 'min:1'],
'count' => ['integer', 'min:1', 'max:100'],
'include' => ['string', 'regex:/^[a-zA-Z,]*$/'],
],
];
/**
* Valid include parameters and their corresponding formatter methods.
* These parameters allow for additional related data, like titles or tags,
* to be included in the search results when requested via the API.
*/
protected const VALID_INCLUDES = [
'titles' => 'withRelatedTitles',
'tags' => 'withTags',
];
public function __construct(SearchRunner $searchRunner, SearchResultsFormatter $resultsFormatter)
{
$this->searchRunner = $searchRunner;
@ -44,13 +33,6 @@ class SearchApiController extends ApiController
* for a full list of search term options. Results contain a 'type' property to distinguish
* between: bookshelf, book, chapter & page.
*
* This method now supports the 'include' parameter, which allows API clients to specify related
* fields (such as titles or tags) that should be included in the search results.
*
* The 'include' parameter is a comma-separated string. For example, adding `include=titles,tags`
* will include both titles and tags in the API response. If the parameter is not provided, only
* basic entity data will be returned.
*
* The paging parameters and response format emulates a standard listing endpoint
* but standard sorting and filtering cannot be done on this endpoint. If a count value
* is provided this will only be taken as a suggestion. The results in the response
@ -63,49 +45,22 @@ class SearchApiController extends ApiController
$options = SearchOptions::fromString($request->get('query') ?? '');
$page = intval($request->get('page', '0')) ?: 1;
$count = min(intval($request->get('count', '0')) ?: 20, 100);
$includes = $this->parseIncludes($request->get('include', ''));
$results = $this->searchRunner->searchEntities($options, 'all', $page, $count);
$this->resultsFormatter->format($results['results']->all(), $options);
$formatter = new ApiEntityListFormatter($results['results']->all());
$formatter->withType(); // Always include type as it's essential for search results
foreach ($includes as $include) {
if (isset(self::VALID_INCLUDES[$include])) {
$method = self::VALID_INCLUDES[$include];
$formatter->$method();
}
}
$formatter->withField('preview_html', function (Entity $entity) {
return [
'name' => (string) $entity->getAttribute('preview_name'),
'content' => (string) $entity->getAttribute('preview_content'),
];
});
$data = (new ApiEntityListFormatter($results['results']->all()))
->withType()->withTags()->withRelatedData()
->withField('preview_html', function (Entity $entity) {
return [
'name' => (string) $entity->getAttribute('preview_name'),
'content' => (string) $entity->getAttribute('preview_content'),
];
})->format();
return response()->json([
'data' => $formatter->format(),
'data' => $data,
'total' => $results['total'],
]);
}
/**
* Parse and validate the include parameter.
*
* @param string $includeString Comma-separated list of includes
* @return array<string>
*/
protected function parseIncludes(string $includeString): array
{
if (empty($includeString)) {
return [];
}
return array_filter(
explode(',', strtolower($includeString)),
fn($include) => isset (self::VALID_INCLUDES[$include])
);
}
}