From ea82c2f61b00231cdbcffd0463361c5b41832062 Mon Sep 17 00:00:00 2001 From: Nikhil Jha Date: Wed, 13 May 2020 19:57:59 -0700 Subject: [PATCH] support exporting books as zip files --- app/Http/Controllers/BookExportController.php | 26 ++++++++++++++++++- dev/docker/Dockerfile | 4 +-- routes/web.php | 1 + 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/BookExportController.php b/app/Http/Controllers/BookExportController.php index 40eec69fe..0414b7250 100644 --- a/app/Http/Controllers/BookExportController.php +++ b/app/Http/Controllers/BookExportController.php @@ -2,9 +2,11 @@ namespace BookStack\Http\Controllers; +use BookStack\Entities\Managers\BookContents; use BookStack\Entities\ExportService; use BookStack\Entities\Repos\BookRepo; use Throwable; +use ZipArchive; class BookExportController extends Controller { @@ -59,9 +61,31 @@ class BookExportController extends Controller */ public function markdown(string $bookSlug) { - // TODO: This should probably export to a zip file. $book = $this->bookRepo->getBySlug($bookSlug); $textContent = $this->exportService->bookToMarkdown($book); return $this->downloadResponse($textContent, $bookSlug . '.md'); } + + /** + * Export a book as a zip file, made of markdown files. + */ + public function zip(string $bookSlug) + { + $book = $this->bookRepo->getBySlug($bookSlug); + $z = new ZipArchive(); + $z->open("book.zip", \ZipArchive::CREATE | \ZipArchive::OVERWRITE); + $bookTree = (new BookContents($book))->getTree(false, true); + foreach ($bookTree as $bookChild) { + if ($bookChild->isA('chapter')) { + $z->addEmptyDir($bookChild->name); + foreach ($bookChild->pages as $page) { + $z->addFromString($bookChild->name . "/" . $page->name . ".md", $this->exportService->pageToMarkdown($page)); + } + } else { + $z->addFromString($bookChild->name . ".md", $this->exportService->pageToMarkdown($bookChild)); + } + } + return response()->download('book.zip'); + // TODO: Is not unlinking it a security issue? + } } diff --git a/dev/docker/Dockerfile b/dev/docker/Dockerfile index 8816615cf..be5af9ed9 100644 --- a/dev/docker/Dockerfile +++ b/dev/docker/Dockerfile @@ -4,9 +4,9 @@ ENV APACHE_DOCUMENT_ROOT /app/public WORKDIR /app RUN apt-get update -y \ - && apt-get install -y git zip unzip libtidy-dev libpng-dev libldap2-dev libxml++2.6-dev wait-for-it \ + && apt-get install -y git zip unzip libtidy-dev libpng-dev libldap2-dev libxml++2.6-dev wait-for-it libzip-dev \ && docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu \ - && docker-php-ext-install pdo pdo_mysql tidy dom xml mbstring gd ldap \ + && docker-php-ext-install pdo pdo_mysql tidy dom xml mbstring gd ldap zip \ && a2enmod rewrite \ && sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf \ && sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf \ diff --git a/routes/web.php b/routes/web.php index f2c4f432e..4d00b5ff6 100644 --- a/routes/web.php +++ b/routes/web.php @@ -48,6 +48,7 @@ Route::group(['middleware' => 'auth'], function () { Route::get('/{bookSlug}/export/html', 'BookExportController@html'); Route::get('/{bookSlug}/export/pdf', 'BookExportController@pdf'); Route::get('/{bookSlug}/export/markdown', 'BookExportController@markdown'); + Route::get('/{bookSlug}/export/zip', 'BookExportController@zip'); Route::get('/{bookSlug}/export/plaintext', 'BookExportController@plainText'); // Pages