Dan Brown

Added editor control in admin settings & Fixed some markdown editor bugs

Also updated the setting system with a more sane approach to handling default values. (Now done via the setting-defaults config file)
...@@ -312,6 +312,7 @@ class PageRepo extends EntityRepo ...@@ -312,6 +312,7 @@ class PageRepo extends EntityRepo
312 $page->fill($input); 312 $page->fill($input);
313 $page->html = $this->formatHtml($input['html']); 313 $page->html = $this->formatHtml($input['html']);
314 $page->text = strip_tags($page->html); 314 $page->text = strip_tags($page->html);
315 + if (setting('app-editor') !== 'markdown') $page->markdown = '';
315 $page->updated_by = $userId; 316 $page->updated_by = $userId;
316 $page->save(); 317 $page->save();
317 318
...@@ -348,6 +349,7 @@ class PageRepo extends EntityRepo ...@@ -348,6 +349,7 @@ class PageRepo extends EntityRepo
348 public function saveRevision(Page $page) 349 public function saveRevision(Page $page)
349 { 350 {
350 $revision = $this->pageRevision->fill($page->toArray()); 351 $revision = $this->pageRevision->fill($page->toArray());
352 + if (setting('app-editor') !== 'markdown') $revision->markdown = '';
351 $revision->page_id = $page->id; 353 $revision->page_id = $page->id;
352 $revision->slug = $page->slug; 354 $revision->slug = $page->slug;
353 $revision->book_slug = $page->book->slug; 355 $revision->book_slug = $page->book->slug;
...@@ -386,6 +388,8 @@ class PageRepo extends EntityRepo ...@@ -386,6 +388,8 @@ class PageRepo extends EntityRepo
386 } 388 }
387 389
388 $draft->fill($data); 390 $draft->fill($data);
391 + if (setting('app-editor') !== 'markdown') $draft->markdown = '';
392 +
389 $draft->save(); 393 $draft->save();
390 return $draft; 394 return $draft;
391 } 395 }
......
...@@ -44,28 +44,39 @@ class SettingService ...@@ -44,28 +44,39 @@ class SettingService
44 44
45 /** 45 /**
46 * Gets a setting value from the cache or database. 46 * Gets a setting value from the cache or database.
47 + * Looks at the system defaults if not cached or in database.
47 * @param $key 48 * @param $key
48 * @param $default 49 * @param $default
49 * @return mixed 50 * @return mixed
50 */ 51 */
51 protected function getValueFromStore($key, $default) 52 protected function getValueFromStore($key, $default)
52 { 53 {
54 + // Check for an overriding value
53 $overrideValue = $this->getOverrideValue($key); 55 $overrideValue = $this->getOverrideValue($key);
54 if ($overrideValue !== null) return $overrideValue; 56 if ($overrideValue !== null) return $overrideValue;
55 57
58 + // Check the cache
56 $cacheKey = $this->cachePrefix . $key; 59 $cacheKey = $this->cachePrefix . $key;
57 if ($this->cache->has($cacheKey)) { 60 if ($this->cache->has($cacheKey)) {
58 return $this->cache->get($cacheKey); 61 return $this->cache->get($cacheKey);
59 } 62 }
60 63
64 + // Check the database
61 $settingObject = $this->getSettingObjectByKey($key); 65 $settingObject = $this->getSettingObjectByKey($key);
62 -
63 if ($settingObject !== null) { 66 if ($settingObject !== null) {
64 $value = $settingObject->value; 67 $value = $settingObject->value;
65 $this->cache->forever($cacheKey, $value); 68 $this->cache->forever($cacheKey, $value);
66 return $value; 69 return $value;
67 } 70 }
68 71
72 + // Check the defaults set in the app config.
73 + $configPrefix = 'setting-defaults.' . $key;
74 + if (config()->has($configPrefix)) {
75 + $value = config($configPrefix);
76 + $this->cache->forever($cacheKey, $value);
77 + return $value;
78 + }
79 +
69 return $default; 80 return $default;
70 } 81 }
71 82
......
1 +<?php
2 +
3 +/**
4 + * The defaults for the system settings that are saved in the database.
5 + */
6 +return [
7 +
8 + 'app-editor' => 'wysiwyg'
9 +
10 +];
...\ No newline at end of file ...\ No newline at end of file
...@@ -13,11 +13,11 @@ class AddMarkdownSupport extends Migration ...@@ -13,11 +13,11 @@ class AddMarkdownSupport extends Migration
13 public function up() 13 public function up()
14 { 14 {
15 Schema::table('pages', function (Blueprint $table) { 15 Schema::table('pages', function (Blueprint $table) {
16 - $table->longText('markdown'); 16 + $table->longText('markdown')->default('');
17 }); 17 });
18 18
19 Schema::table('page_revisions', function (Blueprint $table) { 19 Schema::table('page_revisions', function (Blueprint $table) {
20 - $table->longText('markdown'); 20 + $table->longText('markdown')->default('');
21 }); 21 });
22 } 22 }
23 23
......
...@@ -258,6 +258,10 @@ module.exports = function (ngApp, events) { ...@@ -258,6 +258,10 @@ module.exports = function (ngApp, events) {
258 } 258 }
259 } 259 }
260 260
261 + if (!isMarkdown) {
262 + $scope.editorChange = function() {};
263 + }
264 +
261 /** 265 /**
262 * Start the AutoSave loop, Checks for content change 266 * Start the AutoSave loop, Checks for content change
263 * before performing the costly AJAX request. 267 * before performing the costly AJAX request.
...@@ -292,8 +296,6 @@ module.exports = function (ngApp, events) { ...@@ -292,8 +296,6 @@ module.exports = function (ngApp, events) {
292 296
293 if (isMarkdown) data.markdown = $scope.editContent; 297 if (isMarkdown) data.markdown = $scope.editContent;
294 298
295 - console.log(data.markdown);
296 -
297 $http.put('/ajax/page/' + pageId + '/save-draft', data).then((responseData) => { 299 $http.put('/ajax/page/' + pageId + '/save-draft', data).then((responseData) => {
298 $scope.draftText = responseData.data.message; 300 $scope.draftText = responseData.data.message;
299 if (!$scope.isNewPageDraft) $scope.isUpdateDraft = true; 301 if (!$scope.isNewPageDraft) $scope.isUpdateDraft = true;
......
1 1
2 -<div class="page-editor flex-fill flex" ng-controller="PageEditController" editor-type="{{ config('app.editor') }}" page-id="{{ $model->id or 0 }}" page-new-draft="{{ $model->draft or 0 }}" page-update-draft="{{ $model->isDraft or 0 }}"> 2 +<div class="page-editor flex-fill flex" ng-controller="PageEditController" editor-type="{{ setting('app-editor') }}" page-id="{{ $model->id or 0 }}" page-new-draft="{{ $model->draft or 0 }}" page-update-draft="{{ $model->isDraft or 0 }}">
3 3
4 {{ csrf_field() }} 4 {{ csrf_field() }}
5 <div class="faded-small toolbar"> 5 <div class="faded-small toolbar">
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
42 </div> 42 </div>
43 </div> 43 </div>
44 <div class="edit-area flex-fill flex"> 44 <div class="edit-area flex-fill flex">
45 - @if(config('app.editor') === 'html') 45 + @if(setting('app-editor') === 'wysiwyg')
46 <textarea id="html-editor" tinymce="editorOptions" mce-change="editorChange" mce-model="editContent" name="html" rows="5" 46 <textarea id="html-editor" tinymce="editorOptions" mce-change="editorChange" mce-model="editContent" name="html" rows="5"
47 @if($errors->has('html')) class="neg" @endif>@if(isset($model) || old('html')){{htmlspecialchars( old('html') ? old('html') : $model->html)}}@endif</textarea> 47 @if($errors->has('html')) class="neg" @endif>@if(isset($model) || old('html')){{htmlspecialchars( old('html') ? old('html') : $model->html)}}@endif</textarea>
48 @if($errors->has('html')) 48 @if($errors->has('html'))
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
50 @endif 50 @endif
51 @endif 51 @endif
52 52
53 - @if(config('app.editor') === 'markdown') 53 + @if(setting('app-editor') === 'markdown')
54 <div id="markdown-editor" markdown-editor class="flex-fill flex"> 54 <div id="markdown-editor" markdown-editor class="flex-fill flex">
55 55
56 <div class="markdown-editor-wrap"> 56 <div class="markdown-editor-wrap">
......
...@@ -17,29 +17,37 @@ ...@@ -17,29 +17,37 @@
17 <div class="col-md-6"> 17 <div class="col-md-6">
18 <div class="form-group"> 18 <div class="form-group">
19 <label for="setting-app-name">Application name</label> 19 <label for="setting-app-name">Application name</label>
20 - <input type="text" value="{{ Setting::get('app-name', 'BookStack') }}" name="setting-app-name" id="setting-app-name"> 20 + <input type="text" value="{{ setting('app-name', 'BookStack') }}" name="setting-app-name" id="setting-app-name">
21 </div> 21 </div>
22 <div class="form-group"> 22 <div class="form-group">
23 <label>Allow public viewing?</label> 23 <label>Allow public viewing?</label>
24 - <toggle-switch name="setting-app-public" value="{{ Setting::get('app-public') }}"></toggle-switch> 24 + <toggle-switch name="setting-app-public" value="{{ setting('app-public') }}"></toggle-switch>
25 </div> 25 </div>
26 <div class="form-group"> 26 <div class="form-group">
27 <label>Enable higher security image uploads?</label> 27 <label>Enable higher security image uploads?</label>
28 <p class="small">For performance reasons, all images are public by default, This option adds a random, hard-to-guess characters in front of image names. Ensure directory indexes are not enabled to prevent easy access.</p> 28 <p class="small">For performance reasons, all images are public by default, This option adds a random, hard-to-guess characters in front of image names. Ensure directory indexes are not enabled to prevent easy access.</p>
29 - <toggle-switch name="setting-app-secure-images" value="{{ Setting::get('app-secure-images') }}"></toggle-switch> 29 + <toggle-switch name="setting-app-secure-images" value="{{ setting('app-secure-images') }}"></toggle-switch>
30 + </div>
31 + <div class="form-group">
32 + <label for="setting-app-editor">Page Editor</label>
33 + <p class="small">Select which editor will be used by all users to edit pages.</p>
34 + <select name="setting-app-editor" id="setting-app-editor">
35 + <option @if(setting('app-editor') === 'wysiwyg') selected @endif value="wysiwyg">WYSIWYG</option>
36 + <option @if(setting('app-editor') === 'markdown') selected @endif value="markdown">Markdown</option>
37 + </select>
30 </div> 38 </div>
31 </div> 39 </div>
32 <div class="col-md-6"> 40 <div class="col-md-6">
33 <div class="form-group" id="logo-control"> 41 <div class="form-group" id="logo-control">
34 <label for="setting-app-logo">Application Logo</label> 42 <label for="setting-app-logo">Application Logo</label>
35 <p class="small">This image should be 43px in height. <br>Large images will be scaled down.</p> 43 <p class="small">This image should be 43px in height. <br>Large images will be scaled down.</p>
36 - <image-picker resize-height="43" show-remove="true" resize-width="200" current-image="{{ Setting::get('app-logo', '') }}" default-image="/logo.png" name="setting-app-logo" image-class="logo-image"></image-picker> 44 + <image-picker resize-height="43" show-remove="true" resize-width="200" current-image="{{ setting('app-logo', '') }}" default-image="/logo.png" name="setting-app-logo" image-class="logo-image"></image-picker>
37 </div> 45 </div>
38 <div class="form-group" id="color-control"> 46 <div class="form-group" id="color-control">
39 <label for="setting-app-color">Application Primary Color</label> 47 <label for="setting-app-color">Application Primary Color</label>
40 <p class="small">This should be a hex value. <br> Leave empty to reset to the default color.</p> 48 <p class="small">This should be a hex value. <br> Leave empty to reset to the default color.</p>
41 - <input type="text" value="{{ Setting::get('app-color', '') }}" name="setting-app-color" id="setting-app-color" placeholder="#0288D1"> 49 + <input type="text" value="{{ setting('app-color', '') }}" name="setting-app-color" id="setting-app-color" placeholder="#0288D1">
42 - <input type="hidden" value="{{ Setting::get('app-color-light', '') }}" name="setting-app-color-light" id="setting-app-color-light" placeholder="rgba(21, 101, 192, 0.15)"> 50 + <input type="hidden" value="{{ setting('app-color-light', '') }}" name="setting-app-color-light" id="setting-app-color-light" placeholder="rgba(21, 101, 192, 0.15)">
43 </div> 51 </div>
44 </div> 52 </div>
45 </div> 53 </div>
...@@ -53,14 +61,14 @@ ...@@ -53,14 +61,14 @@
53 <div class="col-md-6"> 61 <div class="col-md-6">
54 <div class="form-group"> 62 <div class="form-group">
55 <label for="setting-registration-enabled">Allow registration?</label> 63 <label for="setting-registration-enabled">Allow registration?</label>
56 - <toggle-switch name="setting-registration-enabled" value="{{ Setting::get('registration-enabled') }}"></toggle-switch> 64 + <toggle-switch name="setting-registration-enabled" value="{{ setting('registration-enabled') }}"></toggle-switch>
57 </div> 65 </div>
58 <div class="form-group"> 66 <div class="form-group">
59 <label for="setting-registration-role">Default user role after registration</label> 67 <label for="setting-registration-role">Default user role after registration</label>
60 <select id="setting-registration-role" name="setting-registration-role" @if($errors->has('setting-registration-role')) class="neg" @endif> 68 <select id="setting-registration-role" name="setting-registration-role" @if($errors->has('setting-registration-role')) class="neg" @endif>
61 @foreach(\BookStack\Role::all() as $role) 69 @foreach(\BookStack\Role::all() as $role)
62 <option value="{{$role->id}}" 70 <option value="{{$role->id}}"
63 - @if(\Setting::get('registration-role', \BookStack\Role::first()->id) == $role->id) selected @endif 71 + @if(setting('registration-role', \BookStack\Role::first()->id) == $role->id) selected @endif
64 > 72 >
65 {{ $role->display_name }} 73 {{ $role->display_name }}
66 </option> 74 </option>
...@@ -70,7 +78,7 @@ ...@@ -70,7 +78,7 @@
70 <div class="form-group"> 78 <div class="form-group">
71 <label for="setting-registration-confirmation">Require email confirmation?</label> 79 <label for="setting-registration-confirmation">Require email confirmation?</label>
72 <p class="small">If domain restriction is used then email confirmation will be required and the below value will be ignored.</p> 80 <p class="small">If domain restriction is used then email confirmation will be required and the below value will be ignored.</p>
73 - <toggle-switch name="setting-registration-confirmation" value="{{ Setting::get('registration-confirmation') }}"></toggle-switch> 81 + <toggle-switch name="setting-registration-confirmation" value="{{ setting('registration-confirmation') }}"></toggle-switch>
74 </div> 82 </div>
75 </div> 83 </div>
76 <div class="col-md-6"> 84 <div class="col-md-6">
...@@ -78,7 +86,7 @@ ...@@ -78,7 +86,7 @@
78 <label for="setting-registration-restrict">Restrict registration to domain</label> 86 <label for="setting-registration-restrict">Restrict registration to domain</label>
79 <p class="small">Enter a comma separated list of email domains you would like to restrict registration to. Users will be sent an email to confirm their address before being allowed to interact with the application. 87 <p class="small">Enter a comma separated list of email domains you would like to restrict registration to. Users will be sent an email to confirm their address before being allowed to interact with the application.
80 <br> Note that users will be able to change their email addresses after successful registration.</p> 88 <br> Note that users will be able to change their email addresses after successful registration.</p>
81 - <input type="text" id="setting-registration-restrict" name="setting-registration-restrict" placeholder="No restriction set" value="{{ Setting::get('registration-restrict', '') }}"> 89 + <input type="text" id="setting-registration-restrict" name="setting-registration-restrict" placeholder="No restriction set" value="{{ setting('registration-restrict', '') }}">
82 </div> 90 </div>
83 </div> 91 </div>
84 </div> 92 </div>
......