Skip to content

Commit cfd5bc0

Browse files
authored
Merge pull request #494 from phpDocumentor/intersphinx2
Make Intersphinx inventories configurable
2 parents c4574c1 + 47cc13b commit cfd5bc0

File tree

21 files changed

+218
-65
lines changed

21 files changed

+218
-65
lines changed

docs/configuration.rst

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,15 @@ you can do so by creating a ``settings.php`` file in the input directory
1919
of the manual you are building (that is the directory you would specify
2020
as a first argument to the CLI).
2121

22-
That file needs to return a ``ProjectSettings``, and typically looks as
22+
That file needs to return an `array`, and typically looks as
2323
follows:
2424

25-
.. code-block:: php
25+
.. code-block:: php
2626
27-
<?php
27+
<?php
2828
29-
use phpDocumentor\Guides\Settings\ProjectSettings;
30-
31-
return new ProjectSettings(
32-
title: 'My Documentation',
33-
version:'42.12.7'
34-
);
29+
return [
30+
'title' => 'My Project',
31+
'version' => '3.1.4',
32+
'inventories' => ['t3coreapi' => 'https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/'],
33+
];

packages/guides-cli/src/Command/Run.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use phpDocumentor\Guides\Handlers\CompileDocumentsCommand;
1717
use phpDocumentor\Guides\Handlers\ParseDirectoryCommand;
1818
use phpDocumentor\Guides\Handlers\RenderCommand;
19+
use phpDocumentor\Guides\Intersphinx\InventoryRepository;
1920
use phpDocumentor\Guides\Nodes\ProjectNode;
2021
use phpDocumentor\Guides\Settings\ProjectSettings;
2122
use phpDocumentor\Guides\Settings\SettingsManager;
@@ -33,6 +34,7 @@
3334
use function count;
3435
use function getcwd;
3536
use function implode;
37+
use function is_array;
3638
use function is_countable;
3739
use function is_dir;
3840
use function is_file;
@@ -47,6 +49,7 @@ public function __construct(
4749
private readonly Logger $logger,
4850
private readonly ThemeManager $themeManager,
4951
private readonly SettingsManager $settingsManager,
52+
private readonly InventoryRepository $inventoryRepository,
5053
) {
5154
parent::__construct('run');
5255

@@ -117,18 +120,20 @@ protected function execute(InputInterface $input, OutputInterface $output): int
117120
}
118121

119122
if (is_file($inputDir . '/settings.php')) {
120-
$settings = require $inputDir . '/settings.php';
121-
if (!$settings instanceof ProjectSettings) {
122-
throw new RuntimeException('settings.php must return an instance of ' . ProjectSettings::class);
123+
$settingsArray = require $inputDir . '/settings.php';
124+
if (!is_array($settingsArray)) {
125+
throw new RuntimeException('settings.php must return an array!');
123126
}
124127

128+
$settings = new ProjectSettings($settingsArray);
125129
$this->settingsManager->setProjectSettings($settings);
126130
$projectNode = new ProjectNode(
127131
$settings->getTitle(),
128132
$settings->getVersion(),
129133
);
134+
$this->inventoryRepository->initialize($settings->getInventories());
130135
} else {
131-
$this->settingsManager->setProjectSettings(new ProjectSettings());
136+
$this->settingsManager->setProjectSettings(new ProjectSettings([]));
132137
$projectNode = new ProjectNode();
133138
}
134139

packages/guides/resources/config/guides.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
use phpDocumentor\Guides\Compiler\NodeTransformer;
1010
use phpDocumentor\Guides\Compiler\NodeTransformers\CustomNodeTransformerFactory;
1111
use phpDocumentor\Guides\Compiler\NodeTransformers\NodeTransformerFactory;
12+
use phpDocumentor\Guides\Intersphinx\InventoryLoader;
13+
use phpDocumentor\Guides\Intersphinx\InventoryRepository;
14+
use phpDocumentor\Guides\Intersphinx\JsonLoader;
1215
use phpDocumentor\Guides\NodeRenderers\DefaultNodeRenderer;
1316
use phpDocumentor\Guides\NodeRenderers\DelegatingNodeRenderer;
1417
use phpDocumentor\Guides\NodeRenderers\Html\DocumentNodeRenderer;
@@ -24,6 +27,7 @@
2427
use phpDocumentor\Guides\ReferenceResolvers\DocReferenceResolver;
2528
use phpDocumentor\Guides\ReferenceResolvers\ExternalReferenceResolver;
2629
use phpDocumentor\Guides\ReferenceResolvers\InternalReferenceResolver;
30+
use phpDocumentor\Guides\ReferenceResolvers\IntersphinxReferenceResolver;
2731
use phpDocumentor\Guides\ReferenceResolvers\ReferenceResolver;
2832
use phpDocumentor\Guides\ReferenceResolvers\ReferenceResolverPreRender;
2933
use phpDocumentor\Guides\ReferenceResolvers\RefReferenceResolver;
@@ -42,6 +46,8 @@
4246
use phpDocumentor\Guides\UrlGeneratorInterface;
4347
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
4448
use Symfony\Component\DependencyInjection\Reference;
49+
use Symfony\Component\HttpClient\HttpClient;
50+
use Symfony\Contracts\HttpClient\HttpClientInterface;
4551
use Twig\Loader\FilesystemLoader;
4652

4753
use function Symfony\Component\DependencyInjection\Loader\Configurator\param;
@@ -99,6 +105,16 @@
99105

100106
->set(DocumentNodeTraverser::class)
101107

108+
->set(InventoryRepository::class)
109+
110+
->set(InventoryLoader::class)
111+
112+
->set(JsonLoader::class)
113+
114+
115+
->set(HttpClientInterface::class)
116+
->factory([HttpClient::class, 'create'])
117+
102118
->set(UrlGenerator::class)
103119

104120
->set(ExternalReferenceResolver::class)
@@ -109,6 +125,8 @@
109125

110126
->set(RefReferenceResolver::class)
111127

128+
->set(IntersphinxReferenceResolver::class)
129+
112130
->set(DelegatingReferenceResolver::class)
113131
->arg('$resolvers', tagged_iterator('phpdoc.guides.reference_resolver', defaultPriorityMethod: 'getPriority'))
114132

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{%- if node.internalTarget -%}
2-
<sup>[<a href="{{- renderInternalTarget(node.internalTarget) -}}">{{- node.value -}}</a>]</sup>
2+
<sup>[<a href="{{- renderTarget(node.internalTarget) -}}">{{- node.value -}}</a>]</sup>
33
{%- else -%}
44
<sup>[{{- node.value -}}]</sup>
55
{%- endif -%}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{%- if node.internalTarget -%}
2-
<sup>[<a href="{{- renderInternalTarget(node.internalTarget) -}}">{{- node.value -}}</a>]</sup>
2+
<sup>[<a href="{{- renderTarget(node.internalTarget) -}}">{{- node.value -}}</a>]</sup>
33
{%- else -%}
44
<sup>[{{- node.value -}}]</sup>
55
{%- endif -%}

packages/guides/src/Intersphinx/Inventory.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ final class Inventory
1414
/** @var InventoryGroup[] */
1515
private array $groups = [];
1616

17+
private bool $isLoaded = false;
18+
1719
public function __construct(private readonly string $baseUrl)
1820
{
1921
}
@@ -59,4 +61,16 @@ public function hasInventoryGroup(string $key): bool
5961

6062
return array_key_exists($lowerCaseKey, $this->groups);
6163
}
64+
65+
public function isLoaded(): bool
66+
{
67+
return $this->isLoaded;
68+
}
69+
70+
public function setIsLoaded(bool $isLoaded): Inventory
71+
{
72+
$this->isLoaded = $isLoaded;
73+
74+
return $this;
75+
}
6276
}

packages/guides/src/Intersphinx/InventoryLoader.php

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,14 @@
99
final class InventoryLoader
1010
{
1111
public function __construct(
12-
private readonly InventoryRepository $inventoryRepository,
1312
private readonly JsonLoader $jsonLoader,
1413
private readonly string $pathToJson = 'objects.inv.json',
1514
) {
1615
}
1716

18-
public function getInventoryRepository(): InventoryRepository
19-
{
20-
return $this->inventoryRepository;
21-
}
22-
2317
/** @param array<String, mixed> $json */
24-
public function loadInventoryFromJson(string $key, string $baseUrl, array $json): void
18+
public function loadInventoryFromJson(Inventory $inventory, array $json): void
2519
{
26-
$newInventory = new Inventory($baseUrl);
2720
foreach ($json as $groupKey => $groupArray) {
2821
$group = new InventoryGroup();
2922
if (is_array($groupArray)) {
@@ -37,16 +30,20 @@ public function loadInventoryFromJson(string $key, string $baseUrl, array $json)
3730
}
3831
}
3932

40-
$newInventory->addGroup($groupKey, $group);
33+
$inventory->addGroup($groupKey, $group);
4134
}
4235

43-
$this->inventoryRepository->addInventory($key, $newInventory);
36+
$inventory->setIsLoaded(true);
4437
}
4538

46-
public function loadInventoryFromUrl(string $key, string $url): void
39+
public function loadInventory(Inventory $inventory): void
4740
{
48-
$json = $this->jsonLoader->loadJsonFromUrl($url . $this->pathToJson);
41+
if ($inventory->isLoaded()) {
42+
return;
43+
}
44+
45+
$json = $this->jsonLoader->loadJsonFromUrl($inventory->getBaseUrl() . $this->pathToJson);
4946

50-
$this->loadInventoryFromJson($key, $url, $json);
47+
$this->loadInventoryFromJson($inventory, $json);
5148
}
5249
}

packages/guides/src/Intersphinx/InventoryRepository.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,20 @@
1111

1212
class InventoryRepository
1313
{
14-
/** @param array<String, Inventory> $inventories */
15-
public function __construct(private array $inventories)
14+
/** @var array<string, Inventory> */
15+
private array $inventories = [];
16+
17+
public function __construct(private readonly InventoryLoader $inventoryLoader)
18+
{
19+
}
20+
21+
/** @param array<string, string> $inventoryConfigs */
22+
public function initialize(array $inventoryConfigs): void
1623
{
24+
$this->inventories = [];
25+
foreach ($inventoryConfigs as $key => $url) {
26+
$this->inventories[$key] = new Inventory($url);
27+
}
1728
}
1829

1930
public function hasInventory(string $key): bool
@@ -30,6 +41,8 @@ public function getInventory(string $key): Inventory
3041
throw new RuntimeException('Inventory with key ' . $lowerCaseKey . ' not found. ', 1_671_398_986);
3142
}
3243

44+
$this->inventoryLoader->loadInventory($this->inventories[$lowerCaseKey]);
45+
3346
return $this->inventories[$lowerCaseKey];
3447
}
3548

packages/guides/src/Intersphinx/JsonLoader.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use RuntimeException;
99
use Symfony\Contracts\HttpClient\HttpClientInterface;
1010

11-
use function implode;
1211
use function is_array;
1312
use function json_decode;
1413

@@ -27,9 +26,8 @@ public function loadJsonFromUrl(string $url): array
2726
'GET',
2827
$url,
2928
);
30-
$jsonString = implode("\n", $response->toArray());
3129

32-
return $this->loadJsonFromString($jsonString, $url);
30+
return $response->toArray();
3331
}
3432

3533
/** @return array<mixed> */
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of phpDocumentor.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*
11+
* @link https://phpdoc.org
12+
*/
13+
14+
namespace phpDocumentor\Guides\Meta;
15+
16+
class ExternalTarget implements Target
17+
{
18+
public function __construct(
19+
private readonly string $url,
20+
private readonly string|null $title = null,
21+
) {
22+
}
23+
24+
public function getUrl(): string
25+
{
26+
return $this->url;
27+
}
28+
29+
public function getTitle(): string|null
30+
{
31+
return $this->title;
32+
}
33+
}

0 commit comments

Comments
 (0)