Files
mdhub/app/application/app/Services/Site/RepositoryService.php

211 lines
7.5 KiB
PHP

<?php declare(strict_types=1);
namespace App\Services\Site;
use App\Dto\Builder\Repository as RepositoryBuilder;
use App\Dto\QuerySettingsDto;
use App\Dto\Service\Site\Repository\StoreUpdate;
use App\Helpers\Helpers;
use App\Models\Repository;
use App\Models\User;
use App\Repositories\RepositoryRepository;
use App\Repositories\TagRepositoryRepository;
use App\Repositories\UserRepository;
use App\ServiceResults\ServiceResultArray;
use App\ServiceResults\ServiceResultError;
use App\ServiceResults\ServiceResultSuccess;
use App\ServiceResults\StoreUpdateResult;
use App\Services\Repository\RepositoryCommandHandler;
use App\Services\Service;
use Illuminate\Support\Facades\DB;
final class RepositoryService extends Service
{
public function __construct(
private readonly RepositoryRepository $repositoryRepository,
private readonly RepositoryCommandHandler $repositoryCommandHandler,
private readonly UserRepository $userRepository,
private readonly TagRepositoryRepository $tagRepositoryRepository,
) { }
public function repositories(QuerySettingsDto $querySettingsDto): ServiceResultArray | ServiceResultError
{
$repositories = $this->repositoryRepository->getRepositories(
new RepositoryBuilder(isPublic: true),
$querySettingsDto->getQueryWith()
)->pagination(
$querySettingsDto->getLimit(),
$querySettingsDto->getPage()
);
if ($querySettingsDto->getPage() > 1 && $repositories->count() === 0) {
return $this->errNotFound(__('Not Found'));
}
return $this->result([
'repositories' => $repositories,
]);
}
public function repository(string $username, string $repositoryName, ?User $user = null): ServiceResultArray | ServiceResultError
{
$pageUser = $this->userRepository->getUserByUsername($username);
if ($pageUser === null) {
return $this->errNotFound(__('Not Found'));
}
$repository = $this->repositoryRepository->getRepositoryByName($pageUser, $repositoryName);
if (!$repository || $user === null && $repository->is_public === false) {
return $this->errNotFound(__('Not Found'));
}
if ($user?->cannot('view', $repository)) {
return $this->errFobidden(__('Access is denied'));
}
return $this->result([
'repository' => $repository,
'pageUser' => $pageUser,
'serviceAddress' => Helpers::dockerServiceAddress(),
]);
}
public function create(string $username, User $user): ServiceResultArray | ServiceResultError
{
$pageUser = $this->userRepository->getUserByUsername($username);
if ($pageUser === null) {
return $this->errNotFound(__('Not Found'));
}
if ($user->cannot('create', [Repository::class, $pageUser])) {
return $this->errFobidden(__('Access is denied'));
}
return $this->result([
'user' => $user,
'repository' => new Repository(),
'pageUser' => $pageUser,
]);
}
public function edit(string $username, string $name, User $user): ServiceResultArray | ServiceResultError
{
$pageUser = $this->userRepository->getUserByUsername($username);
if ($pageUser === null) {
return $this->errNotFound(__('Not Found'));
}
$repository = $this->repositoryRepository->getRepositoryByName($pageUser, $name);
if (!$repository) {
return $this->errNotFound(__('Not Found'));
}
if ($user->cannot('update', $repository)) {
return $this->errFobidden(__('Access is denied'));
}
return $this->result([
'user' => $user,
'repository' => $repository,
'pageUser' => $pageUser,
]);
}
public function store(string $username, StoreUpdate $data, User $user): StoreUpdateResult | ServiceResultError
{
$pageUser = $this->userRepository->getUserByUsername($username);
if ($pageUser === null) {
return $this->errNotFound(__('Not Found'));
}
if ($user->cannot('create', [Repository::class, $pageUser])) {
return $this->errFobidden(__('Access is denied'));
}
if ($this->repositoryRepository->isExistsName($pageUser, $data->getName())) {
return $this->errValidate(
__('validation.unique', ['attribute' => __('validation.attributes.name')]),
['name' => __('validation.unique', ['attribute' => __('validation.attributes.name')])]
);
}
try {
$modelRepository = DB::transaction(function () use ($data, $pageUser) {
$dataRepository = $this->getDataRepository($data);
return $this->repositoryCommandHandler->handleStore($pageUser, $dataRepository, $data->getName());
});
} catch (\Throwable $e) {
\report($e);
return $this->errService(__('Server Error'));
}
return $this->resultStoreUpdateModel($modelRepository, __('site.The repository has been successfully created'));
}
public function update(string $username, string $name, StoreUpdate $data, User $user): StoreUpdateResult | ServiceResultError
{
$pageUser = $this->userRepository->getUserByUsername($username);
if ($pageUser === null) {
return $this->errNotFound(__('Not Found'));
}
$repository = $this->repositoryRepository->getRepositoryByName($pageUser, $name);
if (!$repository) {
return $this->errNotFound(__('Not Found'));
}
if ($user->cannot('update', $repository)) {
return $this->errFobidden(__('Access is denied'));
}
try {
$modelRepository = DB::transaction(function () use ($data, $repository) {
$dataRepository = $this->getDataRepository($data);
return $this->repositoryCommandHandler->handleUpdate($repository, $dataRepository);
});
} catch (\Throwable $e) {
\report($e);
return $this->errService(__('Server Error'));
}
return $this->resultStoreUpdateModel($modelRepository, __('site.The repository has been successfully updated'));
}
public function destroy(string $username, string $name, User $user): ServiceResultError | ServiceResultSuccess
{
$pageUser = $this->userRepository->getUserByUsername($username);
if ($pageUser === null) {
return $this->errNotFound(__('Not Found'));
}
$repository = $this->repositoryRepository->getRepositoryByName($pageUser, $name);
if (!$repository) {
return $this->errNotFound(__('Not Found'));
}
if ($user->cannot('delete', $repository)) {
return $this->errFobidden(__('Access is denied'));
}
try {
DB::transaction(function () use ($repository) {
$this->repositoryCommandHandler->handleDestroy($repository);
});
} catch (\Throwable $e) {
\report($e);
return $this->errService(__('Server Error'));
}
return $this->ok(__('site.Repository deleted successfully'));
}
private function getDataRepository(StoreUpdate $data): array
{
return [
'is_public' => $data->isPublic(),
'description' => $data->getDescription(),
'overview' => $data->getOverview(),
];
}
}