Skip to content

Commit

Permalink
Merge branch 'portazips' into development
Browse files Browse the repository at this point in the history
  • Loading branch information
ssddanbrown committed Dec 1, 2024
2 parents 0a07b0d + bdca9fc commit fdbbcf2
Show file tree
Hide file tree
Showing 84 changed files with 5,269 additions and 717 deletions.
4 changes: 4 additions & 0 deletions app/Activity/ActivityType.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ class ActivityType
const WEBHOOK_UPDATE = 'webhook_update';
const WEBHOOK_DELETE = 'webhook_delete';

const IMPORT_CREATE = 'import_create';
const IMPORT_RUN = 'import_run';
const IMPORT_DELETE = 'import_delete';

/**
* Get all the possible values.
*/
Expand Down
1 change: 1 addition & 0 deletions app/Entities/Models/Chapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public function defaultTemplate(): BelongsTo

/**
* Get the visible pages in this chapter.
* @returns Collection<Page>
*/
public function getVisiblePages(): Collection
{
Expand Down
13 changes: 12 additions & 1 deletion app/Entities/Repos/PageRepo.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,17 @@ public function publishDraft(Page $draft, array $input): Page
return $draft;
}

/**
* Directly update the content for the given page from the provided input.
* Used for direct content access in a way that performs required changes
* (Search index & reference regen) without performing an official update.
*/
public function setContentFromInput(Page $page, array $input): void
{
$this->updateTemplateStatusAndContentFromInput($page, $input);
$this->baseRepo->update($page, []);
}

/**
* Update a page in the system.
*/
Expand Down Expand Up @@ -121,7 +132,7 @@ public function update(Page $page, array $input): Page
return $page;
}

protected function updateTemplateStatusAndContentFromInput(Page $page, array $input)
protected function updateTemplateStatusAndContentFromInput(Page $page, array $input): void
{
if (isset($input['template']) && userCan('templates-manage')) {
$page->template = ($input['template'] === 'true');
Expand Down
17 changes: 6 additions & 11 deletions app/Entities/Tools/Cloner.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,12 @@

class Cloner
{
protected PageRepo $pageRepo;
protected ChapterRepo $chapterRepo;
protected BookRepo $bookRepo;
protected ImageService $imageService;

public function __construct(PageRepo $pageRepo, ChapterRepo $chapterRepo, BookRepo $bookRepo, ImageService $imageService)
{
$this->pageRepo = $pageRepo;
$this->chapterRepo = $chapterRepo;
$this->bookRepo = $bookRepo;
$this->imageService = $imageService;
public function __construct(
protected PageRepo $pageRepo,
protected ChapterRepo $chapterRepo,
protected BookRepo $bookRepo,
protected ImageService $imageService,
) {
}

/**
Expand Down
7 changes: 7 additions & 0 deletions app/Exceptions/ZipExportException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace BookStack\Exceptions;

class ZipExportException extends \Exception
{
}
13 changes: 13 additions & 0 deletions app/Exceptions/ZipImportException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace BookStack\Exceptions;

class ZipImportException extends \Exception
{
public function __construct(
public array $errors
) {
$message = "Import failed with errors:" . implode("\n", $this->errors);
parent::__construct($message);
}
}
12 changes: 12 additions & 0 deletions app/Exceptions/ZipValidationException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace BookStack\Exceptions;

class ZipValidationException extends \Exception
{
public function __construct(
public array $errors
) {
parent::__construct();
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?php

namespace BookStack\Entities\Controllers;
namespace BookStack\Exports\Controllers;

use BookStack\Entities\Queries\BookQueries;
use BookStack\Entities\Tools\ExportFormatter;
use BookStack\Exports\ExportFormatter;
use BookStack\Http\ApiController;
use Throwable;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<?php

namespace BookStack\Entities\Controllers;
namespace BookStack\Exports\Controllers;

use BookStack\Entities\Queries\BookQueries;
use BookStack\Entities\Tools\ExportFormatter;
use BookStack\Exceptions\NotFoundException;
use BookStack\Exports\ExportFormatter;
use BookStack\Exports\ZipExports\ZipExportBuilder;
use BookStack\Http\Controller;
use Throwable;

Expand Down Expand Up @@ -63,4 +65,16 @@ public function markdown(string $bookSlug)

return $this->download()->directly($textContent, $bookSlug . '.md');
}

/**
* Export a book to a contained ZIP export file.
* @throws NotFoundException
*/
public function zip(string $bookSlug, ZipExportBuilder $builder)
{
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
$zip = $builder->buildForBook($book);

return $this->download()->streamedDirectly(fopen($zip, 'r'), $bookSlug . '.zip', filesize($zip));
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?php

namespace BookStack\Entities\Controllers;
namespace BookStack\Exports\Controllers;

use BookStack\Entities\Queries\ChapterQueries;
use BookStack\Entities\Tools\ExportFormatter;
use BookStack\Exports\ExportFormatter;
use BookStack\Http\ApiController;
use Throwable;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<?php

namespace BookStack\Entities\Controllers;
namespace BookStack\Exports\Controllers;

use BookStack\Entities\Queries\ChapterQueries;
use BookStack\Entities\Tools\ExportFormatter;
use BookStack\Exceptions\NotFoundException;
use BookStack\Exports\ExportFormatter;
use BookStack\Exports\ZipExports\ZipExportBuilder;
use BookStack\Http\Controller;
use Throwable;

Expand Down Expand Up @@ -70,4 +71,16 @@ public function markdown(string $bookSlug, string $chapterSlug)

return $this->download()->directly($chapterText, $chapterSlug . '.md');
}

/**
* Export a book to a contained ZIP export file.
* @throws NotFoundException
*/
public function zip(string $bookSlug, string $chapterSlug, ZipExportBuilder $builder)
{
$chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
$zip = $builder->buildForChapter($chapter);

return $this->download()->streamedDirectly(fopen($zip, 'r'), $chapterSlug . '.zip', filesize($zip));
}
}
110 changes: 110 additions & 0 deletions app/Exports/Controllers/ImportController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php

declare(strict_types=1);

namespace BookStack\Exports\Controllers;

use BookStack\Exceptions\ZipImportException;
use BookStack\Exceptions\ZipValidationException;
use BookStack\Exports\ImportRepo;
use BookStack\Http\Controller;
use BookStack\Uploads\AttachmentService;
use Illuminate\Http\Request;

class ImportController extends Controller
{
public function __construct(
protected ImportRepo $imports,
) {
$this->middleware('can:content-import');
}

/**
* Show the view to start a new import, and also list out the existing
* in progress imports that are visible to the user.
*/
public function start()
{
$imports = $this->imports->getVisibleImports();

$this->setPageTitle(trans('entities.import'));

return view('exports.import', [
'imports' => $imports,
'zipErrors' => session()->pull('validation_errors') ?? [],
]);
}

/**
* Upload, validate and store an import file.
*/
public function upload(Request $request)
{
$this->validate($request, [
'file' => ['required', ...AttachmentService::getFileValidationRules()]
]);

$file = $request->file('file');
try {
$import = $this->imports->storeFromUpload($file);
} catch (ZipValidationException $exception) {
return redirect('/import')->with('validation_errors', $exception->errors);
}

return redirect($import->getUrl());
}

/**
* Show a pending import, with a form to allow progressing
* with the import process.
*/
public function show(int $id)
{
$import = $this->imports->findVisible($id);

$this->setPageTitle(trans('entities.import_continue'));

return view('exports.import-show', [
'import' => $import,
'data' => $import->decodeMetadata(),
]);
}

/**
* Run the import process against an uploaded import ZIP.
*/
public function run(int $id, Request $request)
{
$import = $this->imports->findVisible($id);
$parent = null;

if ($import->type === 'page' || $import->type === 'chapter') {
session()->setPreviousUrl($import->getUrl());
$data = $this->validate($request, [
'parent' => ['required', 'string'],
]);
$parent = $data['parent'];
}

try {
$entity = $this->imports->runImport($import, $parent);
} catch (ZipImportException $exception) {
session()->flush();
$this->showErrorNotification(trans('errors.import_zip_failed_notification'));
return redirect($import->getUrl())->with('import_errors', $exception->errors);
}

return redirect($entity->getUrl());
}

/**
* Delete an active pending import from the filesystem and database.
*/
public function delete(int $id)
{
$import = $this->imports->findVisible($id);
$this->imports->deleteImport($import);

return redirect('/import');
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?php

namespace BookStack\Entities\Controllers;
namespace BookStack\Exports\Controllers;

use BookStack\Entities\Queries\PageQueries;
use BookStack\Entities\Tools\ExportFormatter;
use BookStack\Exports\ExportFormatter;
use BookStack\Http\ApiController;
use Throwable;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<?php

namespace BookStack\Entities\Controllers;
namespace BookStack\Exports\Controllers;

use BookStack\Entities\Queries\PageQueries;
use BookStack\Entities\Tools\ExportFormatter;
use BookStack\Entities\Tools\PageContent;
use BookStack\Exceptions\NotFoundException;
use BookStack\Exports\ExportFormatter;
use BookStack\Exports\ZipExports\ZipExportBuilder;
use BookStack\Http\Controller;
use Throwable;

Expand Down Expand Up @@ -74,4 +75,16 @@ public function markdown(string $bookSlug, string $pageSlug)

return $this->download()->directly($pageText, $pageSlug . '.md');
}

/**
* Export a page to a contained ZIP export file.
* @throws NotFoundException
*/
public function zip(string $bookSlug, string $pageSlug, ZipExportBuilder $builder)
{
$page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
$zip = $builder->buildForPage($page);

return $this->download()->streamedDirectly(fopen($zip, 'r'), $pageSlug . '.zip', filesize($zip));
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<?php

namespace BookStack\Entities\Tools;
namespace BookStack\Exports;

use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Page;
use BookStack\Entities\Tools\BookContents;
use BookStack\Entities\Tools\Markdown\HtmlToMarkdown;
use BookStack\Entities\Tools\PageContent;
use BookStack\Uploads\ImageService;
use BookStack\Util\CspService;
use BookStack\Util\HtmlDocument;
Expand Down
Loading

0 comments on commit fdbbcf2

Please sign in to comment.