From 6edf2c155dd24c4876fc15481ffd74bf3b2e4d05 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Mon, 29 Aug 2022 17:30:26 +0100 Subject: [PATCH] Added maintenance action to regenerate references --- .../Controllers/MaintenanceController.php | 21 ++++++- resources/lang/en/settings.php | 4 ++ .../views/settings/maintenance.blade.php | 21 ++++++- routes/web.php | 1 + tests/{ => Settings}/RecycleBinTest.php | 3 +- tests/Settings/RegenerateReferencesTest.php | 55 +++++++++++++++++++ tests/{ => Settings}/TestEmailTest.php | 3 +- 7 files changed, 103 insertions(+), 5 deletions(-) rename tests/{ => Settings}/RecycleBinTest.php (99%) create mode 100644 tests/Settings/RegenerateReferencesTest.php rename tests/{ => Settings}/TestEmailTest.php (98%) diff --git a/app/Http/Controllers/MaintenanceController.php b/app/Http/Controllers/MaintenanceController.php index f13266d7c..8bfefb7ac 100644 --- a/app/Http/Controllers/MaintenanceController.php +++ b/app/Http/Controllers/MaintenanceController.php @@ -5,6 +5,7 @@ namespace BookStack\Http\Controllers; use BookStack\Actions\ActivityType; use BookStack\Entities\Tools\TrashCan; use BookStack\Notifications\TestEmail; +use BookStack\References\ReferenceStore; use BookStack\Uploads\ImageService; use Illuminate\Http\Request; @@ -74,6 +75,24 @@ class MaintenanceController extends Controller $this->showErrorNotification($errorMessage); } - return redirect('/settings/maintenance#image-cleanup')->withInput(); + return redirect('/settings/maintenance#image-cleanup'); + } + + /** + * Action to regenerate the reference index in the system. + */ + public function regenerateReferences(ReferenceStore $referenceStore) + { + $this->checkPermission('settings-manage'); + $this->logActivity(ActivityType::MAINTENANCE_ACTION_RUN, 'regenerate-references'); + + try { + $referenceStore->updateForAllPages(); + $this->showSuccessNotification(trans('settings.maint_regen_references_success')); + } catch (\Exception $exception) { + $this->showErrorNotification($exception->getMessage()); + } + + return redirect('/settings/maintenance#regenerate-references'); } } diff --git a/resources/lang/en/settings.php b/resources/lang/en/settings.php index 3bfe70bc4..9dbd96c5a 100755 --- a/resources/lang/en/settings.php +++ b/resources/lang/en/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Congratulations! As you received this email notification, your email settings seem to be configured properly.', 'maint_recycle_bin_desc' => 'Deleted shelves, books, chapters & pages are sent to the recycle bin so they can be restored or permanently deleted. Older items in the recycle bin may be automatically removed after a while depending on system configuration.', 'maint_recycle_bin_open' => 'Open Recycle Bin', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Recycle Bin', diff --git a/resources/views/settings/maintenance.blade.php b/resources/views/settings/maintenance.blade.php index a2a9ebc81..7ee966e00 100644 --- a/resources/views/settings/maintenance.blade.php +++ b/resources/views/settings/maintenance.blade.php @@ -25,9 +25,10 @@

{{ trans('settings.maint_image_cleanup') }}

-
+

{{ trans('settings.maint_image_cleanup_desc') }}

+

{{ trans('settings.maint_timeout_command_note') }}

@@ -55,7 +56,7 @@

{{ trans('settings.maint_send_test_email') }}

-
+

{{ trans('settings.maint_send_test_email_desc') }}

@@ -68,5 +69,21 @@
+
+

{{ trans('settings.maint_regen_references') }}

+
+
+

{{ trans('settings.maint_regen_references_desc') }}

+

{{ trans('settings.maint_timeout_command_note') }}

+
+
+ + {!! csrf_field() !!} + + +
+
+
+
@stop diff --git a/routes/web.php b/routes/web.php index dc46821cb..26d4b6f13 100644 --- a/routes/web.php +++ b/routes/web.php @@ -218,6 +218,7 @@ Route::middleware('auth')->group(function () { Route::get('/settings/maintenance', [MaintenanceController::class, 'index']); Route::delete('/settings/maintenance/cleanup-images', [MaintenanceController::class, 'cleanupImages']); Route::post('/settings/maintenance/send-test-email', [MaintenanceController::class, 'sendTestEmail']); + Route::post('/settings/maintenance/regenerate-references', [MaintenanceController::class, 'regenerateReferences']); // Recycle Bin Route::get('/settings/recycle-bin', [RecycleBinController::class, 'index']); diff --git a/tests/RecycleBinTest.php b/tests/Settings/RecycleBinTest.php similarity index 99% rename from tests/RecycleBinTest.php rename to tests/Settings/RecycleBinTest.php index 0e0524338..465c1aaad 100644 --- a/tests/RecycleBinTest.php +++ b/tests/Settings/RecycleBinTest.php @@ -1,6 +1,6 @@ asAdmin()->get('/settings/maintenance'); + $formCssSelector = 'form[action$="/settings/maintenance/regenerate-references"]'; + $html = $this->withHtml($pageView); + $html->assertElementExists('#regenerate-references'); + $html->assertElementExists($formCssSelector); + $html->assertElementContains($formCssSelector . ' button', 'Regenerate References'); + } + + public function test_action_runs_reference_regen() + { + $this->mock(ReferenceStore::class) + ->shouldReceive('updateForAllPages') + ->once(); + + $resp = $this->asAdmin()->post('/settings/maintenance/regenerate-references'); + $resp->assertRedirect('/settings/maintenance#regenerate-references'); + $this->assertSessionHas('success', 'Reference index has been regenerated!'); + $this->assertActivityExists(ActivityType::MAINTENANCE_ACTION_RUN, null, 'regenerate-references'); + } + + public function test_settings_manage_permission_required() + { + $editor = $this->getEditor(); + $resp = $this->actingAs($editor)->post('/settings/maintenance/regenerate-references'); + $this->assertPermissionError($resp); + + $this->giveUserPermissions($editor, ['settings-manage']); + + $resp = $this->actingAs($editor)->post('/settings/maintenance/regenerate-references'); + $this->assertNotPermissionError($resp); + } + + public function test_action_failed_shown_as_error_notification() + { + $this->mock(ReferenceStore::class) + ->shouldReceive('updateForAllPages') + ->andThrow(\Exception::class, 'A badger stopped the task'); + + $resp = $this->asAdmin()->post('/settings/maintenance/regenerate-references'); + $resp->assertRedirect('/settings/maintenance#regenerate-references'); + $this->assertSessionError('A badger stopped the task'); + } +} diff --git a/tests/TestEmailTest.php b/tests/Settings/TestEmailTest.php similarity index 98% rename from tests/TestEmailTest.php rename to tests/Settings/TestEmailTest.php index 97f98225d..31c51158f 100644 --- a/tests/TestEmailTest.php +++ b/tests/Settings/TestEmailTest.php @@ -1,10 +1,11 @@