88namespace Opengento \StorePathUrl \Plugin \App \Request ;
99
1010use Magento \Framework \App \Request \Http ;
11- use Magento \Framework \Exception \LocalizedException ;
1211use Magento \Framework \Exception \NoSuchEntityException ;
1312use Magento \Framework \UrlInterface ;
1413use Magento \Store \Api \StoreRepositoryInterface ;
2322
2423class StorePathInfoValidator
2524{
25+ // This hack is necessary to prevent infinite loop because of https://github.com/opengento/magento2-store-path-url/issues/3
26+ // The fix is shipped in the version 2.4.9 of Magento: https://github.com/magento/magento2/pull/38717
2627 private int $ stack = 0 ;
2728
2829 public function __construct (
@@ -32,47 +33,42 @@ public function __construct(
3233
3334 public function beforeGetValidStoreCode (Subject $ subject , Http $ request , string $ pathInfo = '' ): array
3435 {
35- if (++$ this ->stack === 1 && $ this ->config ->isStoreInPath () && $ this ->config ->isBaseUrlResolverEnabled ()) {
36- $ storeCode = $ this ->resolveStoreCode ($ request , $ pathInfo );
37- $ pathInfo = $ storeCode === '' ? $ pathInfo : $ storeCode ;
36+ // If $pathInfo is empty, we are resolving the current scope ID.
37+ // It could also be the path info processor which tries to trim the store path from the url.
38+ if (++$ this ->stack === 1 && $ pathInfo === '' && $ this ->config ->isStoreInPath () && $ this ->config ->isBaseUrlResolverEnabled ()) {
39+ $ pathInfo = $ this ->resolveStoreCode ($ request );
3840 }
3941
4042 return [$ request , $ pathInfo ];
4143 }
42-
44+
4345 public function afterGetValidStoreCode (Subject $ subject , ?string $ store , Http $ request , string $ path = '' ): ?string
4446 {
45- if ($ this ->stack === 1 && !$ this ->config ->isStoreInPath () && $ this ->config ->isBaseUrlResolverEnabled ()) {
46- try {
47- $ store = $ this ->storeRepository ->getActiveStoreByCode (
48- $ this ->resolveStoreCode ($ request , $ path )
49- )->getCode ();
50- } catch (LocalizedException ) {
51- $ store = null ;
52- }
53- }
5447 $ this ->stack --;
5548
5649 return $ store ;
5750 }
5851
59- private function resolveStoreCode (Http $ request, string $ pathInfo ): string
52+ private function resolveStoreCode (Http $ request ): string
6053 {
6154 $ uri = strtok ($ request ->getUriString (), '? ' ) . '/ ' ;
6255 if ($ uri !== false ) {
63- $ pathInfo = $ pathInfo ?: parse_url ($ uri , PHP_URL_PATH );
56+ $ pathInfo = parse_url ($ uri , PHP_URL_PATH );
6457 if ($ pathInfo === false ) {
6558 return '' ;
6659 }
67- $ pathInfo = $ this ->resolveByLinkUrl ($ uri ) ?: $ this ->resolveByWebUrl ($ uri );
60+ // The uri has a valid format, we can look for the matching store base url.
61+ $ pathInfo = $ this ->resolveByLinkUrl ($ uri );
62+ // If the store cannot be resolved, with look for the closest lookalike store.
63+ return $ pathInfo !== false ? $ pathInfo : $ this ->resolveByWebUrl ($ uri );
6864 }
6965
70- return $ pathInfo ;
66+ return '' ;
7167 }
7268
73- private function resolveByLinkUrl (string $ uri ): string
69+ private function resolveByLinkUrl (string $ uri ): bool | string
7470 {
75- $ storeCode = '' ;
71+ $ storeCode = false ;
7672 /** @var Store $store */
7773 foreach ($ this ->storeRepository ->getList () as $ store ) {
7874 if ($ store ->getId ()) {
@@ -100,7 +96,9 @@ private function resolveByWebUrl(string $uri): string
10096 if ($ store ->getId () && str_starts_with ($ uri , $ store ->getBaseUrl (UrlInterface::URL_TYPE_WEB ))) {
10197 try {
10298 $ score = $ this ->calculatePreferenceScore ($ store );
103- $ storeMatch ??= $ store ->getCode ();
99+ if ($ storeMatch === null ) {
100+ $ storeMatch = $ store ->getCode ();
101+ }
104102 if ($ highestScore < $ score ) {
105103 $ highestScore = $ score ;
106104 $ storeMatch = $ store ->getCode ();
0 commit comments