オカズリンクの一次対応
This commit is contained in:
parent
2fe3d7ac49
commit
b562b3b400
@ -10,7 +10,7 @@ class Ejaculation extends Model
|
||||
|
||||
protected $fillable = [
|
||||
'user_id', 'ejaculated_date',
|
||||
'note', 'geo_latitude', 'geo_longitude',
|
||||
'note', 'geo_latitude', 'geo_longitude', 'link',
|
||||
'is_private'
|
||||
];
|
||||
|
||||
|
@ -27,6 +27,7 @@ class EjaculationController extends Controller
|
||||
'date' => 'required|date_format:Y/m/d',
|
||||
'time' => 'required|date_format:H:i',
|
||||
'note' => 'nullable|string|max:500',
|
||||
'link' => 'nullable|url',
|
||||
])->after(function ($validator) use ($request, $inputs) {
|
||||
// 日時の重複チェック
|
||||
if (!$validator->errors()->hasAny(['date', 'time'])) {
|
||||
@ -41,6 +42,7 @@ class EjaculationController extends Controller
|
||||
'user_id' => Auth::id(),
|
||||
'ejaculated_date' => Carbon::createFromFormat('Y/m/d H:i', $inputs['date'] . ' ' . $inputs['time']),
|
||||
'note' => $inputs['note'] ?? '',
|
||||
'link' => $inputs['link'] ?? '',
|
||||
'is_private' => $request->has('is_private') ?? false
|
||||
]);
|
||||
|
||||
@ -88,6 +90,7 @@ class EjaculationController extends Controller
|
||||
'date' => 'required|date_format:Y/m/d',
|
||||
'time' => 'required|date_format:H:i',
|
||||
'note' => 'nullable|string|max:500',
|
||||
'link' => 'nullable|url',
|
||||
])->after(function ($validator) use ($id, $request, $inputs) {
|
||||
// 日時の重複チェック
|
||||
if (!$validator->errors()->hasAny(['date', 'time'])) {
|
||||
@ -101,6 +104,7 @@ class EjaculationController extends Controller
|
||||
$ejaculation->fill([
|
||||
'ejaculated_date' => Carbon::createFromFormat('Y/m/d H:i', $inputs['date'] . ' ' . $inputs['time']),
|
||||
'note' => $inputs['note'] ?? '',
|
||||
'link' => $inputs['link'] ?? '',
|
||||
'is_private' => $request->has('is_private') ?? false
|
||||
])->save();
|
||||
|
||||
|
@ -26,6 +26,7 @@ id,
|
||||
ejaculated_date,
|
||||
note,
|
||||
is_private,
|
||||
link,
|
||||
to_char(lead(ejaculated_date, 1, NULL) OVER (ORDER BY ejaculated_date DESC), 'YYYY/MM/DD HH24:MI') AS before_date,
|
||||
to_char(ejaculated_date - (lead(ejaculated_date, 1, NULL) OVER (ORDER BY ejaculated_date DESC)), 'FMDDD日 FMHH24時間 FMMI分') AS ejaculated_span
|
||||
SQL
|
||||
|
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddLinkToEjaculations extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('ejaculations', function (Blueprint $table) {
|
||||
$table->string('link')->default('');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('ejaculations', function (Blueprint $table) {
|
||||
$table->removeColumn('link');
|
||||
});
|
||||
}
|
||||
}
|
@ -44,32 +44,19 @@
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
--}}
|
||||
<div class="form-row">
|
||||
<div class="form-group col-sm-12">
|
||||
<label for="link"><span class="oi oi-link-intact"></span> オカズリンク</label>
|
||||
<input id="link" type="text" class="form-control" placeholder="https://...">
|
||||
<input id="link" name="link" type="text" class="form-control {{ $errors->has('link') ? ' is-invalid' : '' }}" placeholder="http://..." value="{{ old('link') }}">
|
||||
<small class="form-text text-muted">
|
||||
オカズのURLを貼り付けて登録することができます。
|
||||
</small>
|
||||
</div>
|
||||
<div class="form-group col-sm-12 d-none">
|
||||
<div class="card">
|
||||
<div class="card-header">このオカズで合っていますか?</div>
|
||||
<div class="card-body">
|
||||
<div class="d-flex mb-4">
|
||||
<img src="holder.js/128x128" alt="" class="rounded">
|
||||
<div class="align-self-center ml-2 mr-auto">
|
||||
<p class="mb-1">タイトル</p>
|
||||
<small class="text-muted">概要</small>
|
||||
@if ($errors->has('link'))
|
||||
<div class="invalid-feedback">{{ $errors->first('link') }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" class="btn btn-success"><span class="oi oi-check"></span> 決定</a>
|
||||
<a href="#" class="btn btn-outline-secondary">キャンセル</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
--}}
|
||||
<div class="form-row">
|
||||
<div class="form-group col-sm-12">
|
||||
<label for="note"><span class="oi oi-comment-square"></span> ノート</label>
|
||||
|
@ -45,32 +45,19 @@
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
--}}
|
||||
<div class="form-row">
|
||||
<div class="form-group col-sm-12">
|
||||
<label for="link"><span class="oi oi-link-intact"></span> オカズリンク</label>
|
||||
<input id="link" type="text" class="form-control" placeholder="https://...">
|
||||
<input id="link" name="link" type="text" class="form-control {{ $errors->has('link') ? ' is-invalid' : '' }}" placeholder="http://..." value="{{ old('link') ?? $ejaculation->link }}">
|
||||
<small class="form-text text-muted">
|
||||
オカズのURLを貼り付けて登録することができます。
|
||||
</small>
|
||||
</div>
|
||||
<div class="form-group col-sm-12 d-none">
|
||||
<div class="card">
|
||||
<div class="card-header">このオカズで合っていますか?</div>
|
||||
<div class="card-body">
|
||||
<div class="d-flex mb-4">
|
||||
<img src="holder.js/128x128" alt="" class="rounded">
|
||||
<div class="align-self-center ml-2 mr-auto">
|
||||
<p class="mb-1">タイトル</p>
|
||||
<small class="text-muted">概要</small>
|
||||
@if ($errors->has('link'))
|
||||
<div class="invalid-feedback">{{ $errors->first('link') }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" class="btn btn-success"><span class="oi oi-check"></span> 決定</a>
|
||||
<a href="#" class="btn btn-outline-secondary">キャンセル</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
--}}
|
||||
<div class="form-row">
|
||||
<div class="form-group col-sm-12">
|
||||
<label for="note"><span class="oi oi-comment-square"></span> ノート</label>
|
||||
|
@ -46,17 +46,20 @@
|
||||
</p>
|
||||
@endif
|
||||
<!-- okazu link -->
|
||||
{{--
|
||||
<div class="card mb-2 w-50" style="font-size: small;">
|
||||
<a class="text-dark card-link" href="#">
|
||||
<img src="holder.js/320x240" alt="Thumbnail" class="card-img-top">
|
||||
@if (!empty($ejaculation->link))
|
||||
<div id="linkCard" class="card mb-2 w-50 d-none" style="font-size: small;">
|
||||
<a class="text-dark card-link" href="{{ $ejaculation->link }}">
|
||||
<img src="" alt="Thumbnail" class="card-img-top bg-secondary">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">タイトル</h6>
|
||||
<p class="card-text">コンテンツの説明文</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
--}}
|
||||
<p class="mb-2">
|
||||
<span class="oi oi-link-intact mr-1"></span><a href="{{ $ejaculation->link }}">{{ $ejaculation->link }}</a>
|
||||
</p>
|
||||
@endif
|
||||
<!-- note -->
|
||||
@if (!empty($ejaculation->note))
|
||||
<p class="mb-0 tis-word-wrap">
|
||||
@ -87,6 +90,7 @@
|
||||
@endsection
|
||||
|
||||
@push('script')
|
||||
<script type="text/javascript" src="//cdn.jsdelivr.net/npm/holderjs@2.9.4/holder.min.js"></script>
|
||||
<script>
|
||||
$('#deleteCheckinModal').on('show.bs.modal', function (event) {
|
||||
var target = $(event.relatedTarget);
|
||||
@ -99,5 +103,22 @@
|
||||
form.attr('action', form.attr('action').replace('@', modal.data('id')));
|
||||
form.submit();
|
||||
});
|
||||
|
||||
var $linkCard = $('#linkCard');
|
||||
if ($linkCard.length > 0) {
|
||||
$.ajax({
|
||||
url: '{{ url('/api/ogp') }}',
|
||||
method: 'get',
|
||||
type: 'json',
|
||||
data: {
|
||||
url: $linkCard.find('a').attr('href')
|
||||
}
|
||||
}).then(function (data) {
|
||||
$linkCard.find('.card-title').text(data.title);
|
||||
$linkCard.find('.card-text').text(data.description);
|
||||
$linkCard.find('img').attr('src', data.image);
|
||||
$linkCard.removeClass('d-none');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@endpush
|
@ -32,17 +32,20 @@
|
||||
</p>
|
||||
@endif
|
||||
<!-- okazu link -->
|
||||
{{--
|
||||
<div class="card mb-2 w-50" style="font-size: small;">
|
||||
<a class="text-dark card-link" href="#">
|
||||
<img src="holder.js/320x240" alt="Thumbnail" class="card-img-top">
|
||||
@if (!empty($ejaculation->link))
|
||||
<div class="card link-card mb-2 w-50 d-none" style="font-size: small;">
|
||||
<a class="text-dark card-link" href="{{ $ejaculation->link }}">
|
||||
<img src="" alt="Thumbnail" class="card-img-top bg-secondary">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">タイトル</h6>
|
||||
<p class="card-text">コンテンツの説明文</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
--}}
|
||||
<p class="mb-2">
|
||||
<span class="oi oi-link-intact mr-1"></span><a href="{{ $ejaculation->link }}">{{ $ejaculation->link }}</a>
|
||||
</p>
|
||||
@endif
|
||||
<!-- note -->
|
||||
@if (!empty($ejaculation->note))
|
||||
<p class="mb-0 tis-word-wrap">
|
||||
@ -104,5 +107,22 @@
|
||||
form.attr('action', form.attr('action').replace('@', modal.data('id')));
|
||||
form.submit();
|
||||
});
|
||||
|
||||
$('.link-card').each(function () {
|
||||
var $this = $(this);
|
||||
$.ajax({
|
||||
url: '{{ url('/api/ogp') }}',
|
||||
method: 'get',
|
||||
type: 'json',
|
||||
data: {
|
||||
url: $this.find('a').attr('href')
|
||||
}
|
||||
}).then(function (data) {
|
||||
$this.find('.card-title').text(data.title);
|
||||
$this.find('.card-text').text(data.description);
|
||||
$this.find('img').attr('src', data.image);
|
||||
$this.removeClass('d-none');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
@ -16,3 +16,51 @@ use Illuminate\Http\Request;
|
||||
Route::middleware('auth:api')->get('/user', function (Request $request) {
|
||||
return $request->user();
|
||||
});
|
||||
|
||||
Route::get('/ogp', function (Request $request) {
|
||||
$request->validate([
|
||||
'url:required|url'
|
||||
]);
|
||||
|
||||
$client = new GuzzleHttp\Client();
|
||||
$res = $client->get($request->input('url'));
|
||||
if ($res->getStatusCode() === 200) {
|
||||
$dom = new DOMDocument();
|
||||
@$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;
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json($result);
|
||||
} else {
|
||||
abort($res->getStatusCode());
|
||||
}
|
||||
});
|
Loading…
Reference in New Issue
Block a user