View file app/Controllers/MessageController.php

File size: 7.09Kb
<?php

namespace App\Controllers;

use App\Classes\Validator;
use App\Models\Flood;
use App\Models\Ignore;
use App\Models\Message;
use App\Models\User;
use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Http\Request;

class MessageController extends BaseController
{
    public $user;

    /**
     * Конструктор
     */
    public function __construct()
    {
        parent::__construct();

        if (! $this->user = getUser()) {
            abort(403, 'Для просмотра писем необходимо авторизоваться!');
        }
    }

    /**
     * Главная страница
     */
    public function index(): string
    {
        $total = Message::query()
            ->distinct()
            ->where('user_id', $this->user->id)
            ->count('author_id');
        $page = paginate(setting('privatpost'), $total);

        $latestMessage = Message::query()
            ->select('author_id', DB::connection()->raw('max(created_at) as last_created_at'))
            ->where('user_id', $this->user->id)
            ->groupBy('author_id');

        $messages = Message::query()
            ->joinSub($latestMessage, 'latest_message', function (JoinClause $join) {
                $join->on('messages.created_at', 'latest_message.last_created_at')
                ->whereRaw('messages.author_id = latest_message.author_id');
            })
            ->where('user_id', $this->user->id)
            ->orderBy('created_at', 'desc')
            ->offset($page->offset)
            ->limit($page->limit)
            ->with('author')
            ->get();


        if ($this->user->newprivat) {
            $this->user->update([
                'newprivat'      => 0,
                'sendprivatmail' => 0,
            ]);
        }

        return view('messages/index', compact('messages', 'page'));
    }

    /**
     * Диалог
     *
     * @param string $login
     * @return string
     */
    public function talk(?string $login = null): string
    {
        if ($login) {
            $user = User::query()->where('login', $login)->first();

            if (! $user) {
                abort(404, 'Пользователь не найден!');
            }

            if ($user->id === $this->user->id) {
                abort('default', 'Отсутствует переписка с самим собой!');
            }
        } else {
            $user = new User();
            $user->id = 0;
        }

        $total = Message::query()
            ->where('user_id', $this->user->id)
            ->where('author_id', $user->id)
            ->count();

        $page  = paginate(setting('privatpost'), $total);

        $messages = Message::query()
            ->where('user_id', $this->user->id)
            ->where('author_id', $user->id)
            ->orderBy('created_at', 'desc')
            ->offset($page->offset)
            ->limit($page->limit)
            ->with('user', 'author')
            ->get();

        // Прочитано
        Message::query()
            ->where('user_id', $this->user->id)
            ->where('author_id', $user->id)
            ->update(['reading' => 1]);

        $view = $user->id ? 'messages/talk' : 'messages/talk_system';

        return view($view, compact('messages', 'user', 'page'));
    }

    /**
     * Отправка сообщений
     *
     * @param Request   $request
     * @param Validator $validator
     * @return void
     */
    public function send(Request $request, Validator $validator): void
    {
        $login = check($request->input('user'));
        $token = check($request->input('token'));
        $msg   = check($request->input('msg'));

        $user = User::query()->where('login', $login)->first();

        if (! $user) {
            abort(404, 'Пользователь не найден!');
        }

        $validator->equal($token, $_SESSION['token'], ['msg' => 'Неверный идентификатор сессии, повторите действие!'])
            ->length($msg, 5, 1000, ['msg' => 'Слишком длинное или короткое сообщение!'])
            ->equal(Flood::isFlood(), true, 'Антифлуд! Разрешается отправлять сообщения раз в ' . Flood::getPeriod() . ' сек!')
            ->notEqual($user->id, $this->user->id, 'Нельзя отправлять письмо самому себе!');

        if (! captchaVerify() && $this->user->point < setting('privatprotect')) {
            $validator->addError(['protect' => 'Не удалось пройти проверку captcha!']);
        }

        // Проверка на игнор
        $ignoring = Ignore::query()
            ->where('user_id', $user->id)
            ->where('ignore_id', $this->user->id)
            ->first();

        $validator->empty($ignoring, ['user' => 'Вы внесены в игнор-лист получателя!']);

        if ($validator->isValid()) {

            $msg = antimat($msg);
            $user->increment('newprivat');

            Message::query()->create([
                'user_id'    => $user->id,
                'author_id'  => $this->user->id,
                'text'       => $msg,
                'type'       => 'in',
                'created_at' => SITETIME,
            ])->create([
                'user_id'    => $this->user->id,
                'author_id'  => $user->id,
                'text'       => $msg,
                'type'       => 'out',
                'reading'    => 1,
                'created_at' => SITETIME,
            ]);

            setFlash('success', 'Письмо успешно отправлено!');
        } else {
            setInput($request->all());
            setFlash('danger', $validator->getErrors());
        }

        redirect('/messages/talk/' . $user->login);
    }

    /**
     * Удаление переписки
     *
     * @param int       $uid
     * @param Request   $request
     * @param Validator $validator
     */
    public function delete(int $uid, Request $request, Validator $validator): void
    {
        $token = check($request->input('token'));
        $page  = int($request->input('page', 1));

        $total = Message::query()
            ->where('user_id', $this->user->id)
            ->where('author_id', $uid)
            ->count();

        $validator->equal($token, $_SESSION['token'], 'Неверный идентификатор сессии, повторите действие!')
            ->notEmpty($total, ['user' => 'Переписки с данным пользователем не существует!'])
            ->empty(getUser('newprivat'), 'У вас имеются непрочитанные сообщения!');

        if ($validator->isValid()) {
            Message::query()
                ->where('user_id', getUser('id'))
                ->where('author_id', $uid)
                ->delete();

            setFlash('success', 'Сообщения успешно удалены!');
        } else {
            setFlash('danger', $validator->getErrors());
        }

        redirect('/messages?page=' . $page);
    }
}