Skip to content

Commit

Permalink
Add setting to prioritize root page for countries
Browse files Browse the repository at this point in the history
  • Loading branch information
aschempp committed Aug 27, 2024
1 parent 9ad961a commit 9898208
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 1 deletion.
4 changes: 4 additions & 0 deletions config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,7 @@ services:
Terminal42\Geoip2CountryBundle\Routing\CountryRestrictionFilter:
arguments:
- '@Terminal42\Geoip2CountryBundle\CountryProvider'
-
Terminal42\Geoip2CountryBundle\Routing\CountryPriorityFilter:
arguments:
- '@Terminal42\Geoip2CountryBundle\CountryProvider'
26 changes: 26 additions & 0 deletions contao/dca/tl_page.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

use Contao\CoreBundle\DataContainer\PaletteManipulator;
use Contao\System;

PaletteManipulator::create()
->addField('geoip_priority', 'language_legend', PaletteManipulator::POSITION_APPEND)
->applyToPalette('root', 'tl_page')
->applyToPalette('rootfallback', 'tl_page')
;

$GLOBALS['TL_DCA']['tl_page']['fields'] += [
'geoip_priority' => [
'exclude' => true,
'inputType' => 'select',
'options_callback' => static fn () => System::getContainer()->get('contao.intl.countries')->getCountries(),
'eval' => [
'includeBlankOption' => true,
'multiple' => true,
'chosen' => true,
'csv' => ',',
'tl_class' => 'clr w50',
],
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
],
];
13 changes: 13 additions & 0 deletions contao/languages/en/tl_page.xlf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.1">
<file source-language="en">
<body>
<trans-unit id="tl_page.geoip_priority.0">
<source>GeoIP Priority</source>
</trans-unit>
<trans-unit id="tl_page.geoip_priority.1">
<source>Select countries where this root page should have priority regardless of browser language detection.</source>
</trans-unit>
</body>
</file>
</xliff>
5 changes: 4 additions & 1 deletion src/DependencyInjection/Compiler/RouteFilterPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Terminal42\Geoip2CountryBundle\Routing\CountryPriorityFilter;
use Terminal42\Geoip2CountryBundle\Routing\CountryRestrictionFilter;

class RouteFilterPass implements CompilerPassInterface
Expand All @@ -21,6 +22,8 @@ public function process(ContainerBuilder $container): void
return;
}

$container->getDefinition($this->serviceId)->addMethodCall('addRouteFilter', [new Reference(CountryRestrictionFilter::class)]);
$service = $container->getDefinition($this->serviceId);
$service->addMethodCall('addRouteFilter', [new Reference(CountryRestrictionFilter::class)]);
$service->addMethodCall('addRouteFilter', [new Reference(CountryPriorityFilter::class), 1]);
}
}
68 changes: 68 additions & 0 deletions src/Routing/CountryPriorityFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

declare(strict_types=1);

namespace Terminal42\Geoip2CountryBundle\Routing;

use Contao\PageModel;
use Symfony\Cmf\Component\Routing\NestedMatcher\RouteFilterInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouteCollection;
use Terminal42\Geoip2CountryBundle\CountryProvider;

class CountryPriorityFilter implements RouteFilterInterface
{
public function __construct(private readonly CountryProvider $countryProvider)
{
}

public function filter(RouteCollection $collection, Request $request): RouteCollection
{
$hasPriority = false;
$country = $this->countryProvider->getCountryCode($request);
$map = [];

foreach ($collection as $name => $route) {
$pageModel = $route->getDefault('pageModel');

if (
!$pageModel instanceof PageModel
&& !str_ends_with($name, '.root')
&& !str_ends_with($name, '.fallback')
) {
continue;
}

$map[$name] = $this->hasPriority($this->getRootPage($pageModel), $country);
$hasPriority = $hasPriority ?: $map[$name];
}

if ($hasPriority) {
foreach ($map as $name => $priority) {
if (!$priority) {
$collection->remove($name);
continue;
}

// Fake page to be fallback to fix Contao\CoreBundle\Routing\Matcher\LanguageFilter
$collection->get($name)->getDefault('pageModel')->rootIsFallback = true;
}
}

return $collection;
}

private function getRootPage(PageModel $pageModel): PageModel
{
if ('root' === $pageModel->type) {
return $pageModel;
}

return PageModel::findById($pageModel->loadDetails()->rootId);
}

private function hasPriority(PageModel $pageModel, string $country): bool
{
return \in_array($country, explode(',', (string) $pageModel->geoip_priority), true);
}
}

0 comments on commit 9898208

Please sign in to comment.