Laravelでブログサイトを作る 16. 管理機能・記事一覧の絞り込みと検索

はじめに
前回で記事一覧を作成した続きになります。
Model
app/Models/Article.php
前回作成した一覧取得メソッドを拡張します。
引数に、今回追加分が未指定の場合の初期値を設定しているので、既存の呼び出し箇所に変更は不要となります。
// ...省略...
/**
* 一覧取得
*
* @param int $num 件数
* @param bool $delete 削除済みを含めるか(true => 含める)
* @param int $parent 親カテゴリID 【今回追加】
* @param int $children 子カテゴリID 【今回追加】
* @param string $search 検索ワード 【今回追加】
* @return mixed
*/
public function getList(
int $num,
bool $delete = false,
int $parent = 0,
int $children = 0,
string $search = '')
{
$article = $this;
// 【今回追加】親カテゴリが指定されている場合、記事テーブルのカラムと一致するものを抽出する
if ($parent !== 0) {
$article = $article->where('articles.parent', '=', $parent);
}
// 【今回追加】子カテゴリが指定されている場合、テーブルをJOINする
if ($children !== 0) {
$article = $article
// 記事テーブルと、記事-子カテゴリ関連付けテーブルをJOIN
->leftJoin('article_children', function ($join) {
$join->on('articles.id', '=', 'article_children.article')
->where('article_children.deleted_at', '=', NULL);
})
// 子カテゴリテーブルと、記事-子カテゴリ関連付けテーブルをJOIN
->leftJoin('child_categories', function ($join) {
$join->on('child_categories.id', '=', 'article_children.children');
})
// 子カテゴリの一致するものを抽出する
->where('child_categories.id', '=', $children);
}
// 【今回追加】検索ワードが指定されている場合
if ($search !== '') {
$article = $article
// タイトルか本文のどこかに検索ワードが含まれていれる記事を抽出する
->where(function($query) use ($search) {
$query->where('articles.title', 'like', '%'.$search.'%')
->orWhere('articles.body', 'like', '%'.$search.'%')
;
});
}
// 削除済みを含む場合は`withTrashed()`
if ($delete !== true) {
$article = $article->withTrashed();
}
// ソートは、新しい記事を上位表示
$article = $article->orderBy('open', 'desc');
// 取得
return $article->paginate($num);
}
// ...省略...
Controller
ルーティングで設定したメソッドを用意し、それぞれのパラメータを変更して一覧取得します。
その後は、表示用メソッドlistView()を実行するだけです。
// ...省略...
/**
* 管理画面・親カテゴリ別記事一覧
*
* @param string $parent
* @return mixed
*/
public function adminParentList(string $parent) {
// ブログ記事一覧を取得
$articleData = $this->article->getList($this->ADMIN_LIST_NUM, true, (int)$parent);
return $this->listView($articleData, 'admin');
}
/**
* 管理画面・子カテゴリ別記事一覧
*
* @param string $child
* @return mixed
*/
public function adminChildList(string $child) {
// ブログ記事一覧を取得
$articleData = $this->article->getList($this->ADMIN_LIST_NUM, true, 0, $child);
return $this->listView($articleData, 'admin');
}
/**
* 管理画面・記事一覧(ワード検索)
*
* @param Request $request
* @return mixed
*/
public function adminSearchList(Request $request) {
// ブログ記事一覧を取得
$articleData = $this->article->getList($this->ADMIN_LIST_NUM, true, 0, 0, $request['search']);
return $this->listView($articleData, 'admin');
}
// ...省略...
テンプレート
resources/views/admin/app.blade.php
サイドメニューに、検索ボックスとカテゴリの絞り込みリンクを設置します。
// ...省略...
<section class="aside">
<h3>検索</h3>
<div id="searchWrapper">
<form action="{{ route('admin_article_list_search') }}" method="post" name="searchForm">
{{ csrf_field() }}
<input type="text" id="searchTxt" name="search" placeholder="サイト内検索" />
<a href="javascript:searchForm.submit()" id="searchBtn">
<i class="fas fa-search"></i>
</a>
</form>
</div>
</section>
@if (isset($parentCategoryList))
<section class="aside">
<h3>カテゴリ</h3>
<ul>
@foreach ($parentCategoryList as $parent)
<li>
<a href="{{ route('admin_article_list_parent', ['parent' => $parent->id]) }}">
{{ $parent->name }}
</a>
@if (isset($childCategoryList[$parent->id]))
<ul>
@foreach ($childCategoryList[$parent->id] as $child)
<li>
<a href="{{ route('admin_article_list_child', ['child' => $child->id]) }}">
{{ $child->name }}
</a>
</li>
@endforeach
</ul>
@endif
</li>
@endforeach
</ul>
</section>
@endif
// ...省略...
2022-05-16 09:00:00
