diff --git a/README.md b/README.md index 44d4f46..fdc9947 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,15 @@ need a commercial license of this product depending on your use case! set to the visitors country. +### Note on page visibility + +If the visibility of a root page is configured, it also affects all its subpages. This means +if a root page is not available for a country, none of the pages in this tree will be available. + +Enabling this on the fallback root page can lead to unwanted consequences, because the user will +not be redirected to **any** page if none of the preferred languages match the browser! + + ## Installation Choose the installation method that matches your workflow! diff --git a/src/Routing/CountryRestrictionFilter.php b/src/Routing/CountryRestrictionFilter.php index ed81bc7..8f40adf 100644 --- a/src/Routing/CountryRestrictionFilter.php +++ b/src/Routing/CountryRestrictionFilter.php @@ -18,6 +18,8 @@ public function __construct(private readonly CountryProvider $countryProvider) public function filter(RouteCollection $collection, Request $request): RouteCollection { + $country = $this->countryProvider->getCountryCode($request); + foreach ($collection as $name => $route) { $pageModel = $route->getDefault('pageModel'); @@ -25,18 +27,31 @@ public function filter(RouteCollection $collection, Request $request): RouteColl continue; } - if ('show' !== $pageModel->geoip_visibility && 'hide' !== $pageModel->geoip_visibility) { - continue; + if (!$this->isAvailable($pageModel, $country)) { + $collection->remove($name); } - $countries = explode(',', (string) $pageModel->geoip_countries); - $country = $this->countryProvider->getCountryCode($request); + // Disallow access to a page if its root page is not available for the current country + if ('root' !== $pageModel->type) { + $rootModel = PageModel::findById($pageModel->loadDetails()->rootId); - if (\in_array($country, $countries, true) !== ('show' === $pageModel->geoip_visibility)) { - $collection->remove($name); + if ($rootModel && !$this->isAvailable($rootModel, $country)) { + $collection->remove($name); + } } } return $collection; } + + private function isAvailable(PageModel $pageModel, string $country): bool + { + if ('show' !== $pageModel->geoip_visibility && 'hide' !== $pageModel->geoip_visibility) { + return true; + } + + $countries = explode(',', (string) $pageModel->geoip_countries); + + return \in_array($country, $countries, true) === ('show' === $pageModel->geoip_visibility); + } }