diff --git a/app/Http/Controllers/Api/CardController.php b/app/Http/Controllers/Api/CardController.php index aeaa37a..8cdf980 100644 --- a/app/Http/Controllers/Api/CardController.php +++ b/app/Http/Controllers/Api/CardController.php @@ -2,55 +2,18 @@ namespace App\Http\Controllers\Api; -use App\Metadata; -use App\MetadataResolver\MetadataResolver; -use App\Tag; -use App\Utilities\Formatter; +use App\Services\MetadataResolveService; use Illuminate\Http\Request; class CardController { - /** - * @var MetadataResolver - */ - private $resolver; - /** - * @var Formatter - */ - private $formatter; - - public function __construct(MetadataResolver $resolver, Formatter $formatter) - { - $this->resolver = $resolver; - $this->formatter = $formatter; - } - - public function show(Request $request) + public function show(Request $request, MetadataResolveService $service) { $request->validate([ 'url:required|url' ]); - $url = $this->formatter->normalizeUrl($request->input('url')); - - $metadata = Metadata::find($url); - if ($metadata === null || ($metadata->expires_at !== null && $metadata->expires_at < now())) { - $resolved = $this->resolver->resolve($url); - $metadata = Metadata::updateOrCreate(['url' => $url], [ - 'title' => $resolved->title, - 'description' => $resolved->description, - 'image' => $resolved->image, - 'expires_at' => $resolved->expires_at - ]); - - $tagIds = []; - foreach ($resolved->normalizedTags() as $tagName) { - $tag = Tag::firstOrCreate(['name' => $tagName]); - $tagIds[] = $tag->id; - } - $metadata->tags()->sync($tagIds); - } - + $metadata = $service->execute($request->input('url')); $metadata->load('tags'); $response = response($metadata); diff --git a/app/Listeners/LinkCollector.php b/app/Listeners/LinkCollector.php index 867938f..6c10e21 100644 --- a/app/Listeners/LinkCollector.php +++ b/app/Listeners/LinkCollector.php @@ -3,32 +3,23 @@ namespace App\Listeners; use App\Events\LinkDiscovered; -use App\Metadata; -use App\MetadataResolver\MetadataResolver; -use App\Tag; -use App\Utilities\Formatter; -use GuzzleHttp\Exception\TransferException; +use App\Services\MetadataResolveService; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\InteractsWithQueue; -use Illuminate\Support\Facades\Log; class LinkCollector { - /** @var Formatter */ - private $formatter; - /** @var MetadataResolver */ - private $metadataResolver; + /** @var MetadataResolveService */ + private $metadataResolveService; /** * Create the event listener. * - * @param Formatter $formatter - * @param MetadataResolver $metadataResolver + * @param MetadataResolveService $metadataResolveService */ - public function __construct(Formatter $formatter, MetadataResolver $metadataResolver) + public function __construct(MetadataResolveService $metadataResolveService) { - $this->formatter = $formatter; - $this->metadataResolver = $metadataResolver; + $this->metadataResolveService = $metadataResolveService; } /** @@ -39,33 +30,11 @@ class LinkCollector */ public function handle(LinkDiscovered $event) { - // URLの正規化 - $url = $this->formatter->normalizeUrl($event->url); - - // 無かったら取得 - // TODO: ある程度古かったら再取得とかありだと思う - $metadata = Metadata::find($url); - if ($metadata == null || ($metadata->expires_at !== null && $metadata->expires_at < now())) { - try { - $resolved = $this->metadataResolver->resolve($url); - $metadata = Metadata::updateOrCreate(['url' => $url], [ - 'title' => $resolved->title, - 'description' => $resolved->description, - 'image' => $resolved->image, - 'expires_at' => $resolved->expires_at - ]); - - $tagIds = []; - foreach ($resolved->normalizedTags() as $tagName) { - $tag = Tag::firstOrCreate(['name' => $tagName]); - $tagIds[] = $tag->id; - } - $metadata->tags()->sync($tagIds); - } catch (TransferException $e) { - // 何らかの通信エラーによってメタデータの取得に失敗した時、とりあえずエラーログにURLを残す - Log::error(self::class . ': メタデータの取得に失敗 URL=' . $url); - report($e); - } + try { + $this->metadataResolveService->execute($event->url); + } catch (\Exception $e) { + // 今のところこのイベントは同期実行されるので、上流をクラッシュさせないために雑catchする + report($e); } } } diff --git a/app/Services/MetadataResolveService.php b/app/Services/MetadataResolveService.php new file mode 100644 index 0000000..405ae9f --- /dev/null +++ b/app/Services/MetadataResolveService.php @@ -0,0 +1,58 @@ +resolver = $resolver; + $this->formatter = $formatter; + } + + public function execute(string $url): Metadata + { + // URLの正規化 + $url = $this->formatter->normalizeUrl($url); + + // 無かったら取得 + // TODO: ある程度古かったら再取得とかありだと思う + $metadata = Metadata::find($url); + if ($metadata == null || ($metadata->expires_at !== null && $metadata->expires_at < now())) { + try { + $resolved = $this->resolver->resolve($url); + $metadata = Metadata::updateOrCreate(['url' => $url], [ + 'title' => $resolved->title, + 'description' => $resolved->description, + 'image' => $resolved->image, + 'expires_at' => $resolved->expires_at + ]); + + $tagIds = []; + foreach ($resolved->normalizedTags() as $tagName) { + $tag = Tag::firstOrCreate(['name' => $tagName]); + $tagIds[] = $tag->id; + } + $metadata->tags()->sync($tagIds); + } catch (TransferException $e) { + // 何らかの通信エラーによってメタデータの取得に失敗した時、とりあえずエラーログにURLを残す + Log::error(self::class . ': メタデータの取得に失敗 URL=' . $url); + throw $e; + } + } + + return $metadata; + } +}