224 lines
7.8 KiB
PHP
224 lines
7.8 KiB
PHP
<?php declare(strict_types=1);
|
|
|
|
namespace App\Services\Admin;
|
|
|
|
use App\Dto\Builder\Project as ProjectBuilderDto;
|
|
use App\Dto\QuerySettingsDto;
|
|
use App\Dto\Service\Admin\Project\StoreUpdate;
|
|
use App\Enums\CacheTag;
|
|
use App\Enums\Morph;
|
|
use App\Models\Project;
|
|
use App\Models\ProjectLanguage;
|
|
use App\Models\User;
|
|
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\Project\ProjectCommandHandler;
|
|
use App\Services\ProjectLanguage\ModelSyncCommand;
|
|
use App\Services\Role\CreateAdminRoleForProjectCommand;
|
|
use App\Services\Service;
|
|
use App\Services\Storage\StorageService;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
final class ProjectService extends Service
|
|
{
|
|
public function __construct(
|
|
private readonly ProjectRepository $projectRepository,
|
|
private readonly ProjectCommandHandler $projectCommandHandler,
|
|
private readonly CreateAdminRoleForProjectCommand $createAdminRoleForProjectCommand,
|
|
private readonly ModelSyncCommand $languageModelSyncCommand,
|
|
private readonly StorageService $storageService,
|
|
private readonly ClearCacheCommandHandler $clearCacheCommandHandler,
|
|
) { }
|
|
|
|
public function index(ProjectBuilderDto $projectBuilderDto, QuerySettingsDto $querySettingsDto, User $user): ServiceResultError | ServiceResultArray
|
|
{
|
|
if ($user->cannot('viewAny', Project::class)) {
|
|
return $this->errFobidden(__('Access is denied'));
|
|
}
|
|
|
|
$projects = $this->projectRepository->getProjects(
|
|
$projectBuilderDto,
|
|
$querySettingsDto->getQueryWith()
|
|
)->pagination(
|
|
$querySettingsDto->getLimit(),
|
|
$querySettingsDto->getPage()
|
|
);
|
|
|
|
return $this->result([
|
|
'projects' => $projects,
|
|
'serviceTranslationEnable' => config('translation_service.enable', false),
|
|
]);
|
|
}
|
|
|
|
public function show(int $id, User $user): ServiceResultError | ServiceResultArray
|
|
{
|
|
$project = $this->projectRepository->getProjectById($id);
|
|
|
|
if (is_null($project)) {
|
|
return $this->errNotFound(__('Not Found'));
|
|
}
|
|
|
|
if ($user->cannot('view', $project)) {
|
|
return $this->errFobidden(__('Access is denied'));
|
|
}
|
|
|
|
return $this->result([
|
|
'project' => $project,
|
|
]);
|
|
}
|
|
|
|
public function create(User $user): ServiceResultError | ServiceResultArray
|
|
{
|
|
if ($user->cannot('create', Project::class)) {
|
|
return $this->errFobidden(__('Access is denied'));
|
|
}
|
|
|
|
$language = new ProjectLanguage();
|
|
$language->is_default = true;
|
|
$language->title = $user->lang?->getTitle();
|
|
$language->code = $user->lang?->getLocale();
|
|
return $this->result([
|
|
'project' => new Project(),
|
|
'languages' => collect([$language])->toArray(),
|
|
]);
|
|
}
|
|
|
|
public function edit(int $id, User $user): ServiceResultError | ServiceResultArray
|
|
{
|
|
$project = $this->projectRepository->getProjectById($id);
|
|
|
|
if (is_null($project)) {
|
|
return $this->errNotFound(__('Not Found'));
|
|
}
|
|
|
|
if ($user->cannot('view', $project)) {
|
|
return $this->errFobidden(__('Access is denied'));
|
|
}
|
|
|
|
return $this->result([
|
|
'project' => $project,
|
|
'languages' => $project->languages->toArray(),
|
|
]);
|
|
}
|
|
|
|
public function store(StoreUpdate $data, User $user): ServiceResultError | StoreUpdateResult
|
|
{
|
|
if ($user->cannot('create', Project::class)) {
|
|
return $this->errFobidden(__('Access is denied'));
|
|
}
|
|
|
|
if ($this->projectRepository->isExistsCode($data->getCode())) {
|
|
return $this->errValidate(
|
|
__('validation.unique', ['attribute' => __('validation.attributes.code')]),
|
|
['code' => __('validation.unique', ['attribute' => __('validation.attributes.code')])]
|
|
);
|
|
}
|
|
|
|
$storages = $this->storageService->getStoragesAndValidate($data->getStorages(), Morph::Project);
|
|
if (!$storages->isSuccess()) {
|
|
return $storages;
|
|
}
|
|
|
|
try {
|
|
$project = DB::transaction(function () use ($data, $user, $storages) {
|
|
$dataProject = $this->getDataProject($data);
|
|
|
|
$project = $this->projectCommandHandler->handleStore($dataProject);
|
|
$this->createAdminRoleForProjectCommand->execute($project, $user);
|
|
$this->languageModelSyncCommand->execute($project, $data->getLanguages());
|
|
$this->storageService->saveAndDelete($project, $storages);
|
|
|
|
return $project;
|
|
});
|
|
$this->clearCacheCommandHandler->byTag(CacheTag::Project);
|
|
} catch (\Throwable $e) {
|
|
report($e);
|
|
return $this->errService(__('Server Error'));
|
|
}
|
|
|
|
return $this->resultStoreUpdateModel($project, __('The project was successfully created'));
|
|
}
|
|
|
|
public function update(int $id, StoreUpdate $data, User $user): ServiceResultError | StoreUpdateResult
|
|
{
|
|
$project = $this->projectRepository->getProjectById($id);
|
|
|
|
if (is_null($project)) {
|
|
return $this->errNotFound(__('Not Found'));
|
|
}
|
|
|
|
if ($user->cannot('update', $project)) {
|
|
return $this->errFobidden(__('Access is denied'));
|
|
}
|
|
|
|
if ($this->projectRepository->isExistsCode($data->getCode(), $project->id)) {
|
|
return $this->errValidate(
|
|
__('validation.unique', ['attribute' => __('validation.attributes.code')]),
|
|
['code' => __('validation.unique', ['attribute' => __('validation.attributes.code')])]
|
|
);
|
|
}
|
|
|
|
$storages = $this->storageService->getStoragesAndValidate($data->getStorages(), Morph::Project, $project->id);
|
|
if (!$storages->isSuccess()) {
|
|
return $storages;
|
|
}
|
|
|
|
try {
|
|
$project = DB::transaction(function () use ($data, $project, $storages) {
|
|
$dataProject = $this->getDataProject($data);
|
|
|
|
$project = $this->projectCommandHandler->handleUpdate($project, $dataProject);
|
|
$this->languageModelSyncCommand->execute($project, $data->getLanguages());
|
|
$this->storageService->saveAndDelete($project, $storages);
|
|
|
|
return $project;
|
|
});
|
|
$this->clearCacheCommandHandler->byTag(CacheTag::Project);
|
|
} catch (\Throwable $e) {
|
|
report($e);
|
|
return $this->errService(__('Server Error'));
|
|
}
|
|
|
|
return $this->resultStoreUpdateModel($project, __('The project was successfully updated'));
|
|
}
|
|
|
|
public function destroy(int $id, User $user): ServiceResultError|ServiceResultSuccess
|
|
{
|
|
$project = $this->projectRepository->getProjectById($id);
|
|
|
|
if (is_null($project)) {
|
|
return $this->errNotFound(__('Not Found'));
|
|
}
|
|
|
|
if ($user->cannot('delete', $project)) {
|
|
return $this->errFobidden(__('Access is denied'));
|
|
}
|
|
|
|
try {
|
|
DB::transaction(function () use ($project) {
|
|
$this->projectCommandHandler->handleDestroy($project);
|
|
});
|
|
$this->clearCacheCommandHandler->byTag(CacheTag::Project);
|
|
} catch (\Throwable $e) {
|
|
report($e);
|
|
return $this->errService(__('Server Error'));
|
|
}
|
|
|
|
return $this->ok(__('The project has been deleted'));
|
|
}
|
|
|
|
private function getDataProject(StoreUpdate $data): array
|
|
{
|
|
return [
|
|
'name' => $data->getName(),
|
|
'code' => $data->getCode(),
|
|
'http_host' => $data->getHttpHost(),
|
|
'is_public' => $data->isPublic(),
|
|
];
|
|
}
|
|
}
|