From dabf149411c03130b870932954473dd6e7a992dc Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sun, 15 Jan 2017 16:27:24 +0000 Subject: [PATCH] Added user setting system and added user-lang option Supports #115 --- app/Http/Controllers/UserController.php | 17 +++--- app/Http/Kernel.php | 5 +- app/Http/Middleware/Localization.php | 25 +++++++++ .../Middleware/RedirectIfAuthenticated.php | 4 +- app/Providers/AppServiceProvider.php | 3 - app/Services/SettingService.php | 55 +++++++++++++++++++ app/helpers.php | 5 +- readme.md | 12 +++- resources/lang/en/settings.php | 11 ++++ resources/views/users/edit.blade.php | 11 +++- tests/Permissions/RolesTest.php | 1 - 11 files changed, 124 insertions(+), 25 deletions(-) create mode 100644 app/Http/Middleware/Localization.php diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index b5184c40a..c98d5f87e 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -1,13 +1,8 @@ - 'min:2', 'email' => 'min:2|email|unique:users,email,' . $id, 'password' => 'min:5|required_with:password_confirm', - 'password-confirm' => 'same:password|required_with:password' + 'password-confirm' => 'same:password|required_with:password', + 'setting' => 'array' ]); $user = $this->user->findOrFail($id); @@ -175,6 +171,13 @@ class UserController extends Controller $user->external_auth_id = $request->get('external_auth_id'); } + // Save an user-specific settings + if ($request->has('setting')) { + foreach ($request->get('setting') as $key => $value) { + setting()->putUser($user, $key, $value); + } + } + $user->save(); session()->flash('success', trans('settings.users_edit_success')); diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index f1d95f5c0..c55cc9ab8 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -1,6 +1,4 @@ - [ 'throttle:60,1', diff --git a/app/Http/Middleware/Localization.php b/app/Http/Middleware/Localization.php new file mode 100644 index 000000000..3624e0e01 --- /dev/null +++ b/app/Http/Middleware/Localization.php @@ -0,0 +1,25 @@ +getUser(user(), 'language', $defaultLang); + app()->setLocale($locale); + Carbon::setLocale($locale); + return $next($request); + } +} diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php index 2b3c64695..c27df7af4 100644 --- a/app/Http/Middleware/RedirectIfAuthenticated.php +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -1,6 +1,4 @@ -getMimeType(), $imageMimes); }); - - Carbon::setLocale(config('app.locale')); } /** diff --git a/app/Services/SettingService.php b/app/Services/SettingService.php index 1dc30f8a0..40094a513 100644 --- a/app/Services/SettingService.php +++ b/app/Services/SettingService.php @@ -1,6 +1,7 @@ formatValue($value, $default); } + /** + * Get a user-specific setting from the database or cache. + * @param User $user + * @param $key + * @param bool $default + * @return bool|string + */ + public function getUser($user, $key, $default = false) + { + return $this->get($this->userKey($user->id, $key), $default); + } + /** * Gets a setting value from the cache or database. * Looks at the system defaults if not cached or in database. @@ -111,6 +124,16 @@ class SettingService return $setting !== null; } + /** + * Check if a user setting is in the database. + * @param $key + * @return bool + */ + public function hasUser($key) + { + return $this->has($this->userKey($key)); + } + /** * Add a setting to the database. * @param $key @@ -128,6 +151,28 @@ class SettingService return true; } + /** + * Put a user-specific setting into the database. + * @param User $user + * @param $key + * @param $value + * @return bool + */ + public function putUser($user, $key, $value) + { + return $this->put($this->userKey($user->id, $key), $value); + } + + /** + * Convert a setting key into a user-specific key. + * @param $key + * @return string + */ + protected function userKey($userId, $key = '') + { + return 'user:' . $userId . ':' . $key; + } + /** * Removes a setting from the database. * @param $key @@ -143,6 +188,16 @@ class SettingService return true; } + /** + * Delete settings for a given user id. + * @param $userId + * @return mixed + */ + public function deleteUserSettings($userId) + { + return $this->setting->where('setting_key', 'like', $this->userKey($userId) . '%')->delete(); + } + /** * Gets a setting model from the database for the given key. * @param $key diff --git a/app/helpers.php b/app/helpers.php index b5be0fd11..6decb08e9 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -60,11 +60,12 @@ function userCan($permission, Ownable $ownable = null) * Helper to access system settings. * @param $key * @param bool $default - * @return mixed + * @return bool|string|\BookStack\Services\SettingService */ -function setting($key, $default = false) +function setting($key = null, $default = false) { $settingService = app(\BookStack\Services\SettingService::class); + if (is_null($key)) return $settingService; return $settingService->get($key, $default); } diff --git a/readme.md b/readme.md index fa5c48fe0..63d43e4b7 100644 --- a/readme.md +++ b/readme.md @@ -40,13 +40,19 @@ php artisan db:seed --class=DummyContentSeeder --database=mysql_testing Once done you can run `phpunit` in the application root directory to run all tests. -## Website and Docs +## Translations -The website and project docs are currently stored in the [BookStackApp/website](https://github.com/BookStackApp/website) repo. The docs are stored as markdown files in the `resources/docs` folder +As part of BookStack v0.14 support for translations has been built in. All text strings can be found in the `resources/lang` folder where each language option has its own folder. To add a new language you should copy the `en` folder to an new folder (eg. `fr` for french) then go through and translate all text strings in those files, leaving the keys and file-names intact. If a language string is missing then the `en` translation will be used. To show the language option in the user preferences language drop-down you will need to add your language to the options found at the bottom of the `resources/lang/en/settings.php` file. A system-wide language can also be set in the `.env` file like so: `APP_LANG=en`. + + Some strings have colon-prefixed variables in such as `:userName`. Leave these values as they are as they will be replaced at run-time. + +## Website, Docs & Blog + +The website project docs & Blog can be found in the [BookStackApp/website](https://github.com/BookStackApp/website) repo. ## License -BookStack is provided under the MIT License. +The BookStack source is provided under the MIT License. ## Attribution diff --git a/resources/lang/en/settings.php b/resources/lang/en/settings.php index e61df19d9..e1b544ef9 100644 --- a/resources/lang/en/settings.php +++ b/resources/lang/en/settings.php @@ -101,12 +101,23 @@ return [ 'users_edit_success' => 'User successfully updated', 'users_avatar' => 'User Avatar', 'users_avatar_desc' => 'This image should be approx 256px square.', + 'users_preferred_language' => 'Preferred Language', 'users_social_accounts' => 'Social Accounts', 'users_social_accounts_info' => 'Here you can connect your other accounts for quicker and easier login. Disconnecting an account here does not previously authorized access. Revoke access from your profile settings on the connected social account.', 'users_social_connect' => 'Connect Account', 'users_social_disconnect' => 'Disconnect Account', 'users_social_connected' => ':socialAccount account was successfully attached to your profile.', 'users_social_disconnected' => ':socialAccount account was successfully disconnected from your profile.', + + // Since these labels are already localized this array does not need to be + // translated in the language-specific files. + // DELETE BELOW IF COPIED FROM EN + /////////////////////////////////// + 'language_select' => [ + 'en' => 'English', + 'de' => 'Deutsch' + ] + /////////////////////////////////// ]; diff --git a/resources/views/users/edit.blade.php b/resources/views/users/edit.blade.php index 4db00e31f..c5d512725 100644 --- a/resources/views/users/edit.blade.php +++ b/resources/views/users/edit.blade.php @@ -5,8 +5,6 @@ @include('settings/navbar', ['selected' => 'users']) - -
id}") }}" method="post">
@@ -42,7 +40,14 @@ 'name' => 'image_id', 'imageClass' => 'avatar large' ]) - +
+
+ +
diff --git a/tests/Permissions/RolesTest.php b/tests/Permissions/RolesTest.php index 0f6a7a150..7f1895b91 100644 --- a/tests/Permissions/RolesTest.php +++ b/tests/Permissions/RolesTest.php @@ -583,7 +583,6 @@ class RolesTest extends TestCase public function test_image_delete_own_permission() { $this->giveUserPermissions($this->user, ['image-update-all']); -// $admin = $this->getAdmin(); $page = \BookStack\Page::first(); $image = factory(\BookStack\Image::class)->create(['uploaded_to' => $page->id, 'created_by' => $this->user->id, 'updated_by' => $this->user->id]);