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'],
 | 
			
		||||
            ],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,7 +96,7 @@ class BookController extends Controller
 | 
			
		|||
            'description'         => ['string', 'max:1000'],
 | 
			
		||||
            'image'               => array_merge(['nullable'], $this->getImageValidationRules()),
 | 
			
		||||
            'tags'                => ['array'],
 | 
			
		||||
            'default_template'  => ['nullable', 'integer'],
 | 
			
		||||
            'default_template_id' => ['nullable', 'integer'],
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        $bookshelf = null;
 | 
			
		||||
| 
						 | 
				
			
			@ -171,7 +171,7 @@ class BookController extends Controller
 | 
			
		|||
            'description'         => ['string', 'max:1000'],
 | 
			
		||||
            'image'               => array_merge(['nullable'], $this->getImageValidationRules()),
 | 
			
		||||
            'tags'                => ['array'],
 | 
			
		||||
            'default_template'  => ['nullable', 'integer'],
 | 
			
		||||
            '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