Merge branch 'develop'
This commit is contained in:
		@@ -27,4 +27,9 @@ class Ejaculation extends Model
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->belongsToMany('App\Tag')->withTimestamps();
 | 
					        return $this->belongsToMany('App\Tag')->withTimestamps();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function textTags()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return implode(' ', $this->tags->map(function ($v) { return $v->name; })->all());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								app/MetadataResolver/Metadata.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/MetadataResolver/Metadata.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\MetadataResolver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Metadata
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $title = '';
 | 
				
			||||||
 | 
					    public $description = '';
 | 
				
			||||||
 | 
					    public $image = '';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										24
									
								
								app/MetadataResolver/MetadataResolver.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								app/MetadataResolver/MetadataResolver.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\MetadataResolver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MetadataResolver implements Resolver
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $rules = [
 | 
				
			||||||
 | 
					        '~(((sp\.)?seiga\.nicovideo\.jp/seiga(/#!)?|nico\.ms))/im~' => NicoSeigaResolver::class,
 | 
				
			||||||
 | 
					        '~nijie\.info/view\.php~' => NijieResolver::class,
 | 
				
			||||||
 | 
					        '/.*/' => OGPResolver::class
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function resolve(string $url): Metadata
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        foreach ($this->rules as $pattern => $class) {
 | 
				
			||||||
 | 
					            if (preg_match($pattern, $url) === 1) {
 | 
				
			||||||
 | 
					                $resolver = new $class;
 | 
				
			||||||
 | 
					                return $resolver->resolve($url);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        throw new \UnexpectedValueException('URL not matched.');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										24
									
								
								app/MetadataResolver/NicoSeigaResolver.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								app/MetadataResolver/NicoSeigaResolver.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\MetadataResolver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NicoSeigaResolver implements Resolver
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function resolve(string $url): Metadata
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $client = new \GuzzleHttp\Client();
 | 
				
			||||||
 | 
					        $res = $client->get($url);
 | 
				
			||||||
 | 
					        if ($res->getStatusCode() === 200) {
 | 
				
			||||||
 | 
					            $ogpResolver = new OGPResolver();
 | 
				
			||||||
 | 
					            $metadata = $ogpResolver->parse($res->getBody());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // ページURLからサムネイルURLに変換
 | 
				
			||||||
 | 
					            preg_match('~http://(?:(?:sp\\.)?seiga\\.nicovideo\\.jp/seiga(?:/#!)?|nico\\.ms)/im(\\d+)~', $url, $matches);
 | 
				
			||||||
 | 
					            $metadata->image = "http://lohas.nicoseiga.jp/thumb/${matches[1]}l?";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $metadata;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            throw new \RuntimeException("{$res->getStatusCode()}: $url");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										37
									
								
								app/MetadataResolver/NijieResolver.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								app/MetadataResolver/NijieResolver.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\MetadataResolver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NijieResolver implements Resolver
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function resolve(string $url): Metadata
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (mb_strpos($url, '//sp.nijie.info') !== false) {
 | 
				
			||||||
 | 
					            $url = preg_replace('~//sp\.nijie\.info~', '//nijie.info', $url);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $client = new \GuzzleHttp\Client();
 | 
				
			||||||
 | 
					        $res = $client->get($url);
 | 
				
			||||||
 | 
					        if ($res->getStatusCode() === 200) {
 | 
				
			||||||
 | 
					            $ogpResolver = new OGPResolver();
 | 
				
			||||||
 | 
					            $metadata = $ogpResolver->parse($res->getBody());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $dom = new \DOMDocument();
 | 
				
			||||||
 | 
					            @$dom->loadHTML(mb_convert_encoding($res->getBody(), 'HTML-ENTITIES', 'UTF-8'));
 | 
				
			||||||
 | 
					            $xpath = new \DOMXPath($dom);
 | 
				
			||||||
 | 
					            $dataNode = $xpath->query('//script[substring(@type, string-length(@type) - 3, 4) = "json"]');
 | 
				
			||||||
 | 
					            foreach ($dataNode as $node) {
 | 
				
			||||||
 | 
					                // 改行がそのまま入っていることがあるのでデコード前にエスケープが必要
 | 
				
			||||||
 | 
					                $imageData = json_decode(preg_replace('/\r?\n/', '\n', $node->nodeValue), true);
 | 
				
			||||||
 | 
					                if (isset($imageData['thumbnailUrl']) && !ends_with($imageData['thumbnailUrl'], '.gif') && !ends_with($imageData['thumbnailUrl'], '.mp4')) {
 | 
				
			||||||
 | 
					                    $metadata->image = preg_replace('~nijie\\.info/.*/nijie_picture/~', 'nijie.info/nijie_picture/', $imageData['thumbnailUrl']);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $metadata;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            throw new \RuntimeException("{$res->getStatusCode()}: $url");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										52
									
								
								app/MetadataResolver/OGPResolver.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								app/MetadataResolver/OGPResolver.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\MetadataResolver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class OGPResolver implements Resolver
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function resolve(string $url): Metadata
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $client = new \GuzzleHttp\Client();
 | 
				
			||||||
 | 
					        $res = $client->get($url);
 | 
				
			||||||
 | 
					        if ($res->getStatusCode() === 200) {
 | 
				
			||||||
 | 
					            return $this->parse($res->getBody());
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            throw new \RuntimeException("{$res->getStatusCode()}: $url");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function parse(string $html): Metadata
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $dom = new \DOMDocument();
 | 
				
			||||||
 | 
					        @$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
 | 
				
			||||||
 | 
					        $xpath = new \DOMXPath($dom);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $metadata = new Metadata();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $titleNode = $xpath->query('//meta[@*="og:title"]');
 | 
				
			||||||
 | 
					        foreach ($titleNode as $node) {
 | 
				
			||||||
 | 
					            if (!empty($node->getAttribute('content'))) {
 | 
				
			||||||
 | 
					                $metadata->title = $node->getAttribute('content');
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $descriptionNode = $xpath->query('//meta[@*="og:description"]');
 | 
				
			||||||
 | 
					        foreach ($descriptionNode as $node) {
 | 
				
			||||||
 | 
					            if (!empty($node->getAttribute('content'))) {
 | 
				
			||||||
 | 
					                $metadata->description = $node->getAttribute('content');
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $imageNode = $xpath->query('//meta[@*="og:image"]');
 | 
				
			||||||
 | 
					        foreach ($imageNode as $node) {
 | 
				
			||||||
 | 
					            if (!empty($node->getAttribute('content'))) {
 | 
				
			||||||
 | 
					                $metadata->image = $node->getAttribute('content');
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $metadata;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										8
									
								
								app/MetadataResolver/Resolver.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								app/MetadataResolver/Resolver.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\MetadataResolver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Resolver
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function resolve(string $url): Metadata;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2,6 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Providers;
 | 
					namespace App\Providers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\MetadataResolver\MetadataResolver;
 | 
				
			||||||
use Illuminate\Support\ServiceProvider;
 | 
					use Illuminate\Support\ServiceProvider;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AppServiceProvider extends ServiceProvider
 | 
					class AppServiceProvider extends ServiceProvider
 | 
				
			||||||
@@ -23,6 +24,8 @@ class AppServiceProvider extends ServiceProvider
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function register()
 | 
					    public function register()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        //
 | 
					        $this->app->singleton(MetadataResolver::class, function ($app) {
 | 
				
			||||||
 | 
					            return new MetadataResolver();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,7 +37,7 @@
 | 
				
			|||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div class="form-row">
 | 
					                <div class="form-row">
 | 
				
			||||||
                    <div class="form-group col-sm-12">
 | 
					                    <div class="form-group col-sm-12">
 | 
				
			||||||
                        <input name="tags" type="hidden" value="{{ old('tags') ?? implode(' ', $ejaculation->tags->map(function ($v) { return $v->name; })->all()) }}">
 | 
					                        <input name="tags" type="hidden" value="{{ old('tags') ?? $ejaculation->textTags() }}">
 | 
				
			||||||
                        <label for="tagInput"><span class="oi oi-tags"></span> タグ</label>
 | 
					                        <label for="tagInput"><span class="oi oi-tags"></span> タグ</label>
 | 
				
			||||||
                        <div class="form-control {{ $errors->has('tags') ? ' is-invalid' : '' }}">
 | 
					                        <div class="form-control {{ $errors->has('tags') ? ' is-invalid' : '' }}">
 | 
				
			||||||
                            <ul id="tags" class="list-inline d-inline"></ul>
 | 
					                            <ul id="tags" class="list-inline d-inline"></ul>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,6 +28,7 @@
 | 
				
			|||||||
                            <h5>{{ $ejaculatedSpan ?? '精通' }} <small class="text-muted">{{ $ejaculation->before_date }}{{ !empty($ejaculation->before_date) ? ' ~ ' : '' }}{{ $ejaculation->ejaculated_date->format('Y/m/d H:i') }}</small></h5>
 | 
					                            <h5>{{ $ejaculatedSpan ?? '精通' }} <small class="text-muted">{{ $ejaculation->before_date }}{{ !empty($ejaculation->before_date) ? ' ~ ' : '' }}{{ $ejaculation->ejaculated_date->format('Y/m/d H:i') }}</small></h5>
 | 
				
			||||||
                            @if ($user->isMe())
 | 
					                            @if ($user->isMe())
 | 
				
			||||||
                                <div>
 | 
					                                <div>
 | 
				
			||||||
 | 
					                                    <a class="text-secondary timeline-action-item" href="{{ route('checkin', ['link' => $ejaculation->link, 'tags' => $ejaculation->textTags()]) }}"><span class="oi oi-reload" data-toggle="tooltip" data-placement="bottom" title="同じオカズでチェックイン"></span></a>
 | 
				
			||||||
                                    <a class="text-secondary timeline-action-item" href="{{ route('checkin.edit', ['id' => $ejaculation->id]) }}"><span class="oi oi-pencil" data-toggle="tooltip" data-placement="bottom" title="修正"></span></a>
 | 
					                                    <a class="text-secondary timeline-action-item" href="{{ route('checkin.edit', ['id' => $ejaculation->id]) }}"><span class="oi oi-pencil" data-toggle="tooltip" data-placement="bottom" title="修正"></span></a>
 | 
				
			||||||
                                    <a class="text-secondary timeline-action-item" href="#" data-toggle="modal" data-target="#deleteCheckinModal" data-id="{{ $ejaculation->id }}" data-date="{{ $ejaculation->ejaculated_date }}"><span class="oi oi-trash" data-toggle="tooltip" data-placement="bottom" title="削除"></span></a>
 | 
					                                    <a class="text-secondary timeline-action-item" href="#" data-toggle="modal" data-target="#deleteCheckinModal" data-id="{{ $ejaculation->id }}" data-date="{{ $ejaculation->ejaculated_date }}"><span class="oi oi-trash" data-toggle="tooltip" data-placement="bottom" title="削除"></span></a>
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@
 | 
				
			|||||||
                    <h5>{{ $ejaculation->ejaculated_span ?? '精通' }} <a href="{{ route('checkin.show', ['id' => $ejaculation->id]) }}" class="text-muted"><small>{{ $ejaculation->before_date }}{{ !empty($ejaculation->before_date) ? ' ~ ' : '' }}{{ $ejaculation->ejaculated_date->format('Y/m/d H:i') }}</small></a></h5>
 | 
					                    <h5>{{ $ejaculation->ejaculated_span ?? '精通' }} <a href="{{ route('checkin.show', ['id' => $ejaculation->id]) }}" class="text-muted"><small>{{ $ejaculation->before_date }}{{ !empty($ejaculation->before_date) ? ' ~ ' : '' }}{{ $ejaculation->ejaculated_date->format('Y/m/d H:i') }}</small></a></h5>
 | 
				
			||||||
                    @if ($user->isMe())
 | 
					                    @if ($user->isMe())
 | 
				
			||||||
                    <div>
 | 
					                    <div>
 | 
				
			||||||
 | 
					                        <a class="text-secondary timeline-action-item" href="{{ route('checkin', ['link' => $ejaculation->link, 'tags' => $ejaculation->textTags()]) }}"><span class="oi oi-reload" data-toggle="tooltip" data-placement="bottom" title="同じオカズでチェックイン"></span></a>
 | 
				
			||||||
                        <a class="text-secondary timeline-action-item" href="{{ route('checkin.edit', ['id' => $ejaculation->id]) }}"><span class="oi oi-pencil" data-toggle="tooltip" data-placement="bottom" title="修正"></span></a>
 | 
					                        <a class="text-secondary timeline-action-item" href="{{ route('checkin.edit', ['id' => $ejaculation->id]) }}"><span class="oi oi-pencil" data-toggle="tooltip" data-placement="bottom" title="修正"></span></a>
 | 
				
			||||||
                        <a class="text-secondary timeline-action-item" href="#" data-toggle="modal" data-target="#deleteCheckinModal" data-id="{{ $ejaculation->id }}" data-date="{{ $ejaculation->ejaculated_date }}"><span class="oi oi-trash" data-toggle="tooltip" data-placement="bottom" title="削除"></span></a>
 | 
					                        <a class="text-secondary timeline-action-item" href="#" data-toggle="modal" data-target="#deleteCheckinModal" data-id="{{ $ejaculation->id }}" data-date="{{ $ejaculation->ejaculated_date }}"><span class="oi oi-trash" data-toggle="tooltip" data-placement="bottom" title="削除"></span></a>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\MetadataResolver\MetadataResolver;
 | 
				
			||||||
use Illuminate\Http\Request;
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
@@ -17,75 +18,16 @@ Route::middleware('auth:api')->get('/user', function (Request $request) {
 | 
				
			|||||||
    return $request->user();
 | 
					    return $request->user();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Route::get('/checkin/card', function (Request $request) {
 | 
					Route::get('/checkin/card', function (Request $request, MetadataResolver $resolver) {
 | 
				
			||||||
    $request->validate([
 | 
					    $request->validate([
 | 
				
			||||||
        'url:required|url'
 | 
					        'url:required|url'
 | 
				
			||||||
    ]);
 | 
					    ]);
 | 
				
			||||||
    $url = $request->input('url');
 | 
					    $url = $request->input('url');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $client = new GuzzleHttp\Client();
 | 
					    $metadata = $resolver->resolve($url);
 | 
				
			||||||
    $res = $client->get($url);
 | 
					    $response = response()->json($metadata);
 | 
				
			||||||
    if ($res->getStatusCode() === 200) {
 | 
					    if (!config('app.debug')) {
 | 
				
			||||||
        $dom = new DOMDocument();
 | 
					        $response = $response->setCache(['public' => true, 'max_age' => 86400]);
 | 
				
			||||||
        @$dom->loadHTML(mb_convert_encoding($res->getBody(), 'HTML-ENTITIES', 'UTF-8'));
 | 
					 | 
				
			||||||
        $xpath = new DOMXPath($dom);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $result = [
 | 
					 | 
				
			||||||
            'title' => '',
 | 
					 | 
				
			||||||
            'description' => '',
 | 
					 | 
				
			||||||
            'image' => ''
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $titleNode = $xpath->query('//meta[@*="og:title"]');
 | 
					 | 
				
			||||||
        foreach ($titleNode as $node) {
 | 
					 | 
				
			||||||
            if (!empty($node->getAttribute('content'))) {
 | 
					 | 
				
			||||||
                $result['title'] = $node->getAttribute('content');
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $descriptionNode = $xpath->query('//meta[@*="og:description"]');
 | 
					 | 
				
			||||||
        foreach ($descriptionNode as $node) {
 | 
					 | 
				
			||||||
            if (!empty($node->getAttribute('content'))) {
 | 
					 | 
				
			||||||
                $result['description'] = $node->getAttribute('content');
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $imageNode = $xpath->query('//meta[@*="og:image"]');
 | 
					 | 
				
			||||||
        foreach ($imageNode as $node) {
 | 
					 | 
				
			||||||
            if (!empty($node->getAttribute('content'))) {
 | 
					 | 
				
			||||||
                $result['image'] = $node->getAttribute('content');
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // 一部サイトについては別のサムネイルの取得を試みる
 | 
					 | 
				
			||||||
        if (mb_strpos($url, 'nico.ms/im') !== false ||
 | 
					 | 
				
			||||||
            mb_strpos($url, 'seiga.nicovideo.jp/seiga/im') !== false ||
 | 
					 | 
				
			||||||
            mb_strpos($url, 'sp.seiga.nicovideo.jp/seiga/#!/im') !== false) {
 | 
					 | 
				
			||||||
            // ニコニコ静画用の処理
 | 
					 | 
				
			||||||
            preg_match('~http://(?:(?:sp\\.)?seiga\\.nicovideo\\.jp/seiga(?:/#!)?|nico\\.ms)/im(\\d+)~', $url, $matches);
 | 
					 | 
				
			||||||
            $result['image'] = "http://lohas.nicoseiga.jp/thumb/${matches[1]}l?";
 | 
					 | 
				
			||||||
        } elseif (mb_strpos($url, 'nijie.info/view.php')) {
 | 
					 | 
				
			||||||
            // ニジエ用の処理
 | 
					 | 
				
			||||||
            $dataNode = $xpath->query('//script[substring(@type, string-length(@type) - 3, 4) = "json"]');
 | 
					 | 
				
			||||||
            foreach ($dataNode as $node) {
 | 
					 | 
				
			||||||
                // 改行がそのまま入っていることがあるのでデコード前にエスケープが必要
 | 
					 | 
				
			||||||
                $imageData = json_decode(preg_replace('/\r?\n/', '\n', $node->nodeValue), true);
 | 
					 | 
				
			||||||
                if (isset($imageData['thumbnailUrl'])) {
 | 
					 | 
				
			||||||
                    $result['image'] = preg_replace('~nijie\\.info/.*/nijie_picture/~', 'nijie.info/nijie_picture/', $imageData['thumbnailUrl']);
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $response = response()->json($result);
 | 
					 | 
				
			||||||
        if (!config('app.debug')) {
 | 
					 | 
				
			||||||
            $response = $response->setCache(['public' => true, 'max_age' => 86400]);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return $response;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        abort($res->getStatusCode());
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return $response;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
							
								
								
									
										101
									
								
								tests/Unit/MetadataResolver/NijieResolverTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								tests/Unit/MetadataResolver/NijieResolverTest.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Tests\Unit\MetadataResolver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\MetadataResolver\NijieResolver;
 | 
				
			||||||
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NijieResolverTest extends TestCase
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function testStandardPicture()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sleep(1);
 | 
				
			||||||
 | 
					        $resolver = new NijieResolver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $metadata = $resolver->resolve('https://nijie.info/view.php?id=66384');
 | 
				
			||||||
 | 
					        $this->assertEquals('チンポップくんの日常ep.1「チンポップくんと釣り」 | ニジエ運営', $metadata->title);
 | 
				
			||||||
 | 
					        $this->assertEquals("メールマガジン漫画のバックナンバー第一話です!\r\n最新話はメールマガジンより配信中です。", $metadata->description);
 | 
				
			||||||
 | 
					        $this->assertRegExp('/pic\d+\.nijie\.info/', $metadata->image);
 | 
				
			||||||
 | 
					        $this->assertNotRegExp('~/diff/main/~', $metadata->image);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testMultiplePicture()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sleep(1);
 | 
				
			||||||
 | 
					        $resolver = new NijieResolver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $metadata = $resolver->resolve('https://nijie.info/view.php?id=202707');
 | 
				
			||||||
 | 
					        $this->assertEquals('ニジエ壁紙 | ニジエ運営', $metadata->title);
 | 
				
			||||||
 | 
					        $this->assertEquals("ニジエのPCとiphone用(4.7inch推奨)の壁紙です。\r\n保存してご自由にお使いくださいませ。", $metadata->description);
 | 
				
			||||||
 | 
					        $this->assertRegExp('/pic\d+\.nijie\.info/', $metadata->image);
 | 
				
			||||||
 | 
					        $this->assertNotRegExp('~/diff/main/~', $metadata->image);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testAnimationGif()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sleep(1);
 | 
				
			||||||
 | 
					        $resolver = new NijieResolver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $metadata = $resolver->resolve('https://nijie.info/view.php?id=258078');
 | 
				
			||||||
 | 
					        $this->assertEquals('騎乗位ルーミア | しょったれ', $metadata->title);
 | 
				
			||||||
 | 
					        $this->assertEquals("以前pixivに投稿したgifアニメ。\r\n気の利いたタイトルが浮かばなかった。", $metadata->description);
 | 
				
			||||||
 | 
					        $this->assertRegExp('~/nijie\.info/pic/logo~', $metadata->image);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testMp4Movie()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sleep(1);
 | 
				
			||||||
 | 
					        $resolver = new NijieResolver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $metadata = $resolver->resolve('https://nijie.info/view.php?id=256283');
 | 
				
			||||||
 | 
					        $this->assertEquals('てすと | ニジエ運営', $metadata->title);
 | 
				
			||||||
 | 
					        $this->assertEquals("H264動画てすと あとで消します\r\n\r\n今の所、H264コーデックのみ、出力時に音声なしにしないと投稿できません\r\n動画は勝手にループします", $metadata->description);
 | 
				
			||||||
 | 
					        $this->assertRegExp('~/nijie\.info/pic/logo~', $metadata->image);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testStandardPictureSp()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sleep(1);
 | 
				
			||||||
 | 
					        $resolver = new NijieResolver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $metadata = $resolver->resolve('https://sp.nijie.info/view.php?id=66384');
 | 
				
			||||||
 | 
					        $this->assertEquals('チンポップくんの日常ep.1「チンポップくんと釣り」 | ニジエ運営', $metadata->title);
 | 
				
			||||||
 | 
					        $this->assertEquals("メールマガジン漫画のバックナンバー第一話です!\r\n最新話はメールマガジンより配信中です。", $metadata->description);
 | 
				
			||||||
 | 
					        $this->assertRegExp('/pic\d+\.nijie\.info/', $metadata->image);
 | 
				
			||||||
 | 
					        $this->assertNotRegExp('~/diff/main/~', $metadata->image);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testMultiplePictureSp()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sleep(1);
 | 
				
			||||||
 | 
					        $resolver = new NijieResolver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $metadata = $resolver->resolve('https://sp.nijie.info/view.php?id=202707');
 | 
				
			||||||
 | 
					        $this->assertEquals('ニジエ壁紙 | ニジエ運営', $metadata->title);
 | 
				
			||||||
 | 
					        $this->assertEquals("ニジエのPCとiphone用(4.7inch推奨)の壁紙です。\r\n保存してご自由にお使いくださいませ。", $metadata->description);
 | 
				
			||||||
 | 
					        $this->assertRegExp('/pic\d+\.nijie\.info/', $metadata->image);
 | 
				
			||||||
 | 
					        $this->assertNotRegExp('~/diff/main/~', $metadata->image);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testAnimationGifSp()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sleep(1);
 | 
				
			||||||
 | 
					        $resolver = new NijieResolver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $metadata = $resolver->resolve('https://sp.nijie.info/view.php?id=258078');
 | 
				
			||||||
 | 
					        $this->assertEquals('騎乗位ルーミア | しょったれ', $metadata->title);
 | 
				
			||||||
 | 
					        $this->assertEquals("以前pixivに投稿したgifアニメ。\r\n気の利いたタイトルが浮かばなかった。", $metadata->description);
 | 
				
			||||||
 | 
					        $this->assertRegExp('~/nijie\.info/pic/logo~', $metadata->image);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testMp4MovieSp()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sleep(1);
 | 
				
			||||||
 | 
					        $resolver = new NijieResolver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $metadata = $resolver->resolve('https://sp.nijie.info/view.php?id=256283');
 | 
				
			||||||
 | 
					        $this->assertEquals('てすと | ニジエ運営', $metadata->title);
 | 
				
			||||||
 | 
					        $this->assertEquals("H264動画てすと あとで消します\r\n\r\n今の所、H264コーデックのみ、出力時に音声なしにしないと投稿できません\r\n動画は勝手にループします", $metadata->description);
 | 
				
			||||||
 | 
					        $this->assertRegExp('~/nijie\.info/pic/logo~', $metadata->image);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										28
									
								
								tests/Unit/MetadataResolver/OGPResolverTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								tests/Unit/MetadataResolver/OGPResolverTest.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Tests\Unit\MetadataResolver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\MetadataResolver\OGPResolver;
 | 
				
			||||||
 | 
					use GuzzleHttp\Exception\ClientException;
 | 
				
			||||||
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class OGPResolverTest extends TestCase
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function testMissingUrl()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $resolver = new OGPResolver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->expectException(ClientException::class);
 | 
				
			||||||
 | 
					        $resolver->resolve('http://example.com/404');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testResolve()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $resolver = new OGPResolver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $metadata = $resolver->resolve('http://ogp.me');
 | 
				
			||||||
 | 
					        $this->assertEquals('Open Graph protocol', $metadata->title);
 | 
				
			||||||
 | 
					        $this->assertEquals('The Open Graph protocol enables any web page to become a rich object in a social graph.', $metadata->description);
 | 
				
			||||||
 | 
					        $this->assertEquals('http://ogp.me/logo.png', $metadata->image);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user