]> BookStack Code Mirror - bookstack/commitdiff
API: Added system read endpoint
authorDan Brown <redacted>
Tue, 13 May 2025 19:38:08 +0000 (20:38 +0100)
committerDan Brown <redacted>
Tue, 13 May 2025 19:38:08 +0000 (20:38 +0100)
Standardised logic for reading app version to its own static class.

app/Api/ApiDocsGenerator.php
app/App/AppVersion.php [new file with mode: 0644]
app/App/SystemApiController.php [new file with mode: 0644]
app/App/helpers.php
app/Exceptions/BookStackExceptionHandlerPage.php
app/Exports/ZipExports/ZipExportBuilder.php
app/Settings/MaintenanceController.php
app/Settings/SettingController.php
dev/api/responses/system-read.json [new file with mode: 0644]
routes/api.php

index 9cae80617e5ae2a44c76003f50a0bd32b6744a61..287c838779060b9e23fa600f61e758d862649658 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace BookStack\Api;
 
+use BookStack\App\AppVersion;
 use BookStack\Http\ApiController;
 use Exception;
 use Illuminate\Contracts\Container\BindingResolutionException;
@@ -25,7 +26,7 @@ class ApiDocsGenerator
      */
     public static function generateConsideringCache(): Collection
     {
-        $appVersion = trim(file_get_contents(base_path('version')));
+        $appVersion = AppVersion::get();
         $cacheKey = 'api-docs::' . $appVersion;
         $isProduction = config('app.env') === 'production';
         $cacheVal = $isProduction ? Cache::get($cacheKey) : null;
diff --git a/app/App/AppVersion.php b/app/App/AppVersion.php
new file mode 100644 (file)
index 0000000..af422f6
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+
+namespace BookStack\App;
+
+class AppVersion
+{
+    protected static string $version = '';
+
+    /**
+     * Get the application's version number from its top-level `version` text file.
+     */
+    public static function get(): string
+    {
+        if (!empty(static::$version)) {
+            return static::$version;
+        }
+
+        $versionFile = base_path('version');
+        $version = trim(file_get_contents($versionFile));
+        static::$version = $version;
+
+        return $version;
+    }
+}
diff --git a/app/App/SystemApiController.php b/app/App/SystemApiController.php
new file mode 100644 (file)
index 0000000..c476a74
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+namespace BookStack\App;
+
+use BookStack\Http\ApiController;
+use Illuminate\Http\JsonResponse;
+
+class SystemApiController extends ApiController
+{
+    /**
+     * Read details regarding the BookStack instance.
+     * Some details may be null where not set, like the app logo for example.
+     */
+    public function read(): JsonResponse
+    {
+        $logoSetting = setting('app-logo', '');
+        if ($logoSetting === 'none') {
+            $logo = null;
+        } else {
+            $logo = $logoSetting ? url($logoSetting) : url('/logo.png');
+        }
+
+        return response()->json([
+            'version' => AppVersion::get(),
+            'instance_id' => setting('instance-id'),
+            'app_name' => setting('app-name'),
+            'app_logo' => $logo,
+            'base_url' => url('/'),
+        ]);
+    }
+}
index eec86553fb431c9fe7c638529b5ca80626c3feba..2305c2d72a19f41f240de42f2234fc6ee24c55db 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use BookStack\App\AppVersion;
 use BookStack\App\Model;
 use BookStack\Facades\Theme;
 use BookStack\Permissions\PermissionApplicator;
@@ -13,12 +14,7 @@ use BookStack\Users\Models\User;
  */
 function versioned_asset(string $file = ''): string
 {
-    static $version = null;
-
-    if (is_null($version)) {
-        $versionFile = base_path('version');
-        $version = trim(file_get_contents($versionFile));
-    }
+    $version = AppVersion::get();
 
     $additional = '';
     if (config('app.env') === 'development') {
index 78f586ad0c98d0f930a5c7f78882dbcfcdf5f614..a53733ac7eeaa629dd84a26b9722074d3d6a860e 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace BookStack\Exceptions;
 
+use BookStack\App\AppVersion;
 use Illuminate\Contracts\Foundation\ExceptionRenderer;
 
 class BookStackExceptionHandlerPage implements ExceptionRenderer
@@ -30,9 +31,7 @@ class BookStackExceptionHandlerPage implements ExceptionRenderer
         return [
             'PHP Version'       => phpversion(),
             'BookStack Version' => $this->safeReturn(function () {
-                $versionFile = base_path('version');
-
-                return trim(file_get_contents($versionFile));
+                return AppVersion::get();
             }, 'unknown'),
             'Theme Configured' => $this->safeReturn(function () {
                 return config('view.theme');
index 9a52c9a3cb8d021b8e6f9962edbba75484f76907..9937d158975a8292b5e532aab5a933b07b04a414 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace BookStack\Exports\ZipExports;
 
+use BookStack\App\AppVersion;
 use BookStack\Entities\Models\Book;
 use BookStack\Entities\Models\Chapter;
 use BookStack\Entities\Models\Page;
@@ -70,7 +71,7 @@ class ZipExportBuilder
         $this->data['exported_at'] = date(DATE_ATOM);
         $this->data['instance'] = [
             'id'      => setting('instance-id', ''),
-            'version' => trim(file_get_contents(base_path('version'))),
+            'version' => AppVersion::get(),
         ];
 
         $zipFile = tempnam(sys_get_temp_dir(), 'bszip-');
index 0382ae08a6d18c41b530fbf7c0a9f7cd12eb367b..ac9dd20ccb2c5cd5d8816636db08147a53ea2889 100644 (file)
@@ -3,6 +3,7 @@
 namespace BookStack\Settings;
 
 use BookStack\Activity\ActivityType;
+use BookStack\App\AppVersion;
 use BookStack\Entities\Tools\TrashCan;
 use BookStack\Http\Controller;
 use BookStack\References\ReferenceStore;
@@ -19,14 +20,11 @@ class MaintenanceController extends Controller
         $this->checkPermission('settings-manage');
         $this->setPageTitle(trans('settings.maint'));
 
-        // Get application version
-        $version = trim(file_get_contents(base_path('version')));
-
         // Recycle bin details
         $recycleStats = $trashCan->getTrashedCounts();
 
         return view('settings.maintenance', [
-            'version'      => $version,
+            'version'      => AppVersion::get(),
             'recycleStats' => $recycleStats,
         ]);
     }
index 1c5f13bc67f2059be0ce5fe9b368c065d12fb31c..3b7ba74d58a8afc0342c59f04b12a3560c78dba8 100644 (file)
@@ -3,6 +3,7 @@
 namespace BookStack\Settings;
 
 use BookStack\Activity\ActivityType;
+use BookStack\App\AppVersion;
 use BookStack\Http\Controller;
 use BookStack\Users\Models\User;
 use Illuminate\Http\Request;
@@ -26,12 +27,9 @@ class SettingController extends Controller
         $this->checkPermission('settings-manage');
         $this->setPageTitle(trans('settings.settings'));
 
-        // Get application version
-        $version = trim(file_get_contents(base_path('version')));
-
         return view('settings.categories.' . $category, [
             'category'  => $category,
-            'version'   => $version,
+            'version'   => AppVersion::get(),
             'guestUser' => User::getGuest(),
         ]);
     }
diff --git a/dev/api/responses/system-read.json b/dev/api/responses/system-read.json
new file mode 100644 (file)
index 0000000..4687d6f
--- /dev/null
@@ -0,0 +1,7 @@
+{
+  "version": "v25.02.4",
+  "instance_id": "1234abcd-cc12-7808-af0a-264cb0cbd611",
+  "app_name": "My BookStack Instance",
+  "app_logo": "https://docs.example.com/uploads/images/system/2025-05/cat-icon.png",
+  "base_url": "https://docs.example.com"
+}
\ No newline at end of file
index 71036485597d20d41e8b500aeded1341496d983b..85e872ba4fb1c8fdc128a8a1d2e870129d982eb3 100644 (file)
@@ -8,6 +8,7 @@
 
 use BookStack\Activity\Controllers\AuditLogApiController;
 use BookStack\Api\ApiDocsController;
+use BookStack\App\SystemApiController;
 use BookStack\Entities\Controllers as EntityControllers;
 use BookStack\Exports\Controllers as ExportControllers;
 use BookStack\Permissions\ContentPermissionApiController;
@@ -92,3 +93,5 @@ Route::get('content-permissions/{contentType}/{contentId}', [ContentPermissionAp
 Route::put('content-permissions/{contentType}/{contentId}', [ContentPermissionApiController::class, 'update']);
 
 Route::get('audit-log', [AuditLogApiController::class, 'list']);
+
+Route::get('system', [SystemApiController::class, 'read']);
Morty Proxy This is a proxified and sanitized view of the page, visit original site.