オカズリンクの一次対応
This commit is contained in:
parent
2fe3d7ac49
commit
b562b3b400
@ -10,7 +10,7 @@ class Ejaculation extends Model
|
|||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'user_id', 'ejaculated_date',
|
'user_id', 'ejaculated_date',
|
||||||
'note', 'geo_latitude', 'geo_longitude',
|
'note', 'geo_latitude', 'geo_longitude', 'link',
|
||||||
'is_private'
|
'is_private'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ class EjaculationController extends Controller
|
|||||||
'date' => 'required|date_format:Y/m/d',
|
'date' => 'required|date_format:Y/m/d',
|
||||||
'time' => 'required|date_format:H:i',
|
'time' => 'required|date_format:H:i',
|
||||||
'note' => 'nullable|string|max:500',
|
'note' => 'nullable|string|max:500',
|
||||||
|
'link' => 'nullable|url',
|
||||||
])->after(function ($validator) use ($request, $inputs) {
|
])->after(function ($validator) use ($request, $inputs) {
|
||||||
// 日時の重複チェック
|
// 日時の重複チェック
|
||||||
if (!$validator->errors()->hasAny(['date', 'time'])) {
|
if (!$validator->errors()->hasAny(['date', 'time'])) {
|
||||||
@ -41,6 +42,7 @@ class EjaculationController extends Controller
|
|||||||
'user_id' => Auth::id(),
|
'user_id' => Auth::id(),
|
||||||
'ejaculated_date' => Carbon::createFromFormat('Y/m/d H:i', $inputs['date'] . ' ' . $inputs['time']),
|
'ejaculated_date' => Carbon::createFromFormat('Y/m/d H:i', $inputs['date'] . ' ' . $inputs['time']),
|
||||||
'note' => $inputs['note'] ?? '',
|
'note' => $inputs['note'] ?? '',
|
||||||
|
'link' => $inputs['link'] ?? '',
|
||||||
'is_private' => $request->has('is_private') ?? false
|
'is_private' => $request->has('is_private') ?? false
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -88,6 +90,7 @@ class EjaculationController extends Controller
|
|||||||
'date' => 'required|date_format:Y/m/d',
|
'date' => 'required|date_format:Y/m/d',
|
||||||
'time' => 'required|date_format:H:i',
|
'time' => 'required|date_format:H:i',
|
||||||
'note' => 'nullable|string|max:500',
|
'note' => 'nullable|string|max:500',
|
||||||
|
'link' => 'nullable|url',
|
||||||
])->after(function ($validator) use ($id, $request, $inputs) {
|
])->after(function ($validator) use ($id, $request, $inputs) {
|
||||||
// 日時の重複チェック
|
// 日時の重複チェック
|
||||||
if (!$validator->errors()->hasAny(['date', 'time'])) {
|
if (!$validator->errors()->hasAny(['date', 'time'])) {
|
||||||
@ -101,6 +104,7 @@ class EjaculationController extends Controller
|
|||||||
$ejaculation->fill([
|
$ejaculation->fill([
|
||||||
'ejaculated_date' => Carbon::createFromFormat('Y/m/d H:i', $inputs['date'] . ' ' . $inputs['time']),
|
'ejaculated_date' => Carbon::createFromFormat('Y/m/d H:i', $inputs['date'] . ' ' . $inputs['time']),
|
||||||
'note' => $inputs['note'] ?? '',
|
'note' => $inputs['note'] ?? '',
|
||||||
|
'link' => $inputs['link'] ?? '',
|
||||||
'is_private' => $request->has('is_private') ?? false
|
'is_private' => $request->has('is_private') ?? false
|
||||||
])->save();
|
])->save();
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ id,
|
|||||||
ejaculated_date,
|
ejaculated_date,
|
||||||
note,
|
note,
|
||||||
is_private,
|
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(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
|
to_char(ejaculated_date - (lead(ejaculated_date, 1, NULL) OVER (ORDER BY ejaculated_date DESC)), 'FMDDD日 FMHH24時間 FMMI分') AS ejaculated_span
|
||||||
SQL
|
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>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
--}}
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group col-sm-12">
|
<div class="form-group col-sm-12">
|
||||||
<label for="link"><span class="oi oi-link-intact"></span> オカズリンク</label>
|
<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">
|
<small class="form-text text-muted">
|
||||||
オカズのURLを貼り付けて登録することができます。
|
オカズのURLを貼り付けて登録することができます。
|
||||||
</small>
|
</small>
|
||||||
</div>
|
@if ($errors->has('link'))
|
||||||
<div class="form-group col-sm-12 d-none">
|
<div class="invalid-feedback">{{ $errors->first('link') }}</div>
|
||||||
<div class="card">
|
@endif
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</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-row">
|
||||||
<div class="form-group col-sm-12">
|
<div class="form-group col-sm-12">
|
||||||
<label for="note"><span class="oi oi-comment-square"></span> ノート</label>
|
<label for="note"><span class="oi oi-comment-square"></span> ノート</label>
|
||||||
|
@ -45,32 +45,19 @@
|
|||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
--}}
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group col-sm-12">
|
<div class="form-group col-sm-12">
|
||||||
<label for="link"><span class="oi oi-link-intact"></span> オカズリンク</label>
|
<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">
|
<small class="form-text text-muted">
|
||||||
オカズのURLを貼り付けて登録することができます。
|
オカズのURLを貼り付けて登録することができます。
|
||||||
</small>
|
</small>
|
||||||
</div>
|
@if ($errors->has('link'))
|
||||||
<div class="form-group col-sm-12 d-none">
|
<div class="invalid-feedback">{{ $errors->first('link') }}</div>
|
||||||
<div class="card">
|
@endif
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</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-row">
|
||||||
<div class="form-group col-sm-12">
|
<div class="form-group col-sm-12">
|
||||||
<label for="note"><span class="oi oi-comment-square"></span> ノート</label>
|
<label for="note"><span class="oi oi-comment-square"></span> ノート</label>
|
||||||
|
@ -46,17 +46,20 @@
|
|||||||
</p>
|
</p>
|
||||||
@endif
|
@endif
|
||||||
<!-- okazu link -->
|
<!-- okazu link -->
|
||||||
{{--
|
@if (!empty($ejaculation->link))
|
||||||
<div class="card mb-2 w-50" style="font-size: small;">
|
<div id="linkCard" class="card mb-2 w-50 d-none" style="font-size: small;">
|
||||||
<a class="text-dark card-link" href="#">
|
<a class="text-dark card-link" href="{{ $ejaculation->link }}">
|
||||||
<img src="holder.js/320x240" alt="Thumbnail" class="card-img-top">
|
<img src="" alt="Thumbnail" class="card-img-top bg-secondary">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h6 class="card-title">タイトル</h6>
|
<h6 class="card-title">タイトル</h6>
|
||||||
<p class="card-text">コンテンツの説明文</p>
|
<p class="card-text">コンテンツの説明文</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
--}}
|
<p class="mb-2">
|
||||||
|
<span class="oi oi-link-intact mr-1"></span><a href="{{ $ejaculation->link }}">{{ $ejaculation->link }}</a>
|
||||||
|
</p>
|
||||||
|
@endif
|
||||||
<!-- note -->
|
<!-- note -->
|
||||||
@if (!empty($ejaculation->note))
|
@if (!empty($ejaculation->note))
|
||||||
<p class="mb-0 tis-word-wrap">
|
<p class="mb-0 tis-word-wrap">
|
||||||
@ -87,6 +90,7 @@
|
|||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@push('script')
|
@push('script')
|
||||||
|
<script type="text/javascript" src="//cdn.jsdelivr.net/npm/holderjs@2.9.4/holder.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
$('#deleteCheckinModal').on('show.bs.modal', function (event) {
|
$('#deleteCheckinModal').on('show.bs.modal', function (event) {
|
||||||
var target = $(event.relatedTarget);
|
var target = $(event.relatedTarget);
|
||||||
@ -99,5 +103,22 @@
|
|||||||
form.attr('action', form.attr('action').replace('@', modal.data('id')));
|
form.attr('action', form.attr('action').replace('@', modal.data('id')));
|
||||||
form.submit();
|
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>
|
</script>
|
||||||
@endpush
|
@endpush
|
@ -32,17 +32,20 @@
|
|||||||
</p>
|
</p>
|
||||||
@endif
|
@endif
|
||||||
<!-- okazu link -->
|
<!-- okazu link -->
|
||||||
{{--
|
@if (!empty($ejaculation->link))
|
||||||
<div class="card mb-2 w-50" style="font-size: small;">
|
<div class="card link-card mb-2 w-50 d-none" style="font-size: small;">
|
||||||
<a class="text-dark card-link" href="#">
|
<a class="text-dark card-link" href="{{ $ejaculation->link }}">
|
||||||
<img src="holder.js/320x240" alt="Thumbnail" class="card-img-top">
|
<img src="" alt="Thumbnail" class="card-img-top bg-secondary">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h6 class="card-title">タイトル</h6>
|
<h6 class="card-title">タイトル</h6>
|
||||||
<p class="card-text">コンテンツの説明文</p>
|
<p class="card-text">コンテンツの説明文</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
--}}
|
<p class="mb-2">
|
||||||
|
<span class="oi oi-link-intact mr-1"></span><a href="{{ $ejaculation->link }}">{{ $ejaculation->link }}</a>
|
||||||
|
</p>
|
||||||
|
@endif
|
||||||
<!-- note -->
|
<!-- note -->
|
||||||
@if (!empty($ejaculation->note))
|
@if (!empty($ejaculation->note))
|
||||||
<p class="mb-0 tis-word-wrap">
|
<p class="mb-0 tis-word-wrap">
|
||||||
@ -104,5 +107,22 @@
|
|||||||
form.attr('action', form.attr('action').replace('@', modal.data('id')));
|
form.attr('action', form.attr('action').replace('@', modal.data('id')));
|
||||||
form.submit();
|
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>
|
</script>
|
||||||
@endpush
|
@endpush
|
@ -16,3 +16,51 @@ use Illuminate\Http\Request;
|
|||||||
Route::middleware('auth:api')->get('/user', function (Request $request) {
|
Route::middleware('auth:api')->get('/user', function (Request $request) {
|
||||||
return $request->user();
|
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