Files
my-projects-website/app/application/app/Services/Admin/Project/DocumentationVersionService.php

229 lines
8.6 KiB
PHP

<?php declare(strict_types=1);
namespace App\Services\Admin\Project;
use App\Dto\QuerySettingsDto;
use App\Dto\Builder\DocumentationVersion as DocumentationVersionBuilderDto;
use App\Dto\Service\Admin\Project\DocumentationVersion\StoreUpdate;
use App\Enums\CacheTag;
use App\Enums\DocumentationVersionStatus;
use App\Models\DocumentationVersion;
use App\Models\User;
use App\Repositories\DocumentationVersionRepository;
use App\Repositories\ProjectRepository;
use App\ServiceResults\ServiceResultArray;
use App\ServiceResults\ServiceResultError;
use App\ServiceResults\ServiceResultSuccess;
use App\ServiceResults\StoreUpdateResult;
use App\Services\ClearCacheCommandHandler;
use App\Services\DocumentationVersion\DocumentationVersionCommandHandler;
use App\Services\Service;
use Illuminate\Support\Facades\DB;
final class DocumentationVersionService extends Service
{
public function __construct(
private readonly ProjectRepository $projectRepository,
private readonly DocumentationVersionRepository $documentationVersionRepository,
private readonly DocumentationVersionCommandHandler $documentationVersionCommandHandler,
private readonly ClearCacheCommandHandler $clearCacheCommandHandler,
) { }
public function index(int $projectId, DocumentationVersionBuilderDto $documentationVersionBuilderDto, QuerySettingsDto $querySettingsDto, User $user): ServiceResultError | ServiceResultArray
{
$project = $this->projectRepository->getProjectById($projectId);
if (\is_null($project)) {
return $this->errNotFound(__('Not Found'));
}
if ($user->cannot('viewAny', DocumentationVersion::class)) {
return $this->errFobidden(__('Access is denied'));
}
$versions = $this->documentationVersionRepository->getVersions(
$project->id,
$documentationVersionBuilderDto,
$querySettingsDto->getQueryWith()
)->pagination(
$querySettingsDto->getLimit(),
$querySettingsDto->getPage()
);
return $this->result([
'versions' => $versions,
'project' => $project,
]);
}
public function show(int $projectId, int $versionId, User $user): ServiceResultError | ServiceResultArray
{
$project = $this->projectRepository->getProjectById($projectId);
if (\is_null($project)) {
return $this->errNotFound(__('Not Found'));
}
$version = $this->documentationVersionRepository->getVersionById($versionId);
if (\is_null($version)) {
return $this->errNotFound(__('Not Found'));
}
if ($user->cannot('view', $version)) {
return $this->errFobidden(__('Access is denied'));
}
return $this->result([
'version' => $version,
'project' => $project,
]);
}
public function create(int $projectId, User $user): ServiceResultError | ServiceResultArray
{
$project = $this->projectRepository->getProjectById($projectId);
if (\is_null($project)) {
return $this->errNotFound(__('Not Found'));
}
if ($user->cannot('create', DocumentationVersion::class)) {
return $this->errFobidden(__('Access is denied'));
}
return $this->result([
'version' => new DocumentationVersion(),
'statuses' => DocumentationVersionStatus::toCollection()->pluck( 'title', 'value')->toArray(),
'project' => $project,
]);
}
public function edit(int $projectId, int $versionId, User $user): ServiceResultError | ServiceResultArray
{
$project = $this->projectRepository->getProjectById($projectId);
if (\is_null($project)) {
return $this->errNotFound(__('Not Found'));
}
$version = $this->documentationVersionRepository->getVersionById($versionId);
if (\is_null($version)) {
return $this->errNotFound(__('Not Found'));
}
if ($user->cannot('view', $version)) {
return $this->errFobidden(__('Access is denied'));
}
return $this->result([
'version' => $version,
'statuses' => DocumentationVersionStatus::toCollection()->pluck( 'title', 'value')->toArray(),
'project' => $project,
]);
}
public function store(int $projectId, StoreUpdate $data, User $user): ServiceResultError | StoreUpdateResult
{
if ($user->cannot('create', DocumentationVersion::class)) {
return $this->errFobidden(__('Access is denied'));
}
$project = $this->projectRepository->getProjectById($projectId);
if (\is_null($project)) {
return $this->errNotFound(__('Not Found'));
}
if ($this->documentationVersionRepository->isExistsSlug($projectId, $data->getSlug()) !== false) {
return $this->errValidate(
__('validation.unique', ['attribute' => __('validation.attributes.slug')]),
['slug' => __('validation.unique', ['attribute' => __('validation.attributes.slug')])]
);
}
try {
$version = DB::transaction(function () use ($data, $project, $user) {
$dataVersion = $this->getDataVersion($data);
return $this->documentationVersionCommandHandler->handleStore($project, $dataVersion);
});
$this->clearCacheCommandHandler->byTag(CacheTag::DocumantationVersion);
} catch (\Throwable $e) {
report($e);
return $this->errService(__('Server Error'));
}
return $this->resultStoreUpdateModel($version, __('Documentation version created successfully'));
}
public function update(int $projectId, int $versionId, StoreUpdate $data, User $user): ServiceResultError | StoreUpdateResult
{
$project = $this->projectRepository->getProjectById($projectId);
if (\is_null($project)) {
return $this->errNotFound(__('Not Found'));
}
$version = $this->documentationVersionRepository->getVersionById($versionId);
if (\is_null($version)) {
return $this->errNotFound(__('Not Found'));
}
if ($user->cannot('update', $version)) {
return $this->errFobidden(__('Access is denied'));
}
if ($this->documentationVersionRepository->isExistsSlug($projectId, $data->getSlug(), $version->id) !== false) {
return $this->errValidate(
__('validation.unique', ['attribute' => __('validation.attributes.slug')]),
['slug' => __('validation.unique', ['attribute' => __('validation.attributes.slug')])]
);
}
try {
$version = DB::transaction(function () use ($data, $version) {
$dataVersion = $this->getDataVersion($data);
return $this->documentationVersionCommandHandler->handleUpdate($version, $dataVersion);
});
$this->clearCacheCommandHandler->byTag(CacheTag::DocumantationVersion);
} catch (\Throwable $e) {
report($e);
return $this->errService(__('Server Error'));
}
return $this->resultStoreUpdateModel($version, __('Documentation version updated successfully'));
}
public function destroy(int $projectId, int $versionId, User $user): ServiceResultError|ServiceResultSuccess
{
$project = $this->projectRepository->getProjectById($projectId);
if (\is_null($project)) {
return $this->errNotFound(__('Not Found'));
}
$version = $this->documentationVersionRepository->getVersionById($versionId);
if (\is_null($version)) {
return $this->errNotFound(__('Not Found'));
}
if ($user->cannot('delete', $version)) {
return $this->errFobidden(__('Access is denied'));
}
try {
DB::transaction(function () use ($version) {
$this->documentationVersionCommandHandler->handleDestroy($version);
});
$this->clearCacheCommandHandler->byTag(CacheTag::DocumantationVersion);
} catch (\Throwable $e) {
report($e);
return $this->errService(__('Server Error'));
}
return $this->ok(__('Documentation version successfully removed'));
}
private function getDataVersion(StoreUpdate $data): array
{
return [
'title' => $data->getTitle(),
'slug' => $data->getSlug(),
'is_public' => $data->isPublic(),
'status' => $data->getStatus(),
];
}
}