Passed
Pull Request — 2.7 (#1088)
by
unknown
34:19
created

UniqueSlugNormalizer::normalize()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 9
nc 2
nop 2
dl 0
loc 17
ccs 0
cts 0
cp 0
crap 12
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the league/commonmark package.
7
 *
8
 * (c) Colin O'Dell <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace League\CommonMark\Normalizer;
15
16
// phpcs:disable Squiz.Strings.DoubleQuoteUsage.ContainsVar
17
final class UniqueSlugNormalizer implements UniqueSlugNormalizerInterface
18
{
19
    private TextNormalizerInterface $innerNormalizer;
20
    /** @var array<string, bool> */
21
    private array $alreadyUsed = [];
22
    /** @var array<string, bool> */
23 2398
    private array $blacklist = [];
24
25 2398
    public function __construct(TextNormalizerInterface $innerNormalizer)
26
    {
27
        $this->innerNormalizer = $innerNormalizer;
28 2306
    }
29
30 2306
    /**
31
     * Set a list of IDs that should be treated as already used
32
     *
33
     * These IDs will be considered "taken" and any generated slug matching
34
     * a blacklisted ID will receive a numeric suffix (e.g., -1, -2, etc.)
35
     *
36
     * @param array<string> $blacklistedIds List of IDs to blacklist
37
     */
38 124
    public function setBlacklist(array $blacklistedIds): void
39
    {
40 124
        $this->blacklist = [];
41
        foreach ($blacklistedIds as $id) {
42
            // Normalize the blacklist entry using the same normalizer as headings
43 124
            $normalized = $this->innerNormalizer->normalize($id);
44 18
            if ($normalized !== '') {
45
                $this->blacklist[$normalized] = true;
46 18
            }
47 18
        }
48
        $this->clearHistory();
49 18
    }
50
51
    public function clearHistory(): void
52 124
    {
53
        $this->alreadyUsed = $this->blacklist;
54 124
    }
55
56
57
    /**
58
     * {@inheritDoc}
59
     *
60
     * @psalm-allow-private-mutation
61
     */
62
    public function normalize(string $text, array $context = []): string
63
    {
64
        $normalized = $this->innerNormalizer->normalize($text, $context);
65
66
        // If it's not unique, add an incremental number to the end until we get a unique version
67
        if (\array_key_exists($normalized, $this->alreadyUsed)) {
68
            $suffix = 0;
69
            do {
70
                ++$suffix;
71
            } while (\array_key_exists("$normalized-$suffix", $this->alreadyUsed));
72
73
            $normalized = "$normalized-$suffix";
74
        }
75
76
        $this->alreadyUsed[$normalized] = true;
77
78
        return $normalized;
79
    }
80
}
81