Added book-export endpoints to the API

This commit is contained in:
Dan Brown 2020-04-10 16:05:17 +01:00
parent 29705a25ce
commit 7b8fe5fbc6
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
5 changed files with 95 additions and 2 deletions

View File

@ -3,6 +3,7 @@
use BookStack\Http\Controllers\Api\ApiController;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str;
use ReflectionClass;
use ReflectionException;
use ReflectionMethod;
@ -117,6 +118,7 @@ class ApiDocsGenerator
'method' => $route->methods[0],
'controller' => $controller,
'controller_method' => $controllerMethod,
'controller_method_kebab' => Str::kebab($controllerMethod),
'base_model' => $baseModelName,
];
});

View File

@ -0,0 +1,55 @@
<?php namespace BookStack\Http\Controllers\Api;
use BookStack\Entities\Book;
use BookStack\Entities\ExportService;
use BookStack\Entities\Repos\BookRepo;
use Throwable;
class BooksExportApiController extends ApiController
{
protected $bookRepo;
protected $exportService;
/**
* BookExportController constructor.
*/
public function __construct(BookRepo $bookRepo, ExportService $exportService)
{
$this->bookRepo = $bookRepo;
$this->exportService = $exportService;
parent::__construct();
}
/**
* Export a book as a PDF file.
* @throws Throwable
*/
public function exportPdf(int $id)
{
$book = Book::visible()->findOrFail($id);
$pdfContent = $this->exportService->bookToPdf($book);
return $this->downloadResponse($pdfContent, $book->slug . '.pdf');
}
/**
* Export a book as a contained HTML file.
* @throws Throwable
*/
public function exportHtml(int $id)
{
$book = Book::visible()->findOrFail($id);
$htmlContent = $this->exportService->bookToContainedHtml($book);
return $this->downloadResponse($htmlContent, $book->slug . '.html');
}
/**
* Export a book as a plain text file.
*/
public function exportPlainText(int $id)
{
$book = Book::visible()->findOrFail($id);
$textContent = $this->exportService->bookToPlainText($book);
return $this->downloadResponse($textContent, $book->slug . '.txt');
}
}

View File

@ -26,7 +26,7 @@
<span class="api-method" data-method="{{ $endpoint['method'] }}">{{ $endpoint['method'] }}</span>
</a>
<a href="#{{ $endpoint['name'] }}" class="text-mono">
{{ $endpoint['controller_method'] }}
{{ $endpoint['controller_method_kebab'] }}
</a>
</div>
@endforeach
@ -186,7 +186,7 @@
<h1 class="list-heading text-capitals">{{ $model }}</h1>
@foreach($endpoints as $endpoint)
<h6 class="text-uppercase text-muted float right">{{ $endpoint['controller_method'] }}</h6>
<h6 class="text-uppercase text-muted float right">{{ $endpoint['controller_method_kebab'] }}</h6>
<h5 id="{{ $endpoint['name'] }}" class="text-mono mb-m">
<span class="api-method" data-method="{{ $endpoint['method'] }}">{{ $endpoint['method'] }}</span>
{{ url($endpoint['uri']) }}

View File

@ -15,6 +15,10 @@ Route::get('books/{id}', 'BooksApiController@read');
Route::put('books/{id}', 'BooksApiController@update');
Route::delete('books/{id}', 'BooksApiController@delete');
Route::get('books/{id}/export/html', 'BooksExportApiController@exportHtml');
Route::get('books/{id}/export/pdf', 'BooksExportApiController@exportPdf');
Route::get('books/{id}/export/plaintext', 'BooksExportApiController@exportPlainText');
Route::get('shelves', 'BookshelfApiController@list');
Route::post('shelves', 'BookshelfApiController@create');
Route::get('shelves/{id}', 'BookshelfApiController@read');

View File

@ -105,4 +105,36 @@ class BooksApiTest extends TestCase
$resp->assertStatus(204);
$this->assertActivityExists('book_delete');
}
public function test_export_html_endpoint()
{
$this->actingAsApiEditor();
$book = Book::visible()->first();
$resp = $this->get($this->baseEndpoint . "/{$book->id}/export/html");
$resp->assertStatus(200);
$resp->assertSee($book->name);
$resp->assertHeader('Content-Disposition', 'attachment; filename="' . $book->slug . '.html"');
}
public function test_export_plain_text_endpoint()
{
$this->actingAsApiEditor();
$book = Book::visible()->first();
$resp = $this->get($this->baseEndpoint . "/{$book->id}/export/plaintext");
$resp->assertStatus(200);
$resp->assertSee($book->name);
$resp->assertHeader('Content-Disposition', 'attachment; filename="' . $book->slug . '.txt"');
}
public function test_export_pdf_endpoint()
{
$this->actingAsApiEditor();
$book = Book::visible()->first();
$resp = $this->get($this->baseEndpoint . "/{$book->id}/export/pdf");
$resp->assertStatus(200);
$resp->assertHeader('Content-Disposition', 'attachment; filename="' . $book->slug . '.pdf"');
}
}