]> BookStack Code Mirror - bookstack/commitdiff
Merge branch 'master' of git://github.com/lommes/BookStack into lommes-master
authorDan Brown <redacted>
Sat, 9 Dec 2017 12:48:08 +0000 (12:48 +0000)
committerDan Brown <redacted>
Sat, 9 Dec 2017 12:48:08 +0000 (12:48 +0000)
61 files changed:
app/Book.php
app/Exceptions/Handler.php
app/Http/Controllers/BookController.php
app/Http/Controllers/HomeController.php
app/Http/Controllers/PageController.php
app/Http/Middleware/TrustProxies.php
app/Services/ExportService.php
composer.json
composer.lock
config/app.php
database/migrations/2017_08_29_102650_add_cover_image_display.php [new file with mode: 0644]
public/book_default_cover.png [new file with mode: 0644]
readme.md
resources/assets/js/components/image-picker.js [new file with mode: 0644]
resources/assets/js/components/index.js
resources/assets/js/components/markdown-editor.js
resources/assets/js/pages/page-form.js
resources/assets/js/pages/page-show.js
resources/assets/js/vues/page-editor.js
resources/assets/sass/_forms.scss
resources/assets/sass/_grid.scss
resources/assets/sass/_lists.scss
resources/assets/sass/_tinymce.scss
resources/assets/sass/styles.scss
resources/lang/check.php [new file with mode: 0755]
resources/lang/de/common.php
resources/lang/de/settings.php
resources/lang/en/common.php
resources/lang/en/settings.php
resources/lang/es/common.php
resources/lang/es/settings.php
resources/lang/fr/common.php
resources/lang/fr/settings.php
resources/lang/it/settings.php
resources/lang/ja/common.php
resources/lang/ja/settings.php
resources/lang/nl/common.php
resources/lang/nl/settings.php
resources/lang/pl/common.php
resources/lang/pl/settings.php
resources/lang/pt_BR/common.php
resources/lang/pt_BR/settings.php
resources/lang/ru/settings.php
resources/lang/sk/common.php
resources/lang/sk/settings.php
resources/views/books/create.blade.php
resources/views/books/edit.blade.php
resources/views/books/form.blade.php
resources/views/books/grid-item.blade.php [new file with mode: 0644]
resources/views/books/index.blade.php
resources/views/components/image-picker.blade.php
resources/views/pages/form.blade.php
resources/views/pages/show.blade.php
resources/views/partials/custom-head-content.blade.php [new file with mode: 0644]
resources/views/partials/custom-styles.blade.php
resources/views/settings/index.blade.php
resources/views/users/edit.blade.php
routes/web.php
tests/Entity/CommentSettingTest.php [new file with mode: 0644]
tests/LanguageTest.php
tests/UserProfileTest.php

index 06c00945d43c4dbdea946c21769ffef7a626888f..3fb87b4c519a11804815532932edf59c25093a6f 100644 (file)
@@ -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
index 1dc5094e30fe1e6f350c2d37e058477d49cbf7ab..12792e15184dfb0cef7bafaa8c28958e0ae5e9f8 100644 (file)
@@ -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)
     {
index 7e4b3fd81f80f4a001c368c3f061e972f0e6f5dc..e181aec8967285956ab5f707dc9a4fd09e326bf7 100644 (file)
@@ -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());
     }
 
     /**
index 7d109b70a9bb9225e2d8edfccc678e191765acbf..164becd4dc9a04ebf68af822899251b6b0f1f4c8 100644 (file)
@@ -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');
+    }
+
 }
index c11355db5ce95d1da2ccfa70c3a682cfb1864b09..13e9284650e4f98e725570d43cfe9b4303c2e34b 100644 (file)
@@ -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
+        ]);
     }
 
     /**
index 69fcbe943bbb825647a5be958b1ead653d7217cd..c3102571da2b0d515f87a7c5f42e2373c306c7b2 100644 (file)
@@ -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);
+    }
 }
index a78b133eec454325ebcfd47e0e5457df9d6abc60..1e4e99428ba1c6427efed0f9fdc396a57d5bf1fd 100644 (file)
@@ -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();
     }
index c86af0f456628a363c9d6c81c4cccc4842730b38..5b9802f5299e54e5d96e6d88ef26dad5c9c98a11 100644 (file)
@@ -75,6 +75,8 @@
     "config": {
         "optimize-autoloader": true,
         "preferred-install": "dist",
-        "php": "7.0"
+        "platform": {
+            "php": "7.0"
+        }
     }
 }
index f52a2022b111910b0cbf4604cedf3b4dd2c83296..057e6007a12353df6ff1d13a28c19c6391ce04b1 100644 (file)
@@ -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",
         },
         {
             "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": {
                 "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.*",
             ],
             "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",
         },
         {
             "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",
                 "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": {
                 "framework",
                 "laravel"
             ],
-            "time": "2017-11-14T15:08:13+00:00"
+            "time": "2017-12-07T01:28:21+00:00"
         },
         {
             "name": "laravel/socialite",
         },
         {
             "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"
             },
                 "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": {
             ],
             "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",
         },
         {
             "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": {
             ],
             "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"
             ],
             "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": {
             ],
             "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": {
             ],
             "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",
             ],
             "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",
         },
         {
             "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": {
             ],
             "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",
                 "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": {
             ],
             "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": {
                 "debug",
                 "dump"
             ],
-            "time": "2017-11-07T14:16:22+00:00"
+            "time": "2017-07-28T06:06:09+00:00"
         },
         {
             "name": "tijsverkoyen/css-to-inline-styles",
         },
         {
             "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": {
                 "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": {
                 "throwable",
                 "whoops"
             ],
-            "time": "2017-11-17T08:15:51+00:00"
+            "time": "2017-11-23T18:22:44+00:00"
         },
         {
             "name": "fzaninotto/faker",
         },
         {
             "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\\": [
                 }
             ],
             "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",
         },
         {
             "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": {
             },
             "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": {
                 "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": {
                 "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": {
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "5.2.x-dev"
+                    "dev-master": "5.3.x-dev"
                 }
             },
             "autoload": {
             "authors": [
                 {
                     "name": "Sebastian Bergmann",
-                    "email": "sb@sebastian-bergmann.de",
+                    "email": "sebastian@phpunit.de",
                     "role": "lead"
                 }
             ],
                 "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": {
                 "filesystem",
                 "iterator"
             ],
-            "time": "2016-10-03T07:40:28+00:00"
+            "time": "2017-11-27T13:52:08+00:00"
         },
         {
             "name": "phpunit/php-text-template",
         },
         {
             "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": {
             "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": {
                 "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",
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "6.4.x-dev"
+                    "dev-master": "6.5.x-dev"
                 }
             },
             "autoload": {
                 "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": {
                 "phpunit/phpunit": "<6.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "^6.0"
+                "phpunit/phpunit": "^6.5"
             },
             "suggest": {
                 "ext-soap": "*"
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "4.0.x-dev"
+                    "dev-master": "5.0.x-dev"
                 }
             },
             "autoload": {
             "authors": [
                 {
                     "name": "Sebastian Bergmann",
-                    "email": "sb@sebastian-bergmann.de",
+                    "email": "sebastian@phpunit.de",
                     "role": "lead"
                 }
             ],
                 "mock",
                 "xunit"
             ],
-            "time": "2017-08-03T14:08:16+00:00"
+            "time": "2017-12-02T05:31:19+00:00"
         },
         {
             "name": "sebastian/code-unit-reverse-lookup",
         },
         {
             "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",
             ],
             "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",
         "php": ">=7.0.0",
         "ext-tidy": "*"
     },
-    "platform-dev": []
+    "platform-dev": [],
+    "platform-overrides": {
+        "php": "7.0"
+    }
 }
index e4ccbb26f80854b8c868932fe4d2cc9b140a7d92..3be50b6c59d28655c9fd82380f88156bef4b93e9 100755 (executable)
@@ -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 (file)
index 0000000..6f99329
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class AddCoverImageDisplay extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('books', function (Blueprint $table) {
+            $table->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 (file)
index 0000000..7b6c995
Binary files /dev/null and b/public/book_default_cover.png differ
index e048e8ea63663078e53dfaca590adea7f35f2681..1b3db4a5645c383589c9de1c33f6a4570c9fd138 100644 (file)
--- 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 <lang>
+
+# 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 (file)
index 0000000..d8fd7cc
--- /dev/null
@@ -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
index f37709101088b68ee1da5ee6c4f248e8c6a26fea..4cb16d06afcb6d62bd9da06a0e6e3270349d946b 100644 (file)
@@ -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 = {};
index e646dfd2b37eeb20eaaccd2f571601002e83fc11..7b051dd12cee05957c6b08f087d16f22e535724e 100644 (file)
@@ -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
index ec433b316bbbea1bd1665289d180cb0a75d44e88..904403fc1a5afbb2d9ceb2a0924d0eff5589aca4 100644 (file)
@@ -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);
index 14437cd68a326466b1179cf4639154e329386999..6af5af57d8f979e0017f0482a41ccf141b3fe1a4 100644 (file)
@@ -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
index 9d7179a7e9b08a50009cd6ac2cf508b2f0a90563..d33739b30828b4717695c3cce8a50ca288f5913f 100644 (file)
@@ -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;
index 700c15336ff1d49677d8f20ebc9e8a4ccc17b01a..802a075a252540ef3f56dbcfa0f180627a1da460 100644 (file)
     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 {
index 0f755e9f0cf10bbda66ba50e2aa7bf081af6d17e..c145f4280969d74b2362487f2219e3e2f246ef4f 100644 (file)
@@ -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;
index d30d4d4a22ab98745b5f7b1076db90297dc2fde0..0496d794e4523d6c68657048b0b51f266326eaa8 100644 (file)
@@ -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;
+}
index b8394b25b7e9642eef27eff7c74569b29d046809..92af39a87358ee071b0e2aced28d943ac7489898 100644 (file)
@@ -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;
index e8d87d520260dadee1693d7c7e6b5930c7f42d06..6a80237c5b6a674b9cd4763408e6b82a95002f3c 100644 (file)
@@ -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 (executable)
index 0000000..92a7b1e
--- /dev/null
@@ -0,0 +1,114 @@
+#!/usr/bin/env php
+<?php
+
+/**
+ * Compares translation files to find missing and redundant content.
+ */
+
+$args = array_slice($argv, 1);
+
+if (count($args) === 0) {
+    errorOut("Please provide a language code as the first argument (./check.php fr)");
+}
+
+
+// Get content from files
+$lang = formatLang($args[0]);
+$enContent = loadLang('en');
+$langContent = loadLang($lang);
+
+if (count($langContent) === 0) {
+    errorOut("No language content found for '{$lang}'");
+}
+
+info("Checking '{$lang}' translation content against 'en'");
+
+// Track missing lang strings
+$missingLangStrings = [];
+foreach ($enContent as $enKey => $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
index 3c21a9d0802bab681efb927e572df83f6f9ae77c..2cc98084611a2d02abbb92811e2b9343ee7eeda4 100644 (file)
@@ -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
      */
index 9435ec80853ecea267fdc04126acbe268f50181f..e9d19e01b0290febc091338ed7cd8826129ce827 100644 (file)
@@ -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',
index 269905a59c7f181430f47565b8828fdc16b49b50..7cdd7c23e527a8f8b4394bf8a906ff49185d9247 100644 (file)
@@ -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',
 
     /**
index 468c5981f9641178e8d0dc8f1c1d23904761d690..f35c486ad9f6daa36f90257a3a6be50685fad528 100755 (executable)
@@ -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.',
index 3a62a21776fcc09817ad3d3990c7c68951bdc720..a173f286e3985653d6fa374c19041c282de2cb7d 100644 (file)
@@ -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
index cd6a8b8d9b56eac1852dafbf88dcf620f4291445..3c3281d280a0a8186fc256128c70114d671f6134 100644 (file)
@@ -31,6 +31,8 @@ return [
     'app_logo_desc' => 'Esta imagen debería de ser 43px en altura. <br>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. <br>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.',
index 7a8ec55b605d90f53bc27559b6988b535b6231dd..2553d14822c3ac3ba5b7829a1ef1ed0017c20a6c 100644 (file)
@@ -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
index 92e623795dcbc851cbf006e993859d135b2b624f..2f0163368210a9c152b60dbe94d96c9fc77cd093 100644 (file)
@@ -31,7 +31,8 @@ return [
     'app_logo_desc' => 'Cette image doit faire 43px de hauteur. <br>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. <br>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.',
index d112cbc62330f7bd3c01ee3e63bb64e66ec51db7..480e9302ae1695a7db42a9f75a95bfc5f3144305 100755 (executable)
@@ -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',
index 383294880b5d94d31748c7be61b5d5c7b8db3614..185e6116cf463d7115f3c46c6e3f9d24c741eabb 100644 (file)
@@ -17,7 +17,7 @@ return [
     'name' => '名称',
     'description' => '概要',
     'role' => '権限',
-
+    'cover_image_description' => 'この画像は約 300x170px をする必要があります。',
     /**
      * Actions
      */
index b4cf57aebdfd855c5c36c2c1db7dd1cb62561110..f9c9c5e86e66460b3e85bf2d52856a34fc8a38ff 100644 (file)
@@ -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」がプロフィールから接続解除されました。'
-    
+
 ];
index 1ae0ade7caa082ac39a50a668da8fd77db66c511..fdfb90fb250704d074fa36a84c303ea13a110117 100644 (file)
@@ -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
index 7408a2dc32c53ca5a6f62018bf1acf49d2576dd9..ba73dc7e9d250fcb1a2aa5e0acfd3604df55db56 100644 (file)
@@ -31,6 +31,8 @@ return [
     'app_logo_desc' => 'De afbeelding moet 43px hoog zijn. <br>Grotere afbeeldingen worden geschaald.',
     'app_primary_color' => 'Applicatie hoofdkleur',
     'app_primary_color_desc' => 'Geef een hexadecimale waarde. <br>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.',
index 1c8963653e15743f5f47d0f111fa0e29ab679888..f7741ba6f4b5ac886ee6cba2a8689a082bbb259a 100644 (file)
@@ -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
      */
index 381e5517a1f8c67e87431883e21adc16bd9dd714..d6f3cca1bbc1c6f73a3342f6b78fe484b217a16a 100644 (file)
@@ -31,6 +31,8 @@ return [
     'app_logo_desc' => 'Ten obrazek powinien mieć nie więcej niż 43px w pionie. <br>Większe obrazki będą skalowane w dół.',
     'app_primary_color' => 'Podstawowy kolor aplikacji',
     'app_primary_color_desc' => 'To powinna być wartość HEX. <br>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
index 632a1a078bc99bbdd2affbcb99517e0b73df4b36..991cb0b7e4fbfde96fe75a270cd2176125f5a8c6 100644 (file)
@@ -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',
 
     /**
index 5513c217f7f7326f21630f5d29bdb6afbfa4e643..77a0e6e395ebee8aebc0b5f222e264fc1ea41db5 100644 (file)
@@ -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.',
index 9a9e55fd6ad8ea0c027ff3d8366810b5f8205aad..5d2f07ba9dcdf9eccafb55d8a56e7f4a7219033e 100755 (executable)
@@ -34,6 +34,8 @@ return [
     'app_homepage' => 'Домашняя страница приложения',
     'app_homepage_desc' => 'Выберите страницу, которая будет отображаться на главной странице вместо стандартной. Права на страницы игнорируются для выбранных страниц.',
     'app_homepage_default' => 'Выбрана домашняя страница по-умолчанию',
+    'app_disable_comments' => 'Отключить комментарии',
+    'app_disable_comments_desc' => 'Отключить комментарии на всех страницах приложения. Существующие комментарии не отображаются.',
 
     /**
      * Registration
index 100981597374d714f49c4b284677772e7f16a7f1..a823fb37915c9d0f62bfe26e091833300184aa57 100644 (file)
@@ -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
index 643b4b8ffbde1d2d9e122080544a0711dcb7a6ee..521af196e5b4458b168df6b9c1538491ceedb59c 100644 (file)
@@ -31,6 +31,8 @@ return [
     'app_logo_desc' => 'Tento obrázok by mal mať 43px na výšku. <br>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. <br>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.',
index 385e6b9d7a4e868f4a5b42acf4585c287068c8cd..4798459c21672b2068ecb1d2bb63c5ac932da595 100644 (file)
     <div class="card">
         <h3><i class="zmdi zmdi-plus"></i> {{ trans('entities.books_create') }}</h3>
         <div class="body">
-            <form action="{{ baseUrl("/books") }}" method="POST">
+            <form action="{{ baseUrl("/books") }}" method="POST" enctype="multipart/form-data">
                 @include('books/form')
             </form>
         </div>
     </div>
 </div>
-
+<p class="margin-top large"><br></p>
+    @include('components.image-manager', ['imageType' => 'cover'])
 @stop
\ No newline at end of file
index 9d9c54fec6e521e909c6e5ce159c640c975dc3e5..6bf285f95f2f8fcbe2c76499370eec2e860f046f 100644 (file)
@@ -20,5 +20,5 @@
             </div>
         </div>
     </div>
-
+@include('components.image-manager', ['imageType' => 'cover'])
 @stop
\ No newline at end of file
index 84a30e7e9982a40e7e0c5ecfe9c1bf752c9693b3..06eea7ca9f5aeb8c08b4fdaa4103b304addd32e4 100644 (file)
@@ -9,6 +9,21 @@
     <label for="description">{{ trans('common.description') }}</label>
     @include('form/textarea', ['name' => 'description'])
 </div>
+<div class="form-group" id="logo-control">
+        <label for="user-avatar">{{ trans('common.cover_image') }}</label>
+        <p class="small">{{ trans('common.cover_image_description') }}</p>
+
+        @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'
+        ])
+</div>
 
 <div class="form-group text-right">
     <a href="{{ isset($book) ? $book->getUrl() : baseUrl('/books') }}" class="button outline">{{ trans('common.cancel') }}</a>
diff --git a/resources/views/books/grid-item.blade.php b/resources/views/books/grid-item.blade.php
new file mode 100644 (file)
index 0000000..cb2b447
--- /dev/null
@@ -0,0 +1,18 @@
+<div class="col-xs-12 col-sm-4 col-md-4 col-lg-4 book-grid-item"  data-entity-type="book" data-entity-id="{{$book->id}}">
+    <div class="featured-image-container">
+        <a href="{{$book->getUrl()}}" title="{{$book->name}}">
+            <img width="1600" height="900" src="{{$book->getBookCover()}}" alt="{{$book->name}}">
+        </a>
+    </div>
+    <div class="book-grid-content">
+        <h2><a href="{{$book->getUrl()}}" title="{{$book->name}}" > {{$book->getShortName(35)}} </a></h2>
+        @if(isset($book->searchSnippet))
+            <p >{!! $book->searchSnippet !!}</p>
+        @else
+            <p >{{ $book->getExcerpt(130) }}</p>
+        @endif
+        <div >
+            <span>@include('partials.entity-meta', ['entity' => $book])</span>
+        </div>
+    </div>
+</div>
\ No newline at end of file
index c22b4591f01c43f3efc126cf30dc40a8acc4e1d7..d392af045aab36ee3a99e03a21a8a2a9200517d5 100644 (file)
 @stop
 
 @section('body')
-
-    <div class="container small" ng-non-bindable>
+    @if($booksViewType === 'list')
+        <div class="container small" ng-non-bindable>
+    @else
+        <div class="container" ng-non-bindable>
+    @endif
         <h1>{{ trans('entities.books') }}</h1>
         @if(count($books) > 0)
-            @foreach($books as $book)
-                @include('books/list-item', ['book' => $book])
-                <hr>
-            @endforeach
-            {!! $books->render() !!}
+            @if($booksViewType === 'list')
+                @foreach($books as $book)
+                    @include('books/list-item', ['book' => $book])
+                    <hr>
+                @endforeach
+                {!! $books->render() !!}
+            @else 
+             <div class="row auto-clear">
+                    @foreach($books as $key => $book)
+                            @include('books/grid-item', ['book' => $book])
+                    @endforeach
+                <div class="col-xs-12">
+                    {!! $books->render() !!}
+                </div>
+             </div>
+            @endif
         @else
             <p class="text-muted">{{ trans('entities.books_empty') }}</p>
             @if(userCan('books-create-all'))
@@ -55,5 +69,4 @@
             @endif
         @endif
     </div>
-
 @stop
\ No newline at end of file
index 228e8d230c6663009ed3431758d1007ab4a4ec38..034b65cc5f64389541f13ac323f12e0dd39604b1 100644 (file)
         <button class="text-button neg" data-action="remove-image" type="button">{{ trans('common.remove') }}</button>
     @endif
 
-    <input type="hidden" name="{{$name}}" id="{{$name}}" value="{{ isset($currentId) && ($currentId !== '' && $currentId !== false) ? $currentId : $currentImage}}">
-</div>
-
-<script>
-    (function(){
-
-        var picker = document.querySelector('[image-picker="{{$name}}"]');
-        picker.addEventListener('click', function(event) {
-            if (event.target.nodeName.toLowerCase() !== 'button') return;
-             var button = event.target;
-             var action = button.getAttribute('data-action');
-             var resize = picker.getAttribute('data-resize-height') && picker.getAttribute('data-resize-width');
-             var usingIds = picker.getAttribute('data-current-id') !== '';
-             var resizeCrop = picker.getAttribute('data-resize-crop') !== '';
-             var imageElem = picker.querySelector('img');
-             var input = picker.querySelector('input');
-
-             function setImage(image) {
-                 if (image === 'none') {
-                     imageElem.src = picker.getAttribute('data-default-image');
-                     imageElem.classList.add('none');
-                     input.value = 'none';
-                     return;
-                 }
-                 imageElem.src = image.url;
-                 input.value = usingIds ? image.id : image.url;
-                 imageElem.classList.remove('none');
-             }
-
-             if (action === 'show-image-manager') {
-                 window.ImageManager.show((image) => {
-                     if (!resize) {
-                         setImage(image);
-                         return;
-                     }
-                     var requestString = '/images/thumb/' + image.id + '/' + picker.getAttribute('data-resize-width') + '/' + picker.getAttribute('data-resize-height') + '/' + (resizeCrop ? 'true' : 'false');
-                     $.get(window.baseUrl(requestString), resp => {
-                         image.url = resp.url;
-                         setImage(image);
-                     });
-                 });
-             } else if (action === 'reset-image') {
-                 setImage({id: 0, url: picker.getAttribute('data-default-image')});
-             } else if (action === 'remove-image') {
-                 setImage('none');
-             }
-
-            });
-
-    })();
-</script>
\ No newline at end of file
+    <input type="hidden" name="{{$name}}" id="{{$name}}" value="{{ isset($currentId) && ($currentId !== 0 && $currentId !== false) ? $currentId : $currentImage}}">
+</div>
\ No newline at end of file
index 12f2f3e97c1680732ec9fefd06d99715a9024c28..f450452cec8bce187f238ce89669efc48f0161af 100644 (file)
@@ -97,8 +97,7 @@
                     <div class="editor-toolbar">
                         <div class="">{{ trans('entities.pages_md_preview') }}</div>
                     </div>
-                    <div class="markdown-display">
-                        <div class="page-content"></div>
+                    <div class="markdown-display page-content">
                     </div>
                 </div>
                 <input type="hidden" name="html"/>
index 854417962e128697e985f50d88085e67ea7ffd07..3e10ac63af19a7294e13b9703883ed9e2a5ad836 100644 (file)
     </div>
 
     @include('partials/book-tree', ['book' => $book, 'sidebarTree' => $sidebarTree])
-    
+
 @stop
 
 @section('body')
         @include('pages/page-display')
 
     </div>
-
-    <div class="container small nopad">
-        @include('comments/comments', ['page' => $page])
-    </div>
+    @if ($commentsEnabled)
+      <div class="container small nopad">
+          @include('comments/comments', ['page' => $page])
+      </div>
+    @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 (file)
index 0000000..b245b7a
--- /dev/null
@@ -0,0 +1,5 @@
+@if(setting('app-custom-head', false))
+    <!-- Custom user content -->
+    {!! setting('app-custom-head') !!}
+    <!-- End custom user content -->
+@endif
\ No newline at end of file
index c13051df4f3a363c8bbcfbf140bad183cffbca99..a02f529c7b5351aa3b0a18d188689d3cd48e1334 100644 (file)
@@ -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') }};
index 09e480b4381701b477ac98f689866ce04b0f8c09..bee3ac8da43cc9366b02ab84d5cd65f802f8008b 100644 (file)
                             <p class="small">{{ trans('settings.app_secure_images_desc') }}</p>
                             @include('components.toggle-switch', ['name' => 'setting-app-secure-images', 'value' => setting('app-secure-images')])
                         </div>
+                        <div class="form-group">
+                            <label>{{ trans('settings.app_disable_comments') }}</label>
+                            <p class="small">{{ trans('settings.app_disable_comments_desc') }}</p>
+                            @include('components.toggle-switch', ['name' => 'setting-app-disable-comments', 'value' => setting('app-disable-comments')])
+                        </div>
                         <div class="form-group">
                             <label for="setting-app-editor">{{ trans('settings.app_editor') }}</label>
                             <p class="small">{{ trans('settings.app_editor_desc') }}</p>
index f860d12fd96a27dbb110f1a6705b9966f99a6e98..14ab19e0e9b97a1c651d80c9605243a7b8a8d9ca 100644 (file)
                                     @endforeach
                                 </select>
                             </div>
+                            <div class="form-group">
+                                <label for="books-view-type">{{ trans('settings.users_books_view_type') }}</label>
+                                <select name="setting[books_view_type]" id="books-view-type">
+                                    <option @if(setting()->getUser($user, 'books_view_type', 'list') === 'list') selected @endif value="list">List</option>
+                                    <option @if(setting()->getUser($user, 'books_view_type', 'list') === 'grid') selected @endif value="grid">Grid</option>
+                                </select>
+                            </div>
                         </div>
                     </div>
                     <div class="form-group text-right">
@@ -87,4 +94,4 @@
 
     <p class="margin-top large"><br></p>
     @include('components.image-manager', ['imageType' => 'user'])
-@stop
+@stop
\ No newline at end of file
index 8bff3b2ec0c2db0dee51e789b9e7b2cc70b206fa..f5e59f1095a3adeb1289e945ad3da826dff65640 100644 (file)
@@ -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 (file)
index 0000000..29df8b3
--- /dev/null
@@ -0,0 +1,28 @@
+<?php namespace Tests;
+
+class CommentSettingTest extends BrowserKitTest {
+  protected $page;
+
+  public function setUp() {
+      parent::setUp();
+      $this->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
index bb98a17b0cb0a7419785c2139de24730ca72c35d..c9d6ed6f014ed16fed5c0c25107388c307b8457f 100644 (file)
@@ -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()
index 54671bbf6257cdc64c561241aa8ee2bc108c0433..0c66363f0b34a0e8c241108d8675b7a29ca67105 100644 (file)
@@ -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');
+    }
 }