Forráskód Böngészése

Add file uploads 5/...

Visman 2 éve
szülő
commit
dc7e1be75b

+ 24 - 0
app/Models/Attachment/Attachments.php

@@ -0,0 +1,24 @@
+<?php
+/**
+ * This file is part of the ForkBB <https://github.com/forkbb>.
+ *
+ * @copyright (c) Visman <mio.visman@yandex.ru, https://github.com/MioVisman>
+ * @license   The MIT License (MIT)
+ */
+
+declare(strict_types=1);
+
+namespace ForkBB\Models\Attachment;
+
+use ForkBB\Models\Manager;
+use ForkBB\Models\User\User;
+use RuntimeException;
+
+class Attachments extends Manager
+{
+    /**
+     * Ключ модели для контейнера
+     */
+    protected string $cKey = 'Attachments';
+
+}

+ 1 - 1
app/Models/Pages/Admin/Groups.php

@@ -345,7 +345,7 @@ class Groups extends Admin
     }
 
     /**
-     * Наводит порядок в расширениях
+     * Ограничивает макс. размер файла на основе \Core\Files
      */
     public function vSizeCheck(Validator $v, int $size): int
     {

+ 33 - 0
app/Models/Pages/Admin/Install.php

@@ -684,6 +684,39 @@ class Install extends Admin
             $this->c->DB->exec($query);
         }
 
+        //attachments
+        $schema = [
+            'FIELDS' => [
+                'id'          => ['SERIAL', false],
+                'uid'         => ['INT(10) UNSIGNED', false, 0],
+                'created'     => ['INT(10) UNSIGNED', false, 0],
+                'size_kb'     => ['INT(10) UNSIGNED', false, 0],
+                'path'        => ['VARCHAR(255)', false, ''],
+            ],
+            'PRIMARY KEY' => ['id'],
+            'INDEXES' => [
+                'uid_idx' => ['uid'],
+            ],
+            'ENGINE' => $this->DBEngine,
+        ];
+        $this->c->DB->createTable('::attachments', $schema);
+
+        //attachments_pos
+        $schema = [
+            'FIELDS' => [
+                'id'          => ['SERIAL', false],
+                'pid'         => ['INT(10) UNSIGNED', false, 0],
+            ],
+            'UNIQUE KEYS' => [
+                'id_pid_idx' => ['id', 'pid'],
+            ],
+            'INDEXES' => [
+                'pid_idx' => ['pid'],
+            ],
+            'ENGINE' => $this->DBEngine,
+        ];
+        $this->c->DB->createTable('::attachments_pos', $schema);
+
         // bans
         $schema = [
             'FIELDS' => [

+ 37 - 0
app/Models/Pages/Admin/Update.php

@@ -619,6 +619,37 @@ class Update extends Admin
         $this->c->DB->addField('::groups', 'g_up_size_kb', 'INT(10) UNSIGNED', false, 0);
         $this->c->DB->addField('::groups', 'g_up_limit_mb', 'INT(10) UNSIGNED', false, 0);
 
+        //attachments
+        $schema = [
+            'FIELDS' => [
+                'id'          => ['SERIAL', false],
+                'uid'         => ['INT(10) UNSIGNED', false, 0],
+                'created'     => ['INT(10) UNSIGNED', false, 0],
+                'size_kb'     => ['INT(10) UNSIGNED', false, 0],
+                'path'        => ['VARCHAR(255)', false, ''],
+            ],
+            'PRIMARY KEY' => ['id'],
+            'INDEXES' => [
+                'uid_idx' => ['uid'],
+            ],
+        ];
+        $this->c->DB->createTable('::attachments', $schema);
+
+        //attachments_pos
+        $schema = [
+            'FIELDS' => [
+                'id'          => ['SERIAL', false],
+                'pid'         => ['INT(10) UNSIGNED', false, 0],
+            ],
+            'UNIQUE KEYS' => [
+                'id_pid_idx' => ['id', 'pid'],
+            ],
+            'INDEXES' => [
+                'pid_idx' => ['pid'],
+            ],
+        ];
+        $this->c->DB->createTable('::attachments_pos', $schema);
+
         $coreConfig = new CoreConfig($this->configFile);
 
         $coreConfig->add(
@@ -627,6 +658,12 @@ class Update extends Admin
             'AdminLogs'
         );
 
+        $coreConfig->add(
+            'shared=>attachments',
+            '\\ForkBB\\Models\\Attachment\\Attachments::class',
+            'providerUser'
+        );
+
         $coreConfig->save();
 
         return null;

+ 21 - 1
app/Models/Pages/PostFormTrait.php

@@ -11,7 +11,7 @@ declare(strict_types=1);
 namespace ForkBB\Models\Pages;
 
 use ForkBB\Models\Model;
-use function \ForkBB\__;
+use function \ForkBB\{__, size};
 
 trait PostFormTrait
 {
@@ -97,6 +97,26 @@ trait PostFormTrait
             'fields' => $fieldset,
         ];
 
+        if ($this->userRules->useUpload) {
+            $autofocus = null;
+            $limit     = $this->user->g_up_size_kb * 1024;
+
+            $form['enctype'] = 'multipart/form-data';
+            $form['hidden']['MAX_FILE_SIZE'] = $limit;
+
+            $form['sets']['uesm-attachments'] = [
+                'legend' => 'Attachments',
+                'fields' => [
+                    'attachments[]' => [
+                        'type'     => 'file',
+                        'help'     => ['%1$s (%2$s max size)', \strtr($this->user->g_up_ext, [',' => ', ']), size($limit)],
+                        'accept'   => '.' . \strtr($this->user->g_up_ext, [',' => ',.']),
+                        'multiple' => true,
+                    ]
+                ],
+            ];
+        }
+
         $autofocus = null;
         $fieldset  = [];
 

+ 62 - 0
app/Models/Pages/PostValidatorTrait.php

@@ -103,6 +103,11 @@ trait PostValidatorTrait
     {
         $this->c->Lang->load('validator');
 
+        // обработка вложений + хак с добавление вложений в сообщение на лету
+        if (\is_string($attMessage = $this->attachmentsProc($marker, $args))) {
+            $_POST['message'] .= $attMessage;
+        }
+
         $notPM = $this->fIndex !== self::FI_PM;
 
         if ($this->user->isGuest) {
@@ -259,4 +264,61 @@ trait PostValidatorTrait
 
         return $enable;
     }
+
+    /**
+     * Проверка вложений
+     */
+    public function vCheckAttach(Validator $v, array $files): array
+    {
+        $exts   = \array_flip(\explode(',', $this->user->g_up_ext));
+        $result = [];
+
+        foreach ($files as $file) {
+            if (isset($exts[$file->ext()])) {
+                $result[] = $file;
+            } else {
+                $v->addError(['The %s extension is not allowed', $file->ext()]);
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Обрабатывает загруженные файлы
+     */
+    protected function attachmentsProc(string $marker, array $args): ?string
+    {
+        if (! $this->userRules->useUpload) {
+            return null;
+        }
+
+        $v = $this->c->Validator->reset()
+            ->addValidators([
+                'check_attach'   => [$this, 'vCheckAttach'],
+            ])->addRules([
+                'token'        => 'token:' . $marker,
+                'attachments'  => "file:multiple|max:{$this->user->g_up_size_kb}|check_attach",
+            ])->addAliases([
+                'attachments'  => 'Attachments',
+            ])->addArguments([
+                'token'        => $args,
+            ])->addMessages([
+            ]);
+
+        if (! $v->validation($_FILES + $_POST)) {
+            $this->fIswev = $v->getErrors();
+
+            return null;
+        }
+
+        $attachments = $v->attachments;
+
+        $result = "\n";
+        foreach ($attachments as $a) {
+            $result .= ' ' . $a->name() . '.' . $a->ext();
+        }
+
+        return $result;
+    }
 }

+ 1 - 0
app/config/main.dist.php

@@ -172,6 +172,7 @@ return [
             ],
         ],
         'providerUser'  => \ForkBB\Models\ProviderUser\ProviderUser::class,
+        'attachments'   => \ForkBB\Models\Attachment\Attachments::class,
 
         'Csrf' => [
             'class'  => \ForkBB\Core\Csrf::class,

+ 6 - 0
app/lang/en/post.po

@@ -77,3 +77,9 @@ msgstr "Create topic"
 
 msgid "Re"
 msgstr "Re: "
+
+msgid "%1$s (%2$s max size)"
+msgstr "%1$s (%2$s max size)"
+
+msgid "Attachments"
+msgstr "Attachments"

+ 6 - 0
app/lang/en/topic.po

@@ -121,3 +121,9 @@ msgstr "Unsubscribe from email notifications of new posts"
 
 msgid "Post list"
 msgstr "Posts"
+
+msgid "%1$s (%2$s max size)"
+msgstr "%1$s (%2$s max size)"
+
+msgid "Attachments"
+msgstr "Attachments"

+ 3 - 0
app/lang/en/validator.po

@@ -203,3 +203,6 @@ msgstr "The :alias field contains a link."
 
 msgid "The :alias is not valid email"
 msgstr "The :alias field contains an invalid email address."
+
+msgid "The %s extension is not allowed"
+msgstr "The .%s extension is not allowed."

+ 6 - 0
app/lang/ru/post.po

@@ -77,3 +77,9 @@ msgstr "Создать тему"
 
 msgid "Re"
 msgstr "Re: "
+
+msgid "%1$s (%2$s max size)"
+msgstr "%1$s (макс. %2$s)"
+
+msgid "Attachments"
+msgstr "Вложения"

+ 6 - 0
app/lang/ru/topic.po

@@ -122,3 +122,9 @@ msgstr "Отказаться от получения уведомлений о 
 
 msgid "Post list"
 msgstr "Сообщения"
+
+msgid "%1$s (%2$s max size)"
+msgstr "%1$s (макс. %2$s)"
+
+msgid "Attachments"
+msgstr "Вложения"

+ 3 - 0
app/lang/ru/validator.po

@@ -203,3 +203,6 @@ msgstr "Поле :alias содержит ссылку."
 
 msgid "The :alias is not valid email"
 msgstr "Поле :alias содержит неверный электронный адрес."
+
+msgid "The %s extension is not allowed"
+msgstr "Расширение .%s запрещено."