diff --git a/config/packages/easy_admin.yaml b/config/packages/easy_admin.yaml index a39f8394..ea0c3319 100644 --- a/config/packages/easy_admin.yaml +++ b/config/packages/easy_admin.yaml @@ -155,6 +155,7 @@ easy_admin: fields: - { property: name, label: domains.name } - { property: path, label: domains.path } + - { property: aliases, label: domains.aliases, help: domains.aliases.help } show: max_results: 100 fields: diff --git a/migrations/Version20210907130721.php b/migrations/Version20210907130721.php new file mode 100644 index 00000000..8e200de3 --- /dev/null +++ b/migrations/Version20210907130721.php @@ -0,0 +1,25 @@ +abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE domain_name ADD aliases LONGTEXT NOT NULL COMMENT \'(DC2Type:simple_array)\''); + } + + public function down(Schema $schema): void + { + $this->abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE domain_name DROP aliases'); + } +} diff --git a/src/DataFixtures/DomainFixtures.php b/src/DataFixtures/DomainFixtures.php index 4acd2918..415db379 100644 --- a/src/DataFixtures/DomainFixtures.php +++ b/src/DataFixtures/DomainFixtures.php @@ -18,7 +18,13 @@ public function load(ObjectManager $manager): void $manager->persist($disMoiDomain); $this->addReference('dismoi_domain', $disMoiDomain); + $youtubeDomain = new DomainName('youtube.com'); + $youtubeDomain->addAlias('m.youtube.com'); + $manager->persist($disMoiDomain); + $this->addReference('com_youtube_www', $youtubeDomain); + $domainName1 = new DomainName('first.domainname.fr'); + $domainName1->addAlias('alias.first.domainname.fr'); $manager->persist($domainName1); $this->addReference('first_domain', $domainName1); diff --git a/src/Entity/DomainName.php b/src/Entity/DomainName.php index bef56d96..9f87abb6 100644 --- a/src/Entity/DomainName.php +++ b/src/Entity/DomainName.php @@ -20,6 +20,11 @@ class DomainName { use ORMBehaviors\Timestampable\Timestampable; + /** + * @see https://github.com/doctrine/orm/issues/4673 + */ + public const EMPTY_SIMPLE_ARRAY = ['']; + /** * @var int * @@ -67,6 +72,17 @@ class DomainName */ private $sets; + /** + * @var string[] + * + * @ORM\Column(type="simple_array") + * + * @Assert\All({ + * @Assert\Regex("/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/") + * }) + */ + private $aliases; + /** * Domain constructor. */ @@ -75,6 +91,7 @@ public function __construct(string $name = '') $this->name = $name; $this->matchingContexts = new ArrayCollection(); $this->sets = new ArrayCollection(); + $this->aliases = self::EMPTY_SIMPLE_ARRAY; } public function __toString(): string @@ -118,6 +135,45 @@ public function getSets(): Collection return $this->sets; } + /** + * @param string[] $aliases + */ + public function setAliases(array $aliases = []): self + { + $this->aliases = array_filter($aliases, static function ($alias) { + return '' !== $alias; + }) ?: self::EMPTY_SIMPLE_ARRAY; + + return $this; + } + + /** + * @return string[] + */ + public function getAliases(): array + { + return array_filter($this->aliases, static function ($alias) { + return '' !== $alias; + }); + } + + /** + * @return DomainName + */ + public function addAlias(string $alias): self + { + $this->aliases = array_merge($this->aliases, [$alias]); + + return $this; + } + + public function removeAlias(string $alias): self + { + $this->aliases = array_diff($this->aliases, [$alias]); + + return $this; + } + /** * @return DomainName */ diff --git a/src/Entity/MatchingContext.php b/src/Entity/MatchingContext.php index 12201f96..a12686a3 100644 --- a/src/Entity/MatchingContext.php +++ b/src/Entity/MatchingContext.php @@ -266,9 +266,15 @@ public function getFullUrlRegex(Escaper $escaper = null): string return '('.implode( '|', - array_map(static function (DomainName $dn) use ($escaper) { - return escape($dn->getFullName(), $escaper); - }, $domains) + array_reduce($domains, static function ($accumulator, DomainName $dn) use ($escaper) { + return array_merge( + $accumulator, + [escape($dn->getFullName(), $escaper)], + array_map(static function (string $alias) use ($escaper) { + return escape($alias, $escaper); + }, $dn->getAliases()) + ); + }, []) ).')'.$this->urlRegex; } diff --git a/tests/Entity/MatchingContextTest.php b/tests/Entity/MatchingContextTest.php index 1f21943e..08f92c42 100644 --- a/tests/Entity/MatchingContextTest.php +++ b/tests/Entity/MatchingContextTest.php @@ -25,10 +25,10 @@ public function testItGetFullUrlRegex(): void /** @var MatchingContext $mc */ $mc = $this->referenceRepository->getReference('mc_with_domain_name'); $regex = $mc->getFullUrlRegex($escaper); - self::assertEquals('(duckduckgo.com|www.bing.com|www.google.fr|www.qwant.com|www.yahoo.com|first.domainname.fr|second.domainname.fr)'.$mc->getUrlRegex(), $regex); + self::assertEquals('(duckduckgo.com|www.bing.com|www.google.fr|www.qwant.com|www.yahoo.com|first.domainname.fr|alias.first.domainname.fr|second.domainname.fr)'.$mc->getUrlRegex(), $regex); $regex = $mc->getFullUrlRegex(); - self::assertEquals('(duckduckgo.com|www.bing.com|www.google.fr|www.qwant.com|www.yahoo.com|first.domainname.fr|second.domainname.fr)'.$mc->getUrlRegex(), $regex); + self::assertEquals('(duckduckgo.com|www.bing.com|www.google.fr|www.qwant.com|www.yahoo.com|first.domainname.fr|alias.first.domainname.fr|second.domainname.fr)'.$mc->getUrlRegex(), $regex); /** @var MatchingContext $mc */ $mc = $this->referenceRepository->getReference('mc_without_domain_name'); diff --git a/translations/messages.fr.yml b/translations/messages.fr.yml index 0107cf52..9fb917fb 100644 --- a/translations/messages.fr.yml +++ b/translations/messages.fr.yml @@ -85,6 +85,8 @@ domains: name: Nom du domaine path: Chemin sets: Groupes de domaines liés + aliases: Aliases + aliases.help: "Par exemple m.youtube.com pour www.youtube.com." sets.nb: Nb de groupes de domaines liés matchingContexts: Pages cibles liées matchingContexts.nb: Nb d’ensemble de pages cibles liées