2023-03-08 15:31:49 +00:00
|
|
|
<?php declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace Lewisdale\Webmentions;
|
|
|
|
|
|
|
|
use Symfony\Contracts\HttpClient\ResponseInterface;
|
2023-03-08 16:07:43 +00:00
|
|
|
use Symfony\Component\DomCrawler\Crawler;
|
2023-03-08 21:27:47 +00:00
|
|
|
use League\Uri\Uri;
|
|
|
|
use League\Uri\UriInfo;
|
|
|
|
use League\Uri\UriResolver;
|
2023-03-08 15:31:49 +00:00
|
|
|
|
|
|
|
class EndpointParser {
|
|
|
|
public static function parse(ResponseInterface $response) : string | null
|
|
|
|
{
|
2023-03-08 21:27:47 +00:00
|
|
|
$endpoint = self::parseHeaders($response) ?? self::parseBody($response);
|
|
|
|
return self::absoluteURL($response, $endpoint);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static function parseHeaders(ResponseInterface $response) : string | null {
|
2023-03-08 15:31:49 +00:00
|
|
|
$headers = $response->getHeaders();
|
|
|
|
|
|
|
|
if (isset($headers["link"])) {
|
2023-03-08 21:27:47 +00:00
|
|
|
foreach($headers["link"] as $link) {
|
|
|
|
if (preg_match('/rel=("?)webmention("?)/', $link)) {
|
|
|
|
$matches = [];
|
|
|
|
preg_match('/\<(..*?)\>/', $link, $matches);
|
2023-03-08 15:31:49 +00:00
|
|
|
|
2023-03-08 21:27:47 +00:00
|
|
|
if (count($matches) > 1) {
|
|
|
|
return $matches[1];
|
|
|
|
}
|
2023-03-08 15:31:49 +00:00
|
|
|
}
|
2023-03-08 21:27:47 +00:00
|
|
|
}
|
2023-03-08 15:31:49 +00:00
|
|
|
}
|
|
|
|
|
2023-03-08 21:27:47 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static function absoluteURL(ResponseInterface $response, ?string $endpoint) : string | null {
|
2023-03-08 16:07:43 +00:00
|
|
|
if (!$endpoint) {
|
2023-03-08 21:27:47 +00:00
|
|
|
return null;
|
2023-03-08 16:07:43 +00:00
|
|
|
}
|
|
|
|
|
2023-03-08 21:27:47 +00:00
|
|
|
$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);
|
2023-03-08 15:31:49 +00:00
|
|
|
}
|
2023-03-08 21:27:47 +00:00
|
|
|
|
|
|
|
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;
|
2023-03-08 15:31:49 +00:00
|
|
|
}
|
|
|
|
}
|