63 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			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;
 | 
						|
    }
 | 
						|
} |