]> BookStack Code Mirror - bookstack/commitdiff
API Docs: Allowed multi-paragraph descriptions 4332/head
authorDan Brown <redacted>
Tue, 20 Jun 2023 22:44:39 +0000 (23:44 +0100)
committerDan Brown <redacted>
Tue, 20 Jun 2023 22:44:39 +0000 (23:44 +0100)
Added support for mulit-line endpoint descriptions via blank
intermediate lines in php controller method docblocks.

Also tweaks endpoint header design for better flexing and alignment.

app/Api/ApiDocsGenerator.php
app/Entities/Controllers/PageApiController.php
app/Permissions/ContentPermissionApiController.php
app/Uploads/Controllers/ImageGalleryApiController.php
resources/views/api-docs/parts/endpoint.blade.php
tests/Api/ApiDocsTest.php

index f13842328c67d8b1e555d2905cfc3462a14ed77b..3cd33ffa576b5d8564a91c7827f708e611ff8cdf 100644 (file)
@@ -16,8 +16,8 @@ use ReflectionMethod;
 
 class ApiDocsGenerator
 {
-    protected $reflectionClasses = [];
-    protected $controllerClasses = [];
+    protected array $reflectionClasses = [];
+    protected array $controllerClasses = [];
 
     /**
      * Load the docs form the cache if existing
@@ -139,9 +139,10 @@ class ApiDocsGenerator
     protected function parseDescriptionFromMethodComment(string $comment): string
     {
         $matches = [];
-        preg_match_all('/^\s*?\*\s((?![@\s]).*?)$/m', $comment, $matches);
+        preg_match_all('/^\s*?\*\s?($|((?![\/@\s]).*?))$/m', $comment, $matches);
 
-        return implode(' ', $matches[1] ?? []);
+        $text = implode(' ', $matches[1] ?? []);
+        return str_replace('  ', "\n", $text);
     }
 
     /**
index 93b90b4b7ac11aac6e2b4a79dc57179e8e2d2100..0e8893450fe8e906522c96cea463cea61f4e2f6b 100644 (file)
@@ -82,7 +82,6 @@ class PageApiController extends ApiController
 
     /**
      * View the details of a single page.
-     *
      * Pages will always have HTML content. They may have markdown content
      * if the markdown editor was used to last update the page.
      *
index cd561fdee3abf7544ab5ba459fb07475de7c644a..23b75db359a469962779c0d3cffffbdcd040ad1a 100644 (file)
@@ -38,8 +38,10 @@ class ContentPermissionApiController extends ApiController
 
     /**
      * Read the configured content-level permissions for the item of the given type and ID.
+     *
      * 'contentType' should be one of: page, book, chapter, bookshelf.
      * 'contentId' should be the relevant ID of that item type you'd like to handle permissions for.
+     *
      * The permissions shown are those that override the default for just the specified item, they do not show the
      * full evaluated permission for a role, nor do they reflect permissions inherited from other items in the hierarchy.
      * Fallback permission values may be `null` when inheriting is active.
@@ -57,6 +59,7 @@ class ContentPermissionApiController extends ApiController
     /**
      * Update the configured content-level permission overrides for the item of the given type and ID.
      * 'contentType' should be one of: page, book, chapter, bookshelf.
+     *
      * 'contentId' should be the relevant ID of that item type you'd like to handle permissions for.
      * Providing an empty `role_permissions` array will remove any existing configured role permissions,
      * so you may want to fetch existing permissions beforehand if just adding/removing a single item.
index c444ec663e81f5cfb7e895aa5c994dd202523d70..0d35d2905f71dbeda2302539760baff2119a36c2 100644 (file)
@@ -52,8 +52,10 @@ class ImageGalleryApiController extends ApiController
 
     /**
      * Create a new image in the system.
+     *
      * Since "image" is expected to be a file, this needs to be a 'multipart/form-data' type request.
      * The provided "uploaded_to" should be an existing page ID in the system.
+     *
      * If the "name" parameter is omitted, the filename of the provided image file will be used instead.
      * The "type" parameter should be 'gallery' for page content images, and 'drawio' should only be used
      * when the file is a PNG file with diagrams.net image data embedded within.
index 60c478fe563deaacd6c60c368c8f8cf16fafee6d..024a5ecdf04457a52447d1d8b8dc943a091f61d1 100644 (file)
@@ -1,15 +1,20 @@
-<h6 class="text-uppercase text-muted float right">{{ $endpoint['controller_method_kebab'] }}</h6>
+<div class="flex-container-row items-center gap-m">
+    <span class="api-method text-mono" data-method="{{ $endpoint['method'] }}">{{ $endpoint['method'] }}</span>
+    <h5 id="{{ $endpoint['name'] }}" class="text-mono pb-xs">
+        @if($endpoint['controller_method_kebab'] === 'list')
+            <a style="color: inherit;" target="_blank" rel="noopener" href="{{ url($endpoint['uri']) }}">{{ url($endpoint['uri']) }}</a>
+        @else
+            <span>{{ url($endpoint['uri']) }}</span>
+        @endif
+    </h5>
+    <h6 class="text-uppercase text-muted text-mono ml-auto">{{ $endpoint['controller_method_kebab'] }}</h6>
+</div>
 
-<h5 id="{{ $endpoint['name'] }}" class="text-mono mb-m">
-    <span class="api-method" data-method="{{ $endpoint['method'] }}">{{ $endpoint['method'] }}</span>
-    @if($endpoint['controller_method_kebab'] === 'list')
-        <a style="color: inherit;" target="_blank" rel="noopener" href="{{ url($endpoint['uri']) }}">{{ url($endpoint['uri']) }}</a>
-    @else
-        {{ url($endpoint['uri']) }}
-    @endif
-</h5>
-
-<p class="mb-m">{{ $endpoint['description'] ?? '' }}</p>
+<div class="mb-m">
+    @foreach(explode("\n", $endpoint['description'] ?? '') as $descriptionBlock)
+        <p class="mb-xxs">{{ $descriptionBlock }}</p>
+    @endforeach
+</div>
 
 @if($endpoint['body_params'] ?? false)
     <details class="mb-m">
index 56b09cfb85d707142c875af1daa77a174aaa6979..a1603e0ef8274d244835c75e12a076045cb31ad5 100644 (file)
@@ -8,7 +8,7 @@ class ApiDocsTest extends TestCase
 {
     use TestsApi;
 
-    protected $endpoint = '/api/docs';
+    protected string $endpoint = '/api/docs';
 
     public function test_api_endpoint_redirects_to_docs()
     {