Вход Регистрация
Файл: app/Http/Controllers/ApiController.php
Строк: 252
<?php

declare(strict_types=1);

namespace 
AppHttpControllers;

use 
AppHttpResourcesDialogueResource;
use 
AppHttpResourcesMessageResource;
use 
AppHttpResourcesNewMessageResource;
use 
AppHttpResourcesUserProfileResource;
use 
AppHttpResourcesUserResource;
use 
AppModelsDialogue;
use 
AppModelsFlood;
use 
AppModelsMessage;
use 
AppModelsUser;
use 
Closure;
use 
IlluminateDatabaseQueryJoinClause;
use 
IlluminateHttpJsonResponse;
use 
IlluminateHttpRequest;
use 
IlluminateHttpResourcesJsonJsonResource;
use 
IlluminateSupportFacadesCache;
use 
IlluminateSupportFacadesDB;
use 
IlluminateSupportStr;
use 
IlluminateViewView;

class 
ApiController extends Controller
{
    
/**
     * Главная страница
     */
    
public function index(): View
    
{
        return 
view('api/index');
    }

    
/**
     * Авторизация и получение токена
     */
    
public function auth(Request $request): JsonResponse
    
{
        
$request->validate([
            
'login'    => ['required', 'string'],
            
'password' => ['required', 'string'],
        ]);

        
$user = getUserByLoginOrEmail($request->input('login'));

        if (! 
$user || ! password_verify($request->input('password'), $user->password)) {
            
abort(401, __('users.incorrect_login_or_password'));
        }

        if (
$user->level === User::BANNED) {
            
abort(403, 'User banned');
        }

        if (! 
$user->apikey) {
            
$user->update(['apikey' => Str::random(32)]);
        }

        return 
response()->json(['token' => $user->apikey]);
    }

    
/**
     * Api пользователей
     */
    
public function user(): JsonResource
    
{
        
$user = getUser();

        return new 
UserProfileResource($user);
    }

    
/**
     * Api пользователей
     */
    
public function users(string $login): JsonResource
    
{
        
$user = getUserByLogin($login);

        if (! 
$user) {
            
abort(404, __('validator.user'));
        }

        return new 
UserResource($user);
    }

    
/**
     * Api диалогов
     */
    
public function dialogues(Request $request): JsonResource
    
{
        
$user = getUser();

        
$lastMessage = Dialogue::query()
            ->
select(
                
'author_id',
                
DB::raw('max(message_id) as message_id'),
                
DB::raw('min(case when reading then 1 else 0 end) as all_reading')
            )
            ->
where('user_id', $user->id)
            ->
groupBy('author_id');

        
$dialogues = Message::query()
            ->
select('d.*', 'm.text', 'd2.all_reading', 'd3.reading as recipient_read')
            ->
from('messages as m')
            ->
join('dialogues as d', 'd.message_id', 'm.id')
            ->
joinSub($lastMessage, 'd2', static function (JoinClause $join) {
                
$join->on('d.message_id', 'd2.message_id');
            })
            ->
leftJoin('dialogues as d3', function ($join) {
                
$join->on('d.user_id', 'd3.author_id')
                    ->
whereColumn('d.message_id', 'd3.message_id');
            })
            ->
where('d.user_id', $user->id)
            ->
with('author')
            ->
orderBy('d.created_at', $this->getOrder($request))
            ->
paginate($this->getPerPage($request));

        return 
DialogueResource::collection($dialogues);
    }

    
/**
     * Api приватных сообщений
     */
    
public function talk(string $login, Request $request): JsonResource
    
{
        
$user = getUser();

        if (
is_numeric($login)) {
            
$author = (new User())->setAttribute('id', $login);
        } else {
            
$author = getUserByLogin($login);

            if (! 
$author) {
                
abort(404, __('validator.user'));
            }
        }

        if (
$user->id === $author->id) {
            
abort(200, __('messages.empty_dialogue'));
        }

        
$messages = Message::query()
            ->
select('d.*', 'm.id', 'm.text', 'd2.reading as recipient_read')
            ->
from('messages as m')
            ->
join('dialogues as d', 'd.message_id', 'm.id')
            ->
leftJoin('dialogues as d2', function ($join) {
                
$join->on('d.user_id', 'd2.author_id')
                    ->
whereColumn('d.message_id', 'd2.message_id');
            })
            ->
where('d.user_id', $user->id)
            ->
where('d.author_id', $author->id)
            ->
orderBy('d.created_at', $this->getOrder($request))
            ->
with('user', 'author', 'files')
            ->
paginate($this->getPerPage($request));

        
Dialogue::query()
            ->
where('user_id', $user->id)
            ->
where('author_id', $author->id)
            ->
where('reading', 0)
            ->
update(['reading' => 1]);

        
$dialogue = $messages->first();
        
$dialogue?->setAttribute('all_reading', true);

        return 
MessageResource::collection($messages)
            ->
additional(['dialogue' => $dialogue ? DialogueResource::make($dialogue) : null]);
    }

    
/**
     * Отправляет приватное сообщение
     */
    
public function createTalk(string $login, Request $request, Flood $flood): JsonResponse
    
{
        
$user = getUser();
        
$recipient = getUserByLogin($login);

        
$validated = $request->validate([
            
'text' => [
                
'required',
                
'string',
                
'min:' . setting('comment_text_min'),
                
'max:' . setting('comment_text_max'),
                function (
string $attribute, mixed $value, Closure $fail) use ($user, $recipient, $flood) {
                    if (! 
$recipient) {
                        
$fail(__('validator.user'));
                    } elseif (
$recipient->id === $user->id) {
                        
$fail(__('messages.send_yourself'));
                    } elseif (
$flood->isFlood()) {
                        
$fail(__('validator.flood', ['sec' => $flood->getPeriod()]));
                    }
                },
            ],
            
'files'   => ['nullable', 'array', 'max:' . setting('maxfiles')],
            
'files.*' => ['file', 'max:' . setting('filesize'), 'mimes:' . setting('file_extensions')],
        ]);

        
$text = antimat($validated['text']);
        
$message = $recipient->sendMessage($user, $text);

        foreach (
$request->file('files', []) as $file) {
            
$message->uploadFile($file);
        }

        
$flood->saveState();

        
$message->load('user', 'files');
        
$message->setAttribute('type', Message::OUT);

        return 
response()->json([
            
'message' => __('messages.success_sent'),
            
'data'    => MessageResource::make($message),
        ], 
201);
    }

    
/**
     * Api новых сообщений
     */
    
public function newMessages(): JsonResponse
    
{
        
$user = getUser();

        
$countMessages = Dialogue::query()
            ->
where('user_id', $user->id)
            ->
where('reading', 0)
            ->
count();

        if (! 
$countMessages) {
            return 
response()->json(['count' => 0, 'dialogues' => []]);
        }

        
$dialogues = Dialogue::query()
            ->
select(
                
'author_id',
                
DB::raw('max(created_at) as last_created_at')
            )
            ->
selectRaw('count(*) as cnt')
            ->
where('user_id', $user->id)
            ->
where('reading', 0)
            ->
groupBy('author_id')
            ->
with('author')
            ->
get();

        return 
response()->json([
            
'count'     => $countMessages,
            
'dialogues' => NewMessageResource::collection($dialogues),
        ]);
    }

    
/**
     * Api конфигурации
     */
    
public function config(): JsonResponse
    
{
        
$data = Cache::remember('apiConfig', 600, static fn () => [
            
'site' => [
                
'title'             => setting('title'),
                
'language'          => setting('language'),
                
'money_name'        => setting('moneyname'),
                
'score_name'        => setting('scorename'),
                
'site_closed'       => (bool) setting('closedsite'),
                
'registration_open' => (bool) setting('openreg'),
            ],
            
'upload' => [
                
'max_files'     => setting('maxfiles'),
                
'max_file_size' => setting('filesize'),
                
'extensions'    => explode(',', setting('file_extensions')),
            ],
            
'forum' => [
                
'title_min' => setting('forum_title_min'),
                
'title_max' => setting('forum_title_max'),
                
'text_min'  => setting('forum_text_min'),
                
'text_max'  => setting('forum_text_max'),
            ],
            
'vote' => [
                
'title_min'   => setting('vote_title_min'),
                
'title_max'   => setting('vote_title_max'),
                
'answer_min'  => setting('vote_answer_min'),
                
'answer_max'  => setting('vote_answer_max'),
                
'answers_min' => 2,
                
'answers_max' => 10,
            ],
            
'message' => [
                
'text_min' => setting('comment_text_min'),
                
'text_max' => setting('comment_text_max'),
            ],
        ]);

        return 
response()->json($data);
    }

    
/**
     * Get order direction from request
     */
    
private function getOrder(Request $request, string $default = 'desc'): string
    
{
        
$order = $request->input('order', $default);

        return 
in_array($order, ['asc', 'desc']) ? $order : $default;
    }

    
/**
     * Get per page from request
     */
    
private function getPerPage(Request $request): int
    
{
        
$perPage = $request->integer('per_page', 10);

        return 
max(1, min($perPage, 100));
    }
}
Онлайн: 3
Реклама