Add file uploads 6/...
This commit is contained in:
parent
dc7e1be75b
commit
49acb82f78
6 changed files with 112 additions and 27 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -11,3 +11,5 @@
|
|||
/public/.htaccess
|
||||
/public/index.php
|
||||
!.gitkeep
|
||||
/public/upload/**/*
|
||||
!/public/upload/index.html
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает текст ошибки
|
||||
*/
|
||||
|
|
|
@ -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,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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'),
|
||||
]);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue