109 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						||
 | 
						||
namespace App\MetadataResolver;
 | 
						||
 | 
						||
use GuzzleHttp\Client;
 | 
						||
use GuzzleHttp\Cookie\CookieJar;
 | 
						||
use Symfony\Component\DomCrawler\Crawler;
 | 
						||
 | 
						||
class FanzaResolver implements Resolver
 | 
						||
{
 | 
						||
    /**
 | 
						||
     * @var Client
 | 
						||
     */
 | 
						||
    private $client;
 | 
						||
    /**
 | 
						||
     * @var OGPResolver
 | 
						||
     */
 | 
						||
    private $ogpResolver;
 | 
						||
 | 
						||
    public function __construct(Client $client, OGPResolver $ogpResolver)
 | 
						||
    {
 | 
						||
        $this->client = $client;
 | 
						||
        $this->ogpResolver = $ogpResolver;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * arrayの各要素をtrim・スペースの_置換をした後、重複した値を削除してキーを詰め直す
 | 
						||
     *
 | 
						||
     * @param array $array
 | 
						||
     *
 | 
						||
     * @return array 処理されたarray
 | 
						||
     */
 | 
						||
    public function array_finish(array $array): array
 | 
						||
    {
 | 
						||
        $array = array_map('trim', $array);
 | 
						||
        $array = array_map((function ($value) {
 | 
						||
            return str_replace(' ', '_', $value);
 | 
						||
        }), $array);
 | 
						||
        $array = array_unique($array);
 | 
						||
        $array = array_values($array);
 | 
						||
 | 
						||
        return $array;
 | 
						||
    }
 | 
						||
 | 
						||
    public function resolve(string $url): Metadata
 | 
						||
    {
 | 
						||
        $cookieJar = CookieJar::fromArray(['age_check_done' => '1'], 'dmm.co.jp');
 | 
						||
 | 
						||
        $res = $this->client->get($url, ['cookies' => $cookieJar]);
 | 
						||
        $html = (string) $res->getBody();
 | 
						||
        $crawler = new Crawler($html);
 | 
						||
 | 
						||
        // 動画
 | 
						||
        if (preg_match('~www\.dmm\.co\.jp/digital/(videoa|videoc|anime)/-/detail~', $url)) {
 | 
						||
            $metadata = new Metadata();
 | 
						||
            $metadata->title = trim($crawler->filter('#title')->text(''));
 | 
						||
            $metadata->description = trim($crawler->filter('.box-rank+table+div+div')->text(''));
 | 
						||
            $metadata->image = preg_replace("~(pr|ps)\.jpg$~", 'pl.jpg', $crawler->filter('meta[property="og:image"]')->attr('content'));
 | 
						||
            $metadata->tags = $this->array_finish($crawler->filter('.box-rank+table a:not([href="#review"])')->extract(['_text']));
 | 
						||
 | 
						||
            return $metadata;
 | 
						||
        }
 | 
						||
 | 
						||
        // 同人
 | 
						||
        if (mb_strpos($url, 'www.dmm.co.jp/dc/doujin/-/detail/') !== false) {
 | 
						||
            $genre = $this->array_finish($crawler->filter('.m-productInformation a:not([href="#update-top"])')->extract(['_text']));
 | 
						||
            $genre = array_filter($genre, (function ($text) {
 | 
						||
                return !preg_match('~%OFF対象$~', $text);
 | 
						||
            }));
 | 
						||
 | 
						||
            $metadata = new Metadata();
 | 
						||
            $metadata->title = $crawler->filter('meta[property="og:title"]')->attr('content');
 | 
						||
            $metadata->description = trim($crawler->filter('.summary__txt')->text(''));
 | 
						||
            $metadata->image = $crawler->filter('meta[property="og:image"]')->attr('content');
 | 
						||
            $metadata->tags = array_merge($genre, [$crawler->filter('.circleName__txt')->text('')]);
 | 
						||
 | 
						||
            return $metadata;
 | 
						||
        }
 | 
						||
 | 
						||
        // 電子書籍
 | 
						||
        if (mb_strpos($url, 'book.dmm.co.jp/detail/') !== false) {
 | 
						||
            $metadata = new Metadata();
 | 
						||
            $metadata->title = trim($crawler->filter('#title')->text(''));
 | 
						||
            $metadata->description = trim($crawler->filter('.m-boxDetailProduct__info__story')->text(''));
 | 
						||
            $metadata->image = preg_replace("~(pr|ps)\.jpg$~", 'pl.jpg', $crawler->filter('meta[property="og:image"]')->attr('content'));
 | 
						||
            $metadata->tags = $this->array_finish($crawler->filter('.m-boxDetailProductInfoMainList__description__list__item, .m-boxDetailProductInfo__list__description__item a')->extract(['_text']));
 | 
						||
 | 
						||
            return $metadata;
 | 
						||
        }
 | 
						||
 | 
						||
        // PCゲーム
 | 
						||
        if (mb_strpos($url, 'dlsoft.dmm.co.jp/detail/') !== false) {
 | 
						||
            $metadata = new Metadata();
 | 
						||
            $metadata->title = trim($crawler->filter('#title')->text(''));
 | 
						||
            $metadata->description = trim($crawler->filter('.area-detail-read .text-overflow')->text(''));
 | 
						||
            $metadata->image = preg_replace("~(pr|ps)\.jpg$~", 'pl.jpg', $crawler->filter('meta[property="og:image"]')->attr('content'));
 | 
						||
            $metadata->tags = $this->array_finish($crawler->filter('.area-bskt table a:not([href="#review"])')->extract(['_text']));
 | 
						||
 | 
						||
            return $metadata;
 | 
						||
        }
 | 
						||
 | 
						||
        // 上で特に対応しなかったURL 画像の置換くらいはしておく
 | 
						||
        $metadata = $this->ogpResolver->parse($html);
 | 
						||
        $metadata->image = preg_replace("~(pr|ps)\.jpg$~", 'pl.jpg', $metadata->image);
 | 
						||
 | 
						||
        return $metadata;
 | 
						||
    }
 | 
						||
}
 |