Added the ability to dynamically translate on the project website.
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\Services\Admin\Project;
|
||||
|
||||
use App\Dto\Service\Admin\Project\Translation\Translations;
|
||||
use App\Dto\Service\Admin\Project\Translation\Update;
|
||||
use App\Enums\CacheTag;
|
||||
use App\Models\ProjectTranslation;
|
||||
use App\Models\User;
|
||||
use App\Repositories\ProjectRepository;
|
||||
use App\Repositories\ProjectTranslationRepository;
|
||||
use App\ServiceResults\ServiceResultArray;
|
||||
use App\ServiceResults\ServiceResultError;
|
||||
use App\ServiceResults\ServiceResultSuccess;
|
||||
use App\Services\ClearCacheCommandHandler;
|
||||
use App\Services\ProjectTranslation\ModelSyncCommand;
|
||||
use App\Services\Service;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
final class TranslationService extends Service
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ProjectRepository $projectRepository,
|
||||
private readonly ProjectTranslationRepository $projectTranslationRepository,
|
||||
private readonly ClearCacheCommandHandler $clearCacheCommandHandler,
|
||||
private readonly ModelSyncCommand $translationModelSyncCommand,
|
||||
) { }
|
||||
|
||||
public function languages(int $projectId, User $user): ServiceResultError | ServiceResultArray
|
||||
{
|
||||
$project = $this->projectRepository->getProjectById($projectId);
|
||||
if (\is_null($project)) {
|
||||
return $this->errNotFound(__('Not Found'));
|
||||
}
|
||||
|
||||
if ($user->cannot('viewAny', ProjectTranslation::class)) {
|
||||
return $this->errFobidden(__('Access is denied'));
|
||||
}
|
||||
|
||||
return $this->result([
|
||||
'project' => $project,
|
||||
]);
|
||||
}
|
||||
|
||||
public function edit(int $projectId, int $languageId, User $user): ServiceResultError | ServiceResultArray
|
||||
{
|
||||
$project = $this->projectRepository->getProjectById($projectId);
|
||||
$language = $project?->languages()->firstWhere('id', $languageId);
|
||||
|
||||
if (\is_null($project) || \is_null($language)) {
|
||||
return $this->errNotFound(__('Not Found'));
|
||||
}
|
||||
|
||||
if ($user->cannot('viewAny', ProjectTranslation::class)) {
|
||||
return $this->errFobidden(__('Access is denied'));
|
||||
}
|
||||
|
||||
return $this->result([
|
||||
'project' => $project,
|
||||
'language' => $language,
|
||||
'projectTranslations' => $this->projectTranslationRepository->getProjectTranslations($projectId, $languageId)->all()->pluck('text', 'code')->toArray(),
|
||||
'translations' => Translations::getTranslationCodes(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(int $projectId, int $languageId, Update $data, User $user): ServiceResultError | ServiceResultSuccess
|
||||
{
|
||||
$project = $this->projectRepository->getProjectById($projectId);
|
||||
$language = $project?->languages()->firstWhere('id', $languageId);
|
||||
|
||||
if (\is_null($project) || \is_null($language)) {
|
||||
return $this->errNotFound(__('Not Found'));
|
||||
}
|
||||
|
||||
if ($user->cannot('update', ProjectTranslation::class)) {
|
||||
return $this->errFobidden(__('Access is denied'));
|
||||
}
|
||||
|
||||
try {
|
||||
DB::transaction(function () use ($data, $project, $language) {
|
||||
$this->translationModelSyncCommand->execute($project, $language, $data->getTranslations());
|
||||
});
|
||||
$this->clearCacheCommandHandler->byTag(CacheTag::ProjectTranslation);
|
||||
} catch (\Throwable $e) {
|
||||
report($e);
|
||||
return $this->errService(__('Server Error'));
|
||||
}
|
||||
|
||||
return $this->ok(__('Translations successfully updated'));
|
||||
}
|
||||
}
|
@@ -23,6 +23,8 @@ final readonly class ModelSyncCommand
|
||||
'title' => $language->getTitle(),
|
||||
'sort' => $language->getSort(),
|
||||
'is_default' => $language->isDefault(),
|
||||
'system_lang' => $language->getSystemLang(),
|
||||
'iso_code' => $language->getIsoCode(),
|
||||
];
|
||||
|
||||
if ($language->getId() !== null) {
|
||||
|
@@ -0,0 +1,60 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\Services\ProjectTranslation;
|
||||
|
||||
use App\Dto\Service\Admin\Project\Translation\Translation;
|
||||
use App\Dto\Service\Admin\Project\Translation\Translations;
|
||||
use App\Models\Project;
|
||||
use App\Models\ProjectLanguage;
|
||||
use App\Models\ProjectTranslation;
|
||||
use App\Repositories\ProjectTranslationRepository;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
final readonly class ModelSyncCommand
|
||||
{
|
||||
public function __construct(
|
||||
private ProjectTranslationRepository $projectTranslationRepository,
|
||||
) { }
|
||||
|
||||
public function execute(Project $project, ProjectLanguage $language, Translations $update): void
|
||||
{
|
||||
$modelTranslations = $this->projectTranslationRepository->getProjectTranslationsWithTrashed($project->id, $language->id)->all();
|
||||
$insert = [];
|
||||
foreach ($update->getTranslations() as $translation) {
|
||||
/** @var Translation $translation */
|
||||
/** @var ProjectTranslation $modelTranslation */
|
||||
$modelTranslation = $modelTranslations->firstWhere('code', $translation->getCode());
|
||||
|
||||
if ($modelTranslation === null && $translation->getText() === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($modelTranslation === null && $translation->getText() !== null) {
|
||||
$insert[] = [
|
||||
'created_at' => Carbon::now(),
|
||||
'updated_at' => Carbon::now(),
|
||||
'project_id' => $project->id,
|
||||
'language_id' => $language->id,
|
||||
'code' => $translation->getCode(),
|
||||
'text' => $translation->getText(),
|
||||
];
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($modelTranslation !== null && $translation->getText() === null) {
|
||||
$modelTranslation->delete();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($modelTranslation->trashed()) {
|
||||
$modelTranslation->deleted_at = null;
|
||||
}
|
||||
$modelTranslation->text = $translation->getText();
|
||||
$modelTranslation->save();
|
||||
}
|
||||
|
||||
if (!empty($insert)) {
|
||||
ProjectTranslation::query()->insert($insert);
|
||||
}
|
||||
}
|
||||
}
|
@@ -3,7 +3,6 @@
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Project;
|
||||
use App\Models\ProjectLanguage;
|
||||
use App\ServiceResults\ServiceResultArray;
|
||||
use App\ServiceResults\ServiceResultError;
|
||||
use App\ServiceResults\ServiceResultSuccess;
|
||||
@@ -11,7 +10,6 @@ use App\ServiceResults\Site\PagePossibleWithoutTranslation;
|
||||
use App\ServiceResults\StoreUpdateResult;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
abstract class Service
|
||||
{
|
||||
@@ -60,9 +58,9 @@ abstract class Service
|
||||
return new ServiceResultArray(data: $data);
|
||||
}
|
||||
|
||||
final protected function resultSitePage(Project $project, ProjectLanguage $language, array $data, bool $isTranslation): PagePossibleWithoutTranslation
|
||||
final protected function resultSitePage(Project $project, WebsiteTranslations $websiteTranslations, array $data, bool $isTranslation): PagePossibleWithoutTranslation
|
||||
{
|
||||
return new PagePossibleWithoutTranslation($project, $language, $data, $isTranslation);
|
||||
return new PagePossibleWithoutTranslation($project, $websiteTranslations, $data, $isTranslation);
|
||||
}
|
||||
|
||||
final protected function error(int $code, string $message, array $errors = []): ServiceResultError
|
||||
|
@@ -6,19 +6,18 @@ use App\Models\Project;
|
||||
use App\Models\User;
|
||||
use App\Dto\Builder\Project as ProjectBuilderDto;
|
||||
use App\Repositories\ProjectContentRepository;
|
||||
use App\Repositories\ProjectLanguageRepository;
|
||||
use App\Repositories\ProjectLinkRepository;
|
||||
use App\Repositories\ProjectRepository;
|
||||
use App\ServiceResults\ServiceResultArray;
|
||||
use App\ServiceResults\ServiceResultError;
|
||||
use App\ServiceResults\Site\PagePossibleWithoutTranslation;
|
||||
use App\Services\Service;
|
||||
use App\Services\WebsiteTranslations;
|
||||
|
||||
final class ProjectService extends Service
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ProjectRepository $projectRepository,
|
||||
private readonly ProjectLanguageRepository $projectLanguageRepository,
|
||||
private readonly ProjectContentRepository $projectContentRepository,
|
||||
private readonly ProjectLinkRepository $projectLinkRepository,
|
||||
) { }
|
||||
@@ -39,7 +38,7 @@ final class ProjectService extends Service
|
||||
]);
|
||||
}
|
||||
|
||||
public function getAboutByProject(Project $project, ?string $languageCode, ?User $user = null): ServiceResultError | PagePossibleWithoutTranslation
|
||||
public function getAboutByProject(Project $project, WebsiteTranslations $websiteTranslations, ?User $user = null): ServiceResultError | PagePossibleWithoutTranslation
|
||||
{
|
||||
if (
|
||||
$project->is_public === false
|
||||
@@ -47,17 +46,13 @@ final class ProjectService extends Service
|
||||
) {
|
||||
return $this->errFobidden(__('Access is denied'));
|
||||
}
|
||||
$language = $this->projectLanguageRepository->getProjectLanguageByCodeOrDefault($project, $languageCode);
|
||||
if (!$language) {
|
||||
return $this->errNotFound(__('Language not found'));
|
||||
}
|
||||
|
||||
$data = [
|
||||
'project' => $project,
|
||||
'language' => $language,
|
||||
'content' => $this->projectContentRepository->getContentByLanguageId($project->id, $language->id),
|
||||
'links' => $this->projectLinkRepository->getLinksByProject($project, $language->id),
|
||||
'websiteTranslations' => $websiteTranslations,
|
||||
'content' => $this->projectContentRepository->getContentByLanguageId($project->id, $websiteTranslations->getLanguage()->id),
|
||||
'links' => $this->projectLinkRepository->getLinksByProject($project, $websiteTranslations->getLanguage()->id),
|
||||
];
|
||||
return $this->resultSitePage($project, $language, $data, \is_null($data['content']));
|
||||
return $this->resultSitePage($project, $websiteTranslations, $data, \is_null($data['content']));
|
||||
}
|
||||
}
|
||||
|
23
app/application/app/Services/WebsiteTranslations.php
Normal file
23
app/application/app/Services/WebsiteTranslations.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\ProjectLanguage;
|
||||
|
||||
final readonly class WebsiteTranslations
|
||||
{
|
||||
public function __construct(
|
||||
private ProjectLanguage $language,
|
||||
private array $transactions,
|
||||
) { }
|
||||
|
||||
public function translate(string $text): string
|
||||
{
|
||||
return $this->transactions[$text] ?? __($text);
|
||||
}
|
||||
|
||||
public function getLanguage(): ProjectLanguage
|
||||
{
|
||||
return $this->language;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user