Skip to content

Commit

Permalink
Merge pull request #20 from hyvor/original-url
Browse files Browse the repository at this point in the history
Original url, single config object
  • Loading branch information
supun-io authored Oct 24, 2024
2 parents 64f4314 + aa82bd1 commit df48ff0
Show file tree
Hide file tree
Showing 27 changed files with 287 additions and 168 deletions.
29 changes: 13 additions & 16 deletions src/Embed/Embed.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
use Hyvor\Unfold\Exception\EmbedParserException;
use Hyvor\Unfold\Exception\EmbedUnableToResolveException;
use Hyvor\Unfold\Exception\UnfoldException;
use Hyvor\Unfold\UnfoldCallContext;
use Hyvor\Unfold\UnfoldConfig;
use Hyvor\Unfold\Unfolded\Unfolded;
use Hyvor\Unfold\UnfoldMethod;

class Embed
{
Expand All @@ -16,33 +16,31 @@ class Embed
*/
public static function getParsers(): array
{
$namespace = __NAMESPACE__.'\\Platforms\\';
$namespace = __NAMESPACE__ . '\\Platforms\\';

$parsers = array_map(
fn ($file) => $namespace.pathinfo((string) $file, PATHINFO_FILENAME),
(array) glob(__DIR__.'/Platforms/*.php')
fn($file) => $namespace . pathinfo((string)$file, PATHINFO_FILENAME),
(array)glob(__DIR__ . '/Platforms/*.php')
);

usort($parsers, fn ($a, $b) => $b::PRIORITY <=> $a::PRIORITY);
usort($parsers, fn($a, $b) => $b::PRIORITY <=> $a::PRIORITY);

return $parsers;
}

/**
* @throws EmbedParserException
*/
public static function parse(
string $url,
?UnfoldConfig $config = null,
): EmbedResponseObject {
public static function parse(UnfoldConfig $config): EmbedResponseObject
{
foreach (self::getParsers() as $parserClass) {
/** @var EmbedParserAbstract $parser */
$parser = new $parserClass($url, $config);
$parser = new $parserClass($config);
if ($matches = $parser->match()) {
return $parser->parse($matches);
}
}
throw new EmbedUnableToResolveException;
throw new EmbedUnableToResolveException();
}

/**
Expand All @@ -52,7 +50,7 @@ public static function getMatchingParser(string $url): ?array
{
foreach (self::getParsers() as $parserClass) {
/** @var EmbedParserAbstract $parser */
$parser = new $parserClass($url);
$parser = new $parserClass(UnfoldConfig::withUrlAndMethod($url, UnfoldMethod::EMBED));
if ($parser->match()) {
return [
'parser' => $parser,
Expand All @@ -68,14 +66,13 @@ public static function getMatchingParser(string $url): ?array
* @throws UnfoldException
*/
public static function getUnfoldedObject(
UnfoldCallContext $context,
UnfoldConfig $config,
): Unfolded {
$oembed = self::parse($context->url, $context->config);
$oembed = self::parse($config);

return Unfolded::fromEmbed(
$oembed,
$context->url,
$context
$config
);
}
}
24 changes: 3 additions & 21 deletions src/Embed/EmbedParserAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,8 @@ abstract class EmbedParserAbstract
// define priority relatively
public const PRIORITY = 0;

protected UnfoldConfig $config;

public function __construct(
protected string $url,
?UnfoldConfig $config = null,
) {
$this->config = $config ?? new UnfoldConfig();
}


/**
* TODO: This is not yet used
* If the URL needs to be replaced before sending to the oEmbed endpoint,
* return the new URL here. Otherwise, return null
* Ex: m.facebook.com -> www.facebook.com
* @codeCoverageIgnore
*/
public function replaceUrl(): ?string
public function __construct(protected UnfoldConfig $config)
{
return null;
}

/**
Expand All @@ -65,7 +47,7 @@ public function match(): false|array
$regex = $this->regex();

foreach ($regex as $reg) {
if (preg_match("~$reg~", $this->url, $matches)) {
if (preg_match("~$reg~", $this->config->url, $matches)) {
return $matches;
}
}
Expand Down Expand Up @@ -108,7 +90,7 @@ private function parseOEmbed(): EmbedResponseObject
$uri = Uri::withQueryValues(
new Uri($oEmbedUrl),
[
'url' => $this->url,
'url' => $this->config->url,
'format' => 'json'
]
);
Expand Down
2 changes: 1 addition & 1 deletion src/Embed/Platforms/FacebookPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function regex()

public function getEmbedHtml(array $matches): string
{
$url = $this->url;
$url = $this->config->url;

$name = explode('/', $url)[3] ?? '';
$sdk = FacebookHelper::sdkScript();
Expand Down
2 changes: 1 addition & 1 deletion src/Embed/Platforms/FacebookPost.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function regex()

public function getEmbedHtml(array $matches): string
{
$url = $this->url;
$url = $this->config->url;
$sdk = FacebookHelper::sdkScript();

return <<<HTML
Expand Down
2 changes: 1 addition & 1 deletion src/Embed/Platforms/FacebookVideo.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function regex()
public function getEmbedHtml(array $matches): string
{
$sdk = FacebookHelper::sdkScript();
$url = $this->url;
$url = $this->config->url;
return <<<HTML
$sdk
<div class="fb-video" data-href="$url" data-width="500" data-show-text="true"></div>
Expand Down
2 changes: 1 addition & 1 deletion src/Embed/Platforms/GithubGist.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ public function regex()

public function getEmbedHtml($matches): string
{
return "<script src=\"$this->url.js\"></script>";
return "<script src=\"{$this->config->url}.js\"></script>";
}
}
6 changes: 3 additions & 3 deletions src/Embed/Platforms/Youtube.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ public function getEmbedHtml($matches): string
{
$id = $matches[1] ?? '';

$isShort = str_contains($this->url, '/shorts/');
$isPlaylist = str_contains($this->url, '/playlist?list=');
$isUser = str_contains($this->url, '/user/');
$isShort = str_contains($this->config->url, '/shorts/');
$isPlaylist = str_contains($this->config->url, '/playlist?list=');
$isUser = str_contains($this->config->url, '/user/');

$padding = round(100 * ($isShort ? 16 / 9 : 9 / 16), 2);

Expand Down
33 changes: 23 additions & 10 deletions src/Link/Link.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,39 @@
namespace Hyvor\Unfold\Link;

use GuzzleHttp\Psr7\Request;
use Http\Client\Common\Exception\LoopException;
use Hyvor\Unfold\Exception\LinkScrapeException;
use Hyvor\Unfold\Link\Metadata\MetadataParser;
use Hyvor\Unfold\UnfoldCallContext;
use Hyvor\Unfold\UnfoldConfig;
use Hyvor\Unfold\Unfolded\Unfolded;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Message\RequestInterface;

class Link
{

private ?RequestInterface $lastRequest = null;

public function __construct(
private string $url,
private UnfoldConfig $config,
) {}
) {
}

public function scrape(): string
{
$request = new Request(
'GET',
$this->url
$this->config->url
);

try {
$response = $this->config->httpClient->sendRequest($request);
} catch (ClientExceptionInterface $e) {
throw new LinkScrapeException($e->getMessage());
$message = match (true) {
$e instanceof LoopException => 'Too many redirects',
default => $e->getMessage(),
};
throw new LinkScrapeException($message);
}

$status = $response->getStatusCode();
Expand All @@ -36,19 +44,24 @@ public function scrape(): string
throw new LinkScrapeException("Unable to scrape link. HTTP status code: $status");
}

$this->lastRequest = $this->config->httpRequestRecorder->getLastRequest();

return $response->getBody()->getContents();
}

public static function getUnfoldedObject(
UnfoldCallContext $context,
UnfoldConfig $config,
): Unfolded {
$content = (new Link($context->url, $context->config))->scrape();
$metadata = (new MetadataParser($content, $context))->parse();
$link = new Link($config);
$content = $link->scrape();
$lastRequest = $link->lastRequest;

$metadata = (new MetadataParser($content, $config))->parse();

return Unfolded::fromMetadata(
$context->url,
$config,
$metadata,
$context,
$lastRequest,
);
}
}
4 changes: 2 additions & 2 deletions src/Link/Metadata/MetadataParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use Hyvor\Unfold\Link\Metadata\Parsers\OgParser;
use Hyvor\Unfold\Link\Metadata\Parsers\TitleParser;
use Hyvor\Unfold\Link\Metadata\Parsers\TwitterParser;
use Hyvor\Unfold\UnfoldCallContext;
use Hyvor\Unfold\UnfoldConfig;
use Symfony\Component\DomCrawler\Crawler;

class MetadataParser
Expand All @@ -28,7 +28,7 @@ class MetadataParser

public function __construct(
private string $content,
public UnfoldCallContext $context,
public UnfoldConfig $config,
) {
$this->crawler = new Crawler($this->content);
$this->crawlerMeta = $this->crawler->filterXPath('//meta');
Expand Down
10 changes: 7 additions & 3 deletions src/Link/Metadata/Parsers/LinkParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ public function add(): void
$href = $node->attr('href');

if ($rel === 'canonical' && is_string($href)) {
$this->parser->addMetadata(new MetadataObject(MetadataKeyType::CANONICAL_URL, $this->fixIfRelativeUrl($href)));
$this->parser->addMetadata(
new MetadataObject(MetadataKeyType::CANONICAL_URL, $this->fixIfRelativeUrl($href))
);
}

if ($rel === 'icon' && is_string($href)) {
$this->parser->addMetadata(new MetadataObject(MetadataKeyType::FAVICON_URL, $this->fixIfRelativeUrl($href)));
$this->parser->addMetadata(
new MetadataObject(MetadataKeyType::FAVICON_URL, $this->fixIfRelativeUrl($href))
);
}
});
}
Expand All @@ -30,7 +34,7 @@ public function fixIfRelativeUrl(string $url): string
if (isset($parsedUrl['host'])) {
return $url;
} else {
return Uri::fromBaseUri($url, $this->parser->context->url)->toString();
return Uri::fromBaseUri($url, $this->parser->config->url)->toString();
}
}
}
30 changes: 30 additions & 0 deletions src/Link/RequestRecorder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Hyvor\Unfold\Link;

use Http\Client\Common\Plugin\Journal;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

class RequestRecorder implements Journal
{
/** @var RequestInterface[] */
private array $requests = [];

public function addSuccess(RequestInterface $request, ResponseInterface $response): void
{
$this->requests[] = $request;
}

public function addFailure(RequestInterface $request, ClientExceptionInterface $exception): void
{
}

public function getLastRequest(): ?RequestInterface
{
return count($this->requests) > 0 ?
$this->requests[count($this->requests) - 1] :
null;
}
}
10 changes: 3 additions & 7 deletions src/Unfold.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,12 @@ public static function unfold(
UnfoldConfig $config = null,
): Unfolded {
$config ??= new UnfoldConfig();
$context = new UnfoldCallContext(
$url,
$method,
$config,
);
$config->start($url, $method);

if ($method === UnfoldMethod::LINK) {
return Link::getUnfoldedObject($context);
return Link::getUnfoldedObject($config);
} elseif ($method === UnfoldMethod::EMBED) {
return Embed::getUnfoldedObject($context);
return Embed::getUnfoldedObject($config);
} else {
// both
// TODO:
Expand Down
22 changes: 0 additions & 22 deletions src/UnfoldCallContext.php

This file was deleted.

Loading

0 comments on commit df48ff0

Please sign in to comment.