webmentions/src/EndpointParser.php

63 lines
1.9 KiB
PHP

<?php declare(strict_types=1);
namespace Lewisdale\Webmentions;
use Symfony\Contracts\HttpClient\ResponseInterface;
use Symfony\Component\DomCrawler\Crawler;
use League\Uri\Uri;
use League\Uri\UriInfo;
use League\Uri\UriResolver;
class EndpointParser {
public static function parse(ResponseInterface $response) : string | null
{
$endpoint = self::parseHeaders($response) ?? self::parseBody($response);
return self::absoluteURL($response, $endpoint);
}
private static function parseHeaders(ResponseInterface $response) : string | null {
$headers = $response->getHeaders();
if (isset($headers["link"])) {
foreach($headers["link"] as $link) {
if (preg_match('/rel=("?)webmention("?)/', $link)) {
$matches = [];
preg_match('/\<(..*?)\>/', $link, $matches);
if (count($matches) > 1) {
return $matches[1];
}
}
}
}
return null;
}
private static function absoluteURL(ResponseInterface $response, ?string $endpoint) : string | null {
if (!$endpoint) {
return null;
}
$url = $response->getInfo("redirect_url") ?? $response->getInfo('url');
$uri = Uri::createFromString($url);
$endpoint = Uri::createFromString($endpoint);
if (!UriInfo::isAbsolute($endpoint)) {
return (string) UriResolver::resolve($endpoint, $uri);
}
return (string) $endpoint;
}
private static function parseBody(ResponseInterface $response) : string | null {
$doc = new Crawler($response->getContent());
$webmentions = $doc->filter('[rel="webmention"][href]');
if ($webmentions->count()) {
return $webmentions->first()->attr('href');
}
return null;
}
}