Skip to content

Commit 94cc180

Browse files
linawolfjaapio
authored andcommitted
!![TASK] Improve interlink slug and exception handling
- Add tests - Improve method names, some have been misleading - Always Slug anchors - Do not slug document names (they can be case sensitive etc) This change is breaking for those who extended inventory handling (that should only be TYPO3).
1 parent f13f0f1 commit 94cc180

16 files changed

+261
-69
lines changed

packages/guides/src/Interlink/DefaultInventoryLoader.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44

55
namespace phpDocumentor\Guides\Interlink;
66

7+
use phpDocumentor\Guides\ReferenceResolvers\AnchorReducer;
8+
use phpDocumentor\Guides\ReferenceResolvers\NullAnchorReducer;
79
use Psr\Log\LoggerInterface;
810
use Symfony\Component\HttpClient\Exception\ClientException;
911

12+
use function count;
1013
use function is_array;
1114
use function strval;
1215

@@ -15,6 +18,7 @@ final class DefaultInventoryLoader implements InventoryLoader
1518
public function __construct(
1619
private readonly LoggerInterface $logger,
1720
private readonly JsonLoader $jsonLoader,
21+
private readonly AnchorReducer $anchorReducer,
1822
private readonly string $pathToJson = 'objects.inv.json',
1923
) {
2024
}
@@ -23,19 +27,27 @@ public function __construct(
2327
public function loadInventoryFromJson(Inventory $inventory, array $json): void
2428
{
2529
foreach ($json as $groupKey => $groupArray) {
26-
$group = new InventoryGroup();
30+
$groupAnchorReducer = $this->anchorReducer;
31+
if ($groupKey === 'std:doc') {
32+
// Do not reduce Document names
33+
$groupAnchorReducer = new NullAnchorReducer();
34+
}
35+
36+
$group = new InventoryGroup($groupAnchorReducer);
2737
if (is_array($groupArray)) {
2838
foreach ($groupArray as $linkKey => $linkArray) {
29-
if (!is_array($linkArray)) {
39+
if (!is_array($linkArray) || count($linkArray) < 4) {
3040
continue;
3141
}
3242

43+
$reducedLinkKey = $groupAnchorReducer->reduceAnchor(strval($linkKey));
3344
$link = new InventoryLink($linkArray[0], $linkArray[1], $linkArray[2], $linkArray[3]);
34-
$group->addLink(strval($linkKey), $link);
45+
$group->addLink($reducedLinkKey, $link);
3546
}
3647
}
3748

38-
$inventory->addGroup($groupKey, $group);
49+
$reducedGroupKey = $this->anchorReducer->reduceAnchor(strval($groupKey));
50+
$inventory->addGroup($reducedGroupKey, $group);
3951
}
4052

4153
$inventory->setIsLoaded(true);

packages/guides/src/Interlink/DefaultInventoryRepository.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
namespace phpDocumentor\Guides\Interlink;
66

7+
use phpDocumentor\Guides\Interlink\Exception\InterlinkInventoryNotFound;
8+
use phpDocumentor\Guides\Interlink\Exception\InterlinkNotFound;
79
use phpDocumentor\Guides\ReferenceResolvers\AnchorReducer;
8-
use RuntimeException;
910

1011
use function array_key_exists;
1112

@@ -21,22 +22,32 @@ public function __construct(
2122
array $inventoryConfigs,
2223
) {
2324
foreach ($inventoryConfigs as $inventory) {
24-
$this->inventories[$this->anchorReducer->reduceAnchor($inventory['id'])] = new Inventory($inventory['url']);
25+
$this->inventories[$this->anchorReducer->reduceAnchor($inventory['id'])] = new Inventory($inventory['url'], $anchorReducer);
2526
}
2627
}
2728

29+
/** @throws InterlinkNotFound */
30+
public function getLink(string $inventoryKey, string $groupKey, string $linkKey): InventoryLink
31+
{
32+
$inventory = $this->getInventory($inventoryKey);
33+
$group = $inventory->getGroup($groupKey);
34+
35+
return $group->getLink($linkKey);
36+
}
37+
2838
public function hasInventory(string $key): bool
2939
{
3040
$reducedKey = $this->anchorReducer->reduceAnchor($key);
3141

3242
return array_key_exists($reducedKey, $this->inventories);
3343
}
3444

45+
/** @throws InterlinkInventoryNotFound */
3546
public function getInventory(string $key): Inventory
3647
{
3748
$reducedKey = $this->anchorReducer->reduceAnchor($key);
3849
if (!$this->hasInventory($reducedKey)) {
39-
throw new RuntimeException('Inventory with key ' . $reducedKey . ' not found. ', 1_671_398_986);
50+
throw new InterlinkInventoryNotFound('Inventory with key ' . $reducedKey . ' not found. ', 1_671_398_986);
4051
}
4152

4253
$this->inventoryLoader->loadInventory($this->inventories[$reducedKey]);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace phpDocumentor\Guides\Interlink\Exception;
6+
7+
final class InterlinkGroupNotFound extends InterlinkNotFound
8+
{
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace phpDocumentor\Guides\Interlink\Exception;
6+
7+
final class InterlinkInventoryNotFound extends InterlinkNotFound
8+
{
9+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace phpDocumentor\Guides\Interlink\Exception;
6+
7+
use Exception;
8+
9+
abstract class InterlinkNotFound extends Exception
10+
{
11+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace phpDocumentor\Guides\Interlink\Exception;
6+
7+
final class InterlinkTargetNotFound extends InterlinkNotFound
8+
{
9+
}

packages/guides/src/Interlink/InvalidInventoryLink.php renamed to packages/guides/src/Interlink/Exception/InvalidInventoryLink.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
namespace phpDocumentor\Guides\Interlink;
5+
namespace phpDocumentor\Guides\Interlink\Exception;
66

77
use Exception;
88

packages/guides/src/Interlink/Inventory.php

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44

55
namespace phpDocumentor\Guides\Interlink;
66

7-
use RuntimeException;
7+
use phpDocumentor\Guides\Interlink\Exception\InterlinkGroupNotFound;
8+
use phpDocumentor\Guides\Interlink\Exception\InterlinkNotFound;
9+
use phpDocumentor\Guides\ReferenceResolvers\AnchorReducer;
810

911
use function array_key_exists;
10-
use function strtolower;
12+
use function sprintf;
1113

1214
final class Inventory
1315
{
@@ -16,7 +18,7 @@ final class Inventory
1618

1719
private bool $isLoaded = false;
1820

19-
public function __construct(private readonly string $baseUrl)
21+
public function __construct(private readonly string $baseUrl, private readonly AnchorReducer $anchorReducer)
2022
{
2123
}
2224

@@ -27,8 +29,8 @@ public function getBaseUrl(): string
2729

2830
public function addGroup(string $key, InventoryGroup $group): void
2931
{
30-
$lowerCaseKey = strtolower($key);
31-
$this->groups[$key] = $group;
32+
$reducedKey = $this->anchorReducer->reduceAnchor($key);
33+
$this->groups[$reducedKey] = $group;
3234
}
3335

3436
/** @return InventoryGroup[] */
@@ -37,29 +39,30 @@ public function getGroups(): array
3739
return $this->groups;
3840
}
3941

40-
public function getInventory(string $key): InventoryGroup
42+
/** @throws InterlinkNotFound */
43+
public function getGroup(string $key): InventoryGroup
4144
{
42-
$lowerCaseKey = strtolower($key);
43-
if (!$this->hasInventoryGroup($lowerCaseKey)) {
44-
throw new RuntimeException(
45-
'Inventory group with key ' . $lowerCaseKey . ' not found. ',
45+
$reducedKey = $this->anchorReducer->reduceAnchor($key);
46+
if (!$this->hasGroup($reducedKey)) {
47+
throw new InterlinkGroupNotFound(
48+
sprintf('Inventory group with key "%s" (%s) not found. ', $key, $reducedKey),
4649
1_671_398_986,
4750
);
4851
}
4952

50-
return $this->groups[$lowerCaseKey];
53+
return $this->groups[$reducedKey];
5154
}
5255

53-
public function getLink(string $group, string $key): InventoryLink
56+
public function getLink(string $groupKey, string $key): InventoryLink
5457
{
55-
return $this->getInventory($group)->getLink($key);
58+
return $this->getGroup($groupKey)->getLink($key);
5659
}
5760

58-
public function hasInventoryGroup(string $key): bool
61+
public function hasGroup(string $key): bool
5962
{
60-
$lowerCaseKey = strtolower($key);
63+
$reducedKey = $this->anchorReducer->reduceAnchor($key);
6164

62-
return array_key_exists($lowerCaseKey, $this->groups);
65+
return array_key_exists($reducedKey, $this->groups);
6366
}
6467

6568
public function isLoaded(): bool

packages/guides/src/Interlink/InventoryGroup.php

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,43 @@
44

55
namespace phpDocumentor\Guides\Interlink;
66

7-
use RuntimeException;
7+
use phpDocumentor\Guides\Interlink\Exception\InterlinkNotFound;
8+
use phpDocumentor\Guides\Interlink\Exception\InterlinkTargetNotFound;
9+
use phpDocumentor\Guides\ReferenceResolvers\AnchorReducer;
810

911
use function array_key_exists;
10-
use function strtolower;
12+
use function sprintf;
1113

1214
final class InventoryGroup
1315
{
1416
/** @var InventoryLink[] */
1517
private array $links = [];
1618

19+
public function __construct(private readonly AnchorReducer $anchorReducer)
20+
{
21+
}
22+
1723
public function addLink(string $key, InventoryLink $link): void
1824
{
19-
$lowerCaseKey = strtolower($key);
20-
$this->links[$lowerCaseKey] = $link;
25+
$reducedKey = $this->anchorReducer->reduceAnchor($key);
26+
$this->links[$reducedKey] = $link;
2127
}
2228

2329
public function hasLink(string $key): bool
2430
{
25-
$lowerCaseKey = strtolower($key);
31+
$reducedKey = $this->anchorReducer->reduceAnchor($key);
2632

27-
return array_key_exists($lowerCaseKey, $this->links);
33+
return array_key_exists($reducedKey, $this->links);
2834
}
2935

36+
/** @throws InterlinkNotFound */
3037
public function getLink(string $key): InventoryLink
3138
{
32-
$lowerCaseKey = strtolower($key);
33-
if (!array_key_exists($lowerCaseKey, $this->links)) {
34-
throw new RuntimeException('Inventory link with key ' . $lowerCaseKey . ' not found. ', 1_671_398_986);
39+
$reducedKey = $this->anchorReducer->reduceAnchor($key);
40+
if (!array_key_exists($reducedKey, $this->links)) {
41+
throw new InterlinkTargetNotFound(sprintf('Inventory link with key "%s" (%s) not found. ', $key, $reducedKey), 1_671_398_986);
3542
}
3643

37-
return $this->links[$lowerCaseKey];
44+
return $this->links[$reducedKey];
3845
}
3946
}

packages/guides/src/Interlink/InventoryLink.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace phpDocumentor\Guides\Interlink;
66

7+
use phpDocumentor\Guides\Interlink\Exception\InvalidInventoryLink;
8+
79
use function preg_match;
810

911
final class InventoryLink

0 commit comments

Comments
 (0)