mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-11-29 12:16:04 +08:00
307fae39c4
For book, shelves and chapters. Made much of the existing handling generic to entity types. Added new MixedEntityListLoader to help load lists somewhat efficiently. Only manually tested so far.
97 lines
2.6 KiB
PHP
97 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace BookStack\References;
|
|
|
|
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 entity.
|
|
*/
|
|
public function updateForEntity(Entity $entity): void
|
|
{
|
|
$this->updateForEntities([$entity]);
|
|
}
|
|
|
|
/**
|
|
* Update the outgoing references for all entities in the system.
|
|
*/
|
|
public function updateForAll(): void
|
|
{
|
|
Reference::query()->delete();
|
|
|
|
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 entities in the given array.
|
|
*
|
|
* @param Entity[] $entities
|
|
*/
|
|
protected function updateForEntities(array $entities): void
|
|
{
|
|
if (count($entities) === 0) {
|
|
return;
|
|
}
|
|
|
|
$parser = CrossLinkParser::createWithEntityResolvers();
|
|
$references = [];
|
|
|
|
$this->dropReferencesFromEntities($entities);
|
|
|
|
foreach ($entities as $entity) {
|
|
$models = $parser->extractLinkedModels($entity->getAttribute($entity->htmlField));
|
|
|
|
foreach ($models as $model) {
|
|
$references[] = [
|
|
'from_id' => $entity->id,
|
|
'from_type' => $entity->getMorphClass(),
|
|
'to_id' => $model->id,
|
|
'to_type' => $model->getMorphClass(),
|
|
];
|
|
}
|
|
}
|
|
|
|
foreach (array_chunk($references, 1000) as $referenceDataChunk) {
|
|
Reference::query()->insert($referenceDataChunk);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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();
|
|
}
|
|
}
|
|
}
|