]> BookStack Code Mirror - bookstack/blobdiff - app/References/ReferenceStore.php
respective book and chapter structure added.
[bookstack] / app / References / ReferenceStore.php
index f6e3c04a386f04d4facb21d75d2a5f5ab11a72db..78595084b097a26cc012fac553297b84133d2d9c 100644 (file)
@@ -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();
+        }
+    }
+}