@@ -39,97 +39,9 @@ class Tag extends Model implements HasMedia, TranslatableContract
3939 'count ' => 'integer ' ,
4040 ];
4141
42- /**
43- * Handle filling translations from form data
44- */
45- public function fillTranslations (array $ translations ): self
46- {
47- foreach ($ translations as $ locale => $ data ) {
48- if (! empty ($ data ['title ' ])) {
49- // Get the translation for this locale (or create a new one)
50- $ translation = $ this ->translateOrNew ($ locale );
51-
52- // Check if title has changed
53- if ($ translation ->title !== $ data ['title ' ]) {
54- $ translation ->title = $ data ['title ' ];
55- }
56-
57- // Handle the slug only if it has changed
58- $ slug = $ data ['slug ' ] ?? Str::slug ($ data ['title ' ]);
59- if ($ translation ->slug !== $ slug ) {
60- $ slug = $ this ->generateUniqueSlug ($ slug , $ locale );
61- $ translation ->slug = $ slug ;
62- }
63-
64- // Handle content only if it has changed
65- if ($ translation ->content !== ($ data ['content ' ] ?? null )) {
66- $ translation ->content = $ data ['content ' ] ?? null ;
67- }
68-
69- $ translation ->save ();
70- }
71- }
72-
73- return $ this ;
74- }
75-
76- public function generateUniqueSlug (string $ slug , string $ locale , int $ counter = 0 ): string
77- {
78- // Append counter if needed
79- $ uniqueSlug = $ counter > 0 ? "{$ slug }- {$ counter }" : $ slug ;
80-
81- // Check if the slug exists for this locale
82- $ exists = static ::whereHas ('translations ' , function ($ query ) use ($ uniqueSlug , $ locale ) {
83- $ query ->where ('slug ' , $ uniqueSlug )->where ('locale ' , $ locale );
84- })->exists ();
85-
86- // If exists, try again with an incremented counter
87- return $ exists ? $ this ->generateUniqueSlug ($ slug , $ locale , $ counter + 1 ) : $ uniqueSlug ;
88- }
8942
90- /**
91- * Get all translations as a formatted array
92- */
93- public function getTranslationsArray (): array
94- {
95- $ translations = [];
96-
97- foreach ($ this ->translations as $ translation ) {
98- $ translations [$ translation ->locale ] = [
99- 'title ' => $ translation ->title ,
100- 'slug ' => $ translation ->slug ,
101- 'content ' => $ translation ->content ,
102- ];
103- }
10443
105- return $ translations ;
106- }
10744
108- /**
109- * Create a new tag with translations
110- */
111- public static function createWithTranslations (array $ attributes , array $ translations ): self
112- {
113- $ tag = new static ;
114- $ tag ->fill ($ attributes );
115- $ tag ->save ();
116-
117- $ tag ->fillTranslations ($ translations )->save ();
118-
119- return $ tag ;
120- }
121-
122- /**
123- * Update tag with translations
124- */
125- public function updateWithTranslations (array $ attributes , array $ translations ): self
126- {
127- $ this ->fill ($ attributes );
128- $ this ->fillTranslations ($ translations );
129- $ this ->save ();
130-
131- return $ this ;
132- }
13345
13446 protected static function newFactory (): TagFactory
13547 {
@@ -176,4 +88,110 @@ public function mediaThroughUsables()
17688 'media_id '
17789 )->where ('media_usables.media_usable_type ' , '= ' , static ::class);
17890 }
91+
92+ public function getAttribute ($ key )
93+ {
94+ if (in_array ($ key , $ this ->translatedAttributes )) {
95+ $ lang = request ()->query ('lang ' ) ?? app ()->getLocale ();
96+
97+ return $ this ->translate ($ lang , false ) ? $ this ->translate ($ lang , false )->$ key : null ;
98+ }
99+
100+ return parent ::getAttribute ($ key );
101+ }
102+
103+ public function setAttribute ($ key , $ value )
104+ {
105+ if (in_array ($ key , $ this ->translatedAttributes )) {
106+ $ lang = request ()->query ('lang ' ) ?? app ()->getLocale ();
107+
108+ $ this ->translateOrNew ($ lang )->$ key = $ value ;
109+
110+ return $ this ;
111+ }
112+
113+ return parent ::setAttribute ($ key , $ value );
114+ }
115+
116+ /**
117+ * Helper to get translated value
118+ */
119+ protected function getTranslated ($ key , $ locale )
120+ {
121+ // First try to get from loaded translations
122+ if ($ this ->relationLoaded ('translations ' )) {
123+ $ translation = $ this ->translations
124+ ->where ('locale ' , $ locale )
125+ ->first ();
126+
127+ if ($ translation ) {
128+ return $ translation ->$ key ;
129+ }
130+ }
131+
132+ // Fallback to direct translation lookup
133+ $ translation = $ this ->translate ($ locale );
134+
135+ return $ translation ? $ translation ->$ key : '' ;
136+ }
137+
138+ /**
139+ * Override toArray to include translations
140+ */
141+ public function toArray ()
142+ {
143+ $ attributes = parent ::toArray ();
144+
145+ if ($ locale = request ()->query ('lang ' )) {
146+ foreach ($ this ->translatedAttributes as $ attr ) {
147+ $ attributes [$ attr ] = $ this ->getTranslated ($ attr , $ locale );
148+ }
149+ }
150+
151+ return $ attributes ;
152+ }
153+
154+ /**
155+ * Get all available translations for this model
156+ */
157+ public function getAvailableTranslations (): array
158+ {
159+ return $ this ->translations ->pluck ('locale ' )->toArray ();
160+ }
161+
162+ /**
163+ * Check if a translation exists for a specific locale
164+ */
165+ public function hasTranslation (?string $ locale = null ): bool
166+ {
167+ if ($ locale === null ) {
168+ $ locale = request ()->query ('lang ' ) ?? app ()->getLocale ();
169+ }
170+
171+ return $ this ->translations ->contains ('locale ' , $ locale );
172+ }
173+
174+ /**
175+ * Create a new translation for a specific locale
176+ */
177+ public function createTranslation (string $ locale , array $ attributes = []): void
178+ {
179+ $ translation = $ this ->translateOrNew ($ locale );
180+
181+ foreach ($ attributes as $ key => $ value ) {
182+ if (in_array ($ key , $ this ->translatedAttributes )) {
183+ $ translation ->$ key = $ value ;
184+ }
185+ }
186+
187+ $ this ->translations ()->save ($ translation );
188+ }
189+
190+ /**
191+ * Delete a translation for a specific locale
192+ */
193+ public function deleteTranslation (string $ locale ): bool
194+ {
195+ return $ this ->translations ()->where ('locale ' , $ locale )->delete ();
196+ }
179197}
0 commit comments