Merge pull request 'Version 1.1.0' (#2) from develop into main
Reviewed-on: #2
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
/vendor
 | 
			
		||||
							
								
								
									
										95
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										95
									
								
								README.md
									
									
									
									
									
								
							@@ -2,14 +2,99 @@
 | 
			
		||||
 | 
			
		||||
Библиотека для Laravel, что бы общаться с сервисом перевода от <a href="https://yandex.cloud/ru/docs/translate/" target="_blank">yandex</a>. В будущем (скорей всего в далёком будущем) планирую расширить поддержку разных сервисов перевода. Что бы можно было общаться через один интерфейс с разными сервисами.
 | 
			
		||||
 | 
			
		||||
Параметры в **.env**:
 | 
			
		||||
# Параметры в **.env**:
 | 
			
		||||
 | 
			
		||||
# TRANSLATE_SERVICE
 | 
			
		||||
### TRANSLATE_SERVICE
 | 
			
		||||
По умолчанию через какой сервис обращаться за переводом. На данный момент доступен только один сервис - **yandex**.
 | 
			
		||||
 | 
			
		||||
# TRANSLATE_YANDEX_FOLDER_ID
 | 
			
		||||
### TRANSLATE_YANDEX_FOLDER_ID
 | 
			
		||||
ID folder. Код можно увидеть в адресе console.yandex.cloud/folders/**{тут будет код}**.
 | 
			
		||||
 | 
			
		||||
# TRANSLATE_YANDEX_AUTHORIZED_KEY_PATH
 | 
			
		||||
### TRANSLATE_YANDEX_AUTHORIZED_KEY_PATH
 | 
			
		||||
Абсолютный путь в рамках приложения Laravel к файлу **authorized_key.json**.
 | 
			
		||||
Например: положили файл в корень Laravel. Тогда будет путь такой: **/authorized_key.json**.
 | 
			
		||||
Например: положили файл в корень Laravel. Тогда будет путь такой: **/authorized_key.json**.
 | 
			
		||||
 | 
			
		||||
### TRANSLATE_YANDEX_LIMIT_MAX_REQUEST
 | 
			
		||||
Максимальное количество запросов в период, который указан в TRANSLATE_YANDEX_LIMIT_RATE_SECONDS. По умолчанию 20 запросов в секунду. **На данный момент работает только перевод через систему очередей.**
 | 
			
		||||
 | 
			
		||||
### TRANSLATE_YANDEX_LIMIT_RATE_SECONDS
 | 
			
		||||
Период в котором считается максимальное количество запросов. По умолчанию стоит секунда. **На данный момент работает только перевод через систему очередей.**
 | 
			
		||||
 | 
			
		||||
### TRANSLATE_YANDEX_LIMIT_MAX_SYMBOLS
 | 
			
		||||
Максимальное количество символов за один запрос. Если превышает, то делится на две части и делает по очереди два запроса. По умолчанию стоит 9000 символов. **На данный момент работает только перевод через систему очередей.**
 | 
			
		||||
 | 
			
		||||
# Методы
 | 
			
		||||
### Перевести обычный текст
 | 
			
		||||
> \KorElf\TranslateLaravel\Facades\Translate::translateText(
 | 
			
		||||
> <br>      string | array \$text, 
 | 
			
		||||
> <br>      string            \$targetLanguageCode, 
 | 
			
		||||
> <br>      ?string          \$sourceLanguageCode = null
 | 
			
		||||
> <br>): string | array
 | 
			
		||||
 | 
			
		||||
**\$text** - текст который нужно перевести.
 | 
			
		||||
<br>**\$targetLanguageCode** - язык на который надо перевести.
 | 
			
		||||
<br>**\$sourceLanguageCode** - язык с которого надо перевести. Если **null**, то сервис сам пытается определить язык.
 | 
			
		||||
 | 
			
		||||
<br>
 | 
			
		||||
 | 
			
		||||
### Перевести текст в формате HTML
 | 
			
		||||
> \KorElf\TranslateLaravel\Facades\Translate::translateHtml(
 | 
			
		||||
> <br>      string | array \$text,
 | 
			
		||||
> <br>      string            \$targetLanguageCode,
 | 
			
		||||
> <br>      ?string          \$sourceLanguageCode = null
 | 
			
		||||
> <br>): string | array
 | 
			
		||||
 | 
			
		||||
**\$text** - текст который нужно перевести.
 | 
			
		||||
<br>**\$targetLanguageCode** - язык на который надо перевести.
 | 
			
		||||
<br>**\$sourceLanguageCode** - язык с которого надо перевести. Если **null**, то сервис сам пытается определить язык.
 | 
			
		||||
 | 
			
		||||
<br>
 | 
			
		||||
 | 
			
		||||
### Получить список языков, который сервис поддерживает
 | 
			
		||||
> \KorElf\TranslateLaravel\Facades\Translate::listLanguages(): \KorElf\TranslateLaravel\DTO\Languages
 | 
			
		||||
 | 
			
		||||
<br>
 | 
			
		||||
 | 
			
		||||
### Перевести с помощью очередей (Queues)
 | 
			
		||||
> \KorElf\TranslateLaravel\Facades\Translate::runJob(
 | 
			
		||||
> <br>      \KorElf\TranslateLaravel\DTO\RunTranslateDto                             \$params,
 | 
			
		||||
> <br>      \KorElf\TranslateLaravel\Contracts\TranslationCompletedListener \$completedListener
 | 
			
		||||
<br>): \Illuminate\Foundation\Bus\PendingDispatch
 | 
			
		||||
 | 
			
		||||
**\$params** - параметры перевода.
 | 
			
		||||
<br>**\$completedListener** - после завершения перевода отправляет результат в этот объект. Объект должен соблюдать контракт **\KorElf\TranslateLaravel\Contracts\TranslationCompletedListener**.
 | 
			
		||||
 | 
			
		||||
**Пример:**
 | 
			
		||||
> Создаём файл TranslationListener например в папке app/Services
 | 
			
		||||
> 
 | 
			
		||||
>       <?php declare(strict_types=1);
 | 
			
		||||
>
 | 
			
		||||
>       namespace App\Services;
 | 
			
		||||
>
 | 
			
		||||
>       use Illuminate\Support\Facades\Log;
 | 
			
		||||
>       use KorElf\TranslateLaravel\Contracts\TranslationCompletedListener;
 | 
			
		||||
>
 | 
			
		||||
>       final class TranslationListener implements TranslationCompletedListener
 | 
			
		||||
>       {
 | 
			
		||||
>           public function onTranslationCompleted(array $translatedText): void
 | 
			
		||||
>           {
 | 
			
		||||
>               foreach ($translatedText as $translatedTextKey => $translatedTextValue) {
 | 
			
		||||
>                   Log::info($translatedTextKey . ': ' . $translatedTextValue);
 | 
			
		||||
>               }
 | 
			
		||||
>           }
 | 
			
		||||
>       }
 | 
			
		||||
> 
 | 
			
		||||
> Потом например в каком-то контроллере (а лучше конечно в сервисе) пишем такой метод
 | 
			
		||||
>
 | 
			
		||||
>     public function sendingForTranslation(\App\Services\TranslationListener $translationListener): View
 | 
			
		||||
>     {
 | 
			
		||||
>          // Вначале создаём объект с параметрами
 | 
			
		||||
>         $params = (new \KorElf\TranslateLaravel\DTO\RunTranslateDto)
 | 
			
		||||
>            ->addParamText('title', 'Заголовок', 'en', 'ru')
 | 
			
		||||
>            ->addParamHtml('content', '<p>Привет, Мир!</p>', 'en', 'ru');
 | 
			
		||||
> 
 | 
			
		||||
>         // Отправляем на очередь
 | 
			
		||||
>         \KorElf\TranslateLaravel\Facades\Translate::runJob($params, $translationListener);
 | 
			
		||||
>         
 | 
			
		||||
>         return view('success');
 | 
			
		||||
>     }
 | 
			
		||||
 
 | 
			
		||||
@@ -21,18 +21,20 @@
 | 
			
		||||
    "php": "^8.2",
 | 
			
		||||
    "illuminate/support": "^10.0|^11.0",
 | 
			
		||||
    "guzzlehttp/guzzle": "^7.0.1",
 | 
			
		||||
    "web-token/jwt-framework": "^3.0"
 | 
			
		||||
    "web-token/jwt-framework": "^3.0",
 | 
			
		||||
    "ext-libxml": "^2.11.7",
 | 
			
		||||
    "ext-dom": "^2.11.7"
 | 
			
		||||
  },
 | 
			
		||||
  "extra": {
 | 
			
		||||
    "laravel": {
 | 
			
		||||
      "providers": [
 | 
			
		||||
        "korElf\\TranslateLaravel\\TranslateLaravelProvider"
 | 
			
		||||
        "KorElf\\TranslateLaravel\\TranslateLaravelProvider"
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "autoload": {
 | 
			
		||||
    "psr-4": {
 | 
			
		||||
      "korElf\\TranslateLaravel\\": "src/"
 | 
			
		||||
      "KorElf\\TranslateLaravel\\": "src/"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -24,10 +24,15 @@ return [
 | 
			
		||||
 | 
			
		||||
    'services' => [
 | 
			
		||||
        'yandex' => [
 | 
			
		||||
            'driver' => '\korElf\TranslateLaravel\Translate\YandexDriver',
 | 
			
		||||
            'driver' => '\KorElf\TranslateLaravel\Translate\YandexDriver',
 | 
			
		||||
            'config' => [
 | 
			
		||||
                'folder_id'           => env('TRANSLATE_YANDEX_FOLDER_ID'),
 | 
			
		||||
                'authorized_key_path' => base_path(env('TRANSLATE_YANDEX_AUTHORIZED_KEY_PATH')),
 | 
			
		||||
                'limit' => [
 | 
			
		||||
                    'max_request'  => (int) env('TRANSLATE_YANDEX_LIMIT_MAX_REQUEST', 20),
 | 
			
		||||
                    'rate_seconds' => (int) env('TRANSLATE_YANDEX_LIMIT_RATE_SECONDS', 1),
 | 
			
		||||
                    'max_symbols' => (int) env('TRANSLATE_YANDEX_LIMIT_MAX_SYMBOLS', 9000),
 | 
			
		||||
                ],
 | 
			
		||||
            ],
 | 
			
		||||
        ],
 | 
			
		||||
    ],
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								src/Contracts/ProcessTranslateContract.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/Contracts/ProcessTranslateContract.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace KorElf\TranslateLaravel\Contracts;
 | 
			
		||||
 | 
			
		||||
use KorElf\TranslateLaravel\DTO\ProcessTranslateLimit;
 | 
			
		||||
 | 
			
		||||
interface ProcessTranslateContract
 | 
			
		||||
{
 | 
			
		||||
    public function getLimited(): ProcessTranslateLimit;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace korElf\TranslateLaravel\Contracts;
 | 
			
		||||
namespace KorElf\TranslateLaravel\Contracts;
 | 
			
		||||
 | 
			
		||||
use korElf\TranslateLaravel\DTO\Languages;
 | 
			
		||||
use KorElf\TranslateLaravel\DTO\Languages;
 | 
			
		||||
use Illuminate\Contracts\Foundation\Application;
 | 
			
		||||
 | 
			
		||||
interface Translate
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								src/Contracts/TranslationCompletedListener.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/Contracts/TranslationCompletedListener.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace KorElf\TranslateLaravel\Contracts;
 | 
			
		||||
 | 
			
		||||
interface TranslationCompletedListener
 | 
			
		||||
{
 | 
			
		||||
    public function onTranslationCompleted(array $translatedText): void;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace korElf\TranslateLaravel\DTO;
 | 
			
		||||
namespace KorElf\TranslateLaravel\DTO;
 | 
			
		||||
 | 
			
		||||
final class Languages
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										41
									
								
								src/DTO/Parameter.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/DTO/Parameter.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace KorElf\TranslateLaravel\DTO;
 | 
			
		||||
 | 
			
		||||
use KorElf\TranslateLaravel\Enums\TextType;
 | 
			
		||||
 | 
			
		||||
final readonly class Parameter
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private string   $text,
 | 
			
		||||
        private TextType $textType,
 | 
			
		||||
        private string   $targetLanguageCode,
 | 
			
		||||
        private ?string  $sourceLanguageCode = null,
 | 
			
		||||
        private ?string  $driver = null
 | 
			
		||||
    ) { }
 | 
			
		||||
 | 
			
		||||
    public function getText(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->text;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getTextType(): TextType
 | 
			
		||||
    {
 | 
			
		||||
        return $this->textType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getTargetLanguageCode(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->targetLanguageCode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getSourceLanguageCode(): ?string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->sourceLanguageCode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getDriver(): ?string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->driver;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										59
									
								
								src/DTO/ProcessTranslateDto.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/DTO/ProcessTranslateDto.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace KorElf\TranslateLaravel\DTO;
 | 
			
		||||
 | 
			
		||||
use KorElf\TranslateLaravel\Enums\TextType;
 | 
			
		||||
 | 
			
		||||
final readonly class ProcessTranslateDto
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private string   $groupName,
 | 
			
		||||
        private string   $key,
 | 
			
		||||
        private int      $part,
 | 
			
		||||
        private string   $text,
 | 
			
		||||
        private TextType $textType,
 | 
			
		||||
        private string   $targetLanguageCode,
 | 
			
		||||
        private ?string  $sourceLanguageCode = null,
 | 
			
		||||
        private ?string  $driver = null
 | 
			
		||||
    ) { }
 | 
			
		||||
 | 
			
		||||
    public function getGroupName(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->groupName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getKey(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->key;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getPart(): int
 | 
			
		||||
    {
 | 
			
		||||
        return $this->part;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getText(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->text;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getTextType(): TextType
 | 
			
		||||
    {
 | 
			
		||||
        return $this->textType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getTargetLanguageCode(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->targetLanguageCode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getSourceLanguageCode(): ?string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->sourceLanguageCode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getDriver(): ?string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->driver;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								src/DTO/ProcessTranslateLimit.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/DTO/ProcessTranslateLimit.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace KorElf\TranslateLaravel\DTO;
 | 
			
		||||
 | 
			
		||||
final readonly class ProcessTranslateLimit
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private int    $maxRequest,
 | 
			
		||||
        private int    $rateSeconds,
 | 
			
		||||
        private string $driver,
 | 
			
		||||
    ) { }
 | 
			
		||||
 | 
			
		||||
    public function getMaxRequest(): int
 | 
			
		||||
    {
 | 
			
		||||
        return $this->maxRequest;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getRateSeconds(): int
 | 
			
		||||
    {
 | 
			
		||||
        return $this->rateSeconds;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getDriver(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->driver;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								src/DTO/RunTranslateDto.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/DTO/RunTranslateDto.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace KorElf\TranslateLaravel\DTO;
 | 
			
		||||
 | 
			
		||||
use KorElf\TranslateLaravel\Enums\TextType;
 | 
			
		||||
use KorElf\TranslateLaravel\Exceptions\RunTranslateDtoException;
 | 
			
		||||
 | 
			
		||||
final class RunTranslateDto
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @var array [key => \KorElf\TranslateLaravel\DTO\Parameter]
 | 
			
		||||
     */
 | 
			
		||||
    private array $params = [];
 | 
			
		||||
 | 
			
		||||
    public function addParam(
 | 
			
		||||
        string   $key,
 | 
			
		||||
        string   $text,
 | 
			
		||||
        TextType $textType,
 | 
			
		||||
        string   $targetLanguageCode,
 | 
			
		||||
        ?string  $sourceLanguageCode = null,
 | 
			
		||||
        ?string  $driver = null
 | 
			
		||||
    ): self
 | 
			
		||||
    {
 | 
			
		||||
        if (isset($this->params[$key])) {
 | 
			
		||||
            throw new RunTranslateDtoException('Duplicate key: ' . $key);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->params[$key] = new Parameter(
 | 
			
		||||
            $text,
 | 
			
		||||
            $textType,
 | 
			
		||||
            $targetLanguageCode,
 | 
			
		||||
            $sourceLanguageCode,
 | 
			
		||||
            $driver,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addParamHtml(
 | 
			
		||||
        string   $key,
 | 
			
		||||
        string   $text,
 | 
			
		||||
        string   $targetLanguageCode,
 | 
			
		||||
        ?string  $sourceLanguageCode = null,
 | 
			
		||||
        ?string  $driver = null
 | 
			
		||||
    ): self
 | 
			
		||||
    {
 | 
			
		||||
        return $this->addParam($key, $text, TextType::Html, $targetLanguageCode, $sourceLanguageCode, $driver);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addParamText(
 | 
			
		||||
        string   $key,
 | 
			
		||||
        string   $text,
 | 
			
		||||
        string   $targetLanguageCode,
 | 
			
		||||
        ?string  $sourceLanguageCode = null,
 | 
			
		||||
        ?string  $driver = null
 | 
			
		||||
    ): self
 | 
			
		||||
    {
 | 
			
		||||
        return $this->addParam($key, $text, TextType::Text, $targetLanguageCode, $sourceLanguageCode, $driver);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getParams(): array
 | 
			
		||||
    {
 | 
			
		||||
        return $this->params;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								src/DTO/Translated.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/DTO/Translated.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace KorElf\TranslateLaravel\DTO;
 | 
			
		||||
 | 
			
		||||
final class Translated
 | 
			
		||||
{
 | 
			
		||||
    private array $data = [];
 | 
			
		||||
 | 
			
		||||
    public function add(string $key, int $parts): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->data[$key] = $parts;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function toArray(): array
 | 
			
		||||
    {
 | 
			
		||||
        return $this->data;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								src/Enums/TextType.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/Enums/TextType.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace KorElf\TranslateLaravel\Enums;
 | 
			
		||||
 | 
			
		||||
enum TextType: string
 | 
			
		||||
{
 | 
			
		||||
    case Text = 'text';
 | 
			
		||||
    case Html = 'html';
 | 
			
		||||
 | 
			
		||||
    public function functionName(): string
 | 
			
		||||
    {
 | 
			
		||||
        return match ($this) {
 | 
			
		||||
            self::Text => 'translateText',
 | 
			
		||||
            self::Html => 'translateHtml',
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								src/Exceptions/AfterTranslateException.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/Exceptions/AfterTranslateException.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace KorElf\TranslateLaravel\Exceptions;
 | 
			
		||||
 | 
			
		||||
use RuntimeException;
 | 
			
		||||
 | 
			
		||||
final class AfterTranslateException extends RuntimeException
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								src/Exceptions/RunTranslateDtoException.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/Exceptions/RunTranslateDtoException.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace KorElf\TranslateLaravel\Exceptions;
 | 
			
		||||
 | 
			
		||||
use RuntimeException;
 | 
			
		||||
 | 
			
		||||
final class RunTranslateDtoException extends RuntimeException
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace korElf\TranslateLaravel\Exceptions;
 | 
			
		||||
namespace KorElf\TranslateLaravel\Exceptions;
 | 
			
		||||
 | 
			
		||||
use RuntimeException;
 | 
			
		||||
 | 
			
		||||
class TranslateException extends RuntimeException
 | 
			
		||||
final class TranslateException extends RuntimeException
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,18 +1,22 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace korElf\TranslateLaravel\Facades;
 | 
			
		||||
namespace KorElf\TranslateLaravel\Facades;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Support\Facades\Facade;
 | 
			
		||||
use KorElf\TranslateLaravel\Contracts\TranslationCompletedListener;
 | 
			
		||||
use KorElf\TranslateLaravel\DTO\RunTranslateDto;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @method static \korElf\TranslateLaravel\Contracts\Translate service(?string $name = null)
 | 
			
		||||
 * @method static \korElf\TranslateLaravel\Contracts\Translate resolve(string $name)
 | 
			
		||||
 * @method static \KorElf\TranslateLaravel\Contracts\Translate service(?string $name = null)
 | 
			
		||||
 * @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 translateHtml(string|array $text, string $targetLanguageCode, ?string $sourceLanguageCode = null)
 | 
			
		||||
 * @method static \korElf\TranslateLaravel\DTO\Languages listLanguages()
 | 
			
		||||
 * @method static \Illuminate\Foundation\Bus\PendingDispatch runJob(RunTranslateDto $params, TranslationCompletedListener $completedListener)
 | 
			
		||||
 * @method static \KorElf\TranslateLaravel\DTO\Languages listLanguages()
 | 
			
		||||
 * @method static string getDefaultDriver()
 | 
			
		||||
 * @method static void setDefaultDriver(string $name)
 | 
			
		||||
 * @method static void purge(?string $name)
 | 
			
		||||
 * @method static array getLimit(?string $driver)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
final class Translate extends Facade
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										53
									
								
								src/Jobs/AfterTranslate.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/Jobs/AfterTranslate.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace KorElf\TranslateLaravel\Jobs;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Bus\Queueable;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
			
		||||
use Illuminate\Queue\InteractsWithQueue;
 | 
			
		||||
use Illuminate\Support\Facades\Cache;
 | 
			
		||||
use KorElf\TranslateLaravel\Contracts\TranslationCompletedListener;
 | 
			
		||||
use KorElf\TranslateLaravel\DTO\Translated;
 | 
			
		||||
use KorElf\TranslateLaravel\Exceptions\AfterTranslateException;
 | 
			
		||||
 | 
			
		||||
final class AfterTranslate implements ShouldQueue, ShouldBeEncrypted
 | 
			
		||||
{
 | 
			
		||||
    use Dispatchable, InteractsWithQueue, Queueable;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new job instance.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly string                       $groupName,
 | 
			
		||||
        private readonly TranslationCompletedListener $listener,
 | 
			
		||||
        private readonly Translated                   $translated,
 | 
			
		||||
    ) { }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Execute the job.
 | 
			
		||||
     */
 | 
			
		||||
    public function handle(): void
 | 
			
		||||
    {
 | 
			
		||||
        $translated = [];
 | 
			
		||||
        $data = Cache::get($this->groupName, []);
 | 
			
		||||
 | 
			
		||||
        $errors = [];
 | 
			
		||||
        foreach ($this->translated->toArray() as $key => $parts) {
 | 
			
		||||
            if (!isset($data[$key]) || count($data[$key]) !== $parts) {
 | 
			
		||||
                $errors[] = $key;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $translated[$key] = implode(' ', $data[$key]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (empty($data)) {
 | 
			
		||||
            throw new AfterTranslateException('Part or all of the text has not been translated. Keys: ' . implode(', ', $errors));
 | 
			
		||||
        }
 | 
			
		||||
        Cache::forget($this->groupName);
 | 
			
		||||
 | 
			
		||||
        $this->listener->onTranslationCompleted($translated);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								src/Jobs/ProcessTranslate.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/Jobs/ProcessTranslate.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace KorElf\TranslateLaravel\Jobs;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Bus\Queueable;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
			
		||||
use Illuminate\Queue\InteractsWithQueue;
 | 
			
		||||
use Illuminate\Queue\Middleware\RateLimited;
 | 
			
		||||
use Illuminate\Support\Facades\Cache;
 | 
			
		||||
use KorElf\TranslateLaravel\Contracts\ProcessTranslateContract;
 | 
			
		||||
use KorElf\TranslateLaravel\DTO\ProcessTranslateDto;
 | 
			
		||||
use KorElf\TranslateLaravel\DTO\ProcessTranslateLimit;
 | 
			
		||||
use KorElf\TranslateLaravel\Facades\Translate;
 | 
			
		||||
 | 
			
		||||
final class ProcessTranslate implements ShouldQueue, ShouldBeEncrypted, ProcessTranslateContract
 | 
			
		||||
{
 | 
			
		||||
    use Dispatchable, InteractsWithQueue, Queueable;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new job instance.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly ProcessTranslateDto $param
 | 
			
		||||
    ) { }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the middleware the job should pass through.
 | 
			
		||||
     *
 | 
			
		||||
     * @return array<int, object>
 | 
			
		||||
     */
 | 
			
		||||
    public function middleware(): array
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            new RateLimited('kor-elf-translate'),
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getLimited(): ProcessTranslateLimit
 | 
			
		||||
    {
 | 
			
		||||
        $driver = $this->param->getDriver();
 | 
			
		||||
        if ($driver === null) {
 | 
			
		||||
            $driver = Translate::getDefaultDriver();
 | 
			
		||||
        }
 | 
			
		||||
        $limit = Translate::getLimit($driver);
 | 
			
		||||
 | 
			
		||||
        return new ProcessTranslateLimit(
 | 
			
		||||
            maxRequest: $limit['max_request'] ?? 1000000000,
 | 
			
		||||
            rateSeconds: $limit['rate_seconds'] ?? 1,
 | 
			
		||||
            driver: $driver,
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Execute the job.
 | 
			
		||||
     */
 | 
			
		||||
    public function handle(): void
 | 
			
		||||
    {
 | 
			
		||||
        $param = $this->param;
 | 
			
		||||
        $groupName = $param->getGroupName();
 | 
			
		||||
 | 
			
		||||
        $translated = Cache::get($groupName, []);
 | 
			
		||||
        if (!isset($translated[$param->getKey()])) {
 | 
			
		||||
            $translated[$param->getKey()] = [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $translate = Translate::service($param->getDriver());
 | 
			
		||||
        $function = $param->getTextType()->functionName();
 | 
			
		||||
        $key = $param->getKey();
 | 
			
		||||
        $part = $param->getPart();
 | 
			
		||||
 | 
			
		||||
        $translated[$key][$part] = $param->getText();
 | 
			
		||||
        if (\trim($param->getText()) !== '') {
 | 
			
		||||
 | 
			
		||||
            $translated[$key][$part] = $translate->{$function}(
 | 
			
		||||
                $param->getText(),
 | 
			
		||||
                $param->getTargetLanguageCode(),
 | 
			
		||||
                $param->getSourceLanguageCode()
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Cache::put($groupName, $translated, 86400);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										62
									
								
								src/Jobs/RunTranslate.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/Jobs/RunTranslate.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace KorElf\TranslateLaravel\Jobs;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Bus\Queueable;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
			
		||||
use Illuminate\Queue\InteractsWithQueue;
 | 
			
		||||
use Illuminate\Queue\SerializesModels;
 | 
			
		||||
use Illuminate\Support\Facades\Bus;
 | 
			
		||||
use Illuminate\Support\Str;
 | 
			
		||||
use KorElf\TranslateLaravel\Contracts\TranslationCompletedListener;
 | 
			
		||||
use KorElf\TranslateLaravel\DTO\ProcessTranslateDto;
 | 
			
		||||
use korElf\TranslateLaravel\DTO\RunTranslateDto;
 | 
			
		||||
use KorElf\TranslateLaravel\DTO\Translated;
 | 
			
		||||
use KorElf\TranslateLaravel\Translate\SplitTextIntoPartsCommand;
 | 
			
		||||
 | 
			
		||||
final class RunTranslate implements ShouldQueue, ShouldBeEncrypted
 | 
			
		||||
{
 | 
			
		||||
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new job instance.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly RunTranslateDto              $runTranslateDto,
 | 
			
		||||
        private readonly TranslationCompletedListener $translationCompletedListener,
 | 
			
		||||
    ) { }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Execute the job.
 | 
			
		||||
     */
 | 
			
		||||
    public function handle(SplitTextIntoPartsCommand $splitTextIntoPartsCommand): void
 | 
			
		||||
    {
 | 
			
		||||
        $chains = [];
 | 
			
		||||
        $groupName = 'KorElf\TranslateLaravel\Jobs-' . Str::uuid()->toString();
 | 
			
		||||
        $translated = new Translated();
 | 
			
		||||
        foreach ($this->runTranslateDto->getParams() as $key => $param) {
 | 
			
		||||
            /* @var \KorElf\TranslateLaravel\DTO\Parameter $param */
 | 
			
		||||
 | 
			
		||||
            $texts = $splitTextIntoPartsCommand->execute($param->getText(), $param->getTextType(), $param->getDriver());
 | 
			
		||||
            foreach ($texts as $part => $partText) {
 | 
			
		||||
                $processTranslateDto = new ProcessTranslateDto(
 | 
			
		||||
                    $groupName,
 | 
			
		||||
                    $key,
 | 
			
		||||
                    $part,
 | 
			
		||||
                    $partText,
 | 
			
		||||
                    $param->getTextType(),
 | 
			
		||||
                    $param->getTargetLanguageCode(),
 | 
			
		||||
                    $param->getSourceLanguageCode(),
 | 
			
		||||
                    $param->getDriver(),
 | 
			
		||||
                );
 | 
			
		||||
                $chains[] = new ProcessTranslate($processTranslateDto);
 | 
			
		||||
            }
 | 
			
		||||
            $translated->add($key, count($texts));
 | 
			
		||||
        }
 | 
			
		||||
        $chains[] = new AfterTranslate($groupName, $this->translationCompletedListener, $translated);
 | 
			
		||||
 | 
			
		||||
        Bus::chain($chains)->dispatch();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										115
									
								
								src/Translate/SplitTextIntoPartsCommand.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								src/Translate/SplitTextIntoPartsCommand.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,115 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace KorElf\TranslateLaravel\Translate;
 | 
			
		||||
 | 
			
		||||
use KorElf\TranslateLaravel\Enums\TextType;
 | 
			
		||||
use KorElf\TranslateLaravel\Facades\Translate;
 | 
			
		||||
use DOMDocument;
 | 
			
		||||
 | 
			
		||||
final readonly class SplitTextIntoPartsCommand
 | 
			
		||||
{
 | 
			
		||||
    public function execute(string $text, TextType $textType, ?string $driver): array
 | 
			
		||||
    {
 | 
			
		||||
        $maxLength = Translate::getLimit($driver);
 | 
			
		||||
        $maxLength = $maxLength['max_symbols'] ?? null;
 | 
			
		||||
        if ($maxLength === null || $maxLength > mb_strlen($text)) {
 | 
			
		||||
            return [$text];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($textType === TextType::Html) {
 | 
			
		||||
            return $this->splitHtmlText($text, $maxLength);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this->splitTextBySentences($text, $maxLength);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function splitTextBySentences(string $text, int $maxLength): array
 | 
			
		||||
    {
 | 
			
		||||
        // Common expression for searching for sentences.
 | 
			
		||||
        $sentenceEndings = '/(?<=[.?!])\s+(?=[A-ZА-Я])/u';
 | 
			
		||||
 | 
			
		||||
        //Dividing the text into sentences
 | 
			
		||||
        $sentences = preg_split($sentenceEndings, $text, -1, PREG_SPLIT_NO_EMPTY);
 | 
			
		||||
 | 
			
		||||
        $parts = [];
 | 
			
		||||
        $currentPart = '';
 | 
			
		||||
 | 
			
		||||
        foreach ($sentences as $sentence) {
 | 
			
		||||
            // If adding a sentence does not exceed the limit, add it to the current part.
 | 
			
		||||
            if (mb_strlen($currentPart . ' ' . $sentence) <= $maxLength) {
 | 
			
		||||
                $currentPart .= (empty($currentPart) ? '' : ' ') . $sentence;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Otherwise, save the current part and start a new one.
 | 
			
		||||
            if (!empty($currentPart)) {
 | 
			
		||||
                $parts[] = $currentPart;
 | 
			
		||||
                $currentPart = '';
 | 
			
		||||
            }
 | 
			
		||||
            $currentPart = $sentence;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!empty($currentPart)) {
 | 
			
		||||
            $parts[] = $currentPart;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $parts;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function splitHtmlText(string $html, int $maxLength): array
 | 
			
		||||
    {
 | 
			
		||||
        libxml_use_internal_errors(true);
 | 
			
		||||
 | 
			
		||||
        $dom = new DOMDocument();
 | 
			
		||||
        $dom->loadHTML(mb_convert_encoding('<body>' . $html . '</body>', 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
 | 
			
		||||
 | 
			
		||||
        $parts = [];
 | 
			
		||||
        $currentPart = new DOMDocument();
 | 
			
		||||
        $currentLength = 0;
 | 
			
		||||
 | 
			
		||||
        // Iterate through all child nodes of the root element
 | 
			
		||||
        foreach ($dom->documentElement->childNodes as $node) {
 | 
			
		||||
            if ($node->nodeType === XML_TEXT_NODE || $node->nodeType === XML_CDATA_SECTION_NODE) {
 | 
			
		||||
                // Dividing text nodes into sentences
 | 
			
		||||
                $sentences = preg_split('/(?<=[.?!])\s+(?=[A-ZА-Я])/', $node->textContent, -1, PREG_SPLIT_NO_EMPTY);
 | 
			
		||||
 | 
			
		||||
                foreach ($sentences as $sentence) {
 | 
			
		||||
                    $sentenceHtml = htmlspecialchars($sentence);
 | 
			
		||||
                    if ($currentLength + mb_strlen($sentenceHtml) > $maxLength) {
 | 
			
		||||
                        $parts[] = $currentPart->saveHTML();
 | 
			
		||||
 | 
			
		||||
                        // Start new part
 | 
			
		||||
                        $currentPart = new DOMDocument();
 | 
			
		||||
                        $currentLength = 0;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    $textNode = $currentPart->createTextNode($sentence . ' ');
 | 
			
		||||
                    $currentPart->appendChild($textNode);
 | 
			
		||||
                    $currentLength += mb_strlen($sentenceHtml);
 | 
			
		||||
                }
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $nodeHtml = $dom->saveHTML($node);
 | 
			
		||||
 | 
			
		||||
            if ($currentLength + mb_strlen($nodeHtml) > $maxLength) {
 | 
			
		||||
                $parts[] = $currentPart->saveHTML();
 | 
			
		||||
 | 
			
		||||
                // Start new part
 | 
			
		||||
                $currentPart = new DOMDocument();
 | 
			
		||||
                $currentLength = mb_strlen($nodeHtml);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $currentPart->appendChild($currentPart->importNode($node, true));
 | 
			
		||||
            $currentLength += mb_strlen($nodeHtml);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($currentPart->hasChildNodes()) {
 | 
			
		||||
            $parts[] = $currentPart->saveHTML();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        libxml_clear_errors();
 | 
			
		||||
 | 
			
		||||
        return $parts;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +1,15 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace korElf\TranslateLaravel\Translate;
 | 
			
		||||
namespace KorElf\TranslateLaravel\Translate;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Contracts\Foundation\Application;
 | 
			
		||||
use korElf\TranslateLaravel\Contracts\Translate;
 | 
			
		||||
use Illuminate\Foundation\Bus\PendingDispatch;
 | 
			
		||||
use KorElf\TranslateLaravel\Contracts\CallbackAfterTranslated;
 | 
			
		||||
use KorElf\TranslateLaravel\Contracts\Translate;
 | 
			
		||||
use InvalidArgumentException;
 | 
			
		||||
use KorElf\TranslateLaravel\Contracts\TranslationCompletedListener;
 | 
			
		||||
use KorElf\TranslateLaravel\DTO\RunTranslateDto;
 | 
			
		||||
use KorElf\TranslateLaravel\Jobs\RunTranslate;
 | 
			
		||||
 | 
			
		||||
final class TranslateManager
 | 
			
		||||
{
 | 
			
		||||
@@ -44,7 +49,7 @@ final class TranslateManager
 | 
			
		||||
        $config = $this->getConfig($name);
 | 
			
		||||
 | 
			
		||||
        if (\is_null($config)) {
 | 
			
		||||
            throw new InvalidArgumentException("Translate service [{$name}] is not defined.");
 | 
			
		||||
            throw new InvalidArgumentException('Translate service [' . $name . '] is not defined.');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $config['driver']::init($this->app, $config['config']);
 | 
			
		||||
@@ -60,6 +65,25 @@ final class TranslateManager
 | 
			
		||||
        unset($this->translates[$name]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Run through queues.
 | 
			
		||||
     */
 | 
			
		||||
    public function runJob(RunTranslateDto $params, TranslationCompletedListener $completedListener): PendingDispatch
 | 
			
		||||
    {
 | 
			
		||||
        return RunTranslate::dispatch($params, $completedListener);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getLimit(?string $driver = null): array
 | 
			
		||||
    {
 | 
			
		||||
        if ($driver === null) {
 | 
			
		||||
            $driver = $this->getDefaultDriver();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $config = $this->getConfig($driver);
 | 
			
		||||
 | 
			
		||||
        return $config['config']['limit'] ?? [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Dynamically call the default driver instance.
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace korElf\TranslateLaravel\Translate\Yandex;
 | 
			
		||||
namespace KorElf\TranslateLaravel\Translate\Yandex;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Support\Facades\Http;
 | 
			
		||||
use Illuminate\Support\Facades\Cache;
 | 
			
		||||
@@ -10,15 +10,15 @@ use Jose\Component\KeyManagement\JWKFactory;
 | 
			
		||||
use Jose\Component\Signature\Algorithm\PS256;
 | 
			
		||||
use Jose\Component\Signature\JWSBuilder;
 | 
			
		||||
use Jose\Component\Signature\Serializer\CompactSerializer;
 | 
			
		||||
use korElf\TranslateLaravel\Exceptions\TranslateException;
 | 
			
		||||
use KorElf\TranslateLaravel\Exceptions\TranslateException;
 | 
			
		||||
 | 
			
		||||
final class Connection
 | 
			
		||||
{
 | 
			
		||||
    private readonly string $path;
 | 
			
		||||
    private readonly string $folderId;
 | 
			
		||||
    private readonly string $privateKey;
 | 
			
		||||
    private readonly string $keyId;
 | 
			
		||||
    private readonly string $serviceAccountId;
 | 
			
		||||
    private string $path;
 | 
			
		||||
    private string $folderId;
 | 
			
		||||
    private string $privateKey;
 | 
			
		||||
    private string $keyId;
 | 
			
		||||
    private string $serviceAccountId;
 | 
			
		||||
 | 
			
		||||
    public function __construct(string $path, string $folderId, string $privateKey, string $keyId, string $serviceAccountId)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace korElf\TranslateLaravel\Translate;
 | 
			
		||||
namespace KorElf\TranslateLaravel\Translate;
 | 
			
		||||
 | 
			
		||||
use korElf\TranslateLaravel\Contracts\Translate;
 | 
			
		||||
use korElf\TranslateLaravel\DTO\Languages;
 | 
			
		||||
use korElf\TranslateLaravel\Exceptions\TranslateException;
 | 
			
		||||
use korElf\TranslateLaravel\Translate\Yandex\Connection;
 | 
			
		||||
use KorElf\TranslateLaravel\Contracts\Translate;
 | 
			
		||||
use KorElf\TranslateLaravel\DTO\Languages;
 | 
			
		||||
use KorElf\TranslateLaravel\Exceptions\TranslateException;
 | 
			
		||||
use KorElf\TranslateLaravel\Translate\Yandex\Connection;
 | 
			
		||||
use Illuminate\Contracts\Foundation\Application;
 | 
			
		||||
 | 
			
		||||
final class YandexDriver implements Translate
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,13 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace korElf\TranslateLaravel;
 | 
			
		||||
namespace KorElf\TranslateLaravel;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Cache\RateLimiting\Limit;
 | 
			
		||||
use Illuminate\Support\Facades\RateLimiter;
 | 
			
		||||
use Illuminate\Support\ServiceProvider;
 | 
			
		||||
use Illuminate\Contracts\Foundation\Application;
 | 
			
		||||
use korElf\TranslateLaravel\Translate\TranslateManager;
 | 
			
		||||
use KorElf\TranslateLaravel\Contracts\ProcessTranslateContract;
 | 
			
		||||
use KorElf\TranslateLaravel\Translate\TranslateManager;
 | 
			
		||||
 | 
			
		||||
final class TranslateLaravelProvider extends ServiceProvider
 | 
			
		||||
{
 | 
			
		||||
@@ -13,6 +16,15 @@ final class TranslateLaravelProvider extends ServiceProvider
 | 
			
		||||
        $this->publishes([
 | 
			
		||||
            __DIR__ . '/../config/translate.php' => config_path('translate.php'),
 | 
			
		||||
        ], 'config');
 | 
			
		||||
 | 
			
		||||
        RateLimiter::for('kor-elf-translate', function (ProcessTranslateContract $job) {
 | 
			
		||||
            $limited = $job->getLimited();
 | 
			
		||||
 | 
			
		||||
            return Limit::perSecond(
 | 
			
		||||
                $limited->getMaxRequest(),
 | 
			
		||||
                $limited->getRateSeconds()
 | 
			
		||||
            )->by($limited->getDriver());
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -26,7 +38,6 @@ final class TranslateLaravelProvider extends ServiceProvider
 | 
			
		||||
            __DIR__ . '/../config/translate.php',
 | 
			
		||||
            'translate'
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $this->app->singleton('translate', function (Application $app) {
 | 
			
		||||
            return new TranslateManager($app);
 | 
			
		||||
        });
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user