mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-10-26 11:11:56 +00:00
Some checks are pending
analyse-php / build (push) Waiting to run
lint-php / build (push) Waiting to run
test-migrations / build (8.2) (push) Waiting to run
test-migrations / build (8.3) (push) Waiting to run
test-migrations / build (8.4) (push) Waiting to run
test-php / build (8.2) (push) Waiting to run
test-php / build (8.3) (push) Waiting to run
test-php / build (8.4) (push) Waiting to run
Changes to core entity models are now done on clones to ensure clean state before save, and those clones are returned back if changes are needed after that action.
187 lines
5.8 KiB
PHP
187 lines
5.8 KiB
PHP
<?php
|
|
|
|
namespace BookStack\Entities\Repos;
|
|
|
|
use BookStack\Activity\TagRepo;
|
|
use BookStack\Entities\Models\BookChild;
|
|
use BookStack\Entities\Models\Entity;
|
|
use BookStack\Entities\Models\EntityContainerData;
|
|
use BookStack\Entities\Queries\PageQueries;
|
|
use BookStack\Exceptions\ImageUploadException;
|
|
use BookStack\References\ReferenceStore;
|
|
use BookStack\References\ReferenceUpdater;
|
|
use BookStack\Sorting\BookSorter;
|
|
use BookStack\Uploads\ImageRepo;
|
|
use BookStack\Util\HtmlDescriptionFilter;
|
|
use Illuminate\Http\UploadedFile;
|
|
|
|
class BaseRepo
|
|
{
|
|
public function __construct(
|
|
protected TagRepo $tagRepo,
|
|
protected ImageRepo $imageRepo,
|
|
protected ReferenceUpdater $referenceUpdater,
|
|
protected ReferenceStore $referenceStore,
|
|
protected PageQueries $pageQueries,
|
|
protected BookSorter $bookSorter,
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Create a new entity in the system.
|
|
* @template T of Entity
|
|
* @param T $entity
|
|
* @return T
|
|
*/
|
|
public function create(Entity $entity, array $input): Entity
|
|
{
|
|
$entity = $entity->clone()->refresh();
|
|
$entityInput = array_intersect_key($input, ['name', 'priority']);
|
|
$entity->forceFill($entityInput);
|
|
$entity->forceFill([
|
|
'created_by' => user()->id,
|
|
'updated_by' => user()->id,
|
|
'owned_by' => user()->id,
|
|
]);
|
|
$entity->refreshSlug();
|
|
$entity->save();
|
|
|
|
if ($entity->shouldHaveContainerData()) {
|
|
$containerData = new EntityContainerData();
|
|
$this->updateContainerDescription($containerData, $input);
|
|
$entity->containerData()->save($containerData);
|
|
}
|
|
|
|
if (isset($input['tags'])) {
|
|
$this->tagRepo->saveTagsToEntity($entity, $input['tags']);
|
|
}
|
|
|
|
$entity->refresh();
|
|
$entity->rebuildPermissions();
|
|
$entity->indexForSearch();
|
|
|
|
$this->referenceStore->updateForEntity($entity);
|
|
|
|
return $entity;
|
|
}
|
|
|
|
/**
|
|
* Update the given entity.
|
|
* @template T of Entity
|
|
* @param T $entity
|
|
* @return T
|
|
*/
|
|
public function update(Entity $entity, array $input): Entity
|
|
{
|
|
$entity = $entity->clone()->refresh();
|
|
$oldUrl = $entity->getUrl();
|
|
|
|
$entity->fill($input);
|
|
$entity->updated_by = user()->id;
|
|
|
|
if ($entity->isDirty('name') || empty($entity->slug)) {
|
|
$entity->refreshSlug();
|
|
}
|
|
|
|
$entity->save();
|
|
if ($entity->shouldHaveContainerData() && $entity->containerData) {
|
|
$this->updateContainerDescription($entity->containerData, $input);
|
|
$entity->containerData->save();
|
|
}
|
|
|
|
if (isset($input['tags'])) {
|
|
$this->tagRepo->saveTagsToEntity($entity, $input['tags']);
|
|
$entity->touch();
|
|
}
|
|
|
|
$entity->indexForSearch();
|
|
$this->referenceStore->updateForEntity($entity);
|
|
|
|
if ($oldUrl !== $entity->getUrl()) {
|
|
$this->referenceUpdater->updateEntityReferences($entity, $oldUrl);
|
|
}
|
|
|
|
return $entity;
|
|
}
|
|
|
|
/**
|
|
* Update the given items' cover image or clear it.
|
|
*
|
|
* @throws ImageUploadException
|
|
* @throws \Exception
|
|
*/
|
|
public function updateCoverImage(EntityContainerData $containerData, ?UploadedFile $coverImage, bool $removeImage = false): void
|
|
{
|
|
if (!$containerData->supportsCoverImage()) {
|
|
return;
|
|
}
|
|
|
|
if ($coverImage) {
|
|
$imageType = 'cover_' . $containerData->entity_type;
|
|
$this->imageRepo->destroyImage($containerData->cover()->first());
|
|
$image = $this->imageRepo->saveNew($coverImage, $imageType, $containerData->entity_id, 512, 512, true);
|
|
$containerData->cover()->associate($image);
|
|
$containerData->save();
|
|
}
|
|
|
|
if ($removeImage) {
|
|
$this->imageRepo->destroyImage($containerData->cover()->first());
|
|
$containerData->cover()->dissociate();
|
|
$containerData->save();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update the default page template used for this item.
|
|
* Checks that, if changing, the provided value is a valid template and the user
|
|
* has visibility of the provided page template id.
|
|
*/
|
|
public function updateDefaultTemplate(EntityContainerData $containerData, int $templateId): void
|
|
{
|
|
$changing = $templateId !== intval($containerData->default_template_id);
|
|
if (!$changing || !$containerData->supportsDefaultTemplate()) {
|
|
return;
|
|
}
|
|
|
|
if ($templateId === 0) {
|
|
$containerData->default_template_id = null;
|
|
$containerData->save();
|
|
return;
|
|
}
|
|
|
|
$templateExists = $this->pageQueries->visibleTemplates()
|
|
->where('id', '=', $templateId)
|
|
->exists();
|
|
|
|
$containerData->default_template_id = $templateExists ? $templateId : null;
|
|
$containerData->save();
|
|
}
|
|
|
|
/**
|
|
* Sort the parent of the given entity if any auto sort actions are set for it.
|
|
* Typically ran during create/update/insert events.
|
|
*/
|
|
public function sortParent(Entity $entity): void
|
|
{
|
|
if ($entity instanceof BookChild) {
|
|
$book = $entity->book;
|
|
$this->bookSorter->runBookAutoSort($book);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update the description of the given container data from input data.
|
|
*/
|
|
protected function updateContainerDescription(EntityContainerData $data, array $input): void
|
|
{
|
|
if (isset($input['description_html'])) {
|
|
$data->setDescriptionHtml(
|
|
HtmlDescriptionFilter::filterFromString($input['description_html']),
|
|
html_entity_decode(strip_tags($input['description_html']))
|
|
);
|
|
} else if (isset($input['description'])) {
|
|
$data->setDescriptionHtml('', $input['description']);
|
|
}
|
|
}
|
|
}
|