2019-01-14 16:01:58 +09:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\MetadataResolver;
|
|
|
|
|
|
2019-02-17 02:58:36 +09:00
|
|
|
|
use GuzzleHttp\Client;
|
|
|
|
|
|
2019-01-14 16:01:58 +09:00
|
|
|
|
class PixivResolver implements Resolver
|
|
|
|
|
{
|
2019-02-17 02:58:36 +09:00
|
|
|
|
/**
|
|
|
|
|
* @var Client
|
|
|
|
|
*/
|
|
|
|
|
private $client;
|
|
|
|
|
/**
|
|
|
|
|
* @var OGPResolver
|
|
|
|
|
*/
|
|
|
|
|
private $ogpResolver;
|
|
|
|
|
|
|
|
|
|
public function __construct(Client $client, OGPResolver $ogpResolver)
|
|
|
|
|
{
|
|
|
|
|
$this->client = $client;
|
|
|
|
|
$this->ogpResolver = $ogpResolver;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-14 16:11:14 +09:00
|
|
|
|
/**
|
|
|
|
|
* 直リン可能な pixiv.cat のプロキシ URL に変換する
|
|
|
|
|
* HUGE THANKS TO PIXIV.CAT!
|
|
|
|
|
*
|
2019-01-14 18:34:33 +09:00
|
|
|
|
* @param string $pixivUrl i.pximg URL
|
2019-02-12 22:48:44 +09:00
|
|
|
|
*
|
2019-01-14 16:11:14 +09:00
|
|
|
|
* @return string i.pixiv.cat URL
|
|
|
|
|
*/
|
2019-01-15 00:05:01 +09:00
|
|
|
|
public function proxize(string $pixivUrl): string
|
2019-01-14 16:11:14 +09:00
|
|
|
|
{
|
2019-01-19 03:02:37 +09:00
|
|
|
|
return str_replace('i.pximg.net', 'i.pixiv.cat', $pixivUrl);
|
2019-01-14 16:01:58 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function resolve(string $url): Metadata
|
|
|
|
|
{
|
2019-06-15 05:33:54 +09:00
|
|
|
|
if (preg_match('~www\.pixiv\.net/user/\d+/series/\d+~', $url, $matches)) {
|
|
|
|
|
$res = $this->client->get($url);
|
2019-09-10 07:03:46 +09:00
|
|
|
|
$metadata = $this->ogpResolver->parse($res->getBody());
|
|
|
|
|
$metadata->image = $this->proxize($metadata->image);
|
2019-06-15 05:33:54 +09:00
|
|
|
|
|
2019-09-10 07:03:46 +09:00
|
|
|
|
return $metadata;
|
2019-06-15 05:33:54 +09:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-17 00:24:25 +09:00
|
|
|
|
$page = 0;
|
2019-12-10 13:12:37 +09:00
|
|
|
|
if (preg_match('~www\.pixiv\.net/(en/)?artworks/(?P<illustId>\d+)~', $url, $matches)) {
|
|
|
|
|
$illustId = $matches['illustId'];
|
2019-09-25 08:42:28 +09:00
|
|
|
|
} else {
|
|
|
|
|
parse_str(parse_url($url, PHP_URL_QUERY), $params);
|
|
|
|
|
$illustId = $params['illust_id'];
|
|
|
|
|
|
|
|
|
|
// 漫画ページ(ページ数はmanga_bigならあるかも)
|
|
|
|
|
if ($params['mode'] === 'manga_big' || $params['mode'] === 'manga') {
|
|
|
|
|
$page = $params['page'] ?? 0;
|
|
|
|
|
}
|
2019-02-12 22:48:44 +09:00
|
|
|
|
}
|
2019-01-14 16:01:58 +09:00
|
|
|
|
|
2019-06-14 11:04:42 +09:00
|
|
|
|
$res = $this->client->get('https://www.pixiv.net/ajax/illust/' . $illustId);
|
2019-09-10 07:03:46 +09:00
|
|
|
|
$json = json_decode($res->getBody()->getContents(), true);
|
|
|
|
|
$metadata = new Metadata();
|
2019-01-14 16:01:58 +09:00
|
|
|
|
|
2019-09-10 07:03:46 +09:00
|
|
|
|
$metadata->title = $json['body']['illustTitle'] ?? '';
|
|
|
|
|
$metadata->description = '投稿者: ' . $json['body']['userName'] . PHP_EOL . strip_tags(str_replace('<br />', PHP_EOL, $json['body']['illustComment'] ?? ''));
|
|
|
|
|
$metadata->image = $this->proxize($json['body']['urls']['regular'] ?? '');
|
2019-01-14 16:01:58 +09:00
|
|
|
|
|
2019-09-10 07:03:46 +09:00
|
|
|
|
// ページ数の指定がある場合は画像URLをそのページにする
|
|
|
|
|
if ($page != 0) {
|
|
|
|
|
$metadata->image = str_replace('_p0', '_p' . $page, $metadata->image);
|
|
|
|
|
}
|
2019-02-17 00:24:25 +09:00
|
|
|
|
|
2019-09-10 07:03:46 +09:00
|
|
|
|
// タグ
|
|
|
|
|
if (!empty($json['body']['tags']['tags'])) {
|
|
|
|
|
foreach ($json['body']['tags']['tags'] as $tag) {
|
|
|
|
|
// 一部の固定キーワードは無視
|
|
|
|
|
if (array_search($tag['tag'], ['R-18', 'イラスト', 'pixiv', 'ピクシブ'], true) === false) {
|
|
|
|
|
$metadata->tags[] = preg_replace('/\s/', '_', $tag['tag']);
|
2019-06-14 11:04:42 +09:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-14 16:01:58 +09:00
|
|
|
|
}
|
2019-09-10 07:03:46 +09:00
|
|
|
|
|
|
|
|
|
return $metadata;
|
2019-01-14 16:01:58 +09:00
|
|
|
|
}
|
|
|
|
|
}
|