<?php
declare(strict_types=1);
namespace App\Http\Controllers\Admin;
use App\Classes\Validator;
use App\Models\Sticker;
use App\Models\StickersCategory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use Illuminate\View\View;
class StickerController extends AdminController
{
/**
* Главная страница
*
* @return View
*/
public function index(): View
{
$categories = StickersCategory::query()
->selectRaw('sc.id, sc.name, count(s.id) cnt')
->from('stickers_categories as sc')
->leftJoin('stickers as s', 's.category_id', 'sc.id')
->groupBy('sc.id')
->orderBy('sc.id')
->get();
return view('admin/stickers/index', compact('categories'));
}
/**
* Просмотр стикеров по категориям
*
* @param int $id
*
* @return View
*/
public function category(int $id): View
{
$category = StickersCategory::query()->where('id', $id)->first();
if (! $category) {
abort(404, __('stickers.category_not_exist'));
}
$stickers = Sticker::query()
->where('category_id', $id)
->orderBy(DB::raw('CHAR_LENGTH(code)'))
->orderBy('name')
->with('category')
->paginate(setting('stickerlist'));
return view('admin/stickers/category', compact('category', 'stickers'));
}
/**
* Создание категории
*
* @param Request $request
* @param Validator $validator
*
* @return RedirectResponse
*/
public function create(Request $request, Validator $validator): RedirectResponse
{
$name = $request->input('name');
$validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
->length($name, 3, 50, ['name' => __('validator.text')]);
if ($validator->isValid()) {
/** @var StickersCategory $category */
$category = StickersCategory::query()->create([
'name' => $name,
'created_at' => SITETIME,
]);
setFlash('success', __('stickers.category_success_created'));
return redirect('admin/stickers/' . $category->id);
}
setInput($request->all());
setFlash('danger', $validator->getErrors());
return redirect('admin/stickers');
}
/**
* Редактирование категории
*
* @param int $id
* @param Request $request
* @param Validator $validator
*
* @return View|RedirectResponse
*/
public function edit(int $id, Request $request, Validator $validator)
{
$category = StickersCategory::query()->find($id);
if (! $category) {
abort(404, __('stickers.category_not_exist'));
}
if ($request->isMethod('post')) {
$name = $request->input('name');
$validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
->length($name, 3, 50, ['name' => __('validator.text')]);
if ($validator->isValid()) {
$category->update([
'name' => $name,
'updated_at' => SITETIME,
]);
setFlash('success', __('stickers.category_success_changed'));
return redirect('admin/stickers');
}
setInput($request->all());
setFlash('danger', $validator->getErrors());
}
return view('admin/stickers/edit_category', compact('category'));
}
/**
* Удаление категории
*
* @param int $id
* @param Request $request
* @param Validator $validator
*
* @return RedirectResponse
*/
public function delete(int $id, Request $request, Validator $validator): RedirectResponse
{
/** @var StickersCategory $category */
$category = StickersCategory::query()->find($id);
if (! $category) {
abort(404, __('stickers.category_not_exist'));
}
$validator->equal($request->input('_token'), csrf_token(), __('validator.token'));
$sticker = Sticker::query()->where('category_id', $category->id)->first();
if ($sticker) {
$validator->addError(__('stickers.category_has_stickers'));
}
if ($validator->isValid()) {
$category->delete();
setFlash('success', __('stickers.category_success_deleted'));
} else {
setFlash('danger', $validator->getErrors());
}
return redirect('admin/stickers');
}
/**
* Добавление стикера
*
* @param Request $request
* @param Validator $validator
*
* @return View|RedirectResponse
*/
public function createSticker(Request $request, Validator $validator)
{
$cid = int($request->input('cid'));
$categories = StickersCategory::query()->get();
if ($categories->isEmpty()) {
abort(200, __('stickers.empty_categories'));
}
if (! is_writable(public_path('uploads/stickers'))) {
abort(200, __('main.directory_not_writable'));
}
if ($request->isMethod('post')) {
$code = utfLower($request->input('code'));
$sticker = $request->file('sticker');
$validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
->length($code, 2, 20, ['code' => __('stickers.sticker_length')])
->regex($code, '|^:+[a-яa-z0-9_\-/\(\)]+$|i', ['code' => __('stickers.sticker_requirements')]);
$category = StickersCategory::query()->where('id', $cid)->first();
$validator->notEmpty($category, ['category' => __('stickers.category_not_exist')]);
$duplicate = Sticker::query()->where('code', $code)->first();
$validator->empty($duplicate, ['code' => __('stickers.sticker_exists')]);
$rules = [
'maxsize' => setting('stickermaxsize'),
'maxweight' => setting('stickermaxweight'),
'minweight' => setting('stickerminweight'),
];
$validator->file($sticker, $rules, ['sticker' => __('validator.image_upload_failed')]);
if ($validator->isValid()) {
$newName = uniqueName($sticker->getClientOriginalExtension());
$path = (new Sticker())->uploadPath . '/' . $newName;
$sticker->move(public_path((new Sticker())->uploadPath), $newName);
Sticker::query()->create([
'category_id' => $cid,
'name' => $path,
'code' => $code,
]);
clearCache('stickers');
setFlash('success', __('stickers.sticker_success_created'));
return redirect('admin/stickers/' . $cid);
}
setInput($request->all());
setFlash('danger', $validator->getErrors());
}
return view('admin/stickers/create_sticker', compact('categories', 'cid'));
}
/**
* Редактирование стикера
*
* @param int $id
* @param Request $request
* @param Validator $validator
*
* @return View|RedirectResponse
*/
public function editSticker(int $id, Request $request, Validator $validator)
{
/** @var Sticker $sticker */
$sticker = Sticker::query()->find($id);
$page = int($request->input('page', 1));
if (! $sticker) {
abort(404, __('stickers.sticker_not_exist'));
}
if ($request->isMethod('post')) {
$code = utfLower($request->input('code'));
$cid = int($request->input('cid'));
$validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
->length($code, 2, 20, ['code' => __('stickers.sticker_length')])
->regex($code, '|^:+[a-яa-z0-9_\-/\(\)]+$|i', ['code' => __('stickers.sticker_requirements')]);
$duplicate = Sticker::query()->where('code', $code)->where('id', '<>', $sticker->id)->first();
$validator->empty($duplicate, ['code' => __('stickers.sticker_exists')]);
$category = StickersCategory::query()->where('id', $cid)->first();
$validator->notEmpty($category, ['category' => __('stickers.category_not_exist')]);
if ($validator->isValid()) {
$sticker->update([
'code' => $code,
'category_id' => $cid,
]);
clearCache('stickers');
setFlash('success', __('stickers.sticker_success_changed'));
return redirect('admin/stickers/' . $cid . '?page=' . $page);
}
setInput($request->all());
setFlash('danger', $validator->getErrors());
}
$categories = StickersCategory::query()->get();
return view('admin/stickers/edit_sticker', compact('sticker', 'categories', 'page'));
}
/**
* Удаление стикера
*
* @param int $id
* @param Request $request
* @param Validator $validator
*
* @return RedirectResponse
s*/
public function deleteSticker(int $id, Request $request, Validator $validator): RedirectResponse
{
if (! is_writable(public_path('uploads/stickers'))) {
abort(200, __('main.directory_not_writable'));
}
$sticker = Sticker::query()->where('id', $id)->first();
if (! $sticker) {
abort(404, __('stickers.sticker_not_exist'));
}
$page = int($request->input('page', 1));
$category = $sticker->category->id;
$validator->equal($request->input('_token'), csrf_token(), __('validator.token'));
if ($validator->isValid()) {
deleteFile(public_path($sticker->name));
$sticker->delete();
clearCache('stickers');
setFlash('success', __('stickers.sticker_success_deleted'));
} else {
setFlash('danger', $validator->getErrors());
}
return redirect('admin/stickers/' . $category . '?page=' . $page);
}
}