BookStack\Providers\EventServiceProvider::class,
BookStack\Providers\RouteServiceProvider::class,
BookStack\Providers\CustomFacadeProvider::class,
+ BookStack\Providers\CustomValidationServiceProvider::class,
],
/*
use BookStack\Entities\Managers\TrashCan;
use BookStack\Exceptions\ImageUploadException;
use BookStack\Exceptions\NotFoundException;
-use BookStack\Exceptions\NotifyException;
use BookStack\Facades\Activity;
use BookStack\Uploads\ImageRepo;
use Exception;
-use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Collection;
/**
* BookRepo constructor.
- * @param $tagRepo
*/
public function __construct(BaseRepo $baseRepo, TagRepo $tagRepo, ImageRepo $imageRepo)
{
/**
* BookshelfRepo constructor.
- * @param $baseRepo
*/
public function __construct(BaseRepo $baseRepo)
{
use BookStack\Entities\PageRevision;
use BookStack\Exceptions\MoveOperationException;
use BookStack\Exceptions\NotFoundException;
-use BookStack\Exceptions\NotifyException;
use BookStack\Exceptions\PermissionsException;
use BookStack\Facades\Activity;
use Exception;
use Illuminate\Support\ServiceProvider;
use Schema;
use URL;
-use Validator;
class AppServiceProvider extends ServiceProvider
{
URL::forceScheme($isHttps ? 'https' : 'http');
}
- // Custom validation methods
- Validator::extend('image_extension', function ($attribute, $value, $parameters, $validator) {
- $validImageExtensions = ['png', 'jpg', 'jpeg', 'gif', 'webp'];
- return in_array(strtolower($value->getClientOriginalExtension()), $validImageExtensions);
- });
-
- Validator::extend('no_double_extension', function ($attribute, $value, $parameters, $validator) {
- $uploadName = $value->getClientOriginalName();
- return substr_count($uploadName, '.') < 2;
- });
-
- Validator::extend('safe_url', function ($attribute, $value, $parameters, $validator) {
- $cleanLinkName = strtolower(trim($value));
- $isJs = strpos($cleanLinkName, 'javascript:') === 0;
- $isData = strpos($cleanLinkName, 'data:') === 0;
- return !$isJs && !$isData;
- });
-
// Custom blade view directives
Blade::directive('icon', function ($expression) {
return "<?php echo icon($expression); ?>";
});
- Blade::directive('exposeTranslations', function ($expression) {
- return "<?php \$__env->startPush('translations'); ?>" .
- "<?php foreach({$expression} as \$key): ?>" .
- '<meta name="translation" key="<?php echo e($key); ?>" value="<?php echo e(trans($key)); ?>">' . "\n" .
- "<?php endforeach; ?>" .
- '<?php $__env->stopPush(); ?>';
- });
-
// Allow longer string lengths after upgrade to utf8mb4
Schema::defaultStringLength(191);
--- /dev/null
+<?php
+
+namespace BookStack\Providers;
+
+use Illuminate\Support\Facades\Validator;
+use Illuminate\Support\ServiceProvider;
+
+class CustomValidationServiceProvider extends ServiceProvider
+{
+
+ /**
+ * Register our custom validation rules when the application boots.
+ */
+ public function boot(): void
+ {
+ Validator::extend('image_extension', function ($attribute, $value, $parameters, $validator) {
+ $validImageExtensions = ['png', 'jpg', 'jpeg', 'gif', 'webp'];
+ return in_array(strtolower($value->getClientOriginalExtension()), $validImageExtensions);
+ });
+
+ Validator::extend('no_double_extension', function ($attribute, $value, $parameters, $validator) {
+ $uploadName = $value->getClientOriginalName();
+ return substr_count($uploadName, '.') < 2;
+ });
+
+ Validator::extend('safe_url', function ($attribute, $value, $parameters, $validator) {
+ $cleanLinkName = strtolower(trim($value));
+ $isJs = strpos($cleanLinkName, 'javascript:') === 0;
+ $isData = strpos($cleanLinkName, 'data:') === 0;
+ return !$isJs && !$isData;
+ });
+ }
+}
this.pageId = this.$opts.pageId;
this.textDirection = this.$opts.textDirection;
+ this.imageUploadErrorText = this.$opts.imageUploadErrorText;
this.markdown = new MarkdownIt({html: true});
this.markdown.use(mdTasksLists, {label: true});
const newContent = `[](${resp.data.url})`;
replaceContent(placeHolderText, newContent);
}).catch(err => {
- window.$events.emit('error', trans('errors.image_upload_error'));
+ window.$events.emit('error', context.imageUploadErrorText);
replaceContent(placeHolderText, selectedText);
console.log(err);
});
this.cm.focus();
DrawIO.close();
}).catch(err => {
- window.$events.emit('error', trans('errors.image_upload_error'));
+ window.$events.emit('error', this.imageUploadErrorText);
console.log(err);
});
});
editor.dom.replace(newEl, id);
}).catch(err => {
editor.dom.remove(id);
- window.$events.emit('error', trans('errors.image_upload_error'));
+ window.$events.emit('error', wysiwygComponent.imageUploadErrorText);
console.log(err);
});
}, 10);
});
}
-function drawIoPlugin(drawioUrl, isDarkMode, pageId) {
+function drawIoPlugin(drawioUrl, isDarkMode, pageId, wysiwygComponent) {
let pageEditor = null;
let currentNode = null;
pageEditor.dom.setAttrib(imgElem, 'src', img.url);
pageEditor.dom.setAttrib(currentNode, 'drawio-diagram', img.id);
} catch (err) {
- window.$events.emit('error', trans('errors.image_upload_error'));
+ window.$events.emit('error', wysiwygComponent.imageUploadErrorText);
console.log(err);
}
return;
pageEditor.dom.get(id).parentNode.setAttribute('drawio-diagram', img.id);
} catch (err) {
pageEditor.dom.remove(id);
- window.$events.emit('error', trans('errors.image_upload_error'));
+ window.$events.emit('error', wysiwygComponent.imageUploadErrorText);
console.log(err);
}
}, 5);
class WysiwygEditor {
-
setup() {
this.elem = this.$el;
this.pageId = this.$opts.pageId;
this.textDirection = this.$opts.textDirection;
+ this.imageUploadErrorText = this.$opts.imageUploadErrorText;
this.isDarkMode = document.documentElement.classList.contains('dark-mode');
this.plugins = "image table textcolor paste link autolink fullscreen code customhr autosave lists codeeditor media";
const drawioUrlElem = document.querySelector('[drawio-url]');
if (drawioUrlElem) {
const url = drawioUrlElem.getAttribute('drawio-url');
- drawIoPlugin(url, this.isDarkMode, this.pageId);
+ drawIoPlugin(url, this.isDarkMode, this.pageId, this);
this.plugins += ' drawio';
}
<div id="markdown-editor" component="markdown-editor"
option:markdown-editor:page-id="{{ $model->id ?? 0 }}"
option:markdown-editor:text-direction="{{ config('app.rtl') ? 'rtl' : 'ltr' }}"
+ option:markdown-editor:image-upload-error-text="{{ trans('errors.image_upload_error') }}"
class="flex-fill flex code-fill">
- @exposeTranslations([
- 'errors.image_upload_error',
- ])
<div class="markdown-editor-wrap active">
<div class="editor-toolbar">
<div component="wysiwyg-editor"
option:wysiwyg-editor:page-id="{{ $model->id ?? 0 }}"
option:wysiwyg-editor:text-direction="{{ config('app.rtl') ? 'rtl' : 'ltr' }}"
+ option:wysiwyg-editor:image-upload-error-text="{{ trans('errors.image_upload_error') }}"
class="flex-fill flex">
- @exposeTranslations([
- 'errors.image_upload_error',
- ])
-
<textarea id="html-editor" name="html" rows="5"
@if($errors->has('html')) class="text-neg" @endif>@if(isset($model) || old('html')){{ old('html') ? old('html') : $model->html }}@endif</textarea>
</div>