mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-11-22 13:44:47 +08:00
Added reference handling on page actions
Page update/create/restore/clone/delete. Added a couple of tests to cover a couple of those.
This commit is contained in:
parent
3290ab3ac9
commit
bbe504c559
|
@ -16,20 +16,23 @@ use BookStack\Exceptions\MoveOperationException;
|
|||
use BookStack\Exceptions\NotFoundException;
|
||||
use BookStack\Exceptions\PermissionsException;
|
||||
use BookStack\Facades\Activity;
|
||||
use BookStack\References\ReferenceService;
|
||||
use Exception;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
class PageRepo
|
||||
{
|
||||
protected $baseRepo;
|
||||
protected BaseRepo $baseRepo;
|
||||
protected ReferenceService $references;
|
||||
|
||||
/**
|
||||
* PageRepo constructor.
|
||||
*/
|
||||
public function __construct(BaseRepo $baseRepo)
|
||||
public function __construct(BaseRepo $baseRepo, ReferenceService $references)
|
||||
{
|
||||
$this->baseRepo = $baseRepo;
|
||||
$this->references = $references;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,7 +115,7 @@ class PageRepo
|
|||
public function getParentFromSlugs(string $bookSlug, string $chapterSlug = null): Entity
|
||||
{
|
||||
if ($chapterSlug !== null) {
|
||||
return $chapter = Chapter::visible()->whereSlugs($bookSlug, $chapterSlug)->firstOrFail();
|
||||
return Chapter::visible()->whereSlugs($bookSlug, $chapterSlug)->firstOrFail();
|
||||
}
|
||||
|
||||
return Book::visible()->where('slug', '=', $bookSlug)->firstOrFail();
|
||||
|
@ -170,6 +173,7 @@ class PageRepo
|
|||
|
||||
$this->savePageRevision($draft, trans('entities.pages_initial_revision'));
|
||||
$draft->indexForSearch();
|
||||
$this->references->updateForPage($draft);
|
||||
$draft->refresh();
|
||||
|
||||
Activity::add(ActivityType::PAGE_CREATE, $draft);
|
||||
|
@ -189,6 +193,7 @@ class PageRepo
|
|||
|
||||
$this->updateTemplateStatusAndContentFromInput($page, $input);
|
||||
$this->baseRepo->update($page, $input);
|
||||
$this->references->updateForPage($page);
|
||||
|
||||
// Update with new details
|
||||
$page->revision_count++;
|
||||
|
@ -332,6 +337,7 @@ class PageRepo
|
|||
$page->refreshSlug();
|
||||
$page->save();
|
||||
$page->indexForSearch();
|
||||
$this->references->updateForPage($page);
|
||||
|
||||
$summary = trans('entities.pages_revision_restored_from', ['id' => strval($revisionId), 'summary' => $revision->summary]);
|
||||
$this->savePageRevision($page, $summary);
|
||||
|
@ -430,6 +436,7 @@ class PageRepo
|
|||
->skip(intval($revisionLimit))
|
||||
->take(10)
|
||||
->get(['id']);
|
||||
|
||||
if ($revisionsToDelete->count() > 0) {
|
||||
PageRevision::query()->whereIn('id', $revisionsToDelete->pluck('id'))->delete();
|
||||
}
|
||||
|
|
|
@ -376,6 +376,8 @@ class TrashCan
|
|||
$entity->searchTerms()->delete();
|
||||
$entity->deletions()->delete();
|
||||
$entity->favourites()->delete();
|
||||
$entity->referencesTo()->delete();
|
||||
$entity->referencesFrom()->delete();
|
||||
|
||||
if ($entity instanceof HasCoverImage && $entity->cover()->exists()) {
|
||||
$imageService = app()->make(ImageService::class);
|
||||
|
|
|
@ -14,6 +14,8 @@ use Illuminate\Database\Eloquent\Relations\MorphTo;
|
|||
*/
|
||||
class Reference extends Model
|
||||
{
|
||||
public $timestamps = false;
|
||||
|
||||
public function from(): MorphTo
|
||||
{
|
||||
return $this->morphTo('from');
|
||||
|
|
67
tests/References/ReferencesTest.php
Normal file
67
tests/References/ReferencesTest.php
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\References;
|
||||
|
||||
use BookStack\Entities\Models\Page;
|
||||
use BookStack\Entities\Repos\PageRepo;
|
||||
use BookStack\Entities\Tools\TrashCan;
|
||||
use BookStack\Model;
|
||||
use BookStack\References\Reference;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ReferencesTest extends TestCase
|
||||
{
|
||||
|
||||
public function test_references_created_on_page_update()
|
||||
{
|
||||
/** @var Page $pageA */
|
||||
/** @var Page $pageB */
|
||||
$pageA = Page::query()->first();
|
||||
$pageB = Page::query()->where('id', '!=', $pageA->id)->first();
|
||||
|
||||
$this->assertDatabaseMissing('references', ['from_id' => $pageA->id, 'from_type' => $pageA->getMorphClass()]);
|
||||
|
||||
$this->asEditor()->put($pageA->getUrl(), [
|
||||
'name' => 'Reference test',
|
||||
'html' => '<a href="' . $pageB->getUrl() . '">Testing</a>'
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('references', [
|
||||
'from_id' => $pageA->id,
|
||||
'from_type' => $pageA->getMorphClass(),
|
||||
'to_id' => $pageB->id,
|
||||
'to_type' => $pageB->getMorphClass(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_references_deleted_on_entity_delete()
|
||||
{
|
||||
/** @var Page $pageA */
|
||||
/** @var Page $pageB */
|
||||
$pageA = Page::query()->first();
|
||||
$pageB = Page::query()->where('id', '!=', $pageA->id)->first();
|
||||
|
||||
$this->createReference($pageA, $pageB);
|
||||
$this->createReference($pageB, $pageA);
|
||||
|
||||
$this->assertDatabaseHas('references', ['from_id' => $pageA->id, 'from_type' => $pageA->getMorphClass()]);
|
||||
$this->assertDatabaseHas('references', ['to_id' => $pageA->id, 'to_type' => $pageA->getMorphClass()]);
|
||||
|
||||
app(PageRepo::class)->destroy($pageA);
|
||||
app(TrashCan::class)->empty();
|
||||
|
||||
$this->assertDatabaseMissing('references', ['from_id' => $pageA->id, 'from_type' => $pageA->getMorphClass()]);
|
||||
$this->assertDatabaseMissing('references', ['to_id' => $pageA->id, 'to_type' => $pageA->getMorphClass()]);
|
||||
}
|
||||
|
||||
protected function createReference(Model $from, Model $to)
|
||||
{
|
||||
(new Reference())->forceFill([
|
||||
'from_type' => $from->getMorphClass(),
|
||||
'from_id' => $from->id,
|
||||
'to_type' => $to->getMorphClass(),
|
||||
'to_id' => $to->id,
|
||||
])->save();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user