@@ -11,26 +11,40 @@ class sLangContent extends Eloquent\Model
1111 protected $ fillable = ['resource ' , 'lang ' , 'pagetitle ' , 'longtitle ' , 'description ' , 'introtext ' , 'content ' , 'menutitle ' , 'seotitle ' , 'seodescription ' ];
1212
1313 /**
14- * Add the language and template variable fields to the query
14+ * Add the language and template variable fields to the query.
1515 *
1616 * @param Builder $query The query builder instance
1717 * @param string $locale The language locale
1818 * @param array $tvNames The array of template variable names
1919 * @return Builder The modified query builder instance
20+ *
21+ * @deprecated since 1.0.8
22+ * TODO: REMOVE IN v1.2
2023 */
2124 public function scopeLangAndTvs ($ query , $ locale , $ tvNames = [])
2225 {
23- $ query ->select ('* ' , 's_lang_content.resource as id ' , 's_lang_content.pagetitle as pagetitle ' );
24- $ query ->addSelect ('s_lang_content.longtitle as longtitle ' , 's_lang_content.description as description ' );
25- $ query ->addSelect ('s_lang_content.introtext as introtext ' , 's_lang_content.content as content ' );
26- $ query ->addSelect ('s_lang_content.menutitle as menutitle ' );
27- $ query ->selectTvs ($ tvNames );
28-
29- return $ query ->addSelect ('site_content.pagetitle as pagetitle_orig ' , 'site_content.longtitle as longtitle_orig ' )
30- ->addSelect ('site_content.description as description_orig ' , 'site_content.introtext as introtext_orig ' )
31- ->addSelect ('site_content.content as content_orig ' , 'site_content.menutitle as menutitle_orig ' )
32- ->leftJoin ('site_content ' , 's_lang_content.resource ' , '= ' , 'site_content.id ' )
33- ->where ('lang ' , '= ' , $ locale );
26+ $ query = $ this ->scopeLang ($ query , $ locale );
27+ return $ query ->withTVs ($ tvNames );
28+ }
29+
30+ /**
31+ * Limit the query to a specific language. Falls back to evo()->getLocale() when locale is not provided.
32+ */
33+ public function scopeLang ($ query , ?string $ locale = null )
34+ {
35+ $ query = $ query ->withoutGlobalScope ('language ' );
36+ $ locale = static ::resolveLocale ($ locale );
37+ $ this ->applyContentSelects ($ query );
38+ return $ query ->where ('lang ' , '= ' , $ locale );
39+ }
40+
41+ /**
42+ * Append template variable fields while preserving base selects.
43+ */
44+ public function scopeWithTVs ($ query , array $ tvNames = [])
45+ {
46+ $ this ->applyContentSelects ($ query );
47+ return $ this ->scopeSelectTvs ($ query , $ tvNames );
3448 }
3549
3650 /**
@@ -143,8 +157,94 @@ public function getFullLinkAttribute()
143157 {
144158 $ base_url = UrlProcessor::makeUrl ($ this ->resource );
145159 if (str_starts_with ($ base_url , '/ ' )) {
146- $ base_url = MODX_SITE_URL . ltrim ($ base_url , '/ ' );
160+ $ base_url = EVO_SITE_URL . ltrim ($ base_url , '/ ' );
147161 }
148162 return $ base_url ;
149163 }
164+
165+ /**
166+ * Applies base selects and joins required for language-aware scopes.
167+ */
168+ protected function applyContentSelects (Builder $ query ): Builder
169+ {
170+ $ eloquentQuery = $ query ->getQuery ();
171+
172+ if (empty ($ eloquentQuery ->columns )) {
173+ $ query ->select ('s_lang_content.* ' );
174+ }
175+
176+ $ query ->addSelect (
177+ 's_lang_content.resource as id ' ,
178+ 's_lang_content.pagetitle as pagetitle ' ,
179+ 's_lang_content.longtitle as longtitle ' ,
180+ 's_lang_content.description as description ' ,
181+ 's_lang_content.introtext as introtext ' ,
182+ 's_lang_content.content as content ' ,
183+ 's_lang_content.menutitle as menutitle '
184+ );
185+
186+ if (!$ this ->hasSiteContentJoin ($ eloquentQuery ->joins ?? [])) {
187+ $ query ->leftJoin ('site_content ' , 's_lang_content.resource ' , '= ' , 'site_content.id ' );
188+ }
189+
190+ return $ query ->addSelect (
191+ 'site_content.pagetitle as pagetitle_orig ' ,
192+ 'site_content.longtitle as longtitle_orig ' ,
193+ 'site_content.description as description_orig ' ,
194+ 'site_content.introtext as introtext_orig ' ,
195+ 'site_content.content as content_orig ' ,
196+ 'site_content.menutitle as menutitle_orig '
197+ );
198+ }
199+
200+ /**
201+ * Detect whether site_content join has already been added.
202+ */
203+ protected function hasSiteContentJoin (array $ joins ): bool
204+ {
205+ foreach ($ joins as $ join ) {
206+ if (($ join ->table ?? null ) === 'site_content ' ) {
207+ return true ;
208+ }
209+ }
210+
211+ return false ;
212+ }
213+
214+ /**
215+ * Resolve the locale used by language-aware scopes.
216+ */
217+ protected static function resolveLocale (?string $ locale ): string
218+ {
219+ $ locale = $ locale ?? (function_exists ('evo ' ) ? (string )evo ()->getLocale () : '' );
220+
221+ if ($ locale === '' && function_exists ('evo ' )) {
222+ $ locale = (string )evo ()->getConfig ('lang ' , 'uk ' );
223+ }
224+
225+ if ($ locale === '' ) {
226+ $ locale = 'uk ' ;
227+ }
228+
229+ $ underscorePos = strpos ($ locale , '_ ' );
230+ if ($ underscorePos !== false ) {
231+ $ locale = substr ($ locale , 0 , $ underscorePos );
232+ }
233+
234+ return strtolower ($ locale );
235+ }
236+
237+ /**
238+ * Register the default language scope for the model.
239+ */
240+ protected static function booted (): void
241+ {
242+ static ::addGlobalScope ('language ' , function (Builder $ builder ) {
243+ /** @var self $model */
244+ $ model = new static ;
245+ $ locale = static ::resolveLocale (null );
246+ $ model ->applyContentSelects ($ builder );
247+ $ builder ->where ($ model ->getTable () . '.lang ' , '= ' , $ locale );
248+ });
249+ }
150250}
0 commit comments