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

declare(strict_types=1);

namespace 
AppHttpControllersLoad;

use 
AppClassesValidator;
use 
AppHttpControllersController;
use 
AppModelsComment;
use 
AppModelsDown;
use 
AppModelsFile;
use 
AppModelsFlood;
use 
AppModelsLoad;
use 
AppModelsReader;
use 
AppModelsUser;
use 
IlluminateDatabaseQueryJoinClause;
use 
IlluminateHttpRedirectResponse;
use 
IlluminateHttpRequest;
use 
IlluminateViewView;
use 
SymfonyComponentHttpFoundationResponse;
use 
ZipArchive;

class 
DownController extends Controller
{
    
/**
     * Просмотр загрузки
     */
    
public function index(int $id): View
    
{
        
$down Down::query()
            ->
select('downs.*''pollings.vote')
            ->
where('downs.id'$id)
            ->
leftJoin('pollings', static function (JoinClause $join) {
                
$join->on('downs.id''pollings.relate_id')
                    ->
where('pollings.relate_type'Down::$morphName)
                    ->
where('pollings.user_id'getUser('id'));
            })
            ->
with('category.parent')
            ->
first();

        if (! 
$down) {
            
abort(404__('loads.down_not_exist'));
        }

        if (! 
isAdmin(User::ADMIN) && (! $down->active && getUser() && getUser('id') !== $down->user_id)) {
            
abort(200__('loads.down_not_verified'));
        }

        
$allowDownload getUser() || setting('down_guest_download');

        return 
view('loads/down'compact('down''allowDownload'));
    }

    
/**
     * Создание загрузки
     */
    
public function create(Request $requestValidator $validatorFlood $flood): View|RedirectResponse
    
{
        
$cid int($request->input('category'));

        if (! 
isAdmin() && ! setting('downupload')) {
            
abort(200__('loads.down_closed'));
        }

        if (! 
$user getUser()) {
            
abort(403__('main.not_authorized'));
        }

        
$categories = (new Load())->getChildren();

        if (
$categories->isEmpty()) {
            
abort(200__('loads.empty_loads'));
        }

        if (
$request->isMethod('post')) {
            
$title $request->input('title');
            
$text $request->input('text');
            
$files = (array) $request->file('files');
            
$links = (array) $request->input('links');

            
$links array_unique(array_diff($links, ['']));

            
/** @var Load $category */
            
$category Load::query()->find($cid);

            
$validator
                
->equal($request->input('_token'), csrf_token(), __('validator.token'))
                ->
length($title350, ['title' => __('validator.text')])
                ->
length($text505000, ['text' => __('validator.text')])
                ->
false($flood->isFlood(), ['msg' => __('validator.flood', ['sec' => $flood->getPeriod()])])
                ->
notEmpty($category, ['category' => __('loads.load_not_exist')]);

            if (
$category) {
                
$validator->empty($category->closed, ['category' => __('loads.load_closed')]);

                
$duplicate Down::query()->where('title'$title)->count();
                
$validator->empty($duplicate, ['title' => __('loads.down_name_exists')]);
            }

            
$validator->notEmpty($files || $links, ['files' => __('validator.file_upload_one')]);
            
$validator->lte(count($files) + count($links), setting('maxfiles'), ['files' => __('validator.files_max', ['max' => setting('maxfiles')])]);

            if (
$validator->isValid()) {
                
$allowExtension explode(','setting('allowextload'));

                
$rules = [
                    
'maxsize'    => setting('fileupload'),
                    
'extensions' => $allowExtension,
                    
'minweight'  => 100,
                ];

                foreach (
$files as $file) {
                    
$validator->file($file$rules, ['files' => __('validator.file_upload_failed')]);
                }

                foreach (
$links as $link) {
                    
$validator->length($link5100, ['links' => __('validator.text')])
                        ->
url($link, ['links' => __('validator.url')]);

                    if (! 
in_array(getExtension($link), $allowExtensiontrue)) {
                        
$validator->addError(['links' => __('validator.extension')]);
                    }
                }
            }

            if (
$validator->isValid()) {
                
/** @var Down $down */
                
$down Down::query()->create([
                    
'category_id' => $category->id,
                    
'title'       => $title,
                    
'text'        => $text,
                    
'user_id'     => $user->id,
                    
'created_at'  => SITETIME,
                    
'active'      => isAdmin(User::ADMIN),
                    
'links'       => $links array_values($links) : null,
                ]);

                foreach (
$files as $file) {
                    
$down->uploadAndConvertFile($file);
                }

                if (
isAdmin(User::ADMIN)) {
                    
$down->category->increment('count_downs');
                    
clearCache(['statLoads''recentDowns''DownFeed']);
                } else {
                    
$admins User::query()->whereIn('level', [User::BOSSUser::ADMIN])->get();

                    if (
$admins->isNotEmpty()) {
                        
$text textNotice('down_upload', ['url' => '/admin/downs/edit/' $down->id'title' => $down->title]);

                        
/** @var User $admin */
                        
foreach ($admins as $admin) {
                            
$admin->sendMessage($user$textfalse);
                        }
                    }
                }

                
$flood->saveState();
                
setFlash('success'__('loads.down_added_success'));

                return 
redirect('downs/' $down->id);
            }

            
setInput($request->all());
            
setFlash('danger'$validator->getErrors());
        }

        
$down = new Down();

        return 
view('loads/create'compact('categories''down''cid'));
    }

    
/**
     * Редактирование загрузки
     */
    
public function edit(int $idRequest $requestValidator $validator): View|RedirectResponse
    
{
        
$cid int($request->input('category'));

        
/** @var Down $down */
        
$down Down::query()->where('user_id'getUser('id'))->find($id);

        if (! 
$down) {
            
abort(404__('loads.down_not_exist'));
        }

        if (
$down->active) {
            
abort(200__('loads.down_verified'));
        }

        if (
$request->isMethod('post')) {
            
$title $request->input('title');
            
$text $request->input('text');
            
$files = (array) $request->file('files');
            
$links = (array) $request->input('links');

            
$links array_unique(array_diff($links, ['']));

            
/** @var Load $category */
            
$category Load::query()->find($cid);

            
$validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
                ->
length($title350, ['title' => __('validator.text')])
                ->
length($text505000, ['text' => __('validator.text')])
                ->
notEmpty($category, ['category' => __('loads.load_not_exist')])
                ->
empty($category->closed, ['category' => __('loads.load_closed')]);

            
$duplicate Down::query()->where('title'$title)->where('id''<>'$down->id)->count();
            
$validator->empty($duplicate, ['title' => __('loads.down_name_exists')]);

            
$existFiles $down->files $down->files->count() : 0;
            
$validator->notEmpty(count($files) + count($links) + $existFiles, ['files' => __('validator.file_upload_one')]);
            
$validator->lte(count($files) + count($links) + $existFilessetting('maxfiles'), ['files' => __('validator.files_max', ['max' => setting('maxfiles')])]);

            if (
$validator->isValid()) {
                
$allowExtension explode(','setting('allowextload'));

                
$rules = [
                    
'maxsize'    => setting('fileupload'),
                    
'extensions' => $allowExtension,
                    
'minweight'  => 100,
                ];

                foreach (
$files as $file) {
                    
$validator->file($file$rules, ['files' => __('validator.file_upload_failed')]);
                }

                foreach (
$links as $link) {
                    
$validator->length($link5100, ['links' => __('validator.text')])
                        ->
url($link, ['links' => __('validator.url')]);

                    if (! 
in_array(getExtension($link), $allowExtensiontrue)) {
                        
$validator->addError(['links' => __('validator.extension')]);
                    }
                }
            }

            if (
$validator->isValid()) {
                
$links setting('down_allow_links') ? array_values($links) : null;

                
$down->update([
                    
'category_id' => $category->id,
                    
'title'       => $title,
                    
'text'        => $text,
                    
'links'       => $links,
                ]);

                foreach (
$files as $file) {
                    
$down->uploadAndConvertFile($file);
                }

                
clearCache(['statLoads''recentDowns''DownFeed']);
                
setFlash('success'__('loads.down_edited_success'));

                return 
redirect('downs/' $down->id);
            }

            
setInput($request->all());
            
setFlash('danger'$validator->getErrors());
        }

        
$categories $down->category->getChildren();

        return 
view('loads/edit'compact('categories''down''cid'));
    }

    
/**
     * Удаление файла
     */
    
public function deleteFile(int $idint $fid): RedirectResponse
    
{
        
/** @var Down $down */
        
$down Down::query()->where('user_id'getUser('id'))->find($id);

        if (! 
$down) {
            
abort(404__('loads.down_not_exist'));
        }

        if (
$down->active) {
            
abort(200__('loads.down_verified'));
        }

        
/** @var File $file */
        
$file $down->files()->find($fid);

        if (! 
$file) {
            
abort(404__('loads.down_not_exist'));
        }

        
setFlash('success'__('loads.file_deleted_success'));
        
$file->delete();

        return 
redirect('downs/edit/' $down->id);
    }

    
/**
     * Скачивание файла
     */
    
public function download(int $idValidator $validator): Response
    
{
        
/** @var File $file */
        
$file File::query()->where('relate_type'Down::$morphName)->find($id);

        if (! 
$file || ! $file->relate) {
            
abort(404__('loads.down_not_exist'));
        }

        if (! (
getUser() || setting('down_guest_download'))) {
            
abort(403__('loads.download_authorized'));
        }

        if (! 
$file->relate->active && ! isAdmin(User::ADMIN)) {
            
abort(200__('loads.down_not_verified'));
        }

        
$validator->true(file_exists(public_path($file->hash)), __('loads.down_not_exist'));

        if (
$validator->isValid()) {
            
Reader::countingStat($file->relate);

            return 
response()->download(public_path($file->hash), $file->name);
        }

        
setFlash('danger'$validator->getErrors());

        return 
redirect('downs/' $file->relate->id);
    }

    
/**
     * Скачивание файла по ссылке
     */
    
public function downloadLink(int $idint $linkIdValidator $validator): Response
    
{
        
/** @var Down $down */
        
$down Down::query()->find($id);

        if (! 
$down) {
            
abort(404__('loads.down_not_exist'));
        }

        if (! (
getUser() || setting('down_guest_download'))) {
            
abort(403__('loads.download_authorized'));
        }

        if (! 
$down->active && ! isAdmin(User::ADMIN)) {
            
abort(200__('loads.down_not_verified'));
        }

        
$validator->true($down->links[$linkId] ?? false__('loads.down_not_exist'));

        if (
$validator->isValid()) {
            
Reader::countingStat($down);

            return 
response()->redirectTo($down->links[$linkId]);
        }

        
setFlash('danger'$validator->getErrors());

        return 
redirect('downs/' $down->id);
    }

    
/**
     * Комментарии
     */
    
public function comments(int $idRequest $requestValidator $validatorFlood $flood): View|RedirectResponse
    
{
        
/** @var Down $down */
        
$down Down::query()->find($id);

        if (! 
$down) {
            
abort(404__('loads.down_not_exist'));
        }

        if (! 
$down->active) {
            
abort(200__('loads.down_not_verified'));
        }

        if (
$request->isMethod('post')) {
            
$msg $request->input('msg');

            
$validator
                
->true(getUser(), __('main.not_authorized'))
                ->
equal($request->input('_token'), csrf_token(), __('validator.token'))
                ->
length($msg5setting('comment_length'), ['msg' => __('validator.text')])
                ->
false($flood->isFlood(), ['msg' => __('validator.flood', ['sec' => $flood->getPeriod()])]);

            if (
$validator->isValid()) {
                
/** @var Comment $comment */
                
$comment $down->comments()->create([
                    
'text'       => antimat($msg),
                    
'user_id'    => getUser('id'),
                    
'created_at' => SITETIME,
                    
'ip'         => getIp(),
                    
'brow'       => getBrowser(),
                ]);

                
$user getUser();
                
$user->increment('allcomments');
                
$user->increment('point');
                
$user->increment('money'5);

                
$down->increment('count_comments');

                
$flood->saveState();
                
sendNotify($msg'/downs/comment/' $down->id '/' $comment->id$down->title);

                
setFlash('success'__('main.comment_added_success'));

                return 
redirect('downs/end/' $down->id);
            }

            
setInput($request->all());
            
setFlash('danger'$validator->getErrors());
        }

        
$comments $down->comments()
            ->
orderBy('created_at')
            ->
with('user')
            ->
paginate(setting('comments_per_page'));

        return 
view('loads/comments'compact('down''comments'));
    }

    
/**
     * Подготовка к редактированию комментария
     */
    
public function editComment(int $idint $cidRequest $requestValidator $validator): View|RedirectResponse
    
{
        
$down Down::query()->find($id);

        if (! 
$down) {
            
abort(404__('loads.down_not_exist'));
        }

        
$page int($request->input('page'1));

        if (! 
getUser()) {
            
abort(403__('main.not_authorized'));
        }

        
$comment $down->comments()
            ->
where('id'$cid)
            ->
where('user_id'getUser('id'))
            ->
first();

        if (! 
$comment) {
            
abort(200__('main.comment_deleted'));
        }

        if (
$comment->created_at 600 SITETIME) {
            
abort(200__('main.editing_impossible'));
        }

        if (
$request->isMethod('post')) {
            
$msg $request->input('msg');
            
$page int($request->input('page'1));

            
$validator
                
->equal($request->input('_token'), csrf_token(), __('validator.token'))
                ->
length($msg5setting('comment_length'), ['msg' => __('validator.text')]);

            if (
$validator->isValid()) {
                
$msg antimat($msg);

                
$comment->update([
                    
'text' => $msg,
                ]);

                
setFlash('success'__('main.comment_edited_success'));

                return 
redirect('downs/comments/' $id '?page=' $page);
            }

            
setInput($request->all());
            
setFlash('danger'$validator->getErrors());
        }

        return 
view('loads/editcomment'compact('down''comment''page'));
    }

    
/**
     * Переадресация на последнюю страницу
     */
    
public function end(int $id): RedirectResponse
    
{
        
/** @var Down $down */
        
$down Down::query()->find($id);

        if (! 
$down) {
            
abort(404__('loads.down_not_exist'));
        }

        
$total $down->comments()->count();

        
$end ceil($total setting('comments_per_page'));

        return 
redirect('downs/comments/' $down->id '?page=' $end);
    }

    
/**
     * Просмотр zip архива
     */
    
public function zip(int $id): View
    
{
        
/** @var File $file */
        
$file File::query()->where('relate_type'Down::$morphName)->find($id);
        
$down $file?->relate;

        if (! 
$file || ! $down) {
            
abort(404__('loads.down_not_exist'));
        }

        if (! 
$down->active && ! isAdmin(User::ADMIN)) {
            
abort(200__('loads.down_not_verified'));
        }

        if (
$file->extension !== 'zip') {
            
abort(200__('loads.archive_only_zip'));
        }

        
$archive = new ZipArchive();
        
$opened $archive->open(public_path($file->hash), ZipArchive::RDONLY);

        if (
$opened !== true) {
            
abort(200__('loads.archive_not_open'));
        }

        
$documents = [];
        for (
$i 0$i $archive->count(); $i++) {
            
$stat $archive->statIndex($i);

            
$documents[] = [
                
'index' => $stat['index'],
                
'name'  => $stat['name'],
                
'size'  => $stat['size'],
                
'isDir' => str_ends_with($stat['name'], '/'),
                
'ext'   => getExtension($stat['name']),
            ];
        }

        
$archive->close();

        
/* uasort($documents, static function ($a, $b) {
            if ($a['isDir'] && ! $b['isDir']) {
                return -1;
            }
            if (! $a['isDir'] && $b['isDir']) {
                return 1;
            }

            return strcmp($a['name'], $b['name']);
        });*/

        /*$tree = [];
        foreach ($documents as $key => $document) {
            $path = $archive->getNameIndex($key);
            $pathBySlash = array_filter(explode('/', $path));
            $count = count($pathBySlash) - 1;
            $temp = &$tree;

            for ($j = 0; $j < $count; $j++) {
                if (! isset($temp[$pathBySlash[$j]])) {
                    $temp[$pathBySlash[$j]] = [];
                }

                $temp = &$temp[$pathBySlash[$j]];
            }

            if (str_ends_with($path, '/')) {
                $temp[$pathBySlash[$count]] = [];
            } else {
                $temp[] = $pathBySlash[$count];
            }
        }*/

        
$documents paginate($documentssetting('ziplist'));

        return 
view('loads/zip'compact('down''file''documents'));
    }

    
/**
     * Просмотр файла в zip архиве
     */
    
public function zipView(int $idint $fid): View
    
{
        
/** @var File $file */
        
$file File::query()->where('relate_type'Down::$morphName)->find($id);
        
$down $file?->relate;

        if (! 
$file || ! $down) {
            
abort(404__('loads.down_not_exist'));
        }

        if (! 
$down->active && ! isAdmin(User::ADMIN)) {
            
abort(200__('loads.down_not_verified'));
        }

        if (
$file->extension !== 'zip') {
            
abort(200__('loads.archive_only_zip'));
        }

        
$archive = new ZipArchive();
        
$opened $archive->open(public_path($file->hash), ZipArchive::RDONLY);

        if (
$opened !== true) {
            
abort(200__('loads.archive_not_open'));
        }
        
$content $archive->getFromIndex($fid);
        
$document $archive->statIndex($fid);

        if (
$content === false) {
            
abort(200__('loads.file_not_read'));
        }

        
$archive->close();

        
$ext getExtension($document['name']);

        if (! 
in_array($ext$down->getViewExt(), true)) {
            
abort(200__('loads.file_not_read'));
        }

        if (
            
$document['size'] > 0
            
&& preg_match("/.(gif|png|bmp|jpg|jpeg|webp)$/"$document['name'])
        ) {
            
header('Content-type: image/' $ext);
            
header('Content-Length: ' strlen($content));
            
header('Content-Disposition: inline; filename="' $document['name'] . '";');
            exit(
$content);
        }

        if (! 
isUtf($content)) {
            
$content winToUtf($content);
        }

        return 
view('loads/zip_view'compact('down''file''document''content'));
    }

    
/**
     * RSS комментариев
     */
    
public function rss(int $id): View
    
{
        
$down Down::query()->where('id'$id)->with('lastComments')->first();

        if (! 
$down) {
            
abort(404__('loads.down_not_exist'));
        }

        return 
view('loads/rss_comments'compact('down'));
    }

    
/**
     * Переход к сообщению
     */
    
public function viewComment(int $idint $cid): RedirectResponse
    
{
        
/** @var Down $down */
        
$down Down::query()->find($id);

        if (! 
$down) {
            
abort(404__('loads.down_not_exist'));
        }

        
$total $down->comments()
            ->
where('id''<='$cid)
            ->
orderBy('created_at')
            ->
count();

        
$end ceil($total setting('comments_per_page'));

        return 
redirect('downs/comments/' $down->id '?page=' $end '#comment_' $cid);
    }
}
Онлайн: 0
Реклама