You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

571 lines
17 KiB
PHTML

2 years ago
<?php
namespace App\Libs;
use App\Models\Board;
use App\Models\BoardArticle;
use App\Models\BoardAsset;
use App\Models\BoardComment;
use App\Services\CrossFileService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
trait TraitBoard
{
protected $cookie;
/**
* 게시판 정보
*
* @param string $code
* @return mixed
*/
protected function getBoardInfo(string $code = '')
{
return Board::query()->where('code', $code)->first();
}
/**
* 게시물 목록
*
* @param Request $request
* @param string $code
* @param int $perPage
* @return array
*/
protected function getPostList(Request $request, string $code = '', int $perPage = 15)
{
$board = $this->getBoardInfo($code);
$list = BoardArticle::query()
->with(['user', 'asset', 'assets', 'comments'])
->withCount(['assets', 'comments'])
->where('board_id', $board->id)
->where(function ($query) use ($request) {
if ($request->filled('word')) {
if ($request->filled('field') && $request->field != 'all') {
$query->where($request->field, 'like', '%' . $request->word . '%');
} else {
$query->orWhere('name', 'like', '%'. $request->word .'%')
->orWhere('email', 'like', '%'. $request->word .'%')
->orWhere('phone', 'like', '%'. $request->word .'%')
->orWhere('subject', 'like', '%'. $request->word .'%')
->orWhere('content', 'like', '%'. $request->word .'%');
}
}
})
->orderByDesc('notice')
->latest()
->paginate($perPage);
$list = $this->getListNumber($list);
$search = $request->all();
$list->appends($search);
$searchs = [
'all' => '통합검색',
'subject' => '제목',
'content' => '내용'
];
if ($code == 'inquiry') {
$searchs = [
'all' => '통합검색',
'name' => '이름',
'email' => '이메일',
'phone' => '연락처',
'content' => '내용'
];
}
$data = [
'mode' => 'list',
'code' => $code,
'board' => $board,
'data' => $list,
'search' => $search,
'searchs' => $searchs
];
return $data;
}
/**
* 최근게시물
*
* @param Request $request
* @param string $code
* @param int $perPage
* @return array
*/
protected function getLatest(string $code = '', int $count = 5)
{
$board = $this->getBoardInfo($code);
$data = BoardArticle::query()->where('board_id', $board->id)->latest()->limit($count)->get();
return $data;
}
/**
* 게시글 정보
*
* @param string $uid
* @return mixed
*/
protected function getPostInfo(string $uid = '')
{
$data = BoardArticle::query()
->with(['board', 'user', 'asset', 'assets', 'comments'])
->withCount(['assets', 'comments'])
->where('uid', $uid)
->first();
logger(json_decode(json_encode($data), true));
return $data;
}
/**
* 게시글 보기 화면
*
* @param Request $request
* @param string $code
* @param string $uid
* @return mixed
*/
protected function showPost(Request $request, string $code = '', string $uid = '')
{
$next = null;
$prev = null;
$board = $this->getBoardInfo($code);
$data = $this->getPostInfo($uid);
if ($data) {
$prev = BoardArticle::query()
->where('id', '>', $data->id)
->where('board_id', $data->board->id)
->first();
$next = BoardArticle::query()
->where('id', '<', $data->id)
->where('board_id', $data->board->id)
->orderBy('created_at', "desc")
->first();
} else {
$data = new BoardArticle;
}
$data->mode = 'view';
$data->code = $code;
$data->board = $board;
$data->board_id = $board->id;
$data->next = $next;
$data->prev = $prev;
$data->search = $request->all();
$images = [];
$files = [];
if ($data->assets) {
foreach ($data->assets as $asset) {
if ($asset->asset->width && $asset->asset->height) {
$images[] = $asset->asset;
} else {
$files[] = $asset->asset;
}
}
}
$data->images = $images;
$data->files = $files;
return $data;
}
/**
* 게시글 등록/수정
*
* @param Request $request
* @param string $code
* @param string $uid
* @return array
*/
protected function createPost(Request $request, string $code = '', string $uid = '')
{
$board = $this->getBoardInfo($code);
if ($uid) {
$data = $this->getPostInfo($uid);
$data->mode = 'modify';
} else {
$data = new BoardArticle;
$data->mode = 'add';
$data->board_id = $board->id;
$data->uid = '';
}
$data->code = $code;
$data->board = $board;
$data->search = $request->all();
return $data;
}
/**
* 게시글 저장
*
* @param Request $request
* @param CrossFileService $fileService
* @return mixed
*/
protected function storePost(Request $request, CrossFileService $fileService)
{
return DB::transaction(function() use ($request, $fileService) {
$rules = [
'mode' => 'required|string',
'code' => 'required|string|max:20',
'board_id' => 'required|integer',
'subject' => 'required|string|max:255',
'content' => 'required|string'
];
$boardCode = $request->code;
if ($boardCode == 'inquiry') {
unset($rules['subject']);
$rules['name'] = 'required|string';
$rules['email'] = 'required|string';
$rules['phone'] = 'required|string';
}
$validator = $this->validation($request, $rules);
if ($validator !== true) {
return $this->sendResult($validator);
}
$board = $this->getBoardInfo($boardCode);
if (!$board) {
return $this->sendResult('존재하지 않는 게시판입니다.');
}
$mode = $request->get('mode', 'add');
$uid = (string)$request->get('uid', '');
$data = $this->getPostInfo($uid);
$postData = $request->only([
'board_id', 'category', 'notice',
'name', 'email', 'phone',
'subject', 'content', 'related_link'
]);
$postData = array_map('setDefault', $postData);
if (!isset($postData['subject'])) {
$postData['subject'] = 0;
}
if (!isset($postData['notice'])) {
$postData['notice'] = 0;
}
if (!isset($postData['name'])) {
$postData['name'] = auth()->user()->name;
}
if (!isset($postData['email'])) {
$postData['email'] = auth()->user()->email;
}
if (!isset($postData['phone'])) {
$postData['phone'] = auth()->user()->phone;
}
// 목록이미지 삭제
if ($request->get('delImage', 0)) {
// 기존파일 삭제
if ($data && $data->image) {
$fileService->deleteFile($data->image);
}
$postData['image'] = '';
}
// 갤러리형 목록이미지
if ($request->hasFile('image')) {
// 기존파일 삭제
if ($data && $data->image) {
$fileService->deleteFile($data->image);
}
$asset = $fileService->saveFile(auth()->user(), $request, 'image');
if ($asset) {
$postData['image'] = $asset->uid;
}
}
// 수정
if ($mode == 'modify') {
if (!$data) {
return $this->sendResult('게시글이 존재하지 않습니다.');
}
// 기존파일 삭제
$delFiles = $request->get('delFiles');
if (!empty($delFiles) && $data->assets) {
foreach ($data->assets as $asset) {
if (in_array($asset->uid, $delFiles)) {
$fileService->deleteFile($asset->uid);
$asset->delete();
}
}
}
$appends = [
'updated_id' => auth()->user()->id,
'updated_at' => (string)Carbon::now()
];
$postData = array_merge($postData, $appends);
$data->fill($postData);
$data->save();
} else {
$appends = [
'uid' => Str::uuid()->toString(),
'created_id' => auth()->user()->id,
'created_at' => (string)Carbon::now()
];
$postData = array_merge($postData, $appends);
$data = BoardArticle::query()->create($postData);
if (!$data) {
return $this->sendResult('게시물 등록에 실패했습니다.');
}
}
// 첨부사진
if ($request->file('files')) {
$assets = $fileService->saveFile(auth()->user(), $request, 'files');
if (is_array($assets)) {
foreach ($assets as $asset) {
if ($asset) {
$assetFields = array(
'article_id' => $data->id,
'uid' => $asset->uid
);
BoardAsset::query()->create($assetFields);
}
}
}
}
if ($mode == 'add') {
$message = '게시물이 등록되었습니다.';
} else {
$message = '게시물 정보가 수정되었습니다.';
}
return $this->sendResult($message, 'success');
});
}
/**
* 에디터 이미지 첨부파일 저장하기
*
* @param Request $request
* @param CrossFileService $fileService
* @return array
*/
protected function editorImageUpload(Request $request, CrossFileService $fileService)
{
$message = '';
$statusCode = '';
$data = [];
$validatorRules = [
'image' => 'bail|required|file|image',
];
$validatorMessages = [
'image' => '이미지 파일만 업로드 가능합니다',
];
$validator = Validator::make($request->all(), $validatorRules, $validatorMessages);
if ($validator->fails()) {
$message = $validator->errors()->first('image');
$statusCode = 'error';
} else {
try {
$asset = $fileService->saveFile(auth()->user(), $request, 'image');
if ($asset) {
$data = [
'name' => $asset->name,
'origin' => $asset->orgin_name,
'size' => $asset->size,
'width' => $asset->width,
'height' => $asset->height,
'url' => '/image/' . $asset->uid
];
$statusCode = 'success';
}
} catch (\Exception $exception) {
$message = '업로드 중 에러가 발생했습니다.';
$statusCode = 'error';
}
}
return $this->sendResult($message, $statusCode, ['data' => $data]);
}
/**
* 첨부 파일 삭제하기
*
* @param Request $request
* @param CrossFileService $fileService
* @return array
*/
public function assetDelete(Request $request, CrossFileService $fileService)
{
$data = BoardAsset::query()->where('uid', $request->uid)->first();
$statusCode = 'error';
if ($data) {
$fileService->deleteFile($data->uid);
$data->delete();
$message = '파일이 삭제되었습니다.';
$statusCode = 'success';
} else {
$message = '파일을 삭제하지 못했습니다.';
}
return $this->sendResult($message, $statusCode);
}
/**
* 댓글 저장하기
*
* @param Request $request
* @return array
*/
protected function storeComment(Request $request)
{
return DB::transaction(function () use ($request) {
$rules = [
'artist_id' => 'required|string',
'content' => 'required|string'
];
$validator = $this->validation($request, $rules);
if ($validator !== true) {
return $this->sendResult($validator);
}
$article_id = $request->get('article_id', 0);
$uid = $request->get('uid', '');
$article = $this->getPostInfo($article_id);
if (!$article_id || !$article) {
return $this->sendResult('게시글이 존재하지 않습니다.');
}
$data = BoardComment::query()->where('uid', $uid)->first();
$postData = $request->only([
'content'
]);
$postData = array_map('setDefault', $postData);
// 수정
if ($uid) {
if (!$data) {
return $this->sendResult('댓글이 존재하지 않습니다.');
}
$appends = [
'updated_id' => auth()->user()->id,
'updated_at' => (string)Carbon::now()
];
$postData = array_merge($postData, $appends);
$data->fill($postData);
$data->save();
return $this->sendResult('댓글이 등록되었습니다.', 'success');
} else {
$uid = Str::uuid()->toString();
$appends = [
'article_id' => $article->id,
'uid' => $uid,
'parent_id' => $uid,
'name' => auth()->user()->name,
'created_id' => auth()->user()->id,
'created_at' => (string)Carbon::now()
];
$postData = array_merge($postData, $appends);
$data = BoardComment::query()->create($postData);
if (!$data) {
return $this->sendResult('댓글 등록에 실패했습니다.');
}
return $this->sendResult('댓글이 수정되었습니다.', 'success');
}
});
}
/**
* 댓글 삭제하기
*
* @param Request $request
* @return array
*/
protected function deleteComment(Request $request)
{
return DB::transaction(function () use ($request) {
$uid = $request->get('uid', '');
$data = BoardComment::query()->where('uid', $uid)->first();
if (!$uid || !$data) {
return $this->sendResult('댓글이 존재하지 않습니다.');
}
$data->delete();
return $this->sendResult('댓글이 삭제되었습니다.', 'success');
});
}
/**
* 게시글 삭제
*
* @param Request $request
* @param CrossFileService $fileService
* @return array
*/
public function deletePost(Request $request, CrossFileService $fileService)
{
$uid = $request->get('uid', '');
$data = $this->getPostInfo($uid);
if (!$uid || !$data) {
return $this->sendResult('해당 게시글이 존재하지 않습니다.');
}
// 댓글 삭제
if ($data->comments_count) {
$data->comments->delete();
}
// 첨부파일 삭제
if ($data->assets) {
foreach ($data->assets as $asset) {
$fileService->deleteFile($asset->uid);
$asset->delete();
}
}
$data->delete();
return $this->sendResult('게시글이 삭제되었습니다.', 'success');
}
}