X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/f634b4ea5767e6d823088c512872f9114322f7d0..refs/pull/5676/head:/app/References/ReferenceStore.php diff --git a/app/References/ReferenceStore.php b/app/References/ReferenceStore.php index f6e3c04a3..78595084b 100644 --- a/app/References/ReferenceStore.php +++ b/app/References/ReferenceStore.php @@ -2,63 +2,64 @@ namespace BookStack\References; -use BookStack\Entities\Models\Page; +use BookStack\Entities\EntityProvider; +use BookStack\Entities\Models\Entity; use Illuminate\Database\Eloquent\Collection; class ReferenceStore { + public function __construct( + protected EntityProvider $entityProvider + ) { + } /** - * Update the outgoing references for the given page. + * Update the outgoing references for the given entity. */ - public function updateForPage(Page $page): void + public function updateForEntity(Entity $entity): void { - $this->updateForPages([$page]); + $this->updateForEntities([$entity]); } /** - * Update the outgoing references for all pages in the system. + * Update the outgoing references for all entities in the system. */ - public function updateForAllPages(): void + public function updateForAll(): void { - Reference::query() - ->where('from_type', '=', (new Page())->getMorphClass()) - ->delete(); + Reference::query()->delete(); - Page::query()->select(['id', 'html'])->chunk(100, function(Collection $pages) { - $this->updateForPages($pages->all()); - }); + foreach ($this->entityProvider->all() as $entity) { + $entity->newQuery()->select(['id', $entity->htmlField])->chunk(100, function (Collection $entities) { + $this->updateForEntities($entities->all()); + }); + } } /** - * Update the outgoing references for the pages in the given array. + * Update the outgoing references for the entities in the given array. * - * @param Page[] $pages + * @param Entity[] $entities */ - protected function updateForPages(array $pages): void + protected function updateForEntities(array $entities): void { - if (count($pages) === 0) { + if (count($entities) === 0) { return; } $parser = CrossLinkParser::createWithEntityResolvers(); $references = []; - $pageIds = array_map(fn(Page $page) => $page->id, $pages); - Reference::query() - ->where('from_type', '=', $pages[0]->getMorphClass()) - ->whereIn('from_id', $pageIds) - ->delete(); + $this->dropReferencesFromEntities($entities); - foreach ($pages as $page) { - $models = $parser->extractLinkedModels($page->html); + foreach ($entities as $entity) { + $models = $parser->extractLinkedModels($entity->getAttribute($entity->htmlField)); foreach ($models as $model) { $references[] = [ - 'from_id' => $page->id, - 'from_type' => $page->getMorphClass(), - 'to_id' => $model->id, - 'to_type' => $model->getMorphClass(), + 'from_id' => $entity->id, + 'from_type' => $entity->getMorphClass(), + 'to_id' => $model->id, + 'to_type' => $model->getMorphClass(), ]; } } @@ -68,4 +69,28 @@ class ReferenceStore } } -} \ No newline at end of file + /** + * Delete all the existing references originating from the given entities. + * @param Entity[] $entities + */ + protected function dropReferencesFromEntities(array $entities): void + { + $IdsByType = []; + + foreach ($entities as $entity) { + $type = $entity->getMorphClass(); + if (!isset($IdsByType[$type])) { + $IdsByType[$type] = []; + } + + $IdsByType[$type][] = $entity->id; + } + + foreach ($IdsByType as $type => $entityIds) { + Reference::query() + ->where('from_type', '=', $type) + ->whereIn('from_id', $entityIds) + ->delete(); + } + } +}