1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace BBSLab\NovaTranslation\Models\Relations; |
4
|
|
|
|
5
|
|
|
use BBSLab\NovaTranslation\Models\Contracts\IsTranslatable; |
6
|
|
|
use BBSLab\NovaTranslation\Models\Locale; |
7
|
|
|
use BBSLab\NovaTranslation\Models\Translation; |
8
|
|
|
use BBSLab\NovaTranslation\NovaTranslation; |
9
|
|
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany as Relation; |
10
|
|
|
use Illuminate\Support\Collection; |
11
|
|
|
|
12
|
|
|
class BelongsToMany extends Relation |
13
|
|
|
{ |
14
|
|
|
/** |
15
|
|
|
* The parent model instance. |
16
|
|
|
* |
17
|
|
|
* @var \BBSLab\NovaTranslation\Models\Contracts\IsTranslatable |
18
|
|
|
*/ |
19
|
|
|
protected $parent; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* Attach a model to the parent. |
23
|
|
|
* |
24
|
|
|
* @param mixed $id |
25
|
|
|
* @param array $attributes |
26
|
|
|
* @param bool $touch |
27
|
|
|
* @return void |
28
|
|
|
* @throws \Exception |
29
|
|
|
*/ |
30
|
|
View Code Duplication |
public function attach($id, array $attributes = [], $touch = true) |
|
|
|
|
31
|
|
|
{ |
32
|
|
|
parent::attach($id, $attributes, $touch); |
33
|
|
|
|
34
|
|
|
if (! in_array(get_class($this->parent), NovaTranslation::translatableModels())) { |
35
|
|
|
return; |
36
|
|
|
} |
37
|
|
|
|
38
|
|
|
if ($this->parent->isTranslatingRelation()) { |
39
|
|
|
return; |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
$keys = $this->getTranslatedKeys($this->parseIds($id), $locales = NovaTranslation::otherLocales()); |
43
|
|
|
|
44
|
|
|
$this->parent->translations() |
|
|
|
|
45
|
|
|
->with(['locale', 'translatable']) |
46
|
|
|
->get() |
47
|
|
|
->each(function (Translation $translation) use ($keys, $attributes, $touch) { |
48
|
|
|
$model = $translation->translatable; |
49
|
|
|
$model->translatingRelation(); |
50
|
|
|
$model->{$this->relationName}()->attach( |
51
|
|
|
data_get($keys, $translation->locale->iso, []), |
52
|
|
|
$attributes, |
53
|
|
|
$touch |
54
|
|
|
); |
55
|
|
|
}); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
View Code Duplication |
public function detach($ids = null, $touch = true) |
|
|
|
|
59
|
|
|
{ |
60
|
|
|
$result = parent::detach($ids, $touch); |
61
|
|
|
|
62
|
|
|
if (! in_array(get_class($this->parent), NovaTranslation::translatableModels())) { |
63
|
|
|
return $result; |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
if ($this->parent->isTranslatingRelation()) { |
67
|
|
|
return $result; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
$keys = $this->getTranslatedKeys($this->parseIds($ids), NovaTranslation::otherLocales()); |
71
|
|
|
|
72
|
|
|
$this->parent->translations() |
|
|
|
|
73
|
|
|
->with(['locale', 'translatable']) |
74
|
|
|
->get() |
75
|
|
|
->each(function (Translation $translation) use ($keys, $touch) { |
76
|
|
|
$model = $translation->translatable; |
77
|
|
|
$model->translatingRelation(); |
78
|
|
|
$model->{$this->relationName}()->detach(data_get($keys, $translation->locale->iso, []), $touch); |
79
|
|
|
}); |
80
|
|
|
|
81
|
|
|
return $result; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
View Code Duplication |
public function sync($ids, $detaching = true) |
|
|
|
|
85
|
|
|
{ |
86
|
|
|
$changes = parent::sync($ids, $detaching); |
87
|
|
|
|
88
|
|
|
if (! in_array(get_class($this->parent), NovaTranslation::translatableModels())) { |
89
|
|
|
return $changes; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
if ($this->parent->isTranslatingRelation()) { |
93
|
|
|
return $changes; |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
$keys = $this->getTranslatedKeys($this->parseIds($ids), NovaTranslation::otherLocales()); |
97
|
|
|
|
98
|
|
|
$this->parent->translations() |
|
|
|
|
99
|
|
|
->with(['locale', 'translatable']) |
100
|
|
|
->get() |
101
|
|
|
->each(function (Translation $translation) use ($keys, $detaching) { |
102
|
|
|
$model = $translation->translatable; |
103
|
|
|
$model->translatingRelation(); |
104
|
|
|
$model->{$this->relationName}()->sync(data_get($keys, $translation->locale->iso, []), $detaching); |
105
|
|
|
}); |
106
|
|
|
|
107
|
|
|
return $changes; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
public function getTranslatedKeys(array $keys, Collection $locales): array |
111
|
|
|
{ |
112
|
|
|
if (! $this->related instanceof IsTranslatable) { |
113
|
|
|
return $locales->mapWithKeys(function (Locale $locale) use ($keys) { |
114
|
|
|
return [$locale->iso => $keys]; |
115
|
|
|
})->toArray(); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
return $this->related->newQuery() |
119
|
|
|
->whereIn($this->getRelatedKeyName(), $keys) |
120
|
|
|
->with('translations.locale') |
121
|
|
|
->get() |
122
|
|
|
->groupBy('translations.*.locale.iso') |
123
|
|
|
->mapWithKeys(function (Collection $group, $iso) { |
124
|
|
|
return [ |
125
|
|
|
$iso => $group->flatMap(function (IsTranslatable $translatable) use ($iso) { |
126
|
|
|
return $translatable->translations->filter(function (Translation $translation) use ($iso) { |
|
|
|
|
127
|
|
|
return $translation->locale->iso === $iso; |
128
|
|
|
})->map(function (Translation $translation) { |
129
|
|
|
return $translation->translatable_id; |
130
|
|
|
})->unique(); |
131
|
|
|
}), |
132
|
|
|
]; |
133
|
|
|
})->toArray(); |
134
|
|
|
} |
135
|
|
|
} |
136
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.