mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-29 23:22:34 +01:00
Page Templates: Changed template field name, added API support
This commit is contained in:
parent
7ebe7d4e58
commit
4017048555
@ -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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
@ -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')) {
|
||||
|
@ -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,
|
||||
|
@ -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');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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"}
|
||||
]
|
||||
}
|
@ -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"}
|
||||
]
|
||||
}
|
@ -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"
|
||||
}
|
@ -20,6 +20,7 @@
|
||||
"name": "Admin",
|
||||
"slug": "admin"
|
||||
},
|
||||
"default_template_id": null,
|
||||
"contents": [
|
||||
{
|
||||
"id": 50,
|
||||
|
@ -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
|
||||
}
|
@ -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,
|
||||
])
|
||||
</div>
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user