From: Dan Brown Date: Sat, 9 Dec 2017 12:48:08 +0000 (+0000) Subject: Merge branch 'master' of git://github.com/lommes/BookStack into lommes-master X-Git-Tag: v0.19.0~1^2~3 X-Git-Url: http://source.bookstackapp.com/bookstack/commitdiff_plain/d17eb0f54cd1e12fae9a1d015f4ad4b6b6f764c6?hp=009af9736e8c52710de6764eb159909236c2b3a8 Merge branch 'master' of git://github.com/lommes/BookStack into lommes-master --- diff --git a/app/Book.php b/app/Book.php index 06c00945d..3fb87b4c5 100644 --- a/app/Book.php +++ b/app/Book.php @@ -3,7 +3,7 @@ class Book extends Entity { - protected $fillable = ['name', 'description']; + protected $fillable = ['name', 'description', 'image_id']; /** * Get the url for this book. @@ -18,6 +18,33 @@ class Book extends Entity return baseUrl('/books/' . urlencode($this->slug)); } + /** + * Returns book cover image, if book cover not exists return default cover image. + * @param int $width - Width of the image + * @param int $height - Height of the image + * @return string + */ + public function getBookCover($width = 440, $height = 250) + { + $default = baseUrl('/book_default_cover.png'); + if (!$this->image_id) return $default; + + try { + $cover = $this->cover ? baseUrl($this->cover->getThumb($width, $height, false)) : $default; + } catch (\Exception $err) { + $cover = $default; + } + return $cover; + } + + /** + * Get the cover image of the book + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function cover() + { + return $this->belongsTo(Image::class, 'image_id'); + } /* * Get the edit url for this book. * @return string diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 1dc5094e3..12792e151 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -26,10 +26,10 @@ class Handler extends ExceptionHandler /** * Report or log an exception. - * * This is a great spot to send exceptions to Sentry, Bugsnag, etc. * * @param \Exception $e + * @return mixed */ public function report(Exception $e) { diff --git a/app/Http/Controllers/BookController.php b/app/Http/Controllers/BookController.php index 7e4b3fd81..e181aec89 100644 --- a/app/Http/Controllers/BookController.php +++ b/app/Http/Controllers/BookController.php @@ -40,12 +40,14 @@ class BookController extends Controller $recents = $this->signedIn ? $this->entityRepo->getRecentlyViewed('book', 4, 0) : false; $popular = $this->entityRepo->getPopular('book', 4, 0); $new = $this->entityRepo->getRecentlyCreated('book', 4, 0); - $this->setPageTitle('Books'); + $booksViewType = setting()->getUser($this->currentUser, 'books_view_type', 'list'); + $this->setPageTitle(trans('entities.books')); return view('books/index', [ 'books' => $books, 'recents' => $recents, 'popular' => $popular, - 'new' => $new + 'new' => $new, + 'booksViewType' => $booksViewType ]); } @@ -125,9 +127,9 @@ class BookController extends Controller 'name' => 'required|string|max:255', 'description' => 'string|max:1000' ]); - $book = $this->entityRepo->updateFromInput('book', $book, $request->all()); - Activity::add($book, 'book_update', $book->id); - return redirect($book->getUrl()); + $book = $this->entityRepo->updateFromInput('book', $book, $request->all()); + Activity::add($book, 'book_update', $book->id); + return redirect($book->getUrl()); } /** diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 7d109b70a..164becd4d 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -54,6 +54,7 @@ class HomeController extends Controller /** * Get a js representation of the current translations * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response + * @throws \Exception */ public function getTranslations() { $locale = app()->getLocale(); @@ -86,4 +87,13 @@ class HomeController extends Controller ]); } + /** + * Get custom head HTML, Used in ajax calls to show in editor. + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + */ + public function customHeadContent() + { + return view('partials/custom-head-content'); + } + } diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php index c11355db5..13e928465 100644 --- a/app/Http/Controllers/PageController.php +++ b/app/Http/Controllers/PageController.php @@ -161,14 +161,22 @@ class PageController extends Controller $page->html = $this->entityRepo->renderPage($page); $sidebarTree = $this->entityRepo->getBookChildren($page->book); $pageNav = $this->entityRepo->getPageNav($page->html); - $page->load(['comments.createdBy']); + + // check if the comment's are enabled + $commentsEnabled = !setting('app-disable-comments'); + if ($commentsEnabled) { + $page->load(['comments.createdBy']); + } Views::add($page); $this->setPageTitle($page->getShortName()); return view('pages/show', [ 'page' => $page,'book' => $page->book, - 'current' => $page, 'sidebarTree' => $sidebarTree, - 'pageNav' => $pageNav]); + 'current' => $page, + 'sidebarTree' => $sidebarTree, + 'commentsEnabled' => $commentsEnabled, + 'pageNav' => $pageNav + ]); } /** diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php index 69fcbe943..c3102571d 100644 --- a/app/Http/Middleware/TrustProxies.php +++ b/app/Http/Middleware/TrustProxies.php @@ -2,6 +2,7 @@ namespace BookStack\Http\Middleware; +use Closure; use Illuminate\Http\Request; use Fideloper\Proxy\TrustProxies as Middleware; @@ -26,4 +27,21 @@ class TrustProxies extends Middleware Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT', Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO', ]; + + /** + * Handle the request, Set the correct user-configured proxy information. + * @param Request $request + * @param Closure $next + * @return mixed + */ + public function handle($request, Closure $next) + { + $setProxies = config('app.proxies'); + if ($setProxies !== '**' && $setProxies !== '*' && $setProxies !== '') { + $setProxies = explode(',', $setProxies); + } + $this->proxies = $setProxies; + + return parent::handle($request, $next); + } } diff --git a/app/Services/ExportService.php b/app/Services/ExportService.php index a78b133ee..1e4e99428 100644 --- a/app/Services/ExportService.php +++ b/app/Services/ExportService.php @@ -127,7 +127,7 @@ class ExportService $pdf = \SnappyPDF::loadHTML($containedHtml); $pdf->setOption('print-media-type', true); } else { - $pdf = \PDF::loadHTML($containedHtml); + $pdf = \DomPDF::loadHTML($containedHtml); } return $pdf->output(); } diff --git a/composer.json b/composer.json index c86af0f45..5b9802f52 100644 --- a/composer.json +++ b/composer.json @@ -75,6 +75,8 @@ "config": { "optimize-autoloader": true, "preferred-install": "dist", - "php": "7.0" + "platform": { + "php": "7.0" + } } } diff --git a/composer.lock b/composer.lock index f52a2022b..057e6007a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "384c1805a51b16b9304ab3ac58f9554d", + "content-hash": "7d60f09393b99551e9ffdb6622ed7ade", "packages": [ { "name": "aws/aws-sdk-php", - "version": "3.38.5", + "version": "3.45.3", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "13ffa481127c08e04244f116ae85a64b4172479c" + "reference": "d0abb0b1194fa64973b135191f56df991bc5787c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/13ffa481127c08e04244f116ae85a64b4172479c", - "reference": "13ffa481127c08e04244f116ae85a64b4172479c", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/d0abb0b1194fa64973b135191f56df991bc5787c", + "reference": "d0abb0b1194fa64973b135191f56df991bc5787c", "shasum": "" }, "require": { @@ -39,7 +39,7 @@ "ext-dom": "*", "ext-openssl": "*", "nette/neon": "^2.3", - "phpunit/phpunit": "^4.8.35|^5.4.0", + "phpunit/phpunit": "^4.8.35|^5.4.3", "psr/cache": "^1.0" }, "suggest": { @@ -84,7 +84,7 @@ "s3", "sdk" ], - "time": "2017-11-17T22:08:25+00:00" + "time": "2017-12-08T21:36:50+00:00" }, { "name": "barryvdh/laravel-dompdf", @@ -377,16 +377,16 @@ }, { "name": "dompdf/dompdf", - "version": "v0.8.1", + "version": "v0.8.2", "source": { "type": "git", "url": "https://github.com/dompdf/dompdf.git", - "reference": "9ea852c4bdc74fac5def165e6cd52353f7ca3b3f" + "reference": "5113accd9ae5d466077cce5208dcf3fb871bf8f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dompdf/dompdf/zipball/9ea852c4bdc74fac5def165e6cd52353f7ca3b3f", - "reference": "9ea852c4bdc74fac5def165e6cd52353f7ca3b3f", + "url": "https://api.github.com/repos/dompdf/dompdf/zipball/5113accd9ae5d466077cce5208dcf3fb871bf8f6", + "reference": "5113accd9ae5d466077cce5208dcf3fb871bf8f6", "shasum": "" }, "require": { @@ -395,7 +395,7 @@ "ext-mbstring": "*", "phenx/php-font-lib": "0.5.*", "phenx/php-svg-lib": "0.3.*", - "php": ">=5.3.0" + "php": ">=5.4.0" }, "require-dev": { "phpunit/phpunit": "4.8.*", @@ -435,7 +435,7 @@ ], "description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter", "homepage": "https://github.com/dompdf/dompdf", - "time": "2017-09-14T01:36:24+00:00" + "time": "2017-11-26T14:49:08+00:00" }, { "name": "egulias/email-validator", @@ -898,25 +898,25 @@ }, { "name": "knplabs/knp-snappy", - "version": "v1.0.2", + "version": "v1.0.3", "source": { "type": "git", "url": "https://github.com/KnpLabs/snappy.git", - "reference": "e6a29846ca759ea268a1bca4455b8a14815a3976" + "reference": "68590ef3aa94425b1c0019cc28ce471729f51fcb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/KnpLabs/snappy/zipball/e6a29846ca759ea268a1bca4455b8a14815a3976", - "reference": "e6a29846ca759ea268a1bca4455b8a14815a3976", + "url": "https://api.github.com/repos/KnpLabs/snappy/zipball/68590ef3aa94425b1c0019cc28ce471729f51fcb", + "reference": "68590ef3aa94425b1c0019cc28ce471729f51fcb", "shasum": "" }, "require": { "php": ">=5.6", "psr/log": "^1.0", - "symfony/process": "~2.3|~3.0" + "symfony/process": "~2.3 || ~3.0 || ~4.0" }, "require-dev": { - "phpunit/phpunit": "~4.7" + "phpunit/phpunit": "~4.8.36" }, "suggest": { "h4cc/wkhtmltoimage-amd64": "Provides wkhtmltoimage-amd64 binary for Linux-compatible machines, use version `~0.12` as dependency", @@ -960,20 +960,20 @@ "thumbnail", "wkhtmltopdf" ], - "time": "2017-10-04T19:39:41+00:00" + "time": "2017-12-03T23:18:18+00:00" }, { "name": "laravel/framework", - "version": "v5.5.21", + "version": "v5.5.24", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "6321069a75723d88103526903d3192f0b231544a" + "reference": "06135405bb1f736dac5e9529ed1541fc446c9c0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/6321069a75723d88103526903d3192f0b231544a", - "reference": "6321069a75723d88103526903d3192f0b231544a", + "url": "https://api.github.com/repos/laravel/framework/zipball/06135405bb1f736dac5e9529ed1541fc446c9c0f", + "reference": "06135405bb1f736dac5e9529ed1541fc446c9c0f", "shasum": "" }, "require": { @@ -1093,7 +1093,7 @@ "framework", "laravel" ], - "time": "2017-11-14T15:08:13+00:00" + "time": "2017-12-07T01:28:21+00:00" }, { "name": "laravel/socialite", @@ -2292,20 +2292,20 @@ }, { "name": "symfony/console", - "version": "v3.3.13", + "version": "v3.3.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "63cd7960a0a522c3537f6326706d7f3b8de65805" + "reference": "b0878233cb5c4391347e5495089c7af11b8e6201" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/63cd7960a0a522c3537f6326706d7f3b8de65805", - "reference": "63cd7960a0a522c3537f6326706d7f3b8de65805", + "url": "https://api.github.com/repos/symfony/console/zipball/b0878233cb5c4391347e5495089c7af11b8e6201", + "reference": "b0878233cb5c4391347e5495089c7af11b8e6201", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", + "php": ">=5.5.9", "symfony/debug": "~2.8|~3.0", "symfony/polyfill-mbstring": "~1.0" }, @@ -2318,6 +2318,7 @@ "symfony/dependency-injection": "~3.3", "symfony/event-dispatcher": "~2.8|~3.0", "symfony/filesystem": "~2.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0", "symfony/process": "~2.8|~3.0" }, "suggest": { @@ -2356,7 +2357,7 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2017-11-16T15:24:32+00:00" + "time": "2017-07-29T21:27:59+00:00" }, { "name": "symfony/css-selector", @@ -2413,20 +2414,20 @@ }, { "name": "symfony/debug", - "version": "v3.3.13", + "version": "v3.3.6", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "74557880e2846b5c84029faa96b834da37e29810" + "reference": "7c13ae8ce1e2adbbd574fc39de7be498e1284e13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/74557880e2846b5c84029faa96b834da37e29810", - "reference": "74557880e2846b5c84029faa96b834da37e29810", + "url": "https://api.github.com/repos/symfony/debug/zipball/7c13ae8ce1e2adbbd574fc39de7be498e1284e13", + "reference": "7c13ae8ce1e2adbbd574fc39de7be498e1284e13", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", + "php": ">=5.5.9", "psr/log": "~1.0" }, "conflict": { @@ -2465,24 +2466,24 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2017-11-10T16:38:39+00:00" + "time": "2017-07-28T15:27:31+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v3.3.13", + "version": "v3.3.6", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "271d8c27c3ec5ecee6e2ac06016232e249d638d9" + "reference": "67535f1e3fd662bdc68d7ba317c93eecd973617e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/271d8c27c3ec5ecee6e2ac06016232e249d638d9", - "reference": "271d8c27c3ec5ecee6e2ac06016232e249d638d9", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/67535f1e3fd662bdc68d7ba317c93eecd973617e", + "reference": "67535f1e3fd662bdc68d7ba317c93eecd973617e", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": ">=5.5.9" }, "conflict": { "symfony/dependency-injection": "<3.3" @@ -2528,24 +2529,24 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2017-11-05T15:47:03+00:00" + "time": "2017-06-09T14:53:08+00:00" }, { "name": "symfony/finder", - "version": "v3.3.13", + "version": "v3.3.6", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "138af5ec075d4b1d1bd19de08c38a34bb2d7d880" + "reference": "baea7f66d30854ad32988c11a09d7ffd485810c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/138af5ec075d4b1d1bd19de08c38a34bb2d7d880", - "reference": "138af5ec075d4b1d1bd19de08c38a34bb2d7d880", + "url": "https://api.github.com/repos/symfony/finder/zipball/baea7f66d30854ad32988c11a09d7ffd485810c4", + "reference": "baea7f66d30854ad32988c11a09d7ffd485810c4", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": ">=5.5.9" }, "type": "library", "extra": { @@ -2577,24 +2578,24 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2017-11-05T15:47:03+00:00" + "time": "2017-06-01T21:01:25+00:00" }, { "name": "symfony/http-foundation", - "version": "v3.3.13", + "version": "v3.3.6", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "5943f0f19817a7e05992d20a90729b0dc93faf36" + "reference": "49e8cd2d59a7aa9bfab19e46de680c76e500a031" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/5943f0f19817a7e05992d20a90729b0dc93faf36", - "reference": "5943f0f19817a7e05992d20a90729b0dc93faf36", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/49e8cd2d59a7aa9bfab19e46de680c76e500a031", + "reference": "49e8cd2d59a7aa9bfab19e46de680c76e500a031", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", + "php": ">=5.5.9", "symfony/polyfill-mbstring": "~1.1" }, "require-dev": { @@ -2630,28 +2631,28 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2017-11-13T18:13:16+00:00" + "time": "2017-07-21T11:04:46+00:00" }, { "name": "symfony/http-kernel", - "version": "v3.3.13", + "version": "v3.3.6", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "a2a942172b742217ab2ccd9399494af2aa17c766" + "reference": "db10d05f1d95e4168e638db7a81c79616f568ea5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/a2a942172b742217ab2ccd9399494af2aa17c766", - "reference": "a2a942172b742217ab2ccd9399494af2aa17c766", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/db10d05f1d95e4168e638db7a81c79616f568ea5", + "reference": "db10d05f1d95e4168e638db7a81c79616f568ea5", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", + "php": ">=5.5.9", "psr/log": "~1.0", "symfony/debug": "~2.8|~3.0", "symfony/event-dispatcher": "~2.8|~3.0", - "symfony/http-foundation": "^3.3.11" + "symfony/http-foundation": "~3.3" }, "conflict": { "symfony/config": "<2.8", @@ -2716,7 +2717,7 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2017-11-16T18:14:43+00:00" + "time": "2017-08-01T10:25:59+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -2779,20 +2780,20 @@ }, { "name": "symfony/process", - "version": "v3.3.13", + "version": "v3.3.6", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "a56a3989fb762d7b19a0cf8e7693ee99a6ffb78d" + "reference": "07432804942b9f6dd7b7377faf9920af5f95d70a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/a56a3989fb762d7b19a0cf8e7693ee99a6ffb78d", - "reference": "a56a3989fb762d7b19a0cf8e7693ee99a6ffb78d", + "url": "https://api.github.com/repos/symfony/process/zipball/07432804942b9f6dd7b7377faf9920af5f95d70a", + "reference": "07432804942b9f6dd7b7377faf9920af5f95d70a", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": ">=5.5.9" }, "type": "library", "extra": { @@ -2824,24 +2825,24 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2017-11-13T15:31:11+00:00" + "time": "2017-07-13T13:05:09+00:00" }, { "name": "symfony/routing", - "version": "v3.3.13", + "version": "v3.3.6", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "cf7fa1dfcfee2c96969bfa1c0341e5627ecb1e95" + "reference": "4aee1a917fd4859ff8b51b9fd1dfb790a5ecfa26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/cf7fa1dfcfee2c96969bfa1c0341e5627ecb1e95", - "reference": "cf7fa1dfcfee2c96969bfa1c0341e5627ecb1e95", + "url": "https://api.github.com/repos/symfony/routing/zipball/4aee1a917fd4859ff8b51b9fd1dfb790a5ecfa26", + "reference": "4aee1a917fd4859ff8b51b9fd1dfb790a5ecfa26", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": ">=5.5.9" }, "conflict": { "symfony/config": "<2.8", @@ -2902,24 +2903,24 @@ "uri", "url" ], - "time": "2017-11-07T14:16:22+00:00" + "time": "2017-07-21T17:43:13+00:00" }, { "name": "symfony/translation", - "version": "v3.3.13", + "version": "v3.3.6", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "373e553477e55cd08f8b86b74db766c75b987fdb" + "reference": "35dd5fb003c90e8bd4d8cabdf94bf9c96d06fdc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/373e553477e55cd08f8b86b74db766c75b987fdb", - "reference": "373e553477e55cd08f8b86b74db766c75b987fdb", + "url": "https://api.github.com/repos/symfony/translation/zipball/35dd5fb003c90e8bd4d8cabdf94bf9c96d06fdc3", + "reference": "35dd5fb003c90e8bd4d8cabdf94bf9c96d06fdc3", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", + "php": ">=5.5.9", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { @@ -2967,24 +2968,24 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2017-11-07T14:12:55+00:00" + "time": "2017-06-24T16:45:30+00:00" }, { "name": "symfony/var-dumper", - "version": "v3.3.13", + "version": "v3.3.6", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "805de6bd6869073e60610df1b14ab7d969c61b01" + "reference": "b2623bccb969ad595c2090f9be498b74670d0663" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/805de6bd6869073e60610df1b14ab7d969c61b01", - "reference": "805de6bd6869073e60610df1b14ab7d969c61b01", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b2623bccb969ad595c2090f9be498b74670d0663", + "reference": "b2623bccb969ad595c2090f9be498b74670d0663", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", + "php": ">=5.5.9", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { @@ -3035,7 +3036,7 @@ "debug", "dump" ], - "time": "2017-11-07T14:16:22+00:00" + "time": "2017-07-28T06:06:09+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -3328,32 +3329,32 @@ }, { "name": "doctrine/instantiator", - "version": "1.1.0", + "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=5.3,<8.0-DEV" }, "require-dev": { "athletic/athletic": "~0.1.8", "ext-pdo": "*", "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "squizlabs/php_codesniffer": "^3.0.2" + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { @@ -3378,20 +3379,20 @@ "constructor", "instantiate" ], - "time": "2017-07-22T11:58:36+00:00" + "time": "2015-06-14T21:17:01+00:00" }, { "name": "filp/whoops", - "version": "2.1.13", + "version": "2.1.14", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "9f640a4f129e57d3537887f840380109a4dd182b" + "reference": "c6081b8838686aa04f1e83ba7e91f78b7b2a23e6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/9f640a4f129e57d3537887f840380109a4dd182b", - "reference": "9f640a4f129e57d3537887f840380109a4dd182b", + "url": "https://api.github.com/repos/filp/whoops/zipball/c6081b8838686aa04f1e83ba7e91f78b7b2a23e6", + "reference": "c6081b8838686aa04f1e83ba7e91f78b7b2a23e6", "shasum": "" }, "require": { @@ -3439,7 +3440,7 @@ "throwable", "whoops" ], - "time": "2017-11-17T08:15:51+00:00" + "time": "2017-11-23T18:22:44+00:00" }, { "name": "fzaninotto/faker", @@ -3916,29 +3917,35 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.1.1", + "version": "4.2.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2" + "reference": "66465776cfc249844bde6d117abff1d22e06c2da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/2d3d238c433cf69caeb4842e97a3223a116f94b2", - "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/66465776cfc249844bde6d117abff1d22e06c2da", + "reference": "66465776cfc249844bde6d117abff1d22e06c2da", "shasum": "" }, "require": { "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0@dev", + "phpdocumentor/reflection-common": "^1.0.0", "phpdocumentor/type-resolver": "^0.4.0", "webmozart/assert": "^1.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^4.4" + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": [ @@ -3957,7 +3964,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-08-30T18:51:59+00:00" + "time": "2017-11-27T17:38:31+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -4008,16 +4015,16 @@ }, { "name": "phpspec/prophecy", - "version": "v1.7.2", + "version": "1.7.3", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6" + "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6", - "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", + "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", "shasum": "" }, "require": { @@ -4029,7 +4036,7 @@ }, "require-dev": { "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8 || ^5.6.5" + "phpunit/phpunit": "^4.8.35 || ^5.7" }, "type": "library", "extra": { @@ -4067,20 +4074,20 @@ "spy", "stub" ], - "time": "2017-09-04T11:05:03+00:00" + "time": "2017-11-24T13:59:53+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "5.2.3", + "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d" + "reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d", - "reference": "8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/661f34d0bd3f1a7225ef491a70a020ad23a057a1", + "reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1", "shasum": "" }, "require": { @@ -4089,14 +4096,13 @@ "php": "^7.0", "phpunit/php-file-iterator": "^1.4.2", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^2.0", + "phpunit/php-token-stream": "^2.0.1", "sebastian/code-unit-reverse-lookup": "^1.0.1", "sebastian/environment": "^3.0", "sebastian/version": "^2.0.1", "theseer/tokenizer": "^1.1" }, "require-dev": { - "ext-xdebug": "^2.5", "phpunit/phpunit": "^6.0" }, "suggest": { @@ -4105,7 +4111,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.2.x-dev" + "dev-master": "5.3.x-dev" } }, "autoload": { @@ -4120,7 +4126,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -4131,20 +4137,20 @@ "testing", "xunit" ], - "time": "2017-11-03T13:47:33+00:00" + "time": "2017-12-06T09:29:45+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.2", + "version": "1.4.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", - "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", "shasum": "" }, "require": { @@ -4178,7 +4184,7 @@ "filesystem", "iterator" ], - "time": "2016-10-03T07:40:28+00:00" + "time": "2017-11-27T13:52:08+00:00" }, { "name": "phpunit/php-text-template", @@ -4272,16 +4278,16 @@ }, { "name": "phpunit/php-token-stream", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0" + "reference": "791198a2c6254db10131eecfe8c06670700904db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9a02332089ac48e704c70f6cefed30c224e3c0b0", - "reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", + "reference": "791198a2c6254db10131eecfe8c06670700904db", "shasum": "" }, "require": { @@ -4317,20 +4323,20 @@ "keywords": [ "tokenizer" ], - "time": "2017-08-20T05:47:52+00:00" + "time": "2017-11-27T05:48:46+00:00" }, { "name": "phpunit/phpunit", - "version": "6.4.4", + "version": "6.5.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "562f7dc75d46510a4ed5d16189ae57fbe45a9932" + "reference": "882e886cc928a0abd3c61282b2a64026237d14a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/562f7dc75d46510a4ed5d16189ae57fbe45a9932", - "reference": "562f7dc75d46510a4ed5d16189ae57fbe45a9932", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/882e886cc928a0abd3c61282b2a64026237d14a4", + "reference": "882e886cc928a0abd3c61282b2a64026237d14a4", "shasum": "" }, "require": { @@ -4344,12 +4350,12 @@ "phar-io/version": "^1.0", "php": "^7.0", "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^5.2.2", - "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-code-coverage": "^5.3", + "phpunit/php-file-iterator": "^1.4.3", "phpunit/php-text-template": "^1.2.1", "phpunit/php-timer": "^1.0.9", - "phpunit/phpunit-mock-objects": "^4.0.3", - "sebastian/comparator": "^2.0.2", + "phpunit/phpunit-mock-objects": "^5.0.4", + "sebastian/comparator": "^2.1", "sebastian/diff": "^2.0", "sebastian/environment": "^3.1", "sebastian/exporter": "^3.1", @@ -4375,7 +4381,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "6.4.x-dev" + "dev-master": "6.5.x-dev" } }, "autoload": { @@ -4401,20 +4407,20 @@ "testing", "xunit" ], - "time": "2017-11-08T11:26:09+00:00" + "time": "2017-12-06T09:42:03+00:00" }, { "name": "phpunit/phpunit-mock-objects", - "version": "4.0.4", + "version": "5.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "2f789b59ab89669015ad984afa350c4ec577ade0" + "reference": "16b50f4167e5e85e81ca8a3dd105d0a5fd32009a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/2f789b59ab89669015ad984afa350c4ec577ade0", - "reference": "2f789b59ab89669015ad984afa350c4ec577ade0", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/16b50f4167e5e85e81ca8a3dd105d0a5fd32009a", + "reference": "16b50f4167e5e85e81ca8a3dd105d0a5fd32009a", "shasum": "" }, "require": { @@ -4427,7 +4433,7 @@ "phpunit/phpunit": "<6.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^6.5" }, "suggest": { "ext-soap": "*" @@ -4435,7 +4441,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0.x-dev" + "dev-master": "5.0.x-dev" } }, "autoload": { @@ -4450,7 +4456,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -4460,7 +4466,7 @@ "mock", "xunit" ], - "time": "2017-08-03T14:08:16+00:00" + "time": "2017-12-02T05:31:19+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -5023,20 +5029,20 @@ }, { "name": "symfony/class-loader", - "version": "v3.3.13", + "version": "v3.3.6", "source": { "type": "git", "url": "https://github.com/symfony/class-loader.git", - "reference": "df173ac2af96ce202bf8bb5a3fc0bec8a4fdd4d1" + "reference": "386a294d621576302e7cc36965d6ed53b8c73c4f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/class-loader/zipball/df173ac2af96ce202bf8bb5a3fc0bec8a4fdd4d1", - "reference": "df173ac2af96ce202bf8bb5a3fc0bec8a4fdd4d1", + "url": "https://api.github.com/repos/symfony/class-loader/zipball/386a294d621576302e7cc36965d6ed53b8c73c4f", + "reference": "386a294d621576302e7cc36965d6ed53b8c73c4f", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": ">=5.5.9" }, "require-dev": { "symfony/finder": "~2.8|~3.0", @@ -5075,7 +5081,7 @@ ], "description": "Symfony ClassLoader Component", "homepage": "https://symfony.com", - "time": "2017-11-05T15:47:03+00:00" + "time": "2017-06-02T09:51:43+00:00" }, { "name": "symfony/dom-crawler", @@ -5233,5 +5239,8 @@ "php": ">=7.0.0", "ext-tidy": "*" }, - "platform-dev": [] + "platform-dev": [], + "platform-overrides": { + "php": "7.0" + } } diff --git a/config/app.php b/config/app.php index e4ccbb26f..3be50b6c5 100755 --- a/config/app.php +++ b/config/app.php @@ -219,7 +219,7 @@ return [ */ 'ImageTool' => Intervention\Image\Facades\Image::class, - 'PDF' => Barryvdh\DomPDF\Facade::class, + 'DomPDF' => Barryvdh\DomPDF\Facade::class, 'SnappyPDF' => Barryvdh\Snappy\Facades\SnappyPdf::class, 'Debugbar' => Barryvdh\Debugbar\Facade::class, @@ -234,4 +234,6 @@ return [ ], + 'proxies' => env('APP_PROXIES', ''), + ]; diff --git a/database/migrations/2017_08_29_102650_add_cover_image_display.php b/database/migrations/2017_08_29_102650_add_cover_image_display.php new file mode 100644 index 000000000..6f9932924 --- /dev/null +++ b/database/migrations/2017_08_29_102650_add_cover_image_display.php @@ -0,0 +1,32 @@ +integer('image_id')->nullable()->default(null); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('books', function (Blueprint $table) { + $table->dropColumn('image_id'); + }); + } +} diff --git a/public/book_default_cover.png b/public/book_default_cover.png new file mode 100644 index 000000000..7b6c9953e Binary files /dev/null and b/public/book_default_cover.png differ diff --git a/readme.md b/readme.md index e048e8ea6..1b3db4a56 100644 --- a/readme.md +++ b/readme.md @@ -54,8 +54,19 @@ Once done you can run `phpunit` in the application root directory to run all tes 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`. You will also need to add the language to the `locales` array in the `config/app.php` file. + +There is a script available which compares translation content to `en` files to see what items are missing or redundant. This can be ran like so from your BookStack install folder: + +```bash +# Syntax +php resources/lang/check.php + +# Examples +php resources/lang/check.php fr +php resources/lang/check.php pt_BR +``` - Some strings have colon-prefixed variables in such as `:userName`. Leave these values as they are as they will be replaced at run-time. +Some strings have colon-prefixed variables in such as `:userName`. Leave these values as they are as they will be replaced at run-time. ## Contributing diff --git a/resources/assets/js/components/image-picker.js b/resources/assets/js/components/image-picker.js new file mode 100644 index 000000000..d8fd7cce1 --- /dev/null +++ b/resources/assets/js/components/image-picker.js @@ -0,0 +1,59 @@ + +class ImagePicker { + + constructor(elem) { + this.elem = elem; + this.imageElem = elem.querySelector('img'); + this.input = elem.querySelector('input'); + + this.isUsingIds = elem.getAttribute('data-current-id') !== ''; + this.isResizing = elem.getAttribute('data-resize-height') && elem.getAttribute('data-resize-width'); + this.isResizeCropping = elem.getAttribute('data-resize-crop') !== ''; + + let selectButton = elem.querySelector('button[data-action="show-image-manager"]'); + selectButton.addEventListener('click', this.selectImage.bind(this)); + + let resetButton = elem.querySelector('button[data-action="reset-image"]'); + resetButton.addEventListener('click', this.reset.bind(this)); + + let removeButton = elem.querySelector('button[data-action="remove-image"]'); + if (removeButton) { + removeButton.addEventListener('click', this.removeImage.bind(this)); + } + } + + selectImage() { + window.ImageManager.show(image => { + if (!this.isResizing) { + this.setImage(image); + return; + } + + let requestString = '/images/thumb/' + image.id + '/' + this.elem.getAttribute('data-resize-width') + '/' + this.elem.getAttribute('data-resize-height') + '/' + (this.isResizeCropping ? 'true' : 'false'); + + window.$http.get(window.baseUrl(requestString)).then(resp => { + image.url = resp.data.url; + this.setImage(image); + }); + }); + } + + reset() { + this.setImage({id: 0, url: this.elem.getAttribute('data-default-image')}); + } + + setImage(image) { + this.imageElem.src = image.url; + this.input.value = this.isUsingIds ? image.id : image.url; + this.imageElem.classList.remove('none'); + } + + removeImage() { + this.imageElem.src = this.elem.getAttribute('data-default-image'); + this.imageElem.classList.add('none'); + this.input.value = 'none'; + } + +} + +module.exports = ImagePicker; \ No newline at end of file diff --git a/resources/assets/js/components/index.js b/resources/assets/js/components/index.js index f37709101..4cb16d06a 100644 --- a/resources/assets/js/components/index.js +++ b/resources/assets/js/components/index.js @@ -14,6 +14,7 @@ let componentMapping = { 'wysiwyg-editor': require('./wysiwyg-editor'), 'markdown-editor': require('./markdown-editor'), 'editor-toolbox': require('./editor-toolbox'), + 'image-picker': require('./image-picker'), }; window.components = {}; diff --git a/resources/assets/js/components/markdown-editor.js b/resources/assets/js/components/markdown-editor.js index e646dfd2b..7b051dd12 100644 --- a/resources/assets/js/components/markdown-editor.js +++ b/resources/assets/js/components/markdown-editor.js @@ -84,6 +84,8 @@ class MarkdownEditor { }; // Save draft extraKeys[`${metaKey}-S`] = cm => {window.$events.emit('editor-save-draft')}; + // Save page + extraKeys[`${metaKey}-Enter`] = cm => {window.$events.emit('editor-save-page')}; // Show link selector extraKeys[`Shift-${metaKey}-K`] = cm => {this.actionShowLinkSelector()}; // Insert Link diff --git a/resources/assets/js/pages/page-form.js b/resources/assets/js/pages/page-form.js index ec433b316..904403fc1 100644 --- a/resources/assets/js/pages/page-form.js +++ b/resources/assets/js/pages/page-form.js @@ -71,6 +71,11 @@ function registerEditorShortcuts(editor) { window.$events.emit('editor-save-draft'); }); + // Save page shortcut + editor.shortcuts.add('meta+13', '', () => { + window.$events.emit('editor-save-page'); + }); + // Loop through callout styles editor.shortcuts.add('meta+9', '', function() { let selectedNode = editor.selection.getNode(); @@ -92,6 +97,17 @@ function registerEditorShortcuts(editor) { } +/** + * Load custom HTML head content from the settings into the editor. + * @param editor + */ +function loadCustomHeadContent(editor) { + window.$http.get(window.baseUrl('/custom-head-content')).then(resp => { + if (!resp.data) return; + let head = editor.getDoc().querySelector('head'); + head.innerHTML += resp.data; + }); +} /** * Create and enable our custom code plugin @@ -317,6 +333,9 @@ module.exports = { args.content = ''; } }, + init_instance_callback: function(editor) { + loadCustomHeadContent(editor); + }, setup: function (editor) { editor.on('init ExecCommand change input NodeChange ObjectResized', editorChange); diff --git a/resources/assets/js/pages/page-show.js b/resources/assets/js/pages/page-show.js index 14437cd68..6af5af57d 100644 --- a/resources/assets/js/pages/page-show.js +++ b/resources/assets/js/pages/page-show.js @@ -102,23 +102,28 @@ let setupPageShow = window.setupPageShow = function (pageId) { let $window = $(window); let $sidebar = $("#sidebar .scroll-body"); let $bookTreeParent = $sidebar.parent(); + // Check the page is scrollable and the content is taller than the tree let pageScrollable = ($(document).height() > $window.height()) && ($sidebar.height() < $('.page-content').height()); + // Get current tree's width and header height let headerHeight = $("#header").height() + $(".toolbar").height(); let isFixed = $window.scrollTop() > headerHeight; - // Function to fix the tree as a sidebar + + // Fix the tree as a sidebar function stickTree() { $sidebar.width($bookTreeParent.width() + 15); $sidebar.addClass("fixed"); isFixed = true; } - // Function to un-fix the tree back into position + + // Un-fix the tree back into position function unstickTree() { $sidebar.css('width', 'auto'); $sidebar.removeClass("fixed"); isFixed = false; } + // Checks if the tree stickiness state should change function checkTreeStickiness(skipCheck) { let shouldBeFixed = $window.scrollTop() > headerHeight; @@ -150,6 +155,59 @@ let setupPageShow = window.setupPageShow = function (pageId) { unstickTree(); } }); + + + // Check if support is present for IntersectionObserver + if ('IntersectionObserver' in window && + 'IntersectionObserverEntry' in window && + 'intersectionRatio' in window.IntersectionObserverEntry.prototype) { + addPageHighlighting(); + } + + function addPageHighlighting() { + let pageNav = document.querySelector('.sidebar-page-nav'); + + // fetch all the headings. + let headings = document.querySelector('.page-content').querySelectorAll('h1, h2, h3, h4, h5, h6'); + // if headings are present, add observers. + if (headings.length > 0 && pageNav !== null) { + addNavObserver(headings); + } + + function addNavObserver(headings) { + // Setup the intersection observer. + let intersectOpts = { + rootMargin: '0px 0px 0px 0px', + threshold: 1.0 + }; + let pageNavObserver = new IntersectionObserver(headingVisibilityChange, intersectOpts); + + // observe each heading + for (let i = 0; i !== headings.length; ++i) { + pageNavObserver.observe(headings[i]); + } + } + + function headingVisibilityChange(entries, observer) { + for (let i = 0; i < entries.length; i++) { + let currentEntry = entries[i]; + let isVisible = (currentEntry.intersectionRatio === 1); + toggleAnchorHighlighting(currentEntry.target.id, isVisible); + } + } + + function toggleAnchorHighlighting(elementId, shouldHighlight) { + let anchorsToHighlight = pageNav.querySelectorAll('a[href="#' + elementId + '"]'); + for (let i = 0; i < anchorsToHighlight.length; i++) { + // Change below to use classList.toggle when IE support is dropped. + if (shouldHighlight) { + anchorsToHighlight[i].classList.add('current-heading'); + } else { + anchorsToHighlight[i].classList.remove('current-heading'); + } + } + } + } }; module.exports = setupPageShow; \ No newline at end of file diff --git a/resources/assets/js/vues/page-editor.js b/resources/assets/js/vues/page-editor.js index 9d7179a7e..d33739b30 100644 --- a/resources/assets/js/vues/page-editor.js +++ b/resources/assets/js/vues/page-editor.js @@ -34,8 +34,9 @@ function mounted() { this.draftText = trans('entities.pages_editing_page'); } - // Listen to save draft events from editor + // Listen to save events from editor window.$events.listen('editor-save-draft', this.saveDraft); + window.$events.listen('editor-save-page', this.savePage); // Listen to content changes from the editor window.$events.listen('editor-html-change', html => { @@ -106,6 +107,9 @@ let methods = { }); }, + savePage() { + this.$el.closest('form').submit(); + }, draftNotifyChange(text) { this.draftText = text; diff --git a/resources/assets/sass/_forms.scss b/resources/assets/sass/_forms.scss index 700c15336..802a075a2 100644 --- a/resources/assets/sass/_forms.scss +++ b/resources/assets/sass/_forms.scss @@ -63,9 +63,10 @@ padding: 0 $-m 0; margin-left: -1px; overflow-y: scroll; - .page-content { - margin: 0 auto; - } + } + .markdown-display.page-content { + margin: 0 auto; + max-width: 100%; } } .editor-toolbar { diff --git a/resources/assets/sass/_grid.scss b/resources/assets/sass/_grid.scss index 0f755e9f0..c145f4280 100644 --- a/resources/assets/sass/_grid.scss +++ b/resources/assets/sass/_grid.scss @@ -135,7 +135,7 @@ body.flexbox { width: 30%; left: 0; height: 100%; - overflow-y: scroll; + overflow-y: auto; -ms-overflow-style: none; //background-color: $primary-faded; border-left: 1px solid #DDD; @@ -195,6 +195,14 @@ div[class^="col-"] img { display: inline-block; } +@include larger-than(991px) { + .row.auto-clear .col-md-4:nth-child(3n+1){clear:left;} +} + +@include smaller-than(992px) { + .row.auto-clear .col-xs-6:nth-child(2n+1){clear:left;} +} + .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { position: relative; min-height: 1px; diff --git a/resources/assets/sass/_lists.scss b/resources/assets/sass/_lists.scss index d30d4d4a2..0496d794e 100644 --- a/resources/assets/sass/_lists.scss +++ b/resources/assets/sass/_lists.scss @@ -82,6 +82,9 @@ .h6 { margin-left: $nav-indent*4; } + .current-heading { + font-weight: bold; + } } // Sidebar list @@ -373,3 +376,51 @@ ul.pagination { border-bottom: 1px solid #DDD; } } + +// Books grid view +.featured-image-container { + position: relative; + overflow: hidden; + background: #F2F2F2; + border: 1px solid #ddd; + border-bottom: 0; + img { + display: block; + max-width: 100%; + height: auto; + transition: all .5s ease; + } + img:hover { + transform: scale(1.15); + opacity: .5; + } +} + +.book-grid-content { + padding: 30px; + border: 1px solid #ddd; + border-top: 0; + border-bottom-width: 2px; + h2 { + font-size: 1.5em; + margin: 0 0 10px; + } + h2 a { + display: block; + line-height: 1.2; + color: #009688;; + text-decoration: none; + } + p { + font-size: .85em; + margin: 0 0 10px; + line-height: 1.6em; + } + p.small { + font-size: .8em; + } +} + +.book-grid-item { + margin-bottom : 20px; +} diff --git a/resources/assets/sass/_tinymce.scss b/resources/assets/sass/_tinymce.scss index b8394b25b..92af39a87 100644 --- a/resources/assets/sass/_tinymce.scss +++ b/resources/assets/sass/_tinymce.scss @@ -1,16 +1,13 @@ - -.mce-tinymce.mce-container.fullscreen { +.mce-tinymce.mce-container.mce-fullscreen { position: fixed; top: 0; height: 100%; - width: 825px; + width: 100%; max-width: 100%; - margin-left: -$-s; - box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.08); + z-index: 100; } - .mce-tinymce { .mce-panel { background-color: #FFF; diff --git a/resources/assets/sass/styles.scss b/resources/assets/sass/styles.scss index e8d87d520..6a80237c5 100644 --- a/resources/assets/sass/styles.scss +++ b/resources/assets/sass/styles.scss @@ -231,7 +231,4 @@ $btt-size: 40px; input { width: 100%; } -} - - - +} \ No newline at end of file diff --git a/resources/lang/check.php b/resources/lang/check.php new file mode 100755 index 000000000..92a7b1eaf --- /dev/null +++ b/resources/lang/check.php @@ -0,0 +1,114 @@ +#!/usr/bin/env php + $enStr) { + if (strpos($enKey, 'settings.language_select.') === 0) { + unset($langContent[$enKey]); + continue; + } + if (!isset($langContent[$enKey])) { + $missingLangStrings[$enKey] = $enStr; + continue; + } + unset($langContent[$enKey]); +} + +if (count($missingLangStrings) > 0) { + info("\n========================"); + info("Missing language content"); + info("========================"); + outputFlatArray($missingLangStrings, $lang); +} + +if (count($langContent) > 0) { + info("\n=========================="); + info("Redundant language content"); + info("=========================="); + outputFlatArray($langContent, $lang); +} + +function outputFlatArray($arr, $lang) { + $grouped = []; + foreach ($arr as $key => $val) { + $explodedKey = explode('.', $key); + $group = $explodedKey[0]; + $path = implode('.', array_slice($explodedKey, 1)); + if (!isset($grouped[$group])) $grouped[$group] = []; + $grouped[$group][$path] = $val; + } + foreach ($grouped as $filename => $arr) { + echo "\e[36m" . $lang . '/' . $filename . ".php\e[0m\n"; + echo json_encode($arr, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE) . "\n"; + } +} + +function formatLang($lang) { + $langParts = explode('_', strtoupper($lang)); + $langParts[0] = strtolower($langParts[0]); + return implode('_', $langParts); +} + +function loadLang(string $lang) { + $dir = __DIR__ . "/{$lang}"; + if (!file_exists($dir)) { + errorOut("Expected directory '{$dir}' does not exist"); + } + $files = scandir($dir); + $data = []; + foreach ($files as $file) { + if (substr($file, -4) !== '.php') continue; + $fileData = include ($dir . '/' . $file); + $name = substr($file, 0, -4); + $data[$name] = $fileData; + } + return flattenArray($data); +} + +function flattenArray(array $arr) { + $data = []; + foreach ($arr as $key => $arrItem) { + if (!is_array($arrItem)) { + $data[$key] = $arrItem; + continue; + } + + $toUse = flattenArray($arrItem); + foreach ($toUse as $innerKey => $item) { + $data[$key . '.' . $innerKey] = $item; + } + } + return $data; +} + +function info($text) { + echo "\e[34m" . $text . "\e[0m\n"; +} + +function errorOut($text) { + echo "\e[31m" . $text . "\e[0m\n"; + exit(1); +} \ No newline at end of file diff --git a/resources/lang/de/common.php b/resources/lang/de/common.php index 3c21a9d08..2cc980846 100644 --- a/resources/lang/de/common.php +++ b/resources/lang/de/common.php @@ -17,6 +17,8 @@ return [ 'name' => 'Name', 'description' => 'Beschreibung', 'role' => 'Rolle', + 'cover_image' => 'Titelbild', + 'cover_image_description' => 'Das Bild sollte eine Auflösung von 300x170px haben.', /** * Actions @@ -43,7 +45,7 @@ return [ 'no_items' => 'Keine Einträge gefunden.', 'back_to_top' => 'nach oben', 'toggle_details' => 'Details zeigen/verstecken', - + 'toggle_thumbnails' => 'Thumbnails zeigen/verstecken', /** * Header */ diff --git a/resources/lang/de/settings.php b/resources/lang/de/settings.php index 9435ec808..e9d19e01b 100644 --- a/resources/lang/de/settings.php +++ b/resources/lang/de/settings.php @@ -31,6 +31,8 @@ return [ 'app_logo_desc' => "Dieses Bild sollte 43px hoch sein.\nGrößere Bilder werden verkleinert.", 'app_primary_color' => 'Primäre Anwendungsfarbe', 'app_primary_color_desc' => "Dies sollte ein HEX Wert sein.\nWenn Sie nicht eingeben, wird die Anwendung auf die Standardfarbe zurückgesetzt.", + 'app_disable_comments' => 'Kommentare deaktivieren', + 'app_disable_comments_desc' => 'Deaktiviert Kommentare über alle Seiten in der Anwendung. Vorhandene Kommentare werden nicht angezeigt.', /** * Registration settings @@ -96,6 +98,7 @@ return [ 'users_delete_warning' => 'Der Benutzer ":userName" wird aus dem System gelöscht.', 'users_delete_confirm' => 'Sind Sie sicher, dass Sie diesen Benutzer löschen möchten?', 'users_delete_success' => 'Benutzer erfolgreich gelöscht.', + 'users_books_view_type' => 'Bevorzugtes Display-Layout für Bücher', 'users_edit' => 'Benutzer bearbeiten', 'users_edit_profile' => 'Profil bearbeiten', 'users_edit_success' => 'Benutzer erfolgreich aktualisisert', diff --git a/resources/lang/en/common.php b/resources/lang/en/common.php index 269905a59..7cdd7c23e 100644 --- a/resources/lang/en/common.php +++ b/resources/lang/en/common.php @@ -18,7 +18,9 @@ return [ 'name' => 'Name', 'description' => 'Description', 'role' => 'Role', - + 'cover_image' => 'Cover image', + 'cover_image_description' => 'This image should be approx 440x250px.', + /** * Actions */ @@ -45,6 +47,7 @@ return [ 'no_items' => 'No items available', 'back_to_top' => 'Back to top', 'toggle_details' => 'Toggle Details', + 'toggle_thumbnails' => 'Toggle Thumbnails', 'details' => 'Details', /** diff --git a/resources/lang/en/settings.php b/resources/lang/en/settings.php index 468c5981f..f35c486ad 100755 --- a/resources/lang/en/settings.php +++ b/resources/lang/en/settings.php @@ -34,6 +34,8 @@ return [ 'app_homepage' => 'Application Homepage', 'app_homepage_desc' => 'Select a page to show on the homepage instead of the default view. Page permissions are ignored for selected pages.', 'app_homepage_default' => 'Default homepage view chosen', + 'app_disable_comments' => 'Disable comments', + 'app_disable_comments_desc' => 'Disable comments across all pages in the application. Existing comments are not shown.', /** * Registration settings @@ -94,6 +96,7 @@ return [ 'users_external_auth_id' => 'External Authentication ID', 'users_password_warning' => 'Only fill the below if you would like to change your password:', 'users_system_public' => 'This user represents any guest users that visit your instance. It cannot be used to log in but is assigned automatically.', + 'users_books_view_type' => 'Preferred layout for books viewing', 'users_delete' => 'Delete User', 'users_delete_named' => 'Delete user :userName', 'users_delete_warning' => 'This will fully delete this user with the name \':userName\' from the system.', diff --git a/resources/lang/es/common.php b/resources/lang/es/common.php index 3a62a2177..a173f286e 100644 --- a/resources/lang/es/common.php +++ b/resources/lang/es/common.php @@ -17,7 +17,8 @@ return [ 'name' => 'Nombre', 'description' => 'Descripción', 'role' => 'Rol', - + 'cover_image' => 'Imagen de portada', + 'cover_image_description' => 'Esta imagen debe ser aproximadamente 300x170px.', /** * Actions */ @@ -43,6 +44,7 @@ return [ 'no_items' => 'No hay items disponibles', 'back_to_top' => 'Volver arriba', 'toggle_details' => 'Alternar detalles', + 'toggle_thumbnails' => 'Alternar miniaturas', /** * Header diff --git a/resources/lang/es/settings.php b/resources/lang/es/settings.php index cd6a8b8d9..3c3281d28 100644 --- a/resources/lang/es/settings.php +++ b/resources/lang/es/settings.php @@ -31,6 +31,8 @@ return [ 'app_logo_desc' => 'Esta imagen debería de ser 43px en altura.
Iágenes grandes seán escaladas.', 'app_primary_color' => 'Color primario de la aplicación', 'app_primary_color_desc' => 'Esto debería ser un valor hexadecimal.
Deje el valor vaío para reiniciar al valor por defecto.', + 'app_disable_comments' => 'Deshabilitar comentarios', + 'app_disable_comments_desc' => 'Deshabilita los comentarios en todas las páginas de la aplicación. Los comentarios existentes no se muestran. ', /** * Registration settings @@ -91,6 +93,7 @@ return [ 'users_external_auth_id' => 'ID externo de autenticación', 'users_password_warning' => 'Solo rellene a continuación si desea cambiar su password:', 'users_system_public' => 'Este usuario representa cualquier usuario invitado que visita la aplicación. No puede utilizarse para hacer login sio que es asignado automáticamente.', + 'users_books_view_type' => 'Diseño de pantalla preferido para libros', 'users_delete' => 'Borrar usuario', 'users_delete_named' => 'Borrar usuario :userName', 'users_delete_warning' => 'Se borrará completamente el usuario con el nombre \':userName\' del sistema.', diff --git a/resources/lang/fr/common.php b/resources/lang/fr/common.php index 7a8ec55b6..2553d1482 100644 --- a/resources/lang/fr/common.php +++ b/resources/lang/fr/common.php @@ -17,7 +17,8 @@ return [ 'name' => 'Nom', 'description' => 'Description', 'role' => 'Rôle', - + 'cover_image' => 'Image de couverture', + 'cover_image_description' => 'Cette image doit être environ 300x170px.', /** * Actions */ @@ -43,6 +44,7 @@ return [ 'no_items' => 'Aucun élément', 'back_to_top' => 'Retour en haut', 'toggle_details' => 'Afficher les détails', + 'toggle_thumbnails' => 'Afficher les vignettes', /** * Header diff --git a/resources/lang/fr/settings.php b/resources/lang/fr/settings.php index 92e623795..2f0163368 100644 --- a/resources/lang/fr/settings.php +++ b/resources/lang/fr/settings.php @@ -31,7 +31,8 @@ return [ 'app_logo_desc' => 'Cette image doit faire 43px de hauteur.
Les images plus larges seront réduites.', 'app_primary_color' => 'Couleur principale de l\'application', 'app_primary_color_desc' => 'Cela devrait être une valeur hexadécimale.
Laisser vide pour rétablir la couleur par défaut.', - + 'app_disable_comments' => 'Désactiver les commentaires', + 'app_disable_comments_desc' => 'Désactive les commentaires sur toutes les pages de l\'application. Les commentaires existants ne sont pas affichés.', /** * Registration settings */ @@ -91,6 +92,7 @@ return [ 'users_external_auth_id' => 'Identifiant d\'authentification externe', 'users_password_warning' => 'Remplissez ce fomulaire uniquement si vous souhaitez changer de mot de passe:', 'users_system_public' => 'Cet utilisateur représente les invités visitant votre instance. Il est assigné automatiquement aux invités.', + 'users_books_view_type' => 'Disposition d\'affichage préférée pour les livres', 'users_delete' => 'Supprimer un utilisateur', 'users_delete_named' => 'Supprimer l\'utilisateur :userName', 'users_delete_warning' => 'Ceci va supprimer \':userName\' du système.', diff --git a/resources/lang/it/settings.php b/resources/lang/it/settings.php index d112cbc62..480e9302a 100755 --- a/resources/lang/it/settings.php +++ b/resources/lang/it/settings.php @@ -34,11 +34,12 @@ return [ 'app_homepage' => 'Homepage Applicazione', 'app_homepage_desc' => 'Seleziona una pagina da mostrare nella home anzichè quella di default. I permessi della pagina sono ignorati per quella selezionata.', 'app_homepage_default' => 'Homepage di default scelta', + 'app_disable_comments' => 'Disattiva commenti', + 'app_disable_comments_desc' => 'Disabilita i commenti su tutte le pagine nell\'applicazione. I commenti esistenti non sono mostrati. ', /** * Registration settings */ - 'reg_settings' => 'Impostazioni Registrazione', 'reg_allow' => 'Consentire Registrazione?', 'reg_default_role' => 'Ruolo predefinito dopo la registrazione', diff --git a/resources/lang/ja/common.php b/resources/lang/ja/common.php index 383294880..185e6116c 100644 --- a/resources/lang/ja/common.php +++ b/resources/lang/ja/common.php @@ -17,7 +17,7 @@ return [ 'name' => '名称', 'description' => '概要', 'role' => '権限', - + 'cover_image_description' => 'この画像は約 300x170px をする必要があります。', /** * Actions */ diff --git a/resources/lang/ja/settings.php b/resources/lang/ja/settings.php index b4cf57aeb..f9c9c5e86 100644 --- a/resources/lang/ja/settings.php +++ b/resources/lang/ja/settings.php @@ -31,6 +31,8 @@ return [ 'app_logo_desc' => '高さ43pxで表示されます。これを上回る場合、自動で縮小されます。', 'app_primary_color' => 'プライマリカラー', 'app_primary_color_desc' => '16進数カラーコードで入力します。空にした場合、デフォルトの色にリセットされます。', + 'app_disable_comments' => 'コメントを無効にする', + 'app_disable_comments_desc' => 'アプリケーション内のすべてのページのコメントを無効にします。既存のコメントは表示されません。', /** * Registration settings @@ -108,5 +110,5 @@ return [ 'users_social_disconnect' => 'アカウントを接続解除', 'users_social_connected' => '「:socialAccount」がプロフィールに接続されました。', 'users_social_disconnected' => '「:socialAccount」がプロフィールから接続解除されました。' - + ]; diff --git a/resources/lang/nl/common.php b/resources/lang/nl/common.php index 1ae0ade7c..fdfb90fb2 100644 --- a/resources/lang/nl/common.php +++ b/resources/lang/nl/common.php @@ -18,7 +18,8 @@ return [ 'name' => 'Naam', 'description' => 'Beschrijving', 'role' => 'Rol', - + 'cover_image' => 'Omslagfoto', + 'cover_image_description' => 'Deze afbeelding moet ongeveer 300x170px zijn.', /** * Actions */ @@ -44,6 +45,7 @@ return [ 'no_items' => 'Geen items beschikbaar', 'back_to_top' => 'Terug naar boven', 'toggle_details' => 'Details Weergeven', + 'toggle_thumbnails' => 'Thumbnails Weergeven', /** * Header diff --git a/resources/lang/nl/settings.php b/resources/lang/nl/settings.php index 7408a2dc3..ba73dc7e9 100644 --- a/resources/lang/nl/settings.php +++ b/resources/lang/nl/settings.php @@ -31,6 +31,8 @@ return [ 'app_logo_desc' => 'De afbeelding moet 43px hoog zijn.
Grotere afbeeldingen worden geschaald.', 'app_primary_color' => 'Applicatie hoofdkleur', 'app_primary_color_desc' => 'Geef een hexadecimale waarde.
Als je niks invult wordt de standaardkleur gebruikt.', + 'app_disable_comments' => 'Reacties uitschakelen', + 'app_disable_comments_desc' => 'Schakel opmerkingen uit op alle pagina\'s in de applicatie. Bestaande opmerkingen worden niet getoond.', /** * Registration settings @@ -91,6 +93,7 @@ return [ 'users_external_auth_id' => 'External Authentication ID', 'users_password_warning' => 'Vul onderstaande formulier alleen in als je het wachtwoord wilt aanpassen:', 'users_system_public' => 'De eigenschappen van deze gebruiker worden voor elke gastbezoeker gebruikt. Er kan niet mee ingelogd worden en wordt automatisch toegewezen.', + 'users_books_view_type' => 'Voorkeursuitleg voor het weergeven van boeken', 'users_delete' => 'Verwijder gebruiker', 'users_delete_named' => 'Verwijder gebruiker :userName', 'users_delete_warning' => 'Dit zal de gebruiker \':userName\' volledig uit het systeem verwijderen.', diff --git a/resources/lang/pl/common.php b/resources/lang/pl/common.php index 1c8963653..f7741ba6f 100644 --- a/resources/lang/pl/common.php +++ b/resources/lang/pl/common.php @@ -17,7 +17,9 @@ return [ 'name' => 'Nazwa', 'description' => 'Opis', 'role' => 'Rola', - + 'cover_image' => 'Zdjęcie z okładki', + 'cover_image_description' => 'Ten obraz powinien wynosić około 300 x 170 piksli.', + /** * Actions */ diff --git a/resources/lang/pl/settings.php b/resources/lang/pl/settings.php index 381e5517a..d6f3cca1b 100644 --- a/resources/lang/pl/settings.php +++ b/resources/lang/pl/settings.php @@ -31,6 +31,8 @@ return [ 'app_logo_desc' => 'Ten obrazek powinien mieć nie więcej niż 43px w pionie.
Większe obrazki będą skalowane w dół.', 'app_primary_color' => 'Podstawowy kolor aplikacji', 'app_primary_color_desc' => 'To powinna być wartość HEX.
Zostaw to pole puste, by powrócić do podstawowego koloru.', + 'app_disable_comments' => 'Wyłącz komentarze', + 'app_disable_comments_desc' => 'Wyłącz komentarze na wszystkich stronach w aplikacji. Istniejące komentarze nie są pokazywane.', /** * Registration settings diff --git a/resources/lang/pt_BR/common.php b/resources/lang/pt_BR/common.php index 632a1a078..991cb0b7e 100644 --- a/resources/lang/pt_BR/common.php +++ b/resources/lang/pt_BR/common.php @@ -18,7 +18,8 @@ return [ 'name' => 'Nome', 'description' => 'Descrição', 'role' => 'Regra', - + 'cover_image' => 'Imagem de capa', + 'cover_image_description' => 'Esta imagem deve ser aproximadamente 300x170px.', /** * Actions */ @@ -45,6 +46,7 @@ return [ 'no_items' => 'Nenhum item disponível', 'back_to_top' => 'Voltar ao topo', 'toggle_details' => 'Alternar Detalhes', + 'toggle_thumbnails' => 'Alternar Miniaturas', 'details' => 'Detalhes', /** diff --git a/resources/lang/pt_BR/settings.php b/resources/lang/pt_BR/settings.php index 5513c217f..77a0e6e39 100644 --- a/resources/lang/pt_BR/settings.php +++ b/resources/lang/pt_BR/settings.php @@ -34,6 +34,8 @@ return [ 'app_homepage' => 'Página incial', 'app_homepage_desc' => 'Selecione a página para ser usada como página inicial em vez da padrão. Permissões da página serão ignoradas.', 'app_homepage_default' => 'Escolhida página inicial padrão', + 'app_disable_comments' => 'Desativar comentários', + 'app_disable_comments_desc' => 'Desativar comentários em todas as páginas no aplicativo. Os comentários existentes não são exibidos.', /** * Registration settings @@ -94,6 +96,7 @@ return [ 'users_external_auth_id' => 'ID de Autenticação Externa', 'users_password_warning' => 'Preencha os dados abaixo caso queira modificar a sua senha:', 'users_system_public' => 'Esse usuário representa quaisquer convidados que visitam o aplicativo. Ele não pode ser usado para login.', + 'users_books_view_type' => 'Layout preferido para mostrar livros', 'users_delete' => 'Excluir Usuário', 'users_delete_named' => 'Excluir :userName', 'users_delete_warning' => 'A ação vai excluir completamente o usuário de nome \':userName\' do sistema.', diff --git a/resources/lang/ru/settings.php b/resources/lang/ru/settings.php index 9a9e55fd6..5d2f07ba9 100755 --- a/resources/lang/ru/settings.php +++ b/resources/lang/ru/settings.php @@ -34,6 +34,8 @@ return [ 'app_homepage' => 'Домашняя страница приложения', 'app_homepage_desc' => 'Выберите страницу, которая будет отображаться на главной странице вместо стандартной. Права на страницы игнорируются для выбранных страниц.', 'app_homepage_default' => 'Выбрана домашняя страница по-умолчанию', + 'app_disable_comments' => 'Отключить комментарии', + 'app_disable_comments_desc' => 'Отключить комментарии на всех страницах приложения. Существующие комментарии не отображаются.', /** * Registration diff --git a/resources/lang/sk/common.php b/resources/lang/sk/common.php index 100981597..a823fb379 100644 --- a/resources/lang/sk/common.php +++ b/resources/lang/sk/common.php @@ -17,7 +17,8 @@ return [ 'name' => 'Meno', 'description' => 'Popis', 'role' => 'Rola', - + 'cover_image' => 'Obal knihy', + 'cover_image_description' => 'Tento obrázok by mal byť približne 300 x 170 pixelov.', /** * Actions */ @@ -43,6 +44,7 @@ return [ 'no_items' => 'Žiadne položky nie sú dostupné', 'back_to_top' => 'Späť nahor', 'toggle_details' => 'Prepnúť detaily', + 'toggle_thumbnails' => 'Prepnúť náhľady', /** * Header diff --git a/resources/lang/sk/settings.php b/resources/lang/sk/settings.php index 643b4b8ff..521af196e 100644 --- a/resources/lang/sk/settings.php +++ b/resources/lang/sk/settings.php @@ -31,6 +31,8 @@ return [ 'app_logo_desc' => 'Tento obrázok by mal mať 43px na výšku.
Veľké obrázky budú preškálované na menší rozmer.', 'app_primary_color' => 'Primárna farba pre aplikáciu', 'app_primary_color_desc' => 'Toto by mala byť hodnota v hex tvare.
Nechajte prázdne ak chcete použiť prednastavenú farbu.', + 'app_disable_comments' => 'Zakázať komentáre', + 'app_disable_comments_desc' => 'Zakázať komentáre na všetkých stránkach aplikácie. Existujúce komentáre sa nezobrazujú.', /** * Registration settings @@ -91,6 +93,7 @@ return [ 'users_external_auth_id' => 'Externé autentifikačné ID', 'users_password_warning' => 'Pole nižšie vyplňte iba ak chcete zmeniť heslo:', 'users_system_public' => 'Tento účet reprezentuje každého hosťovského používateľa, ktorý navštívi Vašu inštanciu. Nedá sa pomocou neho prihlásiť a je priradený automaticky.', + 'users_books_view_type' => 'Preferované rozloženie pre prezeranie kníh', 'users_delete' => 'Zmazať používateľa', 'users_delete_named' => 'Zmazať používateľa :userName', 'users_delete_warning' => ' Toto úplne odstráni používateľa menom \':userName\' zo systému.', diff --git a/resources/views/books/create.blade.php b/resources/views/books/create.blade.php index 385e6b9d7..4798459c2 100644 --- a/resources/views/books/create.blade.php +++ b/resources/views/books/create.blade.php @@ -17,11 +17,12 @@

{{ trans('entities.books_create') }}

-
+ @include('books/form')
- +


+ @include('components.image-manager', ['imageType' => 'cover']) @stop \ No newline at end of file diff --git a/resources/views/books/edit.blade.php b/resources/views/books/edit.blade.php index 9d9c54fec..6bf285f95 100644 --- a/resources/views/books/edit.blade.php +++ b/resources/views/books/edit.blade.php @@ -20,5 +20,5 @@ - +@include('components.image-manager', ['imageType' => 'cover']) @stop \ No newline at end of file diff --git a/resources/views/books/form.blade.php b/resources/views/books/form.blade.php index 84a30e7e9..06eea7ca9 100644 --- a/resources/views/books/form.blade.php +++ b/resources/views/books/form.blade.php @@ -9,6 +9,21 @@ @include('form/textarea', ['name' => 'description']) +
+ +

{{ trans('common.cover_image_description') }}

+ + @include('components.image-picker', [ + 'resizeHeight' => '512', + 'resizeWidth' => '512', + 'showRemove' => false, + 'defaultImage' => baseUrl('/book_default_cover.png'), + 'currentImage' => @isset($model) ? $model->getBookCover() : baseUrl('/book_default_cover.png') , + 'currentId' => @isset($model) ? $model->image_id : 0, + 'name' => 'image_id', + 'imageClass' => 'cover' + ]) +
{{ trans('common.cancel') }} diff --git a/resources/views/books/grid-item.blade.php b/resources/views/books/grid-item.blade.php new file mode 100644 index 000000000..cb2b447b0 --- /dev/null +++ b/resources/views/books/grid-item.blade.php @@ -0,0 +1,18 @@ +
+ +
+

{{$book->getShortName(35)}}

+ @if(isset($book->searchSnippet)) +

{!! $book->searchSnippet !!}

+ @else +

{{ $book->getExcerpt(130) }}

+ @endif +
+ @include('partials.entity-meta', ['entity' => $book]) +
+
+
\ No newline at end of file diff --git a/resources/views/books/index.blade.php b/resources/views/books/index.blade.php index c22b4591f..d392af045 100644 --- a/resources/views/books/index.blade.php +++ b/resources/views/books/index.blade.php @@ -39,15 +39,29 @@ @stop @section('body') - -
+ @if($booksViewType === 'list') +
+ @else +
+ @endif

{{ trans('entities.books') }}

@if(count($books) > 0) - @foreach($books as $book) - @include('books/list-item', ['book' => $book]) -
- @endforeach - {!! $books->render() !!} + @if($booksViewType === 'list') + @foreach($books as $book) + @include('books/list-item', ['book' => $book]) +
+ @endforeach + {!! $books->render() !!} + @else +
+ @foreach($books as $key => $book) + @include('books/grid-item', ['book' => $book]) + @endforeach +
+ {!! $books->render() !!} +
+
+ @endif @else

{{ trans('entities.books_empty') }}

@if(userCan('books-create-all')) @@ -55,5 +69,4 @@ @endif @endif
- @stop \ No newline at end of file diff --git a/resources/views/components/image-picker.blade.php b/resources/views/components/image-picker.blade.php index 228e8d230..034b65cc5 100644 --- a/resources/views/components/image-picker.blade.php +++ b/resources/views/components/image-picker.blade.php @@ -13,54 +13,5 @@ @endif - -
- - \ No newline at end of file + +
\ No newline at end of file diff --git a/resources/views/pages/form.blade.php b/resources/views/pages/form.blade.php index 12f2f3e97..f450452ce 100644 --- a/resources/views/pages/form.blade.php +++ b/resources/views/pages/form.blade.php @@ -97,8 +97,7 @@
{{ trans('entities.pages_md_preview') }}
-
-
+
diff --git a/resources/views/pages/show.blade.php b/resources/views/pages/show.blade.php index 854417962..3e10ac63a 100644 --- a/resources/views/pages/show.blade.php +++ b/resources/views/pages/show.blade.php @@ -131,7 +131,7 @@
@include('partials/book-tree', ['book' => $book, 'sidebarTree' => $sidebarTree]) - + @stop @section('body') @@ -148,10 +148,11 @@ @include('pages/page-display') - -
- @include('comments/comments', ['page' => $page]) -
+ @if ($commentsEnabled) +
+ @include('comments/comments', ['page' => $page]) +
+ @endif @stop @section('scripts') diff --git a/resources/views/partials/custom-head-content.blade.php b/resources/views/partials/custom-head-content.blade.php new file mode 100644 index 000000000..b245b7ad6 --- /dev/null +++ b/resources/views/partials/custom-head-content.blade.php @@ -0,0 +1,5 @@ +@if(setting('app-custom-head', false)) + + {!! setting('app-custom-head') !!} + +@endif \ No newline at end of file diff --git a/resources/views/partials/custom-styles.blade.php b/resources/views/partials/custom-styles.blade.php index c13051df4..a02f529c7 100644 --- a/resources/views/partials/custom-styles.blade.php +++ b/resources/views/partials/custom-styles.blade.php @@ -7,6 +7,7 @@ } .button-base, .button, input[type="button"], input[type="submit"] { background-color: {{ setting('app-color') }}; + border-color: {{ setting('app-color') }}; } .button-base:hover, .button:hover, input[type="button"]:hover, input[type="submit"]:hover, .button:focus { background-color: {{ setting('app-color') }}; diff --git a/resources/views/settings/index.blade.php b/resources/views/settings/index.blade.php index 09e480b43..bee3ac8da 100644 --- a/resources/views/settings/index.blade.php +++ b/resources/views/settings/index.blade.php @@ -38,6 +38,11 @@

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

@include('components.toggle-switch', ['name' => 'setting-app-secure-images', 'value' => setting('app-secure-images')]) +
+ +

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

+ @include('components.toggle-switch', ['name' => 'setting-app-disable-comments', 'value' => setting('app-disable-comments')]) +

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

diff --git a/resources/views/users/edit.blade.php b/resources/views/users/edit.blade.php index f860d12fd..14ab19e0e 100644 --- a/resources/views/users/edit.blade.php +++ b/resources/views/users/edit.blade.php @@ -43,6 +43,13 @@ @endforeach
+
+ + +
@@ -87,4 +94,4 @@


@include('components.image-manager', ['imageType' => 'user']) -@stop +@stop \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 8bff3b2ec..f5e59f109 100644 --- a/routes/web.php +++ b/routes/web.php @@ -135,6 +135,7 @@ Route::group(['middleware' => 'auth'], function () { // Other Pages Route::get('/', 'HomeController@index'); Route::get('/home', 'HomeController@index'); + Route::get('/custom-head-content', 'HomeController@customHeadContent'); // Settings Route::group(['prefix' => 'settings'], function() { diff --git a/tests/Entity/CommentSettingTest.php b/tests/Entity/CommentSettingTest.php new file mode 100644 index 000000000..29df8b327 --- /dev/null +++ b/tests/Entity/CommentSettingTest.php @@ -0,0 +1,28 @@ +page = \BookStack\Page::first(); + } + + public function test_comment_disable () { + $this->asAdmin(); + + $this->setSettings(['app-disable-comments' => 'true']); + + $this->asAdmin()->visit($this->page->getUrl()) + ->pageNotHasElement('.comments-list'); + } + + public function test_comment_enable () { + $this->asAdmin(); + + $this->setSettings(['app-disable-comments' => 'false']); + + $this->asAdmin()->visit($this->page->getUrl()) + ->pageHasElement('.comments-list'); + } +} \ No newline at end of file diff --git a/tests/LanguageTest.php b/tests/LanguageTest.php index bb98a17b0..c9d6ed6f0 100644 --- a/tests/LanguageTest.php +++ b/tests/LanguageTest.php @@ -11,7 +11,7 @@ class LanguageTest extends TestCase public function setUp() { parent::setUp(); - $this->langs = array_diff(scandir(resource_path('lang')), ['..', '.']); + $this->langs = array_diff(scandir(resource_path('lang')), ['..', '.', 'check.php']); } public function test_locales_config_key_set_properly() diff --git a/tests/UserProfileTest.php b/tests/UserProfileTest.php index 54671bbf6..0c66363f0 100644 --- a/tests/UserProfileTest.php +++ b/tests/UserProfileTest.php @@ -94,5 +94,25 @@ class UserProfileTest extends BrowserKitTest ->seePageIs('/settings/users/' . $guestUser->id) ->see('cannot delete the guest user'); } - + + public function test_books_view_is_list() + { + $editor = $this->getEditor(); + setting()->putUser($editor, 'books_view_type', 'list'); + + $this->actingAs($editor) + ->visit('/books') + ->pageNotHasElement('.featured-image-container') + ->pageHasElement('.entity-list-item'); + } + + public function test_books_view_is_grid() + { + $editor = $this->getEditor(); + setting()->putUser($editor, 'books_view_type', 'grid'); + + $this->actingAs($editor) + ->visit('/books') + ->pageHasElement('.featured-image-container'); + } }