@@ -123,16 +123,16 @@ public function encoding(array $supported = []): string
123123 * types the application says it supports, and the types requested
124124 * by the client.
125125 *
126- * If loose locale negotiation is enabled and no match is found, the first, highest-ranking client requested
126+ * If strict locale negotiation is disabled and no match is found, the first, highest-ranking client requested
127127 * type is returned.
128128 */
129129 public function language (array $ supported ): string
130130 {
131- if (config (Feature::class)->looseLocaleNegotiation ) {
132- return $ this ->getBestMatch ($ supported , $ this ->request ->getHeaderLine ('accept-language ' ), false , false , true );
131+ if (config (Feature::class)->strictLocaleNegotiation ) {
132+ return $ this ->getBestLocaleMatch ($ supported , $ this ->request ->getHeaderLine ('accept-language ' ));
133133 }
134134
135- return $ this ->getBestLocaleMatch ($ supported , $ this ->request ->getHeaderLine ('accept-language ' ));
135+ return $ this ->getBestMatch ($ supported , $ this ->request ->getHeaderLine ('accept-language ' ), false , false , true );
136136 }
137137
138138 // --------------------------------------------------------------------
@@ -195,19 +195,26 @@ protected function getBestMatch(
195195 }
196196
197197 /**
198- * Strict locale search, including territories (en-*)
198+ * Try to find the best matching locale. It supports strict locale comparison.
199199 *
200- * @param list<string> $supported App-supported values
201- * @param ?string $header Compatible 'Accept-Language' header string
200+ * If Config\App::$supportedLocales have "en-US" and "en-GB" locales, they can be recognized
201+ * as two different locales. This method checks first for the strict match, then fallback
202+ * to the most general locale (in this case "en") ISO 639-1 and finally to the locale variant
203+ * "en-*" (ISO 639-1 plus "wildcard" for ISO 3166-1 alpha-2).
204+ *
205+ * If nothing from above is matched, then it returns the first option from the $supportedLocales array.
206+ *
207+ * @param list<string> $supportedLocales App-supported values
208+ * @param ?string $header Compatible 'Accept-Language' header string
202209 */
203- protected function getBestLocaleMatch (array $ supported , ?string $ header ): string
210+ protected function getBestLocaleMatch (array $ supportedLocales , ?string $ header ): string
204211 {
205- if ($ supported === []) {
212+ if ($ supportedLocales === []) {
206213 throw HTTPException::forEmptySupportedNegotiations ();
207214 }
208215
209216 if ($ header === null || $ header === '' ) {
210- return $ supported [0 ];
217+ return $ supportedLocales [0 ];
211218 }
212219
213220 $ acceptable = $ this ->parseHeader ($ header );
@@ -221,11 +228,11 @@ protected function getBestLocaleMatch(array $supported, ?string $header): string
221228
222229 // if acceptable value is "anything", return the first available
223230 if ($ accept ['value ' ] === '* ' || $ accept ['value ' ] === '*/* ' ) {
224- return $ supported [0 ];
231+ return $ supportedLocales [0 ];
225232 }
226233
227234 // look for exact match
228- if (in_array ($ accept ['value ' ], $ supported , true )) {
235+ if (in_array ($ accept ['value ' ], $ supportedLocales , true )) {
229236 return $ accept ['value ' ];
230237 }
231238
@@ -235,19 +242,19 @@ protected function getBestLocaleMatch(array $supported, ?string $header): string
235242
236243 foreach ($ fallbackLocales as $ fallbackLocale ) {
237244 // look for exact match
238- if (in_array ($ fallbackLocale , $ supported , true )) {
245+ if (in_array ($ fallbackLocale , $ supportedLocales , true )) {
239246 return $ fallbackLocale ;
240247 }
241248
242- // look for locale variants match
243- foreach ($ supported as $ locale ) {
249+ // look for regional locale match
250+ foreach ($ supportedLocales as $ locale ) {
244251 if (str_starts_with ($ locale , $ fallbackLocale . '- ' )) {
245252 return $ locale ;
246253 }
247254 }
248255 }
249256
250- return $ supported [0 ];
257+ return $ supportedLocales [0 ];
251258 }
252259
253260 /**
0 commit comments