227 lines
8.0 KiB
PHP
227 lines
8.0 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Admin;
|
||
|
||
use App\Http\Controllers\Controller;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Support\Facades\DB;
|
||
use Illuminate\Validation\Rule;
|
||
|
||
class NewsController extends Controller
|
||
{
|
||
/** @var string テーブル名 */
|
||
protected string $table = 'news';
|
||
|
||
/** @var string 主キー列名 */
|
||
protected string $pk = 'news_id';
|
||
|
||
/**
|
||
* 現在ログイン中のオペレーターIDを取得
|
||
* @return int|null
|
||
*/
|
||
protected function currentOperatorId(): ?int
|
||
{
|
||
$u = auth()->user();
|
||
return $u->ope_id ?? $u->id ?? null;
|
||
}
|
||
|
||
/**
|
||
* 一覧表示(GET/POST)
|
||
* 検索条件:kw(本文/URL 部分一致)、mode、open_datetime 範囲(from/to)
|
||
*/
|
||
public function list(Request $request)
|
||
{
|
||
// 一覧用クエリ(表示に必要な列のみ)
|
||
$q = DB::table($this->table)->select([
|
||
"{$this->pk} as id",
|
||
'news',
|
||
'mode',
|
||
'open_datetime',
|
||
'link_url',
|
||
'image1_filename',
|
||
'image2_filename',
|
||
'created_at',
|
||
'updated_at',
|
||
]);
|
||
|
||
// キーワード検索(本文/リンクURL)
|
||
if ($kw = trim((string)$request->input('kw', ''))) {
|
||
$q->where(function($w) use ($kw) {
|
||
$w->where('news','like',"%{$kw}%")
|
||
->orWhere('link_url','like',"%{$kw}%");
|
||
});
|
||
}
|
||
|
||
// 表示モードで絞り込み(0:非表示 / 1:公開 / 2:下書き など)
|
||
if ($request->filled('mode')) {
|
||
$q->where('mode', (int)$request->input('mode'));
|
||
}
|
||
|
||
// 公開日時の範囲指定
|
||
if ($request->filled('from')) { $q->where('open_datetime','>=',$request->input('from')); }
|
||
if ($request->filled('to')) { $q->where('open_datetime','<=',$request->input('to')); }
|
||
|
||
// {追加} 並び替え(ホワイトリスト)
|
||
$sort = (string)$request->query('sort', '');
|
||
$dir = strtolower((string)$request->query('dir', 'desc'));
|
||
$dir = in_array($dir, ['asc','desc'], true) ? $dir : 'desc';
|
||
|
||
// 画面キー → 実カラム
|
||
$sortable = [
|
||
'id' => $this->pk, // ニュースID
|
||
'news' => 'news', // ニュース内容
|
||
'open_datetime' => 'open_datetime', // 公開日時
|
||
'mode' => 'mode', // 表示モード
|
||
];
|
||
|
||
if (isset($sortable[$sort])) {
|
||
$q->orderBy($sortable[$sort], $dir);
|
||
} else {
|
||
// 既定:公開日時降順 → 主キー降順
|
||
$q->orderByDesc('open_datetime')
|
||
->orderByDesc($this->pk);
|
||
}
|
||
|
||
// ページング(現在のクエリを維持)
|
||
$rows = $q->paginate(20)->appends($request->except('page'));
|
||
|
||
return view('admin.news.list', compact('rows'));
|
||
}
|
||
|
||
/**
|
||
* 新規作成(GET:フォーム表示 / POST:登録処理)
|
||
*/
|
||
public function add(Request $request)
|
||
{
|
||
if ($request->isMethod('post')) {
|
||
$messages = [
|
||
'required' => ':attribute は、必ず入力してください。',
|
||
'open_datetime.date_format' => '公開日時は :format 形式(YYYY-MM-DD HH:MM:SS)で入力してください。',
|
||
];
|
||
$attributes = [
|
||
'news' => 'ニュース内容',
|
||
'open_datetime' => '公開日時',
|
||
'mode' => '表示モード',
|
||
];
|
||
$v = $request->validate([
|
||
'news' => 'required|string',
|
||
'open_datetime' => 'required|date_format:Y-m-d H:i:s',
|
||
'link_url' => 'nullable|string|max:255',
|
||
'image1_filename' => 'nullable|string|max:255',
|
||
'image2_filename' => 'nullable|string|max:255',
|
||
'mode' => 'required|integer|min:0|max:9',
|
||
], $messages, $attributes);
|
||
|
||
// 登録
|
||
$now = now();
|
||
DB::table($this->table)->insert([
|
||
'news' => $v['news'],
|
||
'open_datetime' => $v['open_datetime'],
|
||
'link_url' => $v['link_url'] ?? null,
|
||
'image1_filename' => $v['image1_filename'] ?? null,
|
||
'image2_filename' => $v['image2_filename'] ?? null,
|
||
'mode' => $v['mode'],
|
||
'created_at' => $now,
|
||
'updated_at' => $now,
|
||
'operator_id' => $this->currentOperatorId(),
|
||
]);
|
||
|
||
return redirect()->route('news')->with('success','ニュースを登録しました。');
|
||
}
|
||
|
||
// フォーム表示
|
||
return view('admin.news.add');
|
||
}
|
||
|
||
/**
|
||
* 編集(GET:フォーム表示 / POST:更新処理)
|
||
* @param int $id ニュースID
|
||
*/
|
||
public function edit($id, Request $request)
|
||
{
|
||
// 対象データ取得
|
||
$news = DB::table($this->table)->where($this->pk, $id)->first();
|
||
if (!$news) { abort(404); }
|
||
|
||
if ($request->isMethod('post')) {
|
||
$messages = [
|
||
'required' => ':attribute は、必ず入力してください。',
|
||
'open_datetime.date_format' => '公開日時は :format 形式(YYYY-MM-DD HH:MM:SS)で入力してください。',
|
||
];
|
||
$attributes = [
|
||
'news' => 'ニュース内容',
|
||
'open_datetime' => '公開日時',
|
||
'mode' => '表示モード',
|
||
];
|
||
$v = $request->validate([
|
||
'news' => 'required|string',
|
||
'open_datetime' => 'required|date_format:Y-m-d H:i:s',
|
||
'link_url' => 'nullable|string|max:255',
|
||
'image1_filename' => 'nullable|string|max:255',
|
||
'image2_filename' => 'nullable|string|max:255',
|
||
'mode' => 'required|integer|min:0|max:9',
|
||
], $messages, $attributes);
|
||
|
||
// 更新
|
||
DB::table($this->table)->where($this->pk, $id)->update([
|
||
'news' => $v['news'],
|
||
'open_datetime' => $v['open_datetime'],
|
||
'link_url' => $v['link_url'] ?? null,
|
||
'image1_filename' => $v['image1_filename'] ?? null,
|
||
'image2_filename' => $v['image2_filename'] ?? null,
|
||
'mode' => $v['mode'],
|
||
'updated_at' => now(),
|
||
'operator_id' => $this->currentOperatorId(),
|
||
]);
|
||
|
||
return redirect()->route('news_edit', ['id'=>$id])->with('success','更新しました。');
|
||
}
|
||
|
||
// フォーム表示
|
||
return view('admin.news.edit', compact('news'));
|
||
}
|
||
|
||
/**
|
||
* 詳細表示
|
||
* @param int $id ニュースID
|
||
*/
|
||
public function info($id)
|
||
{
|
||
// 詳細用に必要な列を選択
|
||
$news = DB::table($this->table)
|
||
->select([
|
||
"{$this->pk} as id",
|
||
'news','mode','open_datetime','link_url',
|
||
'image1_filename','image2_filename',
|
||
'created_at','updated_at','operator_id',
|
||
])->where($this->pk, $id)->first();
|
||
|
||
if (!$news) { abort(404); }
|
||
|
||
return view('admin.news.info', compact('news'));
|
||
}
|
||
|
||
/**
|
||
* 削除(単体 id または 複数 ids[] に対応)
|
||
*/
|
||
public function delete(Request $request)
|
||
{
|
||
// 削除対象IDの取得(単体 or 複数)
|
||
$ids = $request->input('ids');
|
||
if (!$ids) {
|
||
$id = (int)$request->input('id');
|
||
if ($id > 0) { $ids = [$id]; }
|
||
}
|
||
|
||
// バリデーション:削除対象未選択
|
||
if (!is_array($ids) || empty($ids)) {
|
||
return back()->with('error', '削除対象が選択されていません。');
|
||
}
|
||
|
||
// 削除実行
|
||
DB::table($this->table)->whereIn($this->pk, $ids)->delete();
|
||
|
||
return back()->with('success','削除しました。');
|
||
}
|
||
}
|