diff --git a/app/Activity/Models/View.php b/app/Activity/Models/View.php index a6bc2139e..512e08295 100644 --- a/app/Activity/Models/View.php +++ b/app/Activity/Models/View.php @@ -54,12 +54,4 @@ class View extends Model return $view->views; } - - /** - * Clear all views from the system. - */ - public static function clearAll() - { - static::query()->truncate(); - } } diff --git a/app/Console/Commands/CleanupImages.php b/app/Console/Commands/CleanupImages.php index 2399e1cbb..c37cadef0 100644 --- a/app/Console/Commands/CleanupImages.php +++ b/app/Console/Commands/CleanupImages.php @@ -25,38 +25,23 @@ class CleanupImages extends Command */ protected $description = 'Cleanup images and drawings'; - protected $imageService; - - /** - * Create a new command instance. - * - * @param \BookStack\Uploads\ImageService $imageService - */ - public function __construct(ImageService $imageService) - { - $this->imageService = $imageService; - parent::__construct(); - } - /** * Execute the console command. - * - * @return mixed */ - public function handle() + public function handle(ImageService $imageService): int { - $checkRevisions = $this->option('all') ? false : true; - $dryRun = $this->option('force') ? false : true; + $checkRevisions = !$this->option('all'); + $dryRun = !$this->option('force'); if (!$dryRun) { $this->warn("This operation is destructive and is not guaranteed to be fully accurate.\nEnsure you have a backup of your images.\n"); $proceed = $this->confirm("Are you sure you want to proceed?"); if (!$proceed) { - return; + return 0; } } - $deleted = $this->imageService->deleteUnusedImages($checkRevisions, $dryRun); + $deleted = $imageService->deleteUnusedImages($checkRevisions, $dryRun); $deleteCount = count($deleted); if ($dryRun) { @@ -65,21 +50,24 @@ class CleanupImages extends Command $this->showDeletedImages($deleted); $this->comment('Run with -f or --force to perform deletions'); - return; + return 0; } $this->showDeletedImages($deleted); $this->comment($deleteCount . ' images deleted'); + return 0; } - protected function showDeletedImages($paths) + protected function showDeletedImages($paths): void { if ($this->getOutput()->getVerbosity() <= OutputInterface::VERBOSITY_NORMAL) { return; } + if (count($paths) > 0) { $this->line('Images to delete:'); } + foreach ($paths as $path) { $this->line($path); } diff --git a/app/Console/Commands/ClearActivity.php b/app/Console/Commands/ClearActivity.php index 5ccf6e972..b88408e0c 100644 --- a/app/Console/Commands/ClearActivity.php +++ b/app/Console/Commands/ClearActivity.php @@ -21,27 +21,13 @@ class ClearActivity extends Command */ protected $description = 'Clear user activity from the system'; - protected $activity; - - /** - * Create a new command instance. - * - * @param Activity $activity - */ - public function __construct(Activity $activity) - { - $this->activity = $activity; - parent::__construct(); - } - /** * Execute the console command. - * - * @return mixed */ - public function handle() + public function handle(): int { - $this->activity->newQuery()->truncate(); + Activity::query()->truncate(); $this->comment('System activity cleared'); + return 0; } } diff --git a/app/Console/Commands/ClearRevisions.php b/app/Console/Commands/ClearRevisions.php index 681a7564b..e90503c56 100644 --- a/app/Console/Commands/ClearRevisions.php +++ b/app/Console/Commands/ClearRevisions.php @@ -23,28 +23,14 @@ class ClearRevisions extends Command */ protected $description = 'Clear page revisions'; - protected $pageRevision; - - /** - * Create a new command instance. - * - * @param PageRevision $pageRevision - */ - public function __construct(PageRevision $pageRevision) - { - $this->pageRevision = $pageRevision; - parent::__construct(); - } - /** * Execute the console command. - * - * @return mixed */ - public function handle() + public function handle(): int { $deleteTypes = $this->option('all') ? ['version', 'update_draft'] : ['version']; - $this->pageRevision->newQuery()->whereIn('type', $deleteTypes)->delete(); + PageRevision::query()->whereIn('type', $deleteTypes)->delete(); $this->comment('Revisions deleted'); + return 0; } } diff --git a/app/Console/Commands/ClearViews.php b/app/Console/Commands/ClearViews.php index c76b78d23..6cfbd5d5f 100644 --- a/app/Console/Commands/ClearViews.php +++ b/app/Console/Commands/ClearViews.php @@ -21,22 +21,13 @@ class ClearViews extends Command */ protected $description = 'Clear all view-counts for all entities'; - /** - * Create a new command instance. - */ - public function __construct() - { - parent::__construct(); - } - /** * Execute the console command. - * - * @return mixed */ - public function handle() + public function handle(): int { - View::clearAll(); + View::query()->truncate(); $this->comment('Views cleared'); + return 0; } } diff --git a/app/Console/Commands/CopyShelfPermissions.php b/app/Console/Commands/CopyShelfPermissions.php index ec4c875ff..95673cacd 100644 --- a/app/Console/Commands/CopyShelfPermissions.php +++ b/app/Console/Commands/CopyShelfPermissions.php @@ -25,25 +25,10 @@ class CopyShelfPermissions extends Command */ protected $description = 'Copy shelf permissions to all child books'; - protected PermissionsUpdater $permissionsUpdater; - - /** - * Create a new command instance. - * - * @return void - */ - public function __construct(PermissionsUpdater $permissionsUpdater) - { - $this->permissionsUpdater = $permissionsUpdater; - parent::__construct(); - } - /** * Execute the console command. - * - * @return mixed */ - public function handle() + public function handle(PermissionsUpdater $permissionsUpdater): int { $shelfSlug = $this->option('slug'); $cascadeAll = $this->option('all'); @@ -52,7 +37,7 @@ class CopyShelfPermissions extends Command if (!$cascadeAll && !$shelfSlug) { $this->error('Either a --slug or --all option must be provided.'); - return; + return 1; } if ($cascadeAll) { @@ -63,7 +48,7 @@ class CopyShelfPermissions extends Command ); if (!$continue && !$this->hasOption('no-interaction')) { - return; + return 0; } $shelves = Bookshelf::query()->get(['id']); @@ -77,10 +62,11 @@ class CopyShelfPermissions extends Command } foreach ($shelves as $shelf) { - $this->permissionsUpdater->updateBookPermissionsFromShelf($shelf, false); + $permissionsUpdater->updateBookPermissionsFromShelf($shelf, false); $this->info('Copied permissions for shelf [' . $shelf->id . ']'); } $this->info('Permissions copied for ' . $shelves->count() . ' shelves.'); + return 0; } } diff --git a/app/Console/Commands/CreateAdmin.php b/app/Console/Commands/CreateAdmin.php index 377207ed7..617e6ab2f 100644 --- a/app/Console/Commands/CreateAdmin.php +++ b/app/Console/Commands/CreateAdmin.php @@ -2,7 +2,6 @@ namespace BookStack\Console\Commands; -use BookStack\Exceptions\NotFoundException; use BookStack\Users\Models\Role; use BookStack\Users\UserRepo; use Illuminate\Console\Command; @@ -10,7 +9,6 @@ use Illuminate\Support\Facades\Validator; use Illuminate\Support\Str; use Illuminate\Validation\Rules\Password; use Illuminate\Validation\Rules\Unique; -use Symfony\Component\Console\Command\Command as SymfonyCommand; class CreateAdmin extends Command { @@ -32,25 +30,10 @@ class CreateAdmin extends Command */ protected $description = 'Add a new admin user to the system'; - protected $userRepo; - - /** - * Create a new command instance. - */ - public function __construct(UserRepo $userRepo) - { - $this->userRepo = $userRepo; - parent::__construct(); - } - /** * Execute the console command. - * - * @throws NotFoundException - * - * @return mixed */ - public function handle() + public function handle(UserRepo $userRepo): int { $details = $this->snakeCaseOptions(); @@ -82,17 +65,17 @@ class CreateAdmin extends Command $this->error($error); } - return SymfonyCommand::FAILURE; + return 1; } - $user = $this->userRepo->createWithoutActivity($validator->validated()); + $user = $userRepo->createWithoutActivity($validator->validated()); $user->attachRole(Role::getSystemRole('admin')); $user->email_confirmed = true; $user->save(); $this->info("Admin account with email \"{$user->email}\" successfully created!"); - return SymfonyCommand::SUCCESS; + return 0; } protected function snakeCaseOptions(): array diff --git a/app/Console/Commands/DeleteUsers.php b/app/Console/Commands/DeleteUsers.php index c16a5d9a6..f3e7c6852 100644 --- a/app/Console/Commands/DeleteUsers.php +++ b/app/Console/Commands/DeleteUsers.php @@ -15,8 +15,6 @@ class DeleteUsers extends Command */ protected $signature = 'bookstack:delete-users'; - protected $userRepo; - /** * The console command description. * @@ -24,30 +22,32 @@ class DeleteUsers extends Command */ protected $description = 'Delete users that are not "admin" or system users'; - public function __construct(UserRepo $userRepo) + /** + * Execute the console command. + */ + public function handle(UserRepo $userRepo): int { - $this->userRepo = $userRepo; - parent::__construct(); - } + $this->warn('This will delete all users from the system that are not "admin" or system users.'); + $confirm = $this->confirm('Are you sure you want to continue?'); - public function handle() - { - $confirm = $this->ask('This will delete all users from the system that are not "admin" or system users. Are you sure you want to continue? (Type "yes" to continue)'); - $numDeleted = 0; - if (strtolower(trim($confirm)) === 'yes') { - $totalUsers = User::query()->count(); - $users = User::query()->whereNull('system_name')->with('roles')->get(); - foreach ($users as $user) { - if ($user->hasSystemRole('admin')) { - // don't delete users with "admin" role - continue; - } - $this->userRepo->destroy($user); - $numDeleted++; - } - $this->info("Deleted $numDeleted of $totalUsers total users."); - } else { - $this->info('Exiting...'); + if (!$confirm) { + return 0; } + + $totalUsers = User::query()->count(); + $numDeleted = 0; + $users = User::query()->whereNull('system_name')->with('roles')->get(); + + foreach ($users as $user) { + if ($user->hasSystemRole('admin')) { + // don't delete users with "admin" role + continue; + } + $userRepo->destroy($user); + $numDeleted++; + } + + $this->info("Deleted $numDeleted of $totalUsers total users."); + return 0; } } diff --git a/app/Console/Commands/RegenerateCommentContent.php b/app/Console/Commands/RegenerateCommentContent.php index 3052559e3..37e254335 100644 --- a/app/Console/Commands/RegenerateCommentContent.php +++ b/app/Console/Commands/RegenerateCommentContent.php @@ -14,7 +14,8 @@ class RegenerateCommentContent extends Command * * @var string */ - protected $signature = 'bookstack:regenerate-comment-content {--database= : The database connection to use.}'; + protected $signature = 'bookstack:regenerate-comment-content + {--database= : The database connection to use}'; /** * The console command description. @@ -23,35 +24,19 @@ class RegenerateCommentContent extends Command */ protected $description = 'Regenerate the stored HTML of all comments'; - /** - * @var CommentRepo - */ - protected $commentRepo; - - /** - * Create a new command instance. - */ - public function __construct(CommentRepo $commentRepo) - { - $this->commentRepo = $commentRepo; - parent::__construct(); - } - /** * Execute the console command. - * - * @return mixed */ - public function handle() + public function handle(CommentRepo $commentRepo): int { $connection = DB::getDefaultConnection(); if ($this->option('database') !== null) { DB::setDefaultConnection($this->option('database')); } - Comment::query()->chunk(100, function ($comments) { + Comment::query()->chunk(100, function ($comments) use ($commentRepo) { foreach ($comments as $comment) { - $comment->html = $this->commentRepo->commentToHtml($comment->text); + $comment->html = $commentRepo->commentToHtml($comment->text); $comment->save(); } }); diff --git a/app/Console/Commands/RegeneratePermissions.php b/app/Console/Commands/RegeneratePermissions.php index 27dd8ea65..2c994781f 100644 --- a/app/Console/Commands/RegeneratePermissions.php +++ b/app/Console/Commands/RegeneratePermissions.php @@ -13,7 +13,8 @@ class RegeneratePermissions extends Command * * @var string */ - protected $signature = 'bookstack:regenerate-permissions {--database= : The database connection to use.}'; + protected $signature = 'bookstack:regenerate-permissions + {--database= : The database connection to use}'; /** * The console command description. @@ -22,23 +23,10 @@ class RegeneratePermissions extends Command */ protected $description = 'Regenerate all system permissions'; - protected JointPermissionBuilder $permissionBuilder; - - /** - * Create a new command instance. - */ - public function __construct(JointPermissionBuilder $permissionBuilder) - { - $this->permissionBuilder = $permissionBuilder; - parent::__construct(); - } - /** * Execute the console command. - * - * @return mixed */ - public function handle() + public function handle(JointPermissionBuilder $permissionBuilder): int { $connection = DB::getDefaultConnection(); @@ -46,7 +34,7 @@ class RegeneratePermissions extends Command DB::setDefaultConnection($this->option('database')); } - $this->permissionBuilder->rebuildForAll(); + $permissionBuilder->rebuildForAll(); DB::setDefaultConnection($connection); $this->comment('Permissions regenerated'); diff --git a/app/Console/Commands/RegenerateReferences.php b/app/Console/Commands/RegenerateReferences.php index 805fd922d..f85e0cd40 100644 --- a/app/Console/Commands/RegenerateReferences.php +++ b/app/Console/Commands/RegenerateReferences.php @@ -13,7 +13,8 @@ class RegenerateReferences extends Command * * @var string */ - protected $signature = 'bookstack:regenerate-references {--database= : The database connection to use.}'; + protected $signature = 'bookstack:regenerate-references + {--database= : The database connection to use}'; /** * The console command description. @@ -22,25 +23,10 @@ class RegenerateReferences extends Command */ protected $description = 'Regenerate all the cross-item model reference index'; - protected ReferenceStore $references; - - /** - * Create a new command instance. - * - * @return void - */ - public function __construct(ReferenceStore $references) - { - $this->references = $references; - parent::__construct(); - } - /** * Execute the console command. - * - * @return int */ - public function handle() + public function handle(ReferenceStore $references): int { $connection = DB::getDefaultConnection(); @@ -48,7 +34,7 @@ class RegenerateReferences extends Command DB::setDefaultConnection($this->option('database')); } - $this->references->updateForAllPages(); + $references->updateForAllPages(); DB::setDefaultConnection($connection); diff --git a/app/Console/Commands/RegenerateSearch.php b/app/Console/Commands/RegenerateSearch.php index ff584da56..23e2d2d0c 100644 --- a/app/Console/Commands/RegenerateSearch.php +++ b/app/Console/Commands/RegenerateSearch.php @@ -14,7 +14,8 @@ class RegenerateSearch extends Command * * @var string */ - protected $signature = 'bookstack:regenerate-search {--database= : The database connection to use.}'; + protected $signature = 'bookstack:regenerate-search + {--database= : The database connection to use}'; /** * The console command description. @@ -23,33 +24,17 @@ class RegenerateSearch extends Command */ protected $description = 'Re-index all content for searching'; - /** - * @var SearchIndex - */ - protected $searchIndex; - - /** - * Create a new command instance. - */ - public function __construct(SearchIndex $searchIndex) - { - parent::__construct(); - $this->searchIndex = $searchIndex; - } - /** * Execute the console command. - * - * @return mixed */ - public function handle() + public function handle(SearchIndex $searchIndex): int { $connection = DB::getDefaultConnection(); if ($this->option('database') !== null) { DB::setDefaultConnection($this->option('database')); } - $this->searchIndex->indexAllEntities(function (Entity $model, int $processed, int $total): void { + $searchIndex->indexAllEntities(function (Entity $model, int $processed, int $total): void { $this->info('Indexed ' . class_basename($model) . ' entries (' . $processed . '/' . $total . ')'); }); diff --git a/app/Console/Commands/ResetMfa.php b/app/Console/Commands/ResetMfa.php index 4b1813099..2d27fd01e 100644 --- a/app/Console/Commands/ResetMfa.php +++ b/app/Console/Commands/ResetMfa.php @@ -24,22 +24,10 @@ class ResetMfa extends Command */ protected $description = 'Reset & Clear any configured MFA methods for the given user'; - /** - * Create a new command instance. - * - * @return void - */ - public function __construct() - { - parent::__construct(); - } - /** * Execute the console command. - * - * @return mixed */ - public function handle() + public function handle(): int { $id = $this->option('id'); $email = $this->option('email'); @@ -66,13 +54,13 @@ class ResetMfa extends Command $this->info("This will delete any configure multi-factor authentication methods for user: \n- ID: {$user->id}\n- Name: {$user->name}\n- Email: {$user->email}\n"); $this->info('If multi-factor authentication is required for this user they will be asked to reconfigure their methods on next login.'); $confirm = $this->confirm('Are you sure you want to proceed?'); - if ($confirm) { - $user->mfaValues()->delete(); - $this->info('User MFA methods have been reset.'); - - return 0; + if (!$confirm) { + return 1; } - return 1; + $user->mfaValues()->delete(); + $this->info('User MFA methods have been reset.'); + + return 0; } } diff --git a/app/Console/Commands/UpdateUrl.php b/app/Console/Commands/UpdateUrl.php index 0d218b380..2db413ff4 100644 --- a/app/Console/Commands/UpdateUrl.php +++ b/app/Console/Commands/UpdateUrl.php @@ -26,10 +26,8 @@ class UpdateUrl extends Command /** * Execute the console command. - * - * @return mixed */ - public function handle(Connection $db) + public function handle(Connection $db): int { $oldUrl = str_replace("'", '', $this->argument('oldUrl')); $newUrl = str_replace("'", '', $this->argument('newUrl')); diff --git a/app/Console/Commands/UpgradeDatabaseEncoding.php b/app/Console/Commands/UpgradeDatabaseEncoding.php index 32808729a..0692cf6eb 100644 --- a/app/Console/Commands/UpgradeDatabaseEncoding.php +++ b/app/Console/Commands/UpgradeDatabaseEncoding.php @@ -12,7 +12,8 @@ class UpgradeDatabaseEncoding extends Command * * @var string */ - protected $signature = 'bookstack:db-utf8mb4 {--database= : The database connection to use.}'; + protected $signature = 'bookstack:db-utf8mb4 + {--database= : The database connection to use}'; /** * The console command description. @@ -21,20 +22,11 @@ class UpgradeDatabaseEncoding extends Command */ protected $description = 'Generate SQL commands to upgrade the database to UTF8mb4'; - /** - * Create a new command instance. - */ - public function __construct() - { - parent::__construct(); - } /** * Execute the console command. - * - * @return mixed */ - public function handle() + public function handle(): int { $connection = DB::getDefaultConnection(); if ($this->option('database') !== null) { @@ -48,9 +40,11 @@ class UpgradeDatabaseEncoding extends Command $key = 'Tables_in_' . $database; foreach ($tables as $table) { $tableName = $table->$key; - $this->line('ALTER TABLE `' . $tableName . '` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); + $this->line("ALTER TABLE `{$tableName}` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"); } DB::setDefaultConnection($connection); + + return 0; } } diff --git a/tests/Commands/CopyShelfPermissionsCommandTest.php b/tests/Commands/CopyShelfPermissionsCommandTest.php index c4b9fe6f3..5c21a2e34 100644 --- a/tests/Commands/CopyShelfPermissionsCommandTest.php +++ b/tests/Commands/CopyShelfPermissionsCommandTest.php @@ -11,7 +11,7 @@ class CopyShelfPermissionsCommandTest extends TestCase { $this->artisan('bookstack:copy-shelf-permissions') ->expectsOutput('Either a --slug or --all option must be provided.') - ->assertExitCode(0); + ->assertExitCode(1); } public function test_copy_shelf_permissions_command_using_slug() diff --git a/tests/Commands/DeleteUsersCommandTest.php b/tests/Commands/DeleteUsersCommandTest.php index 4d8081b6f..a959df95d 100644 --- a/tests/Commands/DeleteUsersCommandTest.php +++ b/tests/Commands/DeleteUsersCommandTest.php @@ -15,7 +15,7 @@ class DeleteUsersCommandTest extends TestCase $normalUserCount = $userCount - count($normalUsers); $this->artisan('bookstack:delete-users') - ->expectsQuestion('This will delete all users from the system that are not "admin" or system users. Are you sure you want to continue? (Type "yes" to continue)', 'yes') + ->expectsConfirmation('Are you sure you want to continue?', 'yes') ->expectsOutputToContain("Deleted $normalUserCount of $userCount total users.") ->assertExitCode(0); @@ -27,7 +27,7 @@ class DeleteUsersCommandTest extends TestCase $normalUsers = $this->getNormalUsers(); $this->artisan('bookstack:delete-users') - ->expectsQuestion('This will delete all users from the system that are not "admin" or system users. Are you sure you want to continue? (Type "yes" to continue)', 'no') + ->expectsConfirmation('Are you sure you want to continue?', 'no') ->assertExitCode(0); $this->assertDatabaseHas('users', ['id' => $normalUsers->first()->id]);