]> BookStack Code Mirror - bookstack/commitdiff
Added url and preview_html params to search API results
authorDan Brown <redacted>
Mon, 6 Dec 2021 20:42:04 +0000 (20:42 +0000)
committerDan Brown <redacted>
Mon, 6 Dec 2021 20:42:04 +0000 (20:42 +0000)
Allows easy direct linking and usage of the HTML preview content
we show in the UI when viewing search results.
Note: preview_html content is a rough representation only, it does not
match exactly what was matched in the database-search-operation which
finds the results.

For #3096 and #3080

app/Http/Controllers/Api/SearchApiController.php
dev/api/responses/search-all.json
tests/Api/SearchApiTest.php

index ba960b9d2f79d0bc5b4db095a3c5dbdb7c01eb8a..d1c99e21855bd12e70405eb46e7d133e78932fc8 100644 (file)
@@ -4,12 +4,14 @@ namespace BookStack\Http\Controllers\Api;
 
 use BookStack\Entities\Models\Entity;
 use BookStack\Entities\Tools\SearchOptions;
+use BookStack\Entities\Tools\SearchResultsFormatter;
 use BookStack\Entities\Tools\SearchRunner;
 use Illuminate\Http\Request;
 
 class SearchApiController extends ApiController
 {
     protected $searchRunner;
+    protected $resultsFormatter;
 
     protected $rules = [
         'all' => [
@@ -19,9 +21,10 @@ class SearchApiController extends ApiController
         ],
     ];
 
-    public function __construct(SearchRunner $searchRunner)
+    public function __construct(SearchRunner $searchRunner, SearchResultsFormatter $resultsFormatter)
     {
         $this->searchRunner = $searchRunner;
+        $this->resultsFormatter = $resultsFormatter;
     }
 
     /**
@@ -45,6 +48,7 @@ class SearchApiController extends ApiController
         $count = min(intval($request->get('count', '0')) ?: 20, 100);
 
         $results = $this->searchRunner->searchEntities($options, 'all', $page, $count);
+        $this->resultsFormatter->format($results['results']->all(), $options);
 
         /** @var Entity $result */
         foreach ($results['results'] as $result) {
@@ -52,9 +56,14 @@ class SearchApiController extends ApiController
                 'id', 'name', 'slug', 'book_id',
                 'chapter_id', 'draft', 'template',
                 'created_at', 'updated_at',
-                'tags', 'type',
+                'tags', 'type', 'preview_html', 'url',
             ]);
             $result->setAttribute('type', $result->getType());
+            $result->setAttribute('url', $result->getUrl());
+            $result->setAttribute('preview_html', [
+                'name' => (string) $result->getAttribute('preview_name'),
+                'content' => (string) $result->getAttribute('preview_content'),
+            ]);
         }
 
         return response()->json([
index 3096d6da1fabd9681c5368cc9ad4c9abd96e3931..2c7584e3fd0c5adf859b4fa697303ccff33cfc42 100644 (file)
@@ -8,6 +8,11 @@
       "created_at": "2021-11-14T15:57:35.000000Z",
       "updated_at": "2021-11-14T15:57:35.000000Z",
       "type": "chapter",
+      "url": "https://example.com/books/my-book/chapter/a-chapter-for-cats",
+      "preview_html": {
+        "name": "A chapter for <strong>cats</strong>",
+        "content": "...once a bunch of <strong>cats</strong> named tony...behaviour of <strong>cats</strong> is unsuitable"
+      },
       "tags": []
     },
     {
       "created_at": "2021-05-15T16:28:10.000000Z",
       "updated_at": "2021-11-14T15:56:49.000000Z",
       "type": "page",
+      "url": "https://example.com/books/my-book/page/the-hows-and-whys-of-cats",
+      "preview_html": {
+        "name": "The hows and whys of <strong>cats</strong>",
+        "content": "...people ask why <strong>cats</strong>? but there are...the reason that <strong>cats</strong> are fast are due to..."
+      },
       "tags": [
         {
           "name": "Animal",
       "created_at": "2020-11-29T21:55:07.000000Z",
       "updated_at": "2021-11-14T16:02:39.000000Z",
       "type": "page",
+      "url": "https://example.com/books/my-book/page/how-advanced-are-cats",
+      "preview_html": {
+        "name": "How advanced are <strong>cats</strong>?",
+        "content": "<strong>cats</strong> are some of the most advanced animals in the world."
+      },
       "tags": []
     }
   ],
index 55ca0e00946f7270f210489bca3c063026a04f88..eb323fdd92a0e7267c68179d2dba235814f7a800 100644 (file)
@@ -36,6 +36,38 @@ class SearchApiTest extends TestCase
         $resp->assertJsonFragment(['name' => $uniqueTerm, 'type' => 'bookshelf']);
     }
 
+    public function test_all_endpoint_returns_entity_url()
+    {
+        /** @var Page $page */
+        $page = Page::query()->first();
+        $page->update(['name' => 'name with superuniquevalue within']);
+        $page->indexForSearch();
+
+        $resp = $this->actingAsApiAdmin()->getJson($this->baseEndpoint . '?query=superuniquevalue');
+        $resp->assertJsonFragment([
+            'type' => 'page',
+            'url' => $page->getUrl(),
+        ]);
+    }
+
+    public function test_all_endpoint_returns_items_with_preview_html()
+    {
+        /** @var Book $book */
+        $book = Book::query()->first();
+        $book->update(['name' => 'name with superuniquevalue within', 'description' => 'Description with superuniquevalue within']);
+        $book->indexForSearch();
+
+        $resp = $this->actingAsApiAdmin()->getJson($this->baseEndpoint . '?query=superuniquevalue');
+        $resp->assertJsonFragment([
+            'type' => 'book',
+            'url' => $book->getUrl(),
+            'preview_html' => [
+                'name' => 'name with <strong>superuniquevalue</strong> within',
+                'content' => 'Description with <strong>superuniquevalue</strong> within',
+            ]
+        ]);
+    }
+
     public function test_all_endpoint_requires_query_parameter()
     {
         $resp = $this->actingAsApiEditor()->get($this->baseEndpoint);