@@ -179,7 +179,7 @@ public function encoding(array $supported = []): string
179179 */
180180 public function language (array $ supported ): string
181181 {
182- return $ this ->getBestMatch ($ supported , $ this ->request ->getHeaderLine ('accept-language ' ));
182+ return $ this ->getBestMatch ($ supported , $ this ->request ->getHeaderLine ('accept-language ' ), false , false , true );
183183 }
184184
185185 //--------------------------------------------------------------------
@@ -198,10 +198,11 @@ public function language(array $supported): string
198198 * @param boolean $enforceTypes If TRUE, will compare media types and sub-types.
199199 * @param boolean $strictMatch If TRUE, will return empty string on no match.
200200 * If FALSE, will return the first supported element.
201+ * @param boolean $matchLocales If TRUE, will match locale sub-types to a broad type (fr-FR = fr)
201202 *
202203 * @return string Best match
203204 */
204- protected function getBestMatch (array $ supported , string $ header = null , bool $ enforceTypes = false , bool $ strictMatch = false ): string
205+ protected function getBestMatch (array $ supported , string $ header = null , bool $ enforceTypes = false , bool $ strictMatch = false , bool $ matchLocales = false ): string
205206 {
206207 if (empty ($ supported ))
207208 {
@@ -232,7 +233,7 @@ protected function getBestMatch(array $supported, string $header = null, bool $e
232233 // If an acceptable value is supported, return it
233234 foreach ($ supported as $ available )
234235 {
235- if ($ this ->match ($ accept , $ available , $ enforceTypes ))
236+ if ($ this ->match ($ accept , $ available , $ enforceTypes, $ matchLocales ))
236237 {
237238 return $ available ;
238239 }
@@ -337,12 +338,14 @@ public function parseHeader(string $header): array
337338 /**
338339 * Match-maker
339340 *
340- * @param array $acceptable
341- * @param string $supported
342- * @param boolean $enforceTypes
341+ * @param array $acceptable
342+ * @param string $supported
343+ * @param boolean $enforceTypes
344+ * @param boolean $matchLocales
345+ *
343346 * @return boolean
344347 */
345- protected function match (array $ acceptable , string $ supported , bool $ enforceTypes = false ): bool
348+ protected function match (array $ acceptable , string $ supported , bool $ enforceTypes = false , $ matchLocales = false ): bool
346349 {
347350 $ supported = $ this ->parseHeader ($ supported );
348351 if (is_array ($ supported ) && count ($ supported ) === 1 )
@@ -363,6 +366,12 @@ protected function match(array $acceptable, string $supported, bool $enforceType
363366 return $ this ->matchTypes ($ acceptable , $ supported );
364367 }
365368
369+ // Do we need to match locales against broader locales?
370+ if ($ matchLocales )
371+ {
372+ return $ this ->matchLocales ($ acceptable , $ supported );
373+ }
374+
366375 return false ;
367376 }
368377
@@ -409,8 +418,14 @@ protected function matchParameters(array $acceptable, array $supported): bool
409418 */
410419 public function matchTypes (array $ acceptable , array $ supported ): bool
411420 {
412- list ($ aType , $ aSubType ) = explode ('/ ' , $ acceptable ['value ' ]);
413- list ($ sType , $ sSubType ) = explode ('/ ' , $ supported ['value ' ]);
421+ [
422+ $ aType ,
423+ $ aSubType ,
424+ ] = explode ('/ ' , $ acceptable ['value ' ]);
425+ [
426+ $ sType ,
427+ $ sSubType ,
428+ ] = explode ('/ ' , $ supported ['value ' ]);
414429
415430 // If the types don't match, we're done.
416431 if ($ aType !== $ sType )
@@ -429,4 +444,25 @@ public function matchTypes(array $acceptable, array $supported): bool
429444 }
430445
431446 //--------------------------------------------------------------------
447+
448+ /**
449+ * Will match locales against their broader pairs, so that fr-FR would
450+ * match a supported localed of fr
451+ *
452+ * @param array $acceptable
453+ * @param array $supported
454+ *
455+ * @return boolean
456+ */
457+ public function matchLocales (array $ acceptable , array $ supported ): bool
458+ {
459+ $ aBroad = mb_strpos ($ acceptable ['value ' ], '- ' ) > 0
460+ ? mb_substr ($ acceptable ['value ' ], 0 , mb_strpos ($ acceptable ['value ' ], '- ' ))
461+ : $ acceptable ['value ' ];
462+ $ sBroad = mb_strpos ($ supported ['value ' ], '- ' ) > 0
463+ ? mb_substr ($ supported ['value ' ], 0 , mb_strpos ($ supported ['value ' ], '- ' ))
464+ : $ supported ['value ' ];
465+
466+ return strtolower ($ aBroad ) === strtolower ($ sBroad );
467+ }
432468}
0 commit comments