Skip to content

Commit 3cf9eda

Browse files
feat: add overwrite option to model_translate helper and LocaleModel trait
This commit adds the ability to overwrite specific attributes when creating a new translation row using the `model_translate` helper and `LocaleModel` trait. Key changes: - `model_translate` helper: Accepts an optional `$options` array (4th argument) and passes it to `ModelTranslateJob`. - `ModelTranslateJob`: Accepts `$options` in constructor and merges them with defaults before calling `translateTo`. - `LocaleModel` trait: The `translateTo` method now checks for an `overwrites` key in `$options`. If present, these values are filled into the new model instance before saving. - Added unit tests in `LocaleModelTest` to verify the new functionality. Co-authored-by: juzaweb <47020363+juzaweb@users.noreply.github.com>
1 parent d70b17c commit 3cf9eda

4 files changed

Lines changed: 64 additions & 5 deletions

File tree

helpers/helpers.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,7 @@ function current_actor(?string $guard = null): Guest|Authenticatable
857857
);
858858
}
859859

860-
function model_translate(CanBeTranslated $model, string $sourceLocale, string $targetLocale): TranslateHistory
860+
function model_translate(CanBeTranslated $model, string $sourceLocale, string $targetLocale, array $options = []): TranslateHistory
861861
{
862862
if ($sourceLocale === $targetLocale) {
863863
throw new InvalidArgumentException('Source locale and target locale must be different');
@@ -873,7 +873,7 @@ function model_translate(CanBeTranslated $model, string $sourceLocale, string $t
873873
]
874874
);
875875

876-
ModelTranslateJob::dispatch($model, $sourceLocale, $targetLocale);
876+
ModelTranslateJob::dispatch($model, $sourceLocale, $targetLocale, $options);
877877

878878
return $history;
879879
}

src/Traits/LocaleModel.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,16 @@ public function translateTo(string $locale, string $source = 'en', array $option
9595
}
9696

9797
return DB::transaction(
98-
function () use ($locale, $translated, $translateHistory) {
98+
function () use ($locale, $translated, $translateHistory, $options) {
9999
$newTranslation = $this->replicate($this->translateReplicateExcepts ?? []);
100100
$translated['source_id'] = $this->id;
101101
$newTranslation->fill($translated);
102102
$newTranslation->setAttribute($this->getLocaleKey(), $locale);
103103

104+
if (isset($options['overwrites']) && is_array($options['overwrites'])) {
105+
$newTranslation->fill($options['overwrites']);
106+
}
107+
104108
$saved = $newTranslation->save();
105109

106110
if ($saved && property_exists($this, 'mediaChannels')) {

src/Translations/Jobs/ModelTranslateJob.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,19 @@ class ModelTranslateJob implements ShouldQueue
2929
public function __construct(
3030
protected CanBeTranslated $model,
3131
protected string $sourceLocale,
32-
protected string $targetLocale
32+
protected string $targetLocale,
33+
protected array $options = []
3334
) {
3435
$this->onQueue(config('translator.queue', 'default'));
3536
}
3637

3738
public function handle(): void
3839
{
39-
$this->model->translateTo($this->targetLocale, $this->sourceLocale, ['force' => true]);
40+
$this->model->translateTo(
41+
$this->targetLocale,
42+
$this->sourceLocale,
43+
array_merge(['force' => true], $this->options)
44+
);
4045

4146
sleep(1);
4247
}

tests/Unit/LocaleModelTest.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,56 @@ public function test_translate_to_replicates_media_channels()
173173
$this->assertTrue($newPost->hasMedia('thumbnail'), 'Media was not replicated to the new translation');
174174
$this->assertEquals($media->id, $newPost->getFirstMedia('thumbnail')->id);
175175
}
176+
177+
public function test_model_translate_with_overwrites()
178+
{
179+
Queue::fake();
180+
181+
$post = TestPost::create(['title' => 'Hello', 'locale' => 'en']);
182+
183+
$options = ['overwrites' => ['content' => 'Overwritten Content']];
184+
$history = model_translate($post, 'en', 'vi', $options);
185+
186+
$this->assertInstanceOf(TranslateHistory::class, $history);
187+
188+
Queue::assertPushed(ModelTranslateJob::class, function ($job) use ($options) {
189+
$reflection = new \ReflectionClass($job);
190+
$jobOptions = $reflection->getProperty('options')->getValue($job);
191+
return $jobOptions === $options;
192+
});
193+
}
194+
195+
public function test_translate_to_with_overwrites()
196+
{
197+
$this->mock(Translator::class, function ($mock) {
198+
$mock->shouldReceive('translate')
199+
->with('Hello', 'en', 'vi', false)
200+
->andReturn('Xin chào');
201+
});
202+
203+
$post = TestPost::create(['title' => 'Hello', 'content' => 'Original Content', 'locale' => 'en']);
204+
205+
// We simulate the call without the job wrapper to test the trait logic directly
206+
$result = $post->translateTo('vi', 'en', [
207+
'overwrites' => [
208+
'content' => 'Overwritten Content',
209+
]
210+
]);
211+
212+
$this->assertTrue($result);
213+
214+
$this->assertDatabaseHas('test_posts', [
215+
'title' => 'Xin chào',
216+
'content' => 'Overwritten Content',
217+
'locale' => 'vi',
218+
]);
219+
220+
$this->assertDatabaseHas('test_posts', [
221+
'title' => 'Hello',
222+
'content' => 'Original Content',
223+
'locale' => 'en',
224+
]);
225+
}
176226
}
177227

178228
class TestPost extends Model implements CanBeTranslated

0 commit comments

Comments
 (0)