Skip to content

Commit

Permalink
Handle scenarios where two unique tags are added and we have to decid…
Browse files Browse the repository at this point in the history
…e which one to keep
  • Loading branch information
loevgaard committed Jul 26, 2022
1 parent f60433f commit 986e858
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 6 deletions.
55 changes: 49 additions & 6 deletions src/TagBag.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ public function add(TagInterface $tag): void
try {
$renderedValue = $this->renderer->render($tag);
$fingerprint = $tag->getFingerprint() ?? $this->fingerprintGenerator->generate($tag, $renderedValue);
$existingTag = $this->findTagByFingerprint($fingerprint);
if (null !== $existingTag && ($existingTag->unique || $tag->isUnique())) {

if (!$this->handleExistingTag($tag, $fingerprint)) {
return;
}

Expand Down Expand Up @@ -89,6 +89,46 @@ public function renderSection(string $section): string
return $value;
}

/**
* Returns true if the tag should be added
*/
private function handleExistingTag(TagInterface $tag, string $fingerprint): bool
{
$search = $this->findTagByFingerprint($fingerprint);

// if no existing tag exists we should add the tag
if (null === $search) {
return true;
}

[$section, $idx, $existingTag] = $search;

// if both tags are unique
if ($existingTag->unique && $tag->isUnique()) {
// ... we check the priority and if the priority of the new tag is higher than the existing tag
if ($existingTag->priority >= $tag->getPriority()) {
return false;
}

// ... we will remove the old tag and add the new tag
unset($this->tags[$section][$idx]);

return true;
}

// if the old tag is unique, but the new tag isn't, we will not add the new tag
if ($existingTag->unique) {
return false;
}

// if the old tag is not unique, but the new tag is, we will remove the old tag and add the new tag
if ($tag->isUnique()) {
unset($this->tags[$section][$idx]);
}

return true;
}

/**
* @param list<RenderedTag> $tags
*/
Expand Down Expand Up @@ -183,12 +223,15 @@ private function dispatch(object $event): void
$this->eventDispatcher->dispatch($event);
}

private function findTagByFingerprint(string $fingerprint): ?RenderedTag
/**
* @return array{0: string, 1: int, 2: RenderedTag}|null
*/
private function findTagByFingerprint(string $fingerprint): ?array
{
foreach ($this->tags as $section) {
foreach ($section as $tag) {
foreach ($this->tags as $section => $sectionTags) {
foreach ($sectionTags as $idx => $tag) {
if ($tag->fingerprint === $fingerprint) {
return $tag;
return [$section, $idx, $tag];
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions tests/TagBagTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,21 @@ public function it_does_not_ignore_fingerprint_when_one_of_the_tags_is_unique():
self::assertSame('content', $tagBag->renderAll());
}

/**
* @test
*/
public function it_replaces_unique_tag_with_new_one_with_higher_priority(): void
{
$tag1 = $this->getTag('tag1')->unique()->withPriority(10)->withFingerprint('tag');
$tag2 = $this->getTag('tag2')->unique()->withPriority(20)->withFingerprint('tag');

$tagBag = $this->getTagBag();
$tagBag->add($tag1);
$tagBag->add($tag2);

self::assertSame('tag2', $tagBag->renderAll());
}

private function getTag(
string $content = 'content',
string $section = null,
Expand Down

0 comments on commit 986e858

Please sign in to comment.