Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function __construct(
) {
}

public function resolve(LinkInlineNode $node, RenderContext $renderContext): bool
public function resolve(LinkInlineNode $node, RenderContext $renderContext, Messages $messages): bool
{
if (!$node instanceof HyperLinkNode) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function __construct(
) {
}

public function resolve(LinkInlineNode $node, RenderContext $renderContext): bool
public function resolve(LinkInlineNode $node, RenderContext $renderContext, Messages $messages): bool
{
if (!$node instanceof ReferenceNode) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,25 @@

use phpDocumentor\Guides\Nodes\Inline\LinkInlineNode;
use phpDocumentor\Guides\RenderContext;
use Psr\Log\LoggerInterface;

use function sprintf;

/**
* Resolves the URL for all inline link nodes using reference resolvers.
*/
final class DelegatingReferenceResolver
{
/** @param iterable<ReferenceResolver> $resolvers */
public function __construct(private readonly iterable $resolvers, private readonly LoggerInterface $logger)
public function __construct(private readonly iterable $resolvers)
{
}

public function resolve(LinkInlineNode $node, RenderContext $renderContext): void
public function resolve(LinkInlineNode $node, RenderContext $renderContext, Messages $messages): bool
{
foreach ($this->resolvers as $resolver) {
if ($resolver->resolve($node, $renderContext)) {
return;
if ($resolver->resolve($node, $renderContext, $messages)) {
return true;
}
}

$this->logger->warning(
sprintf(
'Reference %s could not be resolved in %s',
$node->getTargetReference(),
$renderContext->getCurrentFileName(),
),
$renderContext->getLoggerInformation(),
);
return false;
}
}
18 changes: 6 additions & 12 deletions packages/guides/src/ReferenceResolvers/DocReferenceResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
use phpDocumentor\Guides\Nodes\Inline\LinkInlineNode;
use phpDocumentor\Guides\RenderContext;
use phpDocumentor\Guides\Renderer\UrlGenerator\UrlGeneratorInterface;
use Psr\Log\LoggerInterface;

use function array_merge;
use function sprintf;

class DocReferenceResolver implements ReferenceResolver
Expand All @@ -20,11 +18,10 @@ class DocReferenceResolver implements ReferenceResolver
public function __construct(
private readonly UrlGeneratorInterface $urlGenerator,
private readonly DocumentNameResolverInterface $documentNameResolver,
private readonly LoggerInterface $logger,
) {
}

public function resolve(LinkInlineNode $node, RenderContext $renderContext): bool
public function resolve(LinkInlineNode $node, RenderContext $renderContext, Messages $messages): bool
{
if (!$node instanceof DocReferenceNode) {
return false;
Expand All @@ -38,14 +35,11 @@ public function resolve(LinkInlineNode $node, RenderContext $renderContext): boo

$document = $renderContext->getProjectNode()->findDocumentEntry($canonicalDocumentName);
if ($document === null) {
$this->logger->warning(
sprintf(
'Document with name "%s" not found, required in file "%s".',
$canonicalDocumentName,
$renderContext->getCurrentFileName(),
),
array_merge($renderContext->getLoggerInformation(), $node->getDebugInformation()),
);
$messages->addWarning(new Message(sprintf(
'Document with name "%s" not found, required in file "%s".',
$canonicalDocumentName,
$renderContext->getCurrentFileName(),
)));

return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class EmailReferenceResolver implements ReferenceResolver
{
public final const PRIORITY = -100;

public function resolve(LinkInlineNode $node, RenderContext $renderContext): bool
public function resolve(LinkInlineNode $node, RenderContext $renderContext, Messages $messages): bool
{
if (filter_var($node->getTargetReference(), FILTER_VALIDATE_EMAIL)) {
$node->setUrl('mailto:' . $node->getTargetReference());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class ExternalReferenceResolver implements ReferenceResolver
public final const PRIORITY = -100;
final public const SUPPORTED_SCHEMAS = '(?:aaa|aaas|about|acap|acct|acd|acr|adiumxtra|adt|afp|afs|aim|amss|android|appdata|apt|ar|ark|at|attachment|aw|barion|bb|beshare|bitcoin|bitcoincash|blob|bolo|browserext|cabal|calculator|callto|cap|cast|casts|chrome|chrome-extension|cid|coap|coap+tcp|coap+ws|coaps|coaps+tcp|coaps+ws|com-eventbrite-attendee|content|content-type|crid|cstr|cvs|dab|dat|data|dav|dhttp|diaspora|dict|did|dis|dlna-playcontainer|dlna-playsingle|dns|dntp|doi|dpp|drm|drop|dtmi|dtn|dvb|dvx|dweb|ed2k|eid|elsi|embedded|ens|ethereum|example|facetime|fax|feed|feedready|fido|file|filesystem|finger|first-run-pen-experience|fish|fm|ftp|fuchsia-pkg|geo|gg|git|gitoid|gizmoproject|go|gopher|graph|grd|gtalk|h323|ham|hcap|hcp|http|https|hxxp|hxxps|hydrazone|hyper|iax|icap|icon|im|imap|info|iotdisco|ipfs|ipn|ipns|ipp|ipps|irc|irc6|ircs|iris|iris\.beep|iris\.lwz|iris\.xpc|iris\.xpcs|isostore|itms|jabber|jar|jms|keyparc|lastfm|lbry|ldap|ldaps|leaptofrogans|lorawan|lpa|lvlt|magnet|mailserver|mailto|maps|market|matrix|message|microsoft\.windows\.camera|microsoft\.windows\.camera\.multipicker|microsoft\.windows\.camera\.picker|mid|mms|modem|mongodb|moz|ms-access|ms-appinstaller|ms-browser-extension|ms-calculator|ms-drive-to|ms-enrollment|ms-excel|ms-eyecontrolspeech|ms-gamebarservices|ms-gamingoverlay|ms-getoffice|ms-help|ms-infopath|ms-inputapp|ms-launchremotedesktop|ms-lockscreencomponent-config|ms-media-stream-id|ms-meetnow|ms-mixedrealitycapture|ms-mobileplans|ms-newsandinterests|ms-officeapp|ms-people|ms-project|ms-powerpoint|ms-publisher|ms-remotedesktop|ms-remotedesktop-launch|ms-restoretabcompanion|ms-screenclip|ms-screensketch|ms-search|ms-search-repair|ms-secondary-screen-controller|ms-secondary-screen-setup|ms-settings|ms-settings-airplanemode|ms-settings-bluetooth|ms-settings-camera|ms-settings-cellular|ms-settings-cloudstorage|ms-settings-connectabledevices|ms-settings-displays-topology|ms-settings-emailandaccounts|ms-settings-language|ms-settings-location|ms-settings-lock|ms-settings-nfctransactions|ms-settings-notifications|ms-settings-power|ms-settings-privacy|ms-settings-proximity|ms-settings-screenrotation|ms-settings-wifi|ms-settings-workplace|ms-spd|ms-stickers|ms-sttoverlay|ms-transit-to|ms-useractivityset|ms-virtualtouchpad|ms-visio|ms-walk-to|ms-whiteboard|ms-whiteboard-cmd|ms-word|msnim|msrp|msrps|mss|mt|mtqp|mumble|mupdate|mvn|news|nfs|ni|nih|nntp|notes|num|ocf|oid|onenote|onenote-cmd|opaquelocktoken|openpgp4fpr|otpauth|p1|pack|palm|paparazzi|payment|payto|pkcs11|platform|pop|pres|prospero|proxy|pwid|psyc|pttp|qb|query|quic-transport|redis|rediss|reload|res|resource|rmi|rsync|rtmfp|rtmp|rtsp|rtsps|rtspu|sarif|secondlife|secret-token|service|session|sftp|sgn|shc|shttp (OBSOLETE)|sieve|simpleledger|simplex|sip|sips|skype|smb|smp|sms|smtp|snews|snmp|soap\.beep|soap\.beeps|soldat|spiffe|spotify|ssb|ssh|starknet|steam|stun|stuns|submit|svn|swh|swid|swidpath|tag|taler|teamspeak|tel|teliaeid|telnet|tftp|things|thismessage|tip|tn3270|tool|turn|turns|tv|udp|unreal|upt|urn|ut2004|uuid-in-package|v-event|vemmi|ventrilo|ves|videotex|vnc|view-source|vscode|vscode-insiders|vsls|w3|wais|web3|wcr|webcal|web+ap|wifi|wpid|ws|wss|wtai|wyciwyg|xcon|xcon-userid|xfire|xmlrpc\.beep|xmlrpc\.beeps|xmpp|xri|ymsgr|z39\.50|z39\.50r|z39\.50s)';

public function resolve(LinkInlineNode $node, RenderContext $renderContext): bool
public function resolve(LinkInlineNode $node, RenderContext $renderContext, Messages $messages): bool
{
if (str_starts_with($node->getTargetReference(), '#')) {
$node->setUrl($node->getTargetReference());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
use phpDocumentor\Guides\Nodes\Inline\DocReferenceNode;
use phpDocumentor\Guides\Nodes\Inline\LinkInlineNode;
use phpDocumentor\Guides\RenderContext;
use Psr\Log\LoggerInterface;

use function array_merge;
use function sprintf;

class InterlinkReferenceResolver implements ReferenceResolver
Expand All @@ -20,11 +18,10 @@ class InterlinkReferenceResolver implements ReferenceResolver

public function __construct(
private readonly InventoryRepository $inventoryRepository,
private readonly LoggerInterface $logger,
) {
}

public function resolve(LinkInlineNode $node, RenderContext $renderContext): bool
public function resolve(LinkInlineNode $node, RenderContext $renderContext, Messages $messages): bool
{
if (!$node instanceof CrossReferenceNode || $node->getInterlinkDomain() === '') {
return false;
Expand All @@ -33,13 +30,15 @@ public function resolve(LinkInlineNode $node, RenderContext $renderContext): boo
$domain = $node->getInterlinkDomain();
$target = $node->getTargetReference();
if (!$this->inventoryRepository->hasInventory($domain)) {
$this->logger->warning(
sprintf(
'Inventory with name "%s" could not be resolved in file "%s". ',
$domain,
$renderContext->getCurrentFileName(),
$messages->addWarning(
new Message(
sprintf(
'Inventory with name "%s" could not be resolved in file "%s". ',
$domain,
$renderContext->getCurrentFileName(),
),
$node->getDebugInformation(),
),
array_merge($renderContext->getLoggerInformation(), $node->getDebugInformation()),
);

return false;
Expand All @@ -48,31 +47,31 @@ public function resolve(LinkInlineNode $node, RenderContext $renderContext): boo
$inventory = $this->inventoryRepository->getInventory($domain);
$group = $node instanceof DocReferenceNode ? 'std:doc' : 'std:label';
if (!$inventory->hasInventoryGroup($group)) {
$this->logger->warning(
$messages->addWarning(new Message(
sprintf(
'Inventory with name "%s" does not contain group %s, required in file "%s". ',
$domain,
$group,
$renderContext->getCurrentFileName(),
),
array_merge($renderContext->getLoggerInformation(), $node->getDebugInformation()),
);
$node->getDebugInformation(),
));

return false;
}

$inventoryGroup = $inventory->getInventory($group);
if (!$inventoryGroup->hasLink($target)) {
$this->logger->warning(
$messages->addWarning(new Message(
sprintf(
'Link with name "%s:%s" not found in group "%s", required in file "%s".',
$domain,
$target,
$group,
$renderContext->getCurrentFileName(),
),
array_merge($renderContext->getLoggerInformation(), $node->getDebugInformation()),
);
$node->getDebugInformation(),
));

return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class InternalReferenceResolver implements ReferenceResolver
{
public final const PRIORITY = 100;

public function resolve(LinkInlineNode $node, RenderContext $renderContext): bool
public function resolve(LinkInlineNode $node, RenderContext $renderContext, Messages $messages): bool
{
$link = $renderContext->getLink($node->getTargetReference());
if ($link) {
Expand Down
26 changes: 26 additions & 0 deletions packages/guides/src/ReferenceResolvers/Message.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace phpDocumentor\Guides\ReferenceResolvers;

class Message
{
/** @param array<string, mixed> $debugInfo */
public function __construct(
private readonly string $message,
private readonly array $debugInfo = [],
) {
}

public function getMessage(): string
{
return $this->message;
}

/** @return mixed[] */
public function getDebugInfo(): array
{
return $this->debugInfo;
}
}
33 changes: 33 additions & 0 deletions packages/guides/src/ReferenceResolvers/Messages.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace phpDocumentor\Guides\ReferenceResolvers;

use function end;

final class Messages
{
/** @var list<Message> */
private array $warnings = [];

public function addWarning(Message $warning): void
{
$this->warnings[] = $warning;
}

/** @return Message[] */
public function getWarnings(): array
{
return $this->warnings;
}

public function getLastWarning(): Message|null
{
if (!empty($this->warnings)) {
return end($this->warnings);
}

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function __construct(
) {
}

public function resolve(LinkInlineNode $node, RenderContext $renderContext): bool
public function resolve(LinkInlineNode $node, RenderContext $renderContext, Messages $messages): bool
{
if (!$node instanceof HyperLinkNode) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
interface ReferenceResolver
{
/** @return bool true if the reference is resolved */
public function resolve(LinkInlineNode $node, RenderContext $renderContext): bool;
public function resolve(LinkInlineNode $node, RenderContext $renderContext, Messages $messages): bool;

public static function getPriority(): int;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@
use phpDocumentor\Guides\Nodes\Inline\LinkInlineNode;
use phpDocumentor\Guides\Nodes\Node;
use phpDocumentor\Guides\RenderContext;
use Psr\Log\LoggerInterface;
use Webmozart\Assert\Assert;

use function array_merge;
use function sprintf;

final class ReferenceResolverPreRender implements PreNodeRenderer
{
public function __construct(private readonly DelegatingReferenceResolver $referenceResolver)
{
public function __construct(
private readonly DelegatingReferenceResolver $referenceResolver,
private readonly LoggerInterface $logger,
) {
}

public function supports(Node $node): bool
Expand All @@ -24,7 +30,18 @@ public function supports(Node $node): bool
public function execute(Node $node, RenderContext $renderContext): Node
{
Assert::isInstanceOf($node, LinkInlineNode::class);
$this->referenceResolver->resolve($node, $renderContext);
$messages = new Messages();
$resolved = $this->referenceResolver->resolve($node, $renderContext, $messages);
if (!$resolved) {
$this->logger->warning(
$messages->getLastWarning()?->getMessage() ?? sprintf(
'Reference %s could not be resolved in %s',
$node->getTargetReference(),
$renderContext->getCurrentFileName(),
),
array_merge($renderContext->getLoggerInformation(), $messages->getLastWarning()?->getDebugInfo() ?? []),
);
}

return $node;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,18 @@ public function testAnchorReducerGetsCalledOndResolvingReference(): void
{
$this->anchorReducer->expects(self::once())->method('reduceAnchor')->willReturn('reduced-anchor');
$input = new ReferenceNode('lorem-ipsum');
self::assertTrue($this->subject->resolve($input, $this->renderContext));
$messages = new Messages();
self::assertTrue($this->subject->resolve($input, $this->renderContext, $messages));
self::assertEmpty($messages->getWarnings());
}

public function testResolvedReferenceReturnsCanonicalUrl(): void
{
$this->urlGenerator->method('generateCanonicalOutputUrl')->willReturn('canonical-url');
$input = new ReferenceNode('lorem-ipsum');
self::assertTrue($this->subject->resolve($input, $this->renderContext));
$messages = new Messages();
self::assertTrue($this->subject->resolve($input, $this->renderContext, $messages));
self::assertEmpty($messages->getWarnings());
self::assertEquals('canonical-url', $input->getUrl());
}
}