Version 1.3.0 #7

Merged
kor-elf merged 2 commits from develop into main 2025-01-16 21:23:42 +05:00
7 changed files with 84 additions and 28 deletions
Showing only changes of commit e63ded1708 - Show all commits

View File

@ -70,12 +70,12 @@ ID folder. Код можно увидеть в адресе console.yandex.cloud
### Перевести с помощью очередей (Queues) ### Перевести с помощью очередей (Queues)
> \KorElf\TranslateLaravel\Facades\Translate::runJob( > \KorElf\TranslateLaravel\Facades\Translate::runJob(
> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\KorElf\TranslateLaravel\DTO\RunTranslateDto &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\$params, > <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\KorElf\TranslateLaravel\DTO\RunTranslateDto &nbsp;&nbsp;\$params,
> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\KorElf\TranslateLaravel\Contracts\TranslationCompletedListener \$completedListener > <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\KorElf\TranslateLaravel\DTO\AfterTranslateDto &nbsp;\$afterTranslateDto
<br>): \Illuminate\Foundation\Bus\PendingDispatch <br>): \Illuminate\Foundation\Bus\PendingDispatch
**\$params** - параметры перевода. **\$params** - параметры перевода.
<br>**\$completedListener** - после завершения перевода отправляет результат в этот объект. Объект должен соблюдать контракт **\KorElf\TranslateLaravel\Contracts\TranslationCompletedListener**. <br>**\$afterTranslateDto** - после завершения перевода отправляет результат в объект \$afterTranslateDto->\$className. Объект должен соблюдать контракт **\KorElf\TranslateLaravel\Contracts\TranslationCompletedListener**.
**Пример:** **Пример:**
> Создаём файл TranslationListener например в папке app/Services > Создаём файл TranslationListener например в папке app/Services
@ -89,25 +89,41 @@ ID folder. Код можно увидеть в адресе console.yandex.cloud
> >
> final class TranslationListener implements TranslationCompletedListener > final class TranslationListener implements TranslationCompletedListener
> { > {
> public function onTranslationCompleted(array $translatedText): void > /**
> * Объекты создаются и пробрасываются автоматически через контейнер `$application->make`,
> * благодаря механизму автоматического внедрения зависимостей (Dependency Injection).
> * Вы можете передавать свои собственные классы, поместив их в качестве параметров конструктора.
> * Контейнер создаст эти объекты автоматически, основываясь на разрешении типа (type-hint).
> */
> // public function __construct(
> // private readonly SaveContentCommand $saveContentCommand
> // ) { }
>
> public function onTranslationCompleted(array $translatedText, array $data = []): void
> { > {
> Log::info($data);
> foreach ($translatedText as $translatedTextKey => $translatedTextValue) { > foreach ($translatedText as $translatedTextKey => $translatedTextValue) {
> Log::info($translatedTextKey . ': ' . $translatedTextValue); > Log::info($translatedTextKey . ': ' . $translatedTextValue);
> } > }
> // $this->saveContentCommand->execute($data['contentId'], $translatedText);
> } > }
> } > }
> >
> Потом например в каком-то контроллере (а лучше конечно в сервисе) пишем такой метод > Потом например в каком-то контроллере (а лучше конечно в сервисе) пишем такой метод
> >
> public function sendingForTranslation(\App\Services\TranslationListener $translationListener): View > public function sendingForTranslation(): View
> { > {
> // Вначале создаём объект с параметрами > // Вначале создаём объект с параметрами
> $params = (new \KorElf\TranslateLaravel\DTO\RunTranslateDto) > $params = (new \KorElf\TranslateLaravel\DTO\RunTranslateDto)
> ->addParamText('title', 'Заголовок', 'en', 'ru') > ->addParamText('title', 'Заголовок', 'en', 'ru')
> ->addParamHtml('content', '<p>Привет, Мир!</p>', 'en', 'ru'); > ->addParamHtml('content', '<p>Привет, Мир!</p>', 'en', 'ru');
> >
> $translationCompletedListener = \App\Services\TranslationListener::class;
> $data = ['contentId' => 1];
> $afterTranslateDto = \KorElf\TranslateLaravel\DTO\AfterTranslateDto($translationCompletedListener, $data);
>
> // Отправляем на очередь > // Отправляем на очередь
> \KorElf\TranslateLaravel\Facades\Translate::runJob($params, $translationListener); > \KorElf\TranslateLaravel\Facades\Translate::runJob($params, $afterTranslateDto);
> >
> return view('success'); > return view('success');
> } > }

View File

@ -4,5 +4,5 @@ namespace KorElf\TranslateLaravel\Contracts;
interface TranslationCompletedListener interface TranslationCompletedListener
{ {
public function onTranslationCompleted(array $translatedText): void; public function onTranslationCompleted(array $translatedText, array $data = []): void;
} }

View File

@ -0,0 +1,32 @@
<?php declare(strict_types=1);
namespace KorElf\TranslateLaravel\DTO;
final readonly class AfterTranslateDto
{
/**
* @param string $className The fully qualified class name (FQN) of a class that implements the TranslationCompletedListener interface.
* @param array $data Additional data associated with the translation process.
*/
public function __construct(
private string $className,
private array $data = [],
) { }
/**
* Get the fully qualified class name (FQN) of a class that implements the TranslationCompletedListener interface.
*
* @return class-string<\KorElf\TranslateLaravel\Contracts\TranslationCompletedListener>
*/
public function getClassName(): string
{
return $this->className;
}
public function getData(): array
{
return $this->data;
}
}

View File

@ -3,7 +3,7 @@
namespace KorElf\TranslateLaravel\Facades; namespace KorElf\TranslateLaravel\Facades;
use Illuminate\Support\Facades\Facade; use Illuminate\Support\Facades\Facade;
use KorElf\TranslateLaravel\Contracts\TranslationCompletedListener; use KorElf\TranslateLaravel\DTO\AfterTranslateDto;
use KorElf\TranslateLaravel\DTO\RunTranslateDto; use KorElf\TranslateLaravel\DTO\RunTranslateDto;
/** /**
@ -11,7 +11,7 @@ use KorElf\TranslateLaravel\DTO\RunTranslateDto;
* @method static \KorElf\TranslateLaravel\Contracts\Translate resolve(string $name) * @method static \KorElf\TranslateLaravel\Contracts\Translate resolve(string $name)
* @method static string|array translateText(string|array $text, string $targetLanguageCode, ?string $sourceLanguageCode = null) * @method static string|array translateText(string|array $text, string $targetLanguageCode, ?string $sourceLanguageCode = null)
* @method static string|array translateHtml(string|array $text, string $targetLanguageCode, ?string $sourceLanguageCode = null) * @method static string|array translateHtml(string|array $text, string $targetLanguageCode, ?string $sourceLanguageCode = null)
* @method static \Illuminate\Foundation\Bus\PendingDispatch runJob(RunTranslateDto $params, TranslationCompletedListener $completedListener) * @method static \Illuminate\Foundation\Bus\PendingDispatch runJob(RunTranslateDto $params, AfterTranslateDto $afterTranslateDto)
* @method static \KorElf\TranslateLaravel\DTO\Languages listLanguages() * @method static \KorElf\TranslateLaravel\DTO\Languages listLanguages()
* @method static string getDefaultDriver() * @method static string getDefaultDriver()
* @method static void setDefaultDriver(string $name) * @method static void setDefaultDriver(string $name)

View File

@ -5,10 +5,11 @@ namespace KorElf\TranslateLaravel\Jobs;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldBeEncrypted;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use KorElf\TranslateLaravel\Contracts\TranslationCompletedListener; use KorElf\TranslateLaravel\DTO\AfterTranslateDto;
use KorElf\TranslateLaravel\DTO\Translated; use KorElf\TranslateLaravel\DTO\Translated;
use KorElf\TranslateLaravel\Exceptions\AfterTranslateException; use KorElf\TranslateLaravel\Exceptions\AfterTranslateException;
@ -21,14 +22,11 @@ final class AfterTranslate implements ShouldQueue, ShouldBeEncrypted
*/ */
public function __construct( public function __construct(
private readonly string $groupName, private readonly string $groupName,
private readonly TranslationCompletedListener $listener,
private readonly Translated $translated, private readonly Translated $translated,
private readonly AfterTranslateDto $afterTranslateDto
) { } ) { }
/** public function handle(Application $application): void
* Execute the job.
*/
public function handle(): void
{ {
$translated = []; $translated = [];
$data = Cache::get($this->groupName, []); $data = Cache::get($this->groupName, []);
@ -43,11 +41,15 @@ final class AfterTranslate implements ShouldQueue, ShouldBeEncrypted
$translated[$key] = implode(' ', $data[$key]); $translated[$key] = implode(' ', $data[$key]);
} }
if (empty($data)) { if (empty($data) || !empty($errors)) {
throw new AfterTranslateException('Part or all of the text has not been translated. Keys: ' . implode(', ', $errors)); throw new AfterTranslateException('Part or all of the text has not been translated. Keys: ' . implode(', ', $errors));
} }
Cache::forget($this->groupName); $objectAfterTranslate = $application->make($this->afterTranslateDto->getClassName());
if (!$objectAfterTranslate instanceof \KorElf\TranslateLaravel\Contracts\TranslationCompletedListener) {
throw new AfterTranslateException('The class must implement the \KorElf\TranslateLaravel\Contracts\TranslationCompletedListener interface.');
}
$objectAfterTranslate->onTranslationCompleted($translated, $this->afterTranslateDto->getData());
$this->listener->onTranslationCompleted($translated); Cache::forget($this->groupName);
} }
} }

View File

@ -10,7 +10,7 @@ use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Bus; use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use KorElf\TranslateLaravel\Contracts\TranslationCompletedListener; use KorElf\TranslateLaravel\DTO\AfterTranslateDto;
use KorElf\TranslateLaravel\DTO\ProcessTranslateDto; use KorElf\TranslateLaravel\DTO\ProcessTranslateDto;
use korElf\TranslateLaravel\DTO\RunTranslateDto; use korElf\TranslateLaravel\DTO\RunTranslateDto;
use KorElf\TranslateLaravel\DTO\Translated; use KorElf\TranslateLaravel\DTO\Translated;
@ -25,7 +25,7 @@ final class RunTranslate implements ShouldQueue, ShouldBeEncrypted
*/ */
public function __construct( public function __construct(
private readonly RunTranslateDto $runTranslateDto, private readonly RunTranslateDto $runTranslateDto,
private readonly TranslationCompletedListener $translationCompletedListener, private readonly AfterTranslateDto $afterTranslateDto,
) { } ) { }
/** /**
@ -55,7 +55,7 @@ final class RunTranslate implements ShouldQueue, ShouldBeEncrypted
} }
$translated->add($key, count($texts)); $translated->add($key, count($texts));
} }
$chains[] = new AfterTranslate($groupName, $this->translationCompletedListener, $translated); $chains[] = new AfterTranslate($groupName, $translated, $this->afterTranslateDto);
Bus::chain($chains)->dispatch(); Bus::chain($chains)->dispatch();
} }

View File

@ -4,10 +4,10 @@ namespace KorElf\TranslateLaravel\Translate;
use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Foundation\Application;
use Illuminate\Foundation\Bus\PendingDispatch; use Illuminate\Foundation\Bus\PendingDispatch;
use KorElf\TranslateLaravel\Contracts\CallbackAfterTranslated;
use KorElf\TranslateLaravel\Contracts\Translate;
use InvalidArgumentException; use InvalidArgumentException;
use KorElf\TranslateLaravel\Contracts\TranslationCompletedListener; use KorElf\TranslateLaravel\Contracts\TranslationCompletedListener;
use KorElf\TranslateLaravel\Contracts\Translate;
use KorElf\TranslateLaravel\DTO\AfterTranslateDto;
use KorElf\TranslateLaravel\DTO\RunTranslateDto; use KorElf\TranslateLaravel\DTO\RunTranslateDto;
use KorElf\TranslateLaravel\Jobs\RunTranslate; use KorElf\TranslateLaravel\Jobs\RunTranslate;
@ -68,9 +68,15 @@ final class TranslateManager
/** /**
* Run through queues. * Run through queues.
*/ */
public function runJob(RunTranslateDto $params, TranslationCompletedListener $completedListener): PendingDispatch public function runJob(RunTranslateDto $params, AfterTranslateDto $afterTranslateDto): PendingDispatch
{ {
return RunTranslate::dispatch($params, $completedListener); $className = $afterTranslateDto->getClassName();
if (!is_subclass_of($className, TranslationCompletedListener::class)) {
throw new InvalidArgumentException('The class ' . $className . ' must implement the \KorElf\TranslateLaravel\Contracts\Translate\TranslationCompletedListener interface.');
}
unset($className);
return RunTranslate::dispatch($params, $afterTranslateDto);
} }
public function getLimit(?string $driver = null): array public function getLimit(?string $driver = null): array