Add file uploads 6/...

This commit is contained in:
Visman 2023-07-08 16:53:24 +07:00
parent dc7e1be75b
commit 49acb82f78
6 changed files with 112 additions and 27 deletions

2
.gitignore vendored
View file

@ -11,3 +11,5 @@
/public/.htaccess
/public/index.php
!.gitkeep
/public/upload/**/*
!/public/upload/index.html

View file

@ -74,25 +74,6 @@ class File
return $this->error;
}
/**
* Фильрует и переводит в латиницу(?) имя файла
*/
protected function filterName(string $name): string
{
$name = \transliterator_transliterate(
"Any-Latin; NFD; [:Nonspacing Mark:] Remove; NFC; [:Punctuation:] Remove; Lower();",
$name
);
$name = \trim(\preg_replace('%[^\w.-]+%', '-', $name), '-');
if (! isset($name[0])) {
$name = (string) \time();
}
return $name;
}
/**
* Возвращает информацию о пути к сохраняемому файлу с учетом подстановок
*/
@ -105,7 +86,7 @@ class File
}
if ('*' === $matches[2]) {
$matches[2] = $this->filterName($this->name);
$matches[2] = $this->files->filterName($this->name);
}
if ('*' === $matches[3]) {
@ -154,7 +135,7 @@ class File
protected function dirProc(string $dirname): bool
{
if (! \is_dir($dirname)) {
if (! \mkdir($dirname, 0755)) {
if (! \mkdir($dirname, 0755, true)) {
$this->error = 'Can not create directory';
return false;

View file

@ -960,6 +960,25 @@ class Files
return 0 + $value;
}
/**
* Фильрует и переводит в латиницу(?) имя файла
*/
public function filterName(string $name): string
{
$name = \transliterator_transliterate(
"Any-Latin; NFD; [:Nonspacing Mark:] Remove; NFC; Lower();",
$name
);
$name = \trim(\preg_replace(['%[^\w-]+%', '%_+%'], ['-', '_'], $name), '-_');
if (! isset($name[0])) {
$name = (string) \time();
}
return $name;
}
/**
* Возвращает текст ошибки
*/

View file

@ -10,15 +10,95 @@ declare(strict_types=1);
namespace ForkBB\Models\Attachment;
use ForkBB\Core\File;
use ForkBB\Core\Image;
use ForkBB\Models\Manager;
use ForkBB\Models\User\User;
use RuntimeException;
class Attachments extends Manager
{
const HTML_CONT = '<!DOCTYPE html><html lang="en"><head><title>.</title></head><body>.</body></html>';
const BAD_EXTS = '%^(?:php.*|phar|phtml?|s?html?|jsp?|htaccess|htpasswd|f?cgi|)$%i';
const FOLDER = '/upload/';
/**
* Ключ модели для контейнера
*/
protected string $cKey = 'Attachments';
/**
* Сохраняет файл
*/
public function addFile(File $file): ?array
{
$ext = $file->ext();
if (\preg_match(self::BAD_EXTS, $ext)) {
return null;
}
$uid = $this->c->user->id;
$now = \time();
$name = $this->c->Files->filterName($file->name());
$vars = [
'uid' => $uid,
'created' => $now,
];
$query = 'INSERT INTO ::attachments (uid, created) VALUES (?i:uid, ?i:created)';
$this->c->DB->exec($query, $vars);
$id = (int) $this->c->DB->lastInsertId();
$p1 = \date('ym');
$p2 = (int) ($id / 1000);
$p3 = \substr($name, 0, 235 - \strlen($ext)) . '_' . \sprintf("%03d", $id - $p2);
$path = "{$p1}/{$p2}/{$p3}.{$ext}";
$location = $this->c->DIR_PUBLIC . self::FOLDER . $path;
$result = $file
->rename(false)
->rewrite(false)
->setQuality($this->c->config->i_upload_img_quality ?? 75)
//->resize($this->c->config->i_avatars_width, $this->c->config->i_avatars_height)
->toFile($location);
if (true !== $result) {
$this->c->Log->warning("Attachments Failed processing {$path}", [
'user' => $this->user->fLog(),
'error' => $file->error(),
]);
$vars = [
':id' => $id,
];
$query = "DELETE FROM ::attachments WHERE id=?i:id";
$this->c->DB->exec($query, $vars);
return null;
}
$size = $this->c->Files->size(\filesize($location), 'K');
$vars = [
':id' => $id,
':path' => $path,
':size_kb' => $size,
];
$query = 'UPDATE ::attachments SET size_kb=?i:size_kb, path=?s:path WHERE id=?i:id';
$this->c->DB->exec($query, $vars);
return [
'id' => $id,
'uid' => $uid,
'created' => $now,
'size_kb' => $size,
'path' => $path,
'location' => $location,
];
}
}

View file

@ -327,7 +327,7 @@ trait PostFormTrait
$cur['data'] = [
'SCEditorConfig' => $scConfig,
'smiliesEnabled' => $smiliesEnabled,
'linkEnabled' => $this->c->user->g_post_links,
'linkEnabled' => $this->user->g_post_links,
];
$this->pageHeader('sceditor', 'script', 9600, [
@ -354,7 +354,7 @@ trait PostFormTrait
'href' => $this->publicLink("/style/sc/themes/default.css"),
]);
if ($this->c->user->g_post_links) {
if ($this->user->g_post_links) {
$this->pageHeader('imgbb', 'script', 0, [
'src' => $this->publicLink('/js/imgbb.js'),
]);

View file

@ -312,11 +312,14 @@ trait PostValidatorTrait
return null;
}
$attachments = $v->attachments;
$result = "\n";
foreach ($attachments as $a) {
$result .= ' ' . $a->name() . '.' . $a->ext();
foreach ($v->attachments as $file) {
$data = $this->c->attachments->addFile($file);
if (\is_array($data)) {
$result .= ' ' . $data['path'];
}
}
return $result;