From 4017048555efd20cced7c6c5feac28b6131ccf2f Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Tue, 12 Dec 2023 12:14:00 +0000 Subject: [PATCH] Page Templates: Changed template field name, added API support --- .../Controllers/BookApiController.php | 14 +++++++------ app/Entities/Controllers/BookController.php | 20 +++++++++---------- app/Entities/Controllers/PageController.php | 4 ++-- app/Entities/Models/Book.php | 4 ++-- app/Entities/Repos/BookRepo.php | 11 +++++----- app/Entities/Tools/TrashCan.php | 4 ++-- ...2_104541_add_default_template_to_books.php | 4 ++-- dev/api/requests/books-create.json | 7 ++++++- dev/api/requests/books-update.json | 6 +++++- dev/api/responses/books-create.json | 1 + dev/api/responses/books-read.json | 1 + dev/api/responses/books-update.json | 9 +++++---- resources/views/books/parts/form.blade.php | 4 ++-- tests/Api/BooksApiTest.php | 6 ++++++ tests/Helpers/EntityProvider.php | 9 +++++++++ 15 files changed, 67 insertions(+), 37 deletions(-) diff --git a/app/Entities/Controllers/BookApiController.php b/app/Entities/Controllers/BookApiController.php index cb67184a0..41ff11dde 100644 --- a/app/Entities/Controllers/BookApiController.php +++ b/app/Entities/Controllers/BookApiController.php @@ -14,11 +14,9 @@ use Illuminate\Validation\ValidationException; class BookApiController extends ApiController { - protected BookRepo $bookRepo; - - public function __construct(BookRepo $bookRepo) - { - $this->bookRepo = $bookRepo; + public function __construct( + protected BookRepo $bookRepo + ) { } /** @@ -58,7 +56,9 @@ class BookApiController extends ApiController */ public function read(string $id) { - $book = Book::visible()->with(['tags', 'cover', 'createdBy', 'updatedBy', 'ownedBy'])->findOrFail($id); + $book = Book::visible() + ->with(['tags', 'cover', 'createdBy', 'updatedBy', 'ownedBy']) + ->findOrFail($id); $contents = (new BookContents($book))->getTree(true, false)->all(); $contentsApiData = (new ApiEntityListFormatter($contents)) @@ -116,12 +116,14 @@ class BookApiController extends ApiController 'description' => ['string', 'max:1000'], 'tags' => ['array'], 'image' => array_merge(['nullable'], $this->getImageValidationRules()), + 'default_template_id' => ['nullable', 'integer'], ], 'update' => [ 'name' => ['string', 'min:1', 'max:255'], 'description' => ['string', 'max:1000'], 'tags' => ['array'], 'image' => array_merge(['nullable'], $this->getImageValidationRules()), + 'default_template_id' => ['nullable', 'integer'], ], ]; } diff --git a/app/Entities/Controllers/BookController.php b/app/Entities/Controllers/BookController.php index 12df935b0..faa578893 100644 --- a/app/Entities/Controllers/BookController.php +++ b/app/Entities/Controllers/BookController.php @@ -92,11 +92,11 @@ class BookController extends Controller { $this->checkPermission('book-create-all'); $validated = $this->validate($request, [ - 'name' => ['required', 'string', 'max:255'], - 'description' => ['string', 'max:1000'], - 'image' => array_merge(['nullable'], $this->getImageValidationRules()), - 'tags' => ['array'], - 'default_template' => ['nullable', 'integer'], + 'name' => ['required', 'string', 'max:255'], + 'description' => ['string', 'max:1000'], + 'image' => array_merge(['nullable'], $this->getImageValidationRules()), + 'tags' => ['array'], + 'default_template_id' => ['nullable', 'integer'], ]); $bookshelf = null; @@ -167,11 +167,11 @@ class BookController extends Controller $this->checkOwnablePermission('book-update', $book); $validated = $this->validate($request, [ - 'name' => ['required', 'string', 'max:255'], - 'description' => ['string', 'max:1000'], - 'image' => array_merge(['nullable'], $this->getImageValidationRules()), - 'tags' => ['array'], - 'default_template' => ['nullable', 'integer'], + 'name' => ['required', 'string', 'max:255'], + 'description' => ['string', 'max:1000'], + 'image' => array_merge(['nullable'], $this->getImageValidationRules()), + 'tags' => ['array'], + 'default_template_id' => ['nullable', 'integer'], ]); if ($request->has('image_reset')) { diff --git a/app/Entities/Controllers/PageController.php b/app/Entities/Controllers/PageController.php index d92934123..0a3e76daa 100644 --- a/app/Entities/Controllers/PageController.php +++ b/app/Entities/Controllers/PageController.php @@ -259,7 +259,7 @@ class PageController extends Controller $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug); $this->checkOwnablePermission('page-delete', $page); $this->setPageTitle(trans('entities.pages_delete_named', ['pageName' => $page->getShortName()])); - $usedAsTemplate = Book::query()->where('default_template', '=', $page->id)->count() > 0; + $usedAsTemplate = Book::query()->where('default_template_id', '=', $page->id)->count() > 0; return view('pages.delete', [ 'book' => $page->book, @@ -279,7 +279,7 @@ class PageController extends Controller $page = $this->pageRepo->getById($pageId); $this->checkOwnablePermission('page-update', $page); $this->setPageTitle(trans('entities.pages_delete_draft_named', ['pageName' => $page->getShortName()])); - $usedAsTemplate = Book::query()->where('default_template', '=', $page->id)->count() > 0; + $usedAsTemplate = Book::query()->where('default_template_id', '=', $page->id)->count() > 0; return view('pages.delete', [ 'book' => $page->book, diff --git a/app/Entities/Models/Book.php b/app/Entities/Models/Book.php index faae276a5..ee9a7f447 100644 --- a/app/Entities/Models/Book.php +++ b/app/Entities/Models/Book.php @@ -15,7 +15,7 @@ use Illuminate\Support\Collection; * * @property string $description * @property int $image_id - * @property ?int $default_template + * @property ?int $default_template_id * @property Image|null $cover * @property \Illuminate\Database\Eloquent\Collection $chapters * @property \Illuminate\Database\Eloquent\Collection $pages @@ -78,7 +78,7 @@ class Book extends Entity implements HasCoverImage */ public function defaultTemplate(): BelongsTo { - return $this->belongsTo(Page::class, 'default_template'); + return $this->belongsTo(Page::class, 'default_template_id'); } /** diff --git a/app/Entities/Repos/BookRepo.php b/app/Entities/Repos/BookRepo.php index b46218fe0..03e1118b1 100644 --- a/app/Entities/Repos/BookRepo.php +++ b/app/Entities/Repos/BookRepo.php @@ -86,6 +86,7 @@ class BookRepo $book = new Book(); $this->baseRepo->create($book, $input); $this->baseRepo->updateCoverImage($book, $input['image'] ?? null); + $this->updateBookDefaultTemplate($book, intval($input['default_template_id'] ?? null)); Activity::add(ActivityType::BOOK_CREATE, $book); return $book; @@ -98,8 +99,8 @@ class BookRepo { $this->baseRepo->update($book, $input); - if (array_key_exists('default_template', $input)) { - $this->updateBookDefaultTemplate($book, intval($input['default_template'])); + if (array_key_exists('default_template_id', $input)) { + $this->updateBookDefaultTemplate($book, intval($input['default_template_id'])); } if (array_key_exists('image', $input)) { @@ -118,13 +119,13 @@ class BookRepo */ protected function updateBookDefaultTemplate(Book $book, int $templateId): void { - $changing = $templateId !== intval($book->default_template); + $changing = $templateId !== intval($book->default_template_id); if (!$changing) { return; } if ($templateId === 0) { - $book->default_template = null; + $book->default_template_id = null; $book->save(); return; } @@ -134,7 +135,7 @@ class BookRepo ->where('id', '=', $templateId) ->exists(); - $book->default_template = $templateExists ? $templateId : null; + $book->default_template_id = $templateExists ? $templateId : null; $book->save(); } diff --git a/app/Entities/Tools/TrashCan.php b/app/Entities/Tools/TrashCan.php index b0c452456..b25103985 100644 --- a/app/Entities/Tools/TrashCan.php +++ b/app/Entities/Tools/TrashCan.php @@ -203,8 +203,8 @@ class TrashCan } // Remove book template usages - Book::query()->where('default_template', '=', $page->id) - ->update(['default_template' => null]); + Book::query()->where('default_template_id', '=', $page->id) + ->update(['default_template_id' => null]); $page->forceDelete(); diff --git a/database/migrations/2023_12_02_104541_add_default_template_to_books.php b/database/migrations/2023_12_02_104541_add_default_template_to_books.php index 913361dcb..c23bebc2e 100644 --- a/database/migrations/2023_12_02_104541_add_default_template_to_books.php +++ b/database/migrations/2023_12_02_104541_add_default_template_to_books.php @@ -14,7 +14,7 @@ class AddDefaultTemplateToBooks extends Migration public function up() { Schema::table('books', function (Blueprint $table) { - $table->integer('default_template')->nullable()->default(null); + $table->integer('default_template_id')->nullable()->default(null); }); } @@ -26,7 +26,7 @@ class AddDefaultTemplateToBooks extends Migration public function down() { Schema::table('books', function (Blueprint $table) { - $table->dropColumn('default_template'); + $table->dropColumn('default_template_id'); }); } } diff --git a/dev/api/requests/books-create.json b/dev/api/requests/books-create.json index 4a6626619..2a38dba83 100644 --- a/dev/api/requests/books-create.json +++ b/dev/api/requests/books-create.json @@ -1,4 +1,9 @@ { "name": "My own book", - "description": "This is my own little book" + "description": "This is my own little book", + "default_template_id": 12, + "tags": [ + {"name": "Category", "value": "Top Content"}, + {"name": "Rating", "value": "Highest"} + ] } \ No newline at end of file diff --git a/dev/api/requests/books-update.json b/dev/api/requests/books-update.json index fc67d5fcc..c026b7b49 100644 --- a/dev/api/requests/books-update.json +++ b/dev/api/requests/books-update.json @@ -1,4 +1,8 @@ { "name": "My updated book", - "description": "This is my book with updated details" + "description": "This is my book with updated details", + "default_template_id": 12, + "tags": [ + {"name": "Subject", "value": "Updates"} + ] } \ No newline at end of file diff --git a/dev/api/responses/books-create.json b/dev/api/responses/books-create.json index 12a3e9e9f..773879125 100644 --- a/dev/api/responses/books-create.json +++ b/dev/api/responses/books-create.json @@ -6,6 +6,7 @@ "created_by": 1, "updated_by": 1, "owned_by": 1, + "default_template_id": 12, "updated_at": "2020-01-12T14:05:11.000000Z", "created_at": "2020-01-12T14:05:11.000000Z" } \ No newline at end of file diff --git a/dev/api/responses/books-read.json b/dev/api/responses/books-read.json index 3744445d0..21e1829b8 100644 --- a/dev/api/responses/books-read.json +++ b/dev/api/responses/books-read.json @@ -20,6 +20,7 @@ "name": "Admin", "slug": "admin" }, + "default_template_id": null, "contents": [ { "id": 50, diff --git a/dev/api/responses/books-update.json b/dev/api/responses/books-update.json index 7d3d6735e..f69677c4a 100644 --- a/dev/api/responses/books-update.json +++ b/dev/api/responses/books-update.json @@ -1,11 +1,12 @@ { "id": 16, - "name": "My own book", - "slug": "my-own-book", - "description": "This is my own little book - updated", + "name": "My updated book", + "slug": "my-updated-book", + "description": "This is my book with updated details", "created_at": "2020-01-12T14:09:59.000000Z", "updated_at": "2020-01-12T14:16:10.000000Z", "created_by": 1, "updated_by": 1, - "owned_by": 1 + "owned_by": 1, + "default_template_id": 12 } \ No newline at end of file diff --git a/resources/views/books/parts/form.blade.php b/resources/views/books/parts/form.blade.php index b16468a09..b4ca2fba5 100644 --- a/resources/views/books/parts/form.blade.php +++ b/resources/views/books/parts/form.blade.php @@ -47,9 +47,9 @@ @include('form.page-picker', [ - 'name' => 'default_template', + 'name' => 'default_template_id', 'placeholder' => trans('entities.books_default_template_select'), - 'value' => $book?->default_template ?? null, + 'value' => $book?->default_template_id ?? null, ]) diff --git a/tests/Api/BooksApiTest.php b/tests/Api/BooksApiTest.php index 326304d6f..c648faaf2 100644 --- a/tests/Api/BooksApiTest.php +++ b/tests/Api/BooksApiTest.php @@ -31,13 +31,16 @@ class BooksApiTest extends TestCase public function test_create_endpoint() { $this->actingAsApiEditor(); + $templatePage = $this->entities->templatePage(); $details = [ 'name' => 'My API book', 'description' => 'A book created via the API', + 'default_template_id' => $templatePage->id, ]; $resp = $this->postJson($this->baseEndpoint, $details); $resp->assertStatus(200); + $newItem = Book::query()->orderByDesc('id')->where('name', '=', $details['name'])->first(); $resp->assertJson(array_merge($details, ['id' => $newItem->id, 'slug' => $newItem->slug])); $this->assertActivityExists('book_create', $newItem); @@ -83,6 +86,7 @@ class BooksApiTest extends TestCase 'owned_by' => [ 'name' => $book->ownedBy->name, ], + 'default_template_id' => null, ]); } @@ -121,9 +125,11 @@ class BooksApiTest extends TestCase { $this->actingAsApiEditor(); $book = $this->entities->book(); + $templatePage = $this->entities->templatePage(); $details = [ 'name' => 'My updated API book', 'description' => 'A book created via the API', + 'default_template_id' => $templatePage->id, ]; $resp = $this->putJson($this->baseEndpoint . "/{$book->id}", $details); diff --git a/tests/Helpers/EntityProvider.php b/tests/Helpers/EntityProvider.php index 3cb8c44d3..982063421 100644 --- a/tests/Helpers/EntityProvider.php +++ b/tests/Helpers/EntityProvider.php @@ -53,6 +53,15 @@ class EntityProvider return $this->page(fn(Builder $query) => $query->where('chapter_id', '=', 0)); } + public function templatePage(): Page + { + $page = $this->page(); + $page->template = true; + $page->save(); + + return $page; + } + /** * Get an un-fetched chapter from the system. */