Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--img/loading.gifbin0 -> 673 bytes
-rw-r--r--img/members/.gitkeep0
-rw-r--r--img/members/.htaccess72
-rw-r--r--img/members/nofile.gifbin0 -> 631 bytes
-rw-r--r--img/upf-i.pngbin0 -> 649 bytes
-rw-r--r--img/upf-it.pngbin0 -> 668 bytes
-rw-r--r--img/upf-x.pngbin0 -> 778 bytes
-rw-r--r--include/upload.php784
-rw-r--r--include/uploadf.php116
-rw-r--r--include/uploadp.php23
-rw-r--r--js/upload.js407
-rw-r--r--lang/English/upload.php92
-rw-r--r--lang/French/upload.php92
-rw-r--r--lang/German/upload.php92
-rw-r--r--lang/Russian/upload.php92
-rw-r--r--plugins/AP_Upload.php638
-rw-r--r--readme.txt157
-rw-r--r--style/imports/upfiles.css171
-rw-r--r--upfiles.php732
19 files changed, 3468 insertions, 0 deletions
diff --git a/img/loading.gif b/img/loading.gif
new file mode 100644
index 0000000..f1c77c7
--- /dev/null
+++ b/img/loading.gif
Binary files differ
diff --git a/img/members/.gitkeep b/img/members/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/img/members/.gitkeep
diff --git a/img/members/.htaccess b/img/members/.htaccess
new file mode 100644
index 0000000..2c530b3
--- /dev/null
+++ b/img/members/.htaccess
@@ -0,0 +1,72 @@
+# ----------------------------------------------------------------------
+# If something is broken, then see the apache config for your site,
+# the AllowOverride directive https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride
+# ----------------------------------------------------------------------
+
+# ----------------------------------------------------------------------
+# Disable directory listing.
+#-----------------------------------------------------------------------
+
+<IfModule mod_autoindex.c>
+ Options -Indexes
+</IfModule>
+
+# ----------------------------------------------------------------------
+# Disable CGI script execution.
+#-----------------------------------------------------------------------
+
+<IfModule mod_cgi.c>
+ Options -ExecCGI
+</IfModule>
+<IfModule mod_cgid.c>
+ Options -ExecCGI
+</IfModule>
+<IfModule mod_fcgid.c>
+ Options -ExecCGI
+</IfModule>
+
+# ----------------------------------------------------------------------
+# Disable PHP script execution if php as apache module.
+# If your php has a module name other than "mod_php", "mod_php_null",
+# "mod_php5" and "mod_php7", then add here one more condition with your name.
+#-----------------------------------------------------------------------
+
+<IfModule mod_php.c>
+ php_flag engine 0
+</IfModule>
+<IfModule mod_php_null.c>
+ php_flag engine 0
+</IfModule>
+<IfModule mod_php5.c>
+ php_flag engine 0
+</IfModule>
+<IfModule mod_php7.c>
+ php_flag engine 0
+</IfModule>
+
+# ----------------------------------------------------------------------
+# Treat these files as plain text.
+# ----------------------------------------------------------------------
+
+<IfModule mod_mime.c>
+ RemoveHandler .asmx .asp .aspx .cgi .dll .exe .fcgi .fpl .htm .html .js .jsp .php .php3 .php4 .php5 .php6 .php7 .phar .phps .phtm .phtml .pl .py .rb .shtm .shtml .wml .xml
+ AddType text/plain .asmx .asp .aspx .cgi .dll .exe .fcgi .fpl .htm .html .js .jsp .php .php3 .php4 .php5 .php6 .php7 .phar .phps .phtm .phtml .pl .py .rb .shtm .shtml .wml .xml
+</IfModule>
+
+# ----------------------------------------------------------------------
+# All files are given through the default handler for static content (Disable script execution).
+# ----------------------------------------------------------------------
+
+SetHandler default-handler
+
+# ----------------------------------------------------------------------
+# Show nofile.gif instead of missing files.
+# ----------------------------------------------------------------------
+
+<IfModule mod_rewrite.c>
+ RewriteEngine On
+# Uncomment and properly set the RewriteBase if the rewrite rules are not working properly
+# RewriteBase /
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteRule .* nofile.gif [L]
+</IfModule>
diff --git a/img/members/nofile.gif b/img/members/nofile.gif
new file mode 100644
index 0000000..8b4224d
--- /dev/null
+++ b/img/members/nofile.gif
Binary files differ
diff --git a/img/upf-i.png b/img/upf-i.png
new file mode 100644
index 0000000..5d96460
--- /dev/null
+++ b/img/upf-i.png
Binary files differ
diff --git a/img/upf-it.png b/img/upf-it.png
new file mode 100644
index 0000000..888173a
--- /dev/null
+++ b/img/upf-it.png
Binary files differ
diff --git a/img/upf-x.png b/img/upf-x.png
new file mode 100644
index 0000000..29185fe
--- /dev/null
+++ b/img/upf-x.png
Binary files differ
diff --git a/include/upload.php b/include/upload.php
new file mode 100644
index 0000000..5d3aac5
--- /dev/null
+++ b/include/upload.php
@@ -0,0 +1,784 @@
+<?php
+
+/**
+ * Copyright (C) 2011-2019 Visman (mio.visman@yandex.ru)
+ * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
+ */
+
+// Make sure no one attempts to run this script "directly"
+if (! defined('PUN')) {
+ exit;
+}
+
+// Load language file
+if (file_exists(PUN_ROOT . 'lang/' . $pun_user['language'] . '/upload.php')) {
+ require PUN_ROOT . 'lang/' . $pun_user['language'] . '/upload.php';
+} else {
+ require PUN_ROOT . 'lang/English/upload.php';
+}
+
+class upfClass
+{
+ protected $blackList = [
+ '' => true,
+ 'asmx' => true,
+ 'asp' => true,
+ 'aspx' => true,
+ 'cgi' => true,
+ 'dll' => true,
+ 'exe' => true,
+ 'fcgi' => true,
+ 'fpl' => true,
+ 'htaccess' => true,
+ 'htm' => true,
+ 'html' => true,
+ 'js' => true,
+ 'jsp' => true,
+ 'php' => true,
+ 'php3' => true,
+ 'php4' => true,
+ 'php5' => true,
+ 'php6' => true,
+ 'php7' => true,
+ 'phar' => true,
+ 'phps' => true,
+ 'phtm' => true,
+ 'phtml' => true,
+ 'pl' => true,
+ 'py' => true,
+ 'rb' => true,
+ 'shtm' => true,
+ 'shtml' => true,
+ 'wml' => true,
+ 'xml' => true,
+ ];
+
+ /**
+ * Список кодов типов картинок и расширений для них????
+ * @var array
+ */
+ protected $imageType = [
+ 1 => ['gif', true],
+ 2 => ['jpg', true],
+ 3 => ['png', true],
+ 4 => ['swf', false],
+ 5 => ['psd', false],
+ 6 => ['bmp', true],
+ 7 => ['tiff', false],
+ 8 => ['tiff', false],
+ 9 => ['jpc', false],
+ 10 => ['jp2', false],
+ 11 => ['jpx', false],
+ 12 => ['jb2', false],
+ 13 => ['swc', false],
+ 14 => ['iff', false],
+ 15 => ['wbmp', false],
+ 16 => ['xbm', false],
+ 17 => ['ico', false],
+ 18 => ['webp', true],
+ ];
+
+ /**
+ * Список единиц измерения
+ * @var string
+ */
+ protected $units = 'BKMGTPEZY';
+
+ protected $UTF8AR = [
+ 'à' => 'a', 'ô' => 'o', 'ď' => 'd', 'ḟ' => 'f', 'ë' => 'e', 'š' => 's', 'ơ' => 'o',
+ 'ß' => 'ss', 'ă' => 'a', 'ř' => 'r', 'ț' => 't', 'ň' => 'n', 'ā' => 'a', 'ķ' => 'k',
+ 'ŝ' => 's', 'ỳ' => 'y', 'ņ' => 'n', 'ĺ' => 'l', 'ħ' => 'h', 'ṗ' => 'p', 'ó' => 'o',
+ 'ú' => 'u', 'ě' => 'e', 'é' => 'e', 'ç' => 'c', 'ẁ' => 'w', 'ċ' => 'c', 'õ' => 'o',
+ 'ṡ' => 's', 'ø' => 'o', 'ģ' => 'g', 'ŧ' => 't', 'ș' => 's', 'ė' => 'e', 'ĉ' => 'c',
+ 'ś' => 's', 'î' => 'i', 'ű' => 'u', 'ć' => 'c', 'ę' => 'e', 'ŵ' => 'w', 'ṫ' => 't',
+ 'ū' => 'u', 'č' => 'c', 'ö' => 'oe', 'è' => 'e', 'ŷ' => 'y', 'ą' => 'a', 'ł' => 'l',
+ 'ų' => 'u', 'ů' => 'u', 'ş' => 's', 'ğ' => 'g', 'ļ' => 'l', 'ƒ' => 'f', 'ž' => 'z',
+ 'ẃ' => 'w', 'ḃ' => 'b', 'å' => 'a', 'ì' => 'i', 'ï' => 'i', 'ḋ' => 'd', 'ť' => 't',
+ 'ŗ' => 'r', 'ä' => 'ae', 'í' => 'i', 'ŕ' => 'r', 'ê' => 'e', 'ü' => 'ue', 'ò' => 'o',
+ 'ē' => 'e', 'ñ' => 'n', 'ń' => 'n', 'ĥ' => 'h', 'ĝ' => 'g', 'đ' => 'd', 'ĵ' => 'j',
+ 'ÿ' => 'y', 'ũ' => 'u', 'ŭ' => 'u', 'ư' => 'u', 'ţ' => 't', 'ý' => 'y', 'ő' => 'o',
+ 'â' => 'a', 'ľ' => 'l', 'ẅ' => 'w', 'ż' => 'z', 'ī' => 'i', 'ã' => 'a', 'ġ' => 'g',
+ 'ṁ' => 'm', 'ō' => 'o', 'ĩ' => 'i', 'ù' => 'u', 'į' => 'i', 'ź' => 'z', 'á' => 'a',
+ 'û' => 'u', 'þ' => 'th', 'ð' => 'dh', 'æ' => 'ae', 'µ' => 'u', 'ĕ' => 'e',
+ 'À' => 'A', 'Ô' => 'O', 'Ď' => 'D', 'Ḟ' => 'F', 'Ë' => 'E', 'Š' => 'S', 'Ơ' => 'O',
+ 'Ă' => 'A', 'Ř' => 'R', 'Ț' => 'T', 'Ň' => 'N', 'Ā' => 'A', 'Ķ' => 'K',
+ 'Ŝ' => 'S', 'Ỳ' => 'Y', 'Ņ' => 'N', 'Ĺ' => 'L', 'Ħ' => 'H', 'Ṗ' => 'P', 'Ó' => 'O',
+ 'Ú' => 'U', 'Ě' => 'E', 'É' => 'E', 'Ç' => 'C', 'Ẁ' => 'W', 'Ċ' => 'C', 'Õ' => 'O',
+ 'Ṡ' => 'S', 'Ø' => 'O', 'Ģ' => 'G', 'Ŧ' => 'T', 'Ș' => 'S', 'Ė' => 'E', 'Ĉ' => 'C',
+ 'Ś' => 'S', 'Î' => 'I', 'Ű' => 'U', 'Ć' => 'C', 'Ę' => 'E', 'Ŵ' => 'W', 'Ṫ' => 'T',
+ 'Ū' => 'U', 'Č' => 'C', 'Ö' => 'Oe', 'È' => 'E', 'Ŷ' => 'Y', 'Ą' => 'A', 'Ł' => 'L',
+ 'Ų' => 'U', 'Ů' => 'U', 'Ş' => 'S', 'Ğ' => 'G', 'Ļ' => 'L', 'Ƒ' => 'F', 'Ž' => 'Z',
+ 'Ẃ' => 'W', 'Ḃ' => 'B', 'Å' => 'A', 'Ì' => 'I', 'Ï' => 'I', 'Ḋ' => 'D', 'Ť' => 'T',
+ 'Ŗ' => 'R', 'Ä' => 'Ae', 'Í' => 'I', 'Ŕ' => 'R', 'Ê' => 'E', 'Ü' => 'Ue', 'Ò' => 'O',
+ 'Ē' => 'E', 'Ñ' => 'N', 'Ń' => 'N', 'Ĥ' => 'H', 'Ĝ' => 'G', 'Đ' => 'D', 'Ĵ' => 'J',
+ 'Ÿ' => 'Y', 'Ũ' => 'U', 'Ŭ' => 'U', 'Ư' => 'U', 'Ţ' => 'T', 'Ý' => 'Y', 'Ő' => 'O',
+ 'Â' => 'A', 'Ľ' => 'L', 'Ẅ' => 'W', 'Ż' => 'Z', 'Ī' => 'I', 'Ã' => 'A', 'Ġ' => 'G',
+ 'Ṁ' => 'M', 'Ō' => 'O', 'Ĩ' => 'I', 'Ù' => 'U', 'Į' => 'I', 'Ź' => 'Z', 'Á' => 'A',
+ 'Û' => 'U', 'Þ' => 'Th', 'Ð' => 'Dh', 'Æ' => 'Ae', 'Ĕ' => 'E',
+ 'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e', 'ё' => 'jo',
+ 'ж' => 'zh', 'з' => 'z', 'и' => 'i', 'й' => 'jj', 'к' => 'k', 'л' => 'l', 'м' => 'm',
+ 'н' => 'n', 'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's', 'т' => 't', 'у' => 'u',
+ 'ф' => 'f', 'х' => 'kh', 'ц' => 'c', 'ч' => 'ch', 'ш' => 'sh', 'щ' => 'shh', 'ъ' => '',
+ 'ы' => 'y', 'ь' => '', 'э' => 'eh', 'ю' => 'ju', 'я' => 'ja',
+ 'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 'Д' => 'D', 'Е' => 'E', 'Ё' => 'Jo',
+ 'Ж' => 'Zh', 'З' => 'Z', 'И' => 'I', 'Й' => 'Jj', 'К' => 'K', 'Л' => 'L', 'М' => 'M',
+ 'Н' => 'N', 'О' => 'O', 'П' => 'P', 'Р' => 'R', 'С' => 'S', 'Т' => 'T', 'У' => 'U',
+ 'Ф' => 'F', 'Х' => 'Kh', 'Ц' => 'C', 'Ч' => 'Ch', 'Ш' => 'Sh', 'Щ' => 'Shh', 'Ъ' => '',
+ 'Ы' => 'Y', 'Ь' => '', 'Э' => 'Eh', 'Ю' => 'Ju', 'Я' => 'Ja',
+ ];
+
+ const GD = 1;
+ const IMAGICK = 2;
+
+ protected $resizeFlag = false;
+ protected $libType;
+ protected $libName = '-';
+ protected $libVersion = '-';
+ protected $error;
+ protected $quality = 75;
+
+ public function __construct()
+ {
+ if (\extension_loaded('imagick') && \class_exists('\Imagick')) {
+ $this->resizeFlag = true;
+ $this->libType = self::IMAGICK;
+ $this->libName = 'ImageMagick';
+ $imagick = \Imagick::getVersion();
+ $this->libVersion = \trim(\preg_replace(['%ImageMagick%i', '%http[^\s]+%i'], '', $imagick['versionString']));
+ } elseif (\extension_loaded('gd') && \function_exists('\\imagecreatetruecolor')) {
+ $this->resizeFlag = true;
+ $this->libType = self::GD;
+ $this->libName = 'GD';
+ $gd = \gd_info();
+ $this->libVersion = $gd['GD Version'];
+ }
+ }
+
+ public function isResize()
+ {
+ return $this->resizeFlag;
+ }
+
+ public function getLibName()
+ {
+ return $this->libName;
+ }
+
+ public function getLibVersion()
+ {
+ return $this->libVersion;
+ }
+
+ public function getError()
+ {
+ $error = $this->error;
+ $this->error = null;
+ return $error;
+ }
+
+ protected function isBadLink($link)
+ {
+ if (false !== \strpos($link, ':', 2) || false !== \strpos($link, '//') || \preg_match('%\bphar\b%i', $link)) {
+ $this->error = 'Bad link';
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public function inBlackList($ext)
+ {
+ return isset($this->blackList[\strtolower($ext)]);
+ }
+
+ public function dirSize($dir)
+ {
+ if ($this->isBadLink($dir)) {
+ return false;
+ }
+ if (! \is_dir($dir)) {
+ $this->error = 'Directory expected';
+ return false;
+ }
+ if (false === ($dh = \opendir($dir))) {
+ $this->error = 'Could not open directory';
+ return false;
+ }
+
+ $size = 0;
+ while (false !== ($file = \readdir($dh))) {
+ if ('' == \trim($file) || '.' === $file[0] || '#' === $file[0] || ! \is_file($dir . $file)) {
+ continue;
+ }
+ $ext = \strtolower(\substr(\strrchr($file, '.'), 1)); // расширение файла
+ if (isset($this->blackList[$ext])) {
+ continue;
+ }
+ $size += \filesize($dir . $file);
+ }
+
+ \closedir($dh);
+ return $size;
+ }
+
+ /**
+ * Переводит объем информации из одних единиц в другие
+ * кило = 1024, а не 1000
+ *
+ * @param int|float|string $value
+ * @param string $to
+ *
+ * @return int|float|false
+ */
+ public function size($value, $to = null)
+ {
+ if (\is_string($value)) {
+ if (! \preg_match('%^([^a-z]+)([a-z]+)?$%i', \trim($value), $matches)) {
+ $this->error = 'Expected string indicating the amount of information';
+ return false;
+ }
+ if (! \is_numeric($matches[1])) {
+ $this->error = 'String does not contain number';
+ return false;
+ }
+
+ $value = 0 + $matches[1];
+
+ if (! empty($matches[2])) {
+ $unit = \strtoupper($matches[2][0]);
+ $expo = \strpos($this->units, $unit);
+
+ if (false === $expo) {
+ $this->error = 'Unknown unit';
+ return false;
+ }
+
+ $value *= 1024 ** $expo;
+ }
+ }
+
+ if (\is_string($to)) {
+ $to = \trim($to);
+ $unit = \strtoupper($to[0]);
+ $expo = \strpos($this->units, $unit);
+
+ if (false === $expo) {
+ $this->error = 'Unknown unit';
+ return false;
+ }
+
+ $value /= 1024 ** $expo;
+ }
+
+ return 0 + $value;
+ }
+
+ /**
+ * Определяет по содержимому файла расширение картинки????
+ *
+ * @param string $path
+ *
+ * @return false|array
+ */
+ public function imageExt($path)
+ {
+ if ($this->isBadLink($path)) {
+ return false;
+ }
+
+ if (\function_exists('\\exif_imagetype')) {
+ $type = \exif_imagetype($path);
+ } elseif (
+ \function_exists('\\getimagesize')
+ && false !== ($type = @\getimagesize($path))
+ && $type[0] > 0
+ && $type[1] > 0
+ ) {
+ $type = $type[2];
+ } else {
+ $type = 0;
+ }
+ return isset($this->imageType[$type]) ? $this->imageType[$type] : false;
+ }
+
+ /**
+ * Фильрует и переводит в латиницу(?) имя файла
+ *
+ * @param string $name
+ *
+ * @return string
+ */
+ protected function filterName($name)
+ {
+ $new = false;
+ if (\function_exists('\\transliterator_transliterate')) {
+ $new = \transliterator_transliterate("Any-Latin; NFD; [:Nonspacing Mark:] Remove; NFC;", $name);
+ }
+ if (! \is_string($new)) {
+ $new = str_replace(array_keys($this->UTF8AR), array_values($this->UTF8AR), $name);
+ }
+
+ $name = \trim(\preg_replace('%[^\w-]+%', '-', $new), '-_');
+
+ if (! isset($name[0])) {
+ $name = $this->filterName(\date('Ymd\-His'));
+ }
+
+ return $name;
+ }
+
+ public function getFileExt()
+ {
+ return $this->fileExt;
+ }
+
+ public function getFileName()
+ {
+ return $this->fileName;
+ }
+
+ public function prepFileName()
+ {
+ if ('mini_' === \substr($this->fileName, 0, 5)) {
+ $this->fileName = \substr($this->fileName, 5);
+ }
+ if (\strlen($this->fileName) > 100) {
+ $this->fileName = \substr($this->fileName, 0, 100);
+ }
+ if ('' == $this->fileName) {
+ $this->fileName = 'none';
+ }
+ }
+
+ public function isImage()
+ {
+ return $this->fileAsImage;
+ }
+
+ public function setImageQuality($quality)
+ {
+ $this->quality = \min(\max((int) $quality, 1), 100);
+ }
+
+ protected $filePath;
+ protected $fileName;
+ protected $fileExt;
+ protected $fileCalcExt;
+ protected $fileAsImage;
+ protected $fileIsUp;
+ protected $image;
+
+ public function loadFile($path, $basename = null)
+ {
+ $this->filePath = null;
+ $this->fileName = null;
+ $this->fileExt = null;
+ $this->fileCalcExt = null;
+ $this->fileAsImage = false;
+ $this->fileIsUp = null !== $basename;
+
+ $this->destroyImage();
+ $this->image = null;
+
+ if ($this->isBadLink($path)) {
+ return false;
+ }
+
+ if (null !== $basename) {
+ $pattern = '%^(.+)\.(\w+)$%';
+ $subject = $basename;
+ } else {
+ $pattern = '%[\\/]([\w-]+)\.(\w+)$%';
+ $subject = $path;
+ }
+ if (! \preg_match($pattern, $subject, $matches)) {
+ $this->error = 'Bad file name or extension';
+ return false;
+ }
+
+ $this->fileExt = $this->fileCalcExt = \strtolower($matches[2]);
+ if (isset($this->blackList[$this->fileExt])) {
+ $this->error = 'Bad file extension';
+ return false;
+ }
+
+ if (null !== $basename) {
+ if (! \is_uploaded_file($path)) {
+ $this->error = 'File was not uploaded';
+ return false;
+ }
+ } else {
+ if (! \is_file($path)) {
+ $this->error = 'No file';
+ return false;
+ }
+ }
+ if (! \is_readable($path)) {
+ $this->error = 'File unreadable';
+ return false;
+ }
+
+ $imageInfo = $this->imageExt($path);
+ if (\is_array($imageInfo)) {
+ if (null !== $basename) {
+ $this->fileExt = $imageInfo[0];
+ }
+ $this->fileCalcExt = $imageInfo[0];
+ $this->fileAsImage = $imageInfo[1];
+ }
+
+ $this->fileName = null !== $basename ? $this->filterName($matches[1]) : $matches[1];
+ $this->filePath = $path;
+
+ return true;
+ }
+
+ public function isUnsafeContent()
+ {
+ if (null === $this->filePath) {
+ return true;
+ }
+
+ $f = \fopen($this->filePath, "rb");
+ if (false === $f) {
+ return true;
+ }
+
+ $buf1 = '';
+ while ($buf2 = \fread($f, 4096)) {
+ if (\preg_match( "%<(?:script|html|head|title|body|table|a\s+href|img\s|plaintext|cross\-domain\-policy|embed|applet|i?frame|\?php)%msi", $buf1 . $buf2)) {
+ \fclose($f);
+ return true;
+ }
+ $buf1 = \substr($buf2, -30);
+ }
+ \fclose($f);
+ return false;
+ }
+
+ public function loadImage()
+ {
+ if (null === $this->filePath || true !== $this->fileAsImage) {
+ $this->error = 'No image';
+ return false;
+ }
+ switch ($this->libType) {
+ case self::IMAGICK:
+ try {
+ $image = new \Imagick(\realpath($this->filePath));
+ $width = $image->getImageWidth();
+ $height = $image->getImageHeight();
+ } catch (\Exception $e) {
+ $this->error = $this->hidePath($e->getMessage());
+ return false;
+ }
+ break;
+ case self::GD:
+ $type = $this->fileCalcExt;
+ switch ($type) {
+ case 'jpg':
+ $type = 'jpeg';
+ break;
+ }
+
+ $func = '\\imagecreatefrom' . $type;
+ if (! \function_exists($func)) {
+ $this->error = 'No function to create image';
+ return false;
+ }
+
+ $image = @$func($this->filePath);
+ if (! $image) {
+ $this->error = 'Failed to create image';
+ return false;
+ }
+ if (false === \imagealphablending($image, false) || false === \imagesavealpha($image, true)) {
+ $this->error = 'Failed to adjust image';
+ return false;
+ }
+ $width = \imagesx($image);
+ $height = \imagesy($image);
+ break;
+ default:
+ $this->error = 'Graphics library type not defined';
+ return false;
+ }
+ $this->image = $image;
+
+ return [
+ $width,
+ $height,
+ ];
+ }
+
+ public function saveFile($path, $overwrite = false)
+ {
+ return $this->save($path, $overwrite, false);
+ }
+
+ public function saveImage($path, $overwrite = false)
+ {
+ if (empty($this->image)) {
+ $this->error = 'No image';
+ return false;
+ }
+
+ return $this->save($path, $overwrite, true);
+ }
+
+ protected function save($path, $overwrite, $isImage)
+ {
+ if ($this->isBadLink($path)) {
+ return false;
+ }
+
+ if (! \preg_match('%^(.+[\\/])([\w-]+)\.(\w+)$%', $path, $matches)) {
+ $this->error = 'Bad dir name, file name or extension';
+ return false;
+ }
+
+ $ext = \strtolower($matches[3]);
+ if (isset($this->blackList[$ext])) {
+ $this->error = 'Bad file extension';
+ return false;
+ }
+ $name = $matches[2];
+ $dir = $matches[1];
+
+ if (true !== $overwrite) {
+ $tmp = '';
+ $i = 0;
+ while (\is_file($dir . $name . $tmp . '.' . $ext) && $i < 100) {
+ $tmp = '-' . random_pass(4);
+ ++$i;
+ }
+ if ($i >= 100) {
+ $this->error = 'Many similar names';
+ return false;
+ }
+ $name .= $tmp;
+ }
+ $path = $dir . $name . '.' . $ext;
+
+ if (false === $isImage) {
+ $func = $this->fileIsUp ? '\\move_uploaded_file' : '\\copy';
+ $result = @$func($this->filePath, $path);
+ if (! $result) {
+ $this->error = 'Failed to copy file';
+ return false;
+ }
+ } else {
+ switch ($this->libType) {
+ case self::IMAGICK:
+ try {
+ //var_dump($this->image->getImageColors());
+ $type = $this->fileCalcExt;
+ switch ($type) {
+ case 'png':
+ $this->image->setImageCompressionQuality(0);
+ break;
+ default:
+ $this->image->setImageCompressionQuality($this->quality);
+ break;
+ }
+ $this->image->writeImages($path, true);
+ } catch (\Exception $e) {
+ $this->error = $this->hidePath($e->getMessage(), $path);
+ return false;
+ }
+ break;
+ case self::GD:
+ $result = false;
+ $type = $this->fileCalcExt;
+ $args = [$this->image, $path];
+ switch ($type) {
+ case 'jpg':
+ $type = 'jpeg';
+ $args[] = $this->quality;
+ break;
+ case 'png':
+ //$args[] = -1;
+ //$args[] = \PNG_ALL_FILTERS; // \PNG_NO_FILTER;
+ // imagecolorstotal
+ // , int $quality = -1 , int $filters = -1
+ break;
+ case 'webp':
+ $args[] = $this->quality;
+ break;
+ }
+ $func = '\\image' . $type;
+ if (! \function_exists($func)) {
+ $this->error = 'No function to save image';
+ return false;
+ }
+
+ $result = @$func(...$args);
+ if (true !== $result) {
+ $this->error = 'Failed to copy image';
+ return false;
+ }
+ break;
+ default:
+ $this->error = 'Graphics library type not defined';
+ return false;
+ }
+ }
+
+ @\chmod($path, 0644);
+
+ return [
+ 'path' => $path,
+ 'dirname' => $dir,
+ 'filename' => $name,
+ 'extension' => $ext,
+ ];
+ }
+
+ public function resizeImage($width, $height = null)
+ {
+ if (empty($this->image)) {
+ $this->error = 'No image';
+ return false;
+ }
+
+ switch ($this->libType) {
+ case self::IMAGICK:
+ try {
+ $oldWidth = $this->image->getImageWidth();
+ $oldHeight = $this->image->getImageHeight();
+ } catch (\Exception $e) {
+ $this->error = $this->hidePath($e->getMessage());
+ return false;
+ }
+ break;
+ case self::GD:
+ $oldWidth = \imagesx($this->image);
+ $oldHeight = \imagesy($this->image);
+ break;
+ default:
+ $this->error = 'Graphics library type not defined';
+ return false;
+ }
+
+ $w = (empty($width) || $width < 16) ? 1 : $width / $oldWidth;
+ $h = (empty($height) || $height < 16) ? 1 : $height / $oldHeight;
+ $r = \min(1, $w, $h);
+ if (1 == $r) { // ?
+ return 1;
+ }
+ $width = (int) \round($oldWidth * $r);
+ $height = (int) \round($oldHeight * $r);
+
+ switch ($this->libType) {
+ case self::IMAGICK:
+ try {
+ // есть анимация
+ if ($this->image->getImageDelay() > 0) {
+ $image = $this->image->coalesceImages();
+
+ foreach ($image as $frame) {
+ $frame->resizeImage($width, $height, \Imagick::FILTER_LANCZOS, 1);
+ $frame->setImagePage($width, $height, 0, 0);
+ }
+
+ $image = $image->deconstructImages();
+ //$image = $image->optimizeImageLayers();
+ // нет анимации
+ } else {
+ $image = clone $this->image;
+ $image->resizeImage($width, $height, \Imagick::FILTER_LANCZOS, 1);
+ }
+ } catch (\Exception $e) {
+ $this->error = $this->hidePath($e->getMessage());
+ return false;
+ }
+ break;
+ case self::GD:
+ if (false === ($image = \imagecreatetruecolor($width, $height))) {
+ $this->error = 'Failed to create new truecolor image';
+ return false;
+ }
+ if (false === ($transparent = \imagecolorallocatealpha($image, 255, 255, 255, 127))) {
+ $this->error = 'Failed to create color for image';
+ return false;
+ }
+ if (false === \imagefill($image, 0, 0, $transparent)) {
+ $this->error = 'Failed to fill image with color';
+ return false;
+ }
+ \imagecolortransparent($image, $transparent);
+ $colors = \imagecolorstotal($this->image);
+ if ($colors > 0 && false === \imagetruecolortopalette($image, true, $colors)) {
+ $this->error = 'Failed to convert image to palette';
+ return false;
+ }
+ if (false === \imagealphablending($image, false) || false === \imagesavealpha($image, true)) {
+ $this->error = 'Failed to adjust image';
+ return false;
+ }
+ if (false === \imagecopyresampled($image, $this->image, 0, 0, 0, 0, $width, $height, $oldWidth, $oldHeight)) {
+ $this->error = 'Failed to resize image';
+ return false;
+ }
+ break;
+ }
+
+ if (false === $this->destroyImage()) {
+ return false;
+ }
+ $this->image = $image;
+
+ return $r;
+ }
+
+ public function destroyImage()
+ {
+ if (empty($this->image)) {
+ return true;
+ }
+
+ $result = false;
+
+ switch ($this->libType) {
+ case self::IMAGICK:
+ try {
+ $result = $this->image->clear();
+ } catch (\Exception $e) {
+ $result = false;
+ }
+ break;
+ case self::GD:
+ $result = \imagedestroy($this->image);
+ break;
+ }
+
+ if (true === $result) {
+ $this->image = null;
+ } else {
+ $this->error = 'Failed to clear resource';
+ }
+
+ return $result;
+ }
+
+ public function __destruct()
+ {
+ $this->destroyImage();
+ }
+
+ protected function hidePath($str, $path = null)
+ {
+ $search = [];
+ if (null !== $this->filePath) {
+ $search[] = \realpath($this->filePath);
+ $search[] = $this->filePath;
+ }
+ if (null !== $path) {
+ $search[] = \realpath($path);
+ $search[] = $path;
+ }
+ return empty($search) ? $str : \str_replace($search, '', $str);
+ }
+}
+
+$upf_class = new upfClass();
diff --git a/include/uploadf.php b/include/uploadf.php
new file mode 100644
index 0000000..527bc32
--- /dev/null
+++ b/include/uploadf.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Copyright (C) 2011-2020 Visman (visman@inbox.ru)
+ * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
+ */
+
+// Make sure no one attempts to run this script "directly"
+if (! defined('PUN')) {
+ exit;
+}
+
+if (!$pun_user['is_guest'] && isset($pun_config['o_upload_config'], $required_fields['req_message'])) {
+ if ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_up_limit'] > 0 && $pun_user['g_up_max'] > 0)) {
+ // Load language file
+ if (! isset($lang_up)) {
+ if (file_exists(PUN_ROOT.'lang/'.$pun_user['language'].'/upload.php')) {
+ require PUN_ROOT.'lang/'.$pun_user['language'].'/upload.php';
+ } else {
+ require PUN_ROOT.'lang/English/upload.php';
+ }
+ }
+
+ if (file_exists(PUN_ROOT.'style/'.$pun_user['style'].'/upfiles.css')) {
+ $style = 'style/'.$pun_user['style'].'/upfiles.css';
+ } else {
+ $style = 'style/imports/upfiles.css';
+ }
+
+ $upf_conf = unserialize($pun_config['o_upload_config']);
+ $upf_max_size = (int) (10485.76 * $pun_user['g_up_max'])
+
+?>
+<script type="text/javascript">
+/* <![CDATA[ */
+if (typeof FluxBB === 'undefined' || !FluxBB) {var FluxBB = {};}
+FluxBB.uploadvars = {
+ action: 'upfiles.php',
+ style: '<?= addslashes($style) ?>',
+ lang: {
+ upfiles: '<strong><?= addslashes($lang_up['upfiles']) ?></strong>',
+ confirmation: '<?= addslashes($lang_up['delete file']) ?>',
+ large: '<?= addslashes($lang_up['Too large']) ?>',
+ bad_type: '<?= addslashes($lang_up['Bad type']) ?>'
+ },
+ maxsize: <?= $upf_max_size ?>,
+ exts: ['<?= str_replace([' ', ','], ['', '\', \''], addslashes($pun_user['g_up_ext'])) ?>'],
+ token: '<?= addslashes(function_exists('csrf_hash') ? csrf_hash('upfiles.php') : pun_csrf_token()) ?>'
+};
+/* ]]> */
+</script>
+<script type="text/javascript" src="js/upload.js"></script>
+
+<div id="upf-template" style="width: 0; height: 0; overflow: hidden; margin: 0; padding: 0;">
+ <div class="inform upf-fmess">
+ <fieldset>
+ <legend><?= $lang_up['upfiles'] ?></legend>
+ <div class="infldset">
+ <button id="upf-button" type="button"><?= $lang_up['fichier'] ?></button>
+ <span><?= sprintf($lang_up['info_2'], pun_htmlspecialchars(str_replace([' ', ','], ['', ', '], $pun_user['g_up_ext'])), pun_htmlspecialchars(file_size($upf_max_size))) ?></span>
+ </div>
+ </fieldset>
+ </div>
+ <div class="inform upf-fmess">
+ <fieldset id="upf-list-fls">
+ <div class="infldset">
+ <div id="upf-container">
+ <ul id="upf-list">
+ <li id="upf--">
+ <div class="upf-name" title="End">
+ <span>&#160;</span>
+ </div>
+ <div class="upf-file" style="height: <?= max((int) $upf_conf['thumb_size'], 100) ?>px;">
+ <a>
+ <span>&#160;</span>
+ </a>
+ </div>
+ <div class="upf-size">
+ <span>&#160;</span>
+ </div>
+ <div class="upf-but upf-delete">
+ <a title="<?= $lang_up['delete'] ?>">
+ <span></span>
+ </a>
+ </div>
+ <div class="upf-but upf-insert">
+ <a title="<?= $lang_up['insert'] ?>">
+ <span></span>
+ </a>
+ </div>
+ <div class="upf-but upf-insert-t">
+ <a title="<?= $lang_up['insert_thumb'] ?>">
+ <span></span>
+ </a>
+ </div>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </fieldset>
+ </div>
+ <div class="inform upf-fmess">
+ <fieldset>
+ <div class="infldset">
+ <div id="upf-legend">
+ <div style="background-color: rgb(0, 255, 0); width: 0%;"><span>0%</span></div>
+ </div>
+ <p id="upf-legend-p"><?= sprintf($lang_up['info_4'], 0, pun_htmlspecialchars(file_size(1048576 * $pun_user['g_up_limit']))) ?></p>
+ </div>
+ </fieldset>
+ </div>
+</div>
+
+<?php
+
+ }
+}
diff --git a/include/uploadp.php b/include/uploadp.php
new file mode 100644
index 0000000..82f1bb5
--- /dev/null
+++ b/include/uploadp.php
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * Copyright (C) 2011-2019 Visman (mio.visman@yandex.ru)
+ * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
+ */
+
+// Make sure no one attempts to run this script "directly"
+if (! defined('PUN')) {
+ exit;
+}
+
+if (isset($pun_config['o_upload_config'])) {
+ if ($pun_user['g_id'] == PUN_ADMIN || ($id == $pun_user['id'] && $pun_user['g_up_limit'] > 0 && $pun_user['g_up_max'] > 0)) {
+ if (file_exists(PUN_ROOT . 'lang/' . $pun_user['language'] . '/upload.php')) {
+ require PUN_ROOT . 'lang/' . $pun_user['language'] . '/upload.php';
+ } else {
+ require PUN_ROOT . 'lang/English/upload.php';
+ }
+
+ echo "\t\t\t\t\t" . '<li' . (($page == 'upload') ? ' class="isactive"' : '') . '><a href="upfiles.php?id=' . $id . '">' . $lang_up['upfiles'] . '</a></li>' . "\n";
+ }
+}
diff --git a/js/upload.js b/js/upload.js
new file mode 100644
index 0000000..9087dd4
--- /dev/null
+++ b/js/upload.js
@@ -0,0 +1,407 @@
+// upload.js v3.0.2 Copyright (C) 2020 Visman (mio.visman@yandex.ru)
+if (typeof FluxBB === 'undefined' || !FluxBB) {var FluxBB = {};}
+
+FluxBB.upload = (function (doc, win) {
+ 'use strict';
+
+ var state = 0,
+ anchor,
+ files = {},
+ page = 0,
+ pages = 1,
+ textarea;
+
+ function get(elem) {
+ return doc.getElementById(elem);
+ }
+
+ function newXhr() {
+ if (typeof XMLHttpRequest === 'undefined') {
+ try {
+ return new ActiveXObject('Microsoft.XMLHTTP');
+ } catch (e) {}
+ } else {
+ return new XMLHttpRequest();
+ }
+ return false;
+ }
+
+ function createStartLink(ul) {
+ var a = doc.createElement('a'),
+ span = doc.createElement('span'),
+ li = doc.createElement('li');
+ a.innerHTML = FluxBB.uploadvars.lang.upfiles;
+ a.href = FluxBB.uploadvars.action;
+ span.appendChild(a);
+ li.appendChild(span);
+ ul.appendChild(li);
+ return a;
+ }
+
+ function findAnchor(node) {
+ while (node) {
+ if ('FIELDSET' === node.tagName) {
+ anchor = node.parentNode;
+ return true;
+ }
+ node = node.parentNode;
+ }
+ return false;
+ }
+
+ function popUp(url) {
+ var h = Math.min(430, screen.height),
+ w = Math.min(820, screen.width),
+ t = Math.max((screen.height - h) / 3, 0),
+ l = (screen.width - w) / 2;
+ win.open(url, 'gest', 'top=' + t + ',left=' + l + ',width=' + w + ',height=' + h + ',resizable=yes,location=no,menubar=no,status=no,scrollbars=yes');
+ }
+
+ function insertAfter(newNode, node) {
+ if (node.parentNode.lastChild === node) {
+ return node.parentNode.appendChild(newNode);
+ } else {
+ return node.parentNode.insertBefore(newNode, node.nextSibling);
+ }
+ }
+
+ function setInput(name, value, type) {
+ var input = doc.createElement('input');
+ input.type = type || 'hidden';
+ input.name = name;
+ input.value = value;
+ return input;
+ }
+
+ function initLoader() {
+ var style = doc.createElement('link'),
+ head = doc.querySelector('head');
+ style.href = FluxBB.uploadvars.style;
+ style.rel = 'stylesheet';
+ style.type = 'text/css';
+ head.appendChild(style);
+
+ var tmp = get('upf-template').children;
+ while (tmp[0]) {
+ anchor = insertAfter(tmp[0], anchor);
+ }
+
+ var form = doc.createElement('form');
+ form.id = 'upf-dataform';
+ var div = doc.createElement('div');
+ form.appendChild(div);
+
+ var input = setInput('upfile', '', 'file');
+ input.id = 'upfile';
+ div.appendChild(input);
+ div.appendChild(setInput('csrf_hash', FluxBB.uploadvars.token));
+ div.appendChild(setInput('ajx', '1'));
+ div.appendChild(setInput('action', 'upload'));
+ get('upf-template').appendChild(form);
+
+ get('upf-button').addEventListener('click', FluxBB.upload.buttonHandler, false);
+ input.addEventListener('change', FluxBB.upload.changeHandler, false);
+
+ files['-'] = {link: get('upf--')};
+ loadFileData();
+ }
+
+ function postData(data, successHandler, errorHandler) {
+ var xhr = newXhr();
+ if (!xhr) {
+ errorHandler && errorHandler(0, 'XMLHttpRequest not working');
+ return;
+ }
+ xhr.open('POST', FluxBB.uploadvars.action, true);
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ var data = xhr.responseText;
+ if (typeof data === 'string') {
+ try {
+ data = JSON.parse(data);
+ } catch (e) {
+ errorHandler && errorHandler(0, e.message);
+ return;
+ }
+ }
+ if ('error' in data) {
+ errorHandler && errorHandler(0, data.error);
+ } else {
+ successHandler && successHandler(data);
+ }
+ } else {
+ errorHandler && errorHandler(xhr.status, xhr.statusText);
+ }
+ }
+ };
+ if (data instanceof FormData) {
+ xhr.send(data);
+ } else {
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ data.ajx = 1;
+ data.csrf_hash = FluxBB.uploadvars.token;
+ var query = '',
+ separator = '';
+ for (var key in data) {
+ query += separator + key + '=' + encodeURIComponent(data[key]);
+ separator = '&';
+ }
+ xhr.send(query);
+ }
+ }
+
+ function updateData(data, auto) {
+ pages = data.pages;
+
+ setLegend(data.size, data.percent);
+
+ for (var key in data.files) {
+ addFileToGallery(key, data.files[key]);
+ if (auto) {
+ insertCode(key, true);
+ }
+ }
+
+ get('upf-container').addEventListener('scroll', FluxBB.upload.listHandler, false);
+ var event;
+ if (typeof Event === 'function') {
+ event = new Event('scroll');
+ } else {
+ event = document.createEvent('Event');
+ event.initEvent('scroll', false, false);
+ }
+ get('upf-container').dispatchEvent(event);
+ }
+
+ function loadFileData() {
+ get('upf-container').removeEventListener('scroll', FluxBB.upload.listHandler, false);
+
+ if (page >= pages) {
+ return;
+ }
+ ++page;
+
+ postData({action: 'view', p: page}, function (data) {
+ updateData(data);
+ }, function (status, text) {
+ alert(text);
+ });
+ }
+
+ function addFileToGallery(key, data) {
+ if (key in files) {
+ return;
+ }
+ var max = '';
+ for (var cur in files) {
+ if (key > cur && cur > max) {
+ max = cur;
+ }
+ }
+ var node = files['-'].link.cloneNode(true);
+ node.id = 'upf-' + key;
+
+ var name = node.querySelector('.upf-name');
+ name.title = data.filename;
+ name.querySelector('span').textContent = data.alt;
+
+ node.querySelector('.upf-size').querySelector('span').textContent = data.size;
+
+ var url = node.querySelector('.upf-file').querySelector('a');
+ url.href = data.url;
+ var child = url.querySelector('span');
+ if (data.mini) {
+ url.removeChild(child);
+ var child = doc.createElement('img');
+ child.src = data.mini;
+ child.alt = data.alt;
+ url.appendChild(child);
+ } else {
+ child.textContent = data.alt;
+ }
+
+ node.querySelector('.upf-delete').querySelector('a').addEventListener('click', FluxBB.upload.actionHandler, false);
+ node.querySelector('.upf-insert').querySelector('a').addEventListener('click', FluxBB.upload.actionHandler, false);
+ if (data.mini) {
+ node.querySelector('.upf-insert-t').querySelector('a').addEventListener('click', FluxBB.upload.actionHandler, false);
+ } else {
+ node.querySelector('.upf-insert-t').style.display = 'none';
+ }
+
+ files[max].link.parentNode.insertBefore(node, files[max].link);
+ data.link = node;
+ files[key] = data;
+ }
+
+ function setLegend(size, percent)
+ {
+ try {
+ var rgb = 'rgb(' + Math.ceil((percent > 50 ? 50 : percent)*255/50) + ', ' + Math.ceil((percent < 50 ? 50 : 100 - percent)*255/50) + ', 0)',
+ legend = get('upf-legend'),
+ div = legend.querySelector('div'),
+ span = div.querySelector('span');
+ legend.style.borderColor = div.style.backgroundColor = rgb;
+ div.style.width = span.textContent = percent + '%';
+ } catch (e) {}
+ try {
+ get('upf-legend-p').querySelector('span').textContent = size;
+ } catch (e) {}
+ }
+
+ function deleteFile(key) {
+ if (!confirm(FluxBB.uploadvars.lang.confirmation)) {
+ return;
+ }
+
+ var file = files[key];
+
+ file.link.classList.add('upf-removal');
+
+ postData({action: 'delete', file: file.filename, p: page}, function (data) {
+ file.link.parentNode.removeChild(file.link);
+ file.link = null;
+ delete files[key];
+ updateData(data);
+ }, function (status, text) {
+ file.link.classList.remove('upf-removal');
+ alert(text);
+ });
+ }
+
+ function insertCode(key, thumb) {
+ var file = files[key];
+ thumb = thumb && file.mini;
+
+ if (thumb) {
+ insertText('', '[url=' + file.url + '][img]' + file.mini + '[/img][/url]', '');
+ } else if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].indexOf(file.ext) > -1) {
+ insertText('', '[img]' + file.url + '[/img]', '');
+ } else {
+ insertText('[url=' + file.url + ']', '[/url]', file.filename);
+ }
+ }
+
+ function insertText(open, close, text) {
+ textarea.focus();
+ // all and IE9+
+ if ('selectionStart' in textarea) {
+ var len = textarea.value.length,
+ sp = Math.min(textarea.selectionStart, len), // IE bug
+ ep = Math.min(textarea.selectionEnd, len); // IE bug
+
+ textarea.value = textarea.value.substring(0, sp)
+ + open
+ + (sp == ep ? text : textarea.value.substring(sp, ep))
+ + close
+ + textarea.value.substring(ep);
+
+ textarea.selectionStart = textarea.selectionEnd = ep + close.length + open.length + (sp == ep ? text.length : 0);
+ }
+ // IE9-
+ else if (doc.selection && doc.selection.createRange) {
+ var sel = doc.selection.createRange();
+ sel.text = open + (!sel.text ? text : sel.text) + close;
+ }
+ textarea.focus();
+ }
+//*********************//
+ return {
+ init : function () {
+ if (0 !== state) {
+ return false;
+ }
+ state = -1;
+
+ doc.removeEventListener("DOMContentLoaded", FluxBB.upload.init, false);
+
+ textarea = doc.getElementsByName('req_message')[0];
+ if (textarea && false !== findAnchor(textarea)) {
+ var bblinks = anchor.querySelector('.bblinks');
+ if (bblinks) {
+ var link = createStartLink(bblinks);
+ link.addEventListener('click', FluxBB.upload.clickStart, false);
+ state = (typeof FormData === 'undefined') ? 1 : 2;
+ }
+ }
+ },
+
+ clickStart : function (event) {
+ event.preventDefault();
+ switch (state) {
+ case 1:
+ popUp(FluxBB.uploadvars.action);
+ break;
+ case 2:
+ initLoader();
+ state = 3;
+ break;
+ }
+ },
+
+ listHandler : function (event) {
+ var list = event.currentTarget;
+ if (list.scrollWidth - list.scrollLeft - list.clientWidth < 140) {
+ loadFileData();
+ }
+ },
+
+ actionHandler : function (event) {
+ event.preventDefault();
+ var target = event.currentTarget.parentNode,
+ cl = target.className,
+ key = target.parentNode.id.substring(4);
+
+ if (!(key in files)) {
+ return;
+ }
+
+ if (cl.indexOf('delete') > -1) {
+ deleteFile(key);
+ } else if (cl.indexOf('insert-t') > -1) {
+ insertCode(key, true)
+ } else if (cl.indexOf('insert') > -1) {
+ insertCode(key, false)
+ }
+ },
+
+ buttonHandler : function(event) {
+ var event;
+ try {
+ event = new MouseEvent('click');
+ } catch (e) {
+ event = document.createEvent('MouseEvent');
+ event.initEvent('click', false, false);
+ }
+ get('upfile').dispatchEvent(event);
+ },
+
+ changeHandler : function(event) {
+ var files = event.target.files;
+ if (1 !== files.length) {
+ return;
+ }
+
+ var file = files[0];
+ if (file.size > FluxBB.uploadvars.maxsize) {
+ alert(FluxBB.uploadvars.lang.large);
+ } else if (FluxBB.uploadvars.exts.indexOf(file.name.match(/\.([^.]*)$/)[1].toLowerCase()) < 0) {
+ alert(FluxBB.uploadvars.lang.bad_type);
+ } else {
+ var form = new FormData(get('upf-dataform'));
+ get('upf-button').classList.add('upf-uploading');
+ postData(form, function (data) {
+ get('upf-button').classList.remove('upf-uploading');
+ updateData(data, true);
+ }, function (status, text) {
+ get('upf-button').classList.remove('upf-uploading');
+ alert(text);
+ });
+ }
+ }
+ };
+}(document, window));
+
+if (document.addEventListener) {
+ document.addEventListener("DOMContentLoaded", FluxBB.upload.init, false);
+}
diff --git a/lang/English/upload.php b/lang/English/upload.php
new file mode 100644
index 0000000..8f8aa9a
--- /dev/null
+++ b/lang/English/upload.php
@@ -0,0 +1,92 @@
+<?php
+
+$lang_up = array(
+'No upfiles' => 'No upload.',
+'Error' => '<strong>Error</strong> : ',
+'Error DB' => 'Unable to insert in table %s',
+'Error DB ins-up' => 'Error in the DB insert/update',
+'Error space' => 'You exceeded your storage space. Delete files and try again.',
+'Error delete' => 'Error during the file delete.',
+'Error img' => 'Invalid format of the picture. Or the server doesn\'t support processing of pictures.',
+'Error no mod img' => 'The picture has crash at updating.',
+'Error open' => 'Uploaded file doesn\'t open.',
+'Error inject' => 'Uploaded file contains the forbidden string. Archive this file and try again, Or speak to administrator.',
+'Error usage' => 'File used in %d post(s).',
+
+'Redirect' => 'Options updated. Redirecting …',
+'Install info' => 'Prepare the database and cache to operate Uploadile.',
+'Install' => 'Install',
+'Update info' => 'Update the cache. (default values)',
+'Update' => 'Update',
+'Uninstall info' => 'Restore the DB and modify the cache to uninstall Uploadile.',
+'Uninstall' => 'Uninstall',
+
+'configuration' => 'Configuration',
+'plugin_desc' => 'This plugin gives the chance to operate uploading of files.',
+'legend_2' => 'Setup of pictures',
+'laws' => 'File type allowed. Separate with a comma (,).',
+'thumb' => 'Activate thumbnails',
+'thumb_size' => 'Thumbs size: ',
+'quality' => 'Quality: ',
+'maxsize_member' => 'Max size members can upload (MBytes).',
+'limit_member' => 'Space allocated to members (MBytes).',
+'px' => 'Pixel',
+'kbytes' => 'KBytes',
+'pictures' => 'Pictures',
+'for pictures' => 'For files greater than',
+'Install quality' => 'Install quality:',
+'Size not more' => 'Size not more (WxH):',
+'to jpeg' => 'Convert to jpeg',
+
+'Redirect delete' => 'File(s) deleted with success. Redirecting …',
+'Redirect upload' => 'File uploaded. Redirecting …',
+
+'uploadile' => 'My uploads',
+'titre_2' => 'Upload a file',
+'titre_4' => 'My uploads',
+'popup_title' => 'File manager',
+
+'info_2' => '%1$s (%2$s max file size)',
+'info_4' => 'Storage space used: <span>%s</span> of %s allowed.',
+'legend' => 'File',
+'fichier' => 'Select a file',
+
+'th0' => 'Username',
+'th1' => 'File name',
+'th2' => 'Preview',
+'no_preview' => 'None',
+'Member files' => 'Member files (new above)',
+
+'legend_1' => 'Convert',
+'convert' => 'Convert',
+'mo' => 'Value in MB',
+'ko' => 'Value in KB',
+'o' => 'Value in B',
+'texte' => 'Your text here',
+'delete' => 'Delete',
+'delete file' => 'Do you want to delete this file?',
+'insert' => 'Insert',
+'insert_thumb' => 'Insert thumbnail',
+'update_thumb' => 'Update thumbs',
+
+'upfiles' => 'Uploads',
+
+'groups' => 'Adjustment of groups',
+'group' => 'Group',
+
+// Avatar upload stuff
+'Bad type' => 'The file you tried to upload is not of an allowed type.',
+'Too large' => 'The file you tried to upload is larger than the maximum allowed',
+'Move failed' => 'The server was unable to save the uploaded file.',
+'Unknown failure' => 'An unknown error occurred.',
+'Upload' => 'Upload',
+
+'UPLOAD_ERR_INI_SIZE' => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
+'UPLOAD_ERR_FORM_SIZE' => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
+'UPLOAD_ERR_PARTIAL' => 'The uploaded file was only partially uploaded.',
+'UPLOAD_ERR_NO_FILE' => 'No file was uploaded.',
+'UPLOAD_ERR_NO_TMP_DIR' => 'Missing a temporary folder.',
+'UPLOAD_ERR_CANT_WRITE' => 'Failed to write file to disk.',
+'UPLOAD_ERR_EXTENSION' => 'A PHP extension stopped the file upload.',
+'UPLOAD_ERR_UNKNOWN' => 'Unknown upload error.',
+);
diff --git a/lang/French/upload.php b/lang/French/upload.php
new file mode 100644
index 0000000..b6113d7
--- /dev/null
+++ b/lang/French/upload.php
@@ -0,0 +1,92 @@
+<?php
+
+$lang_up = array(
+'No upfiles' => 'Pas de téléchargement.',
+'Error' => '<strong>Erreur</strong> : ',
+'Error DB' => 'Impossible d\'insérer dans la table %s',
+'Error DB ins-up' => 'Erreur pendant la mise à jour de la base de données',
+'Error space' => 'Vous avez dépassé votre espace de stockage autorisé. Supprimez des fichiers et essayez à nouveau.',
+'Error delete' => 'Erreur pendant lors de la supression du fichier, essayez à nouveau.',
+'Error img' => 'Format invalide d\'image. Ou le serveur ne supporte pas le traitement d\'images.',
+'Error no mod img' => 'L\'image a été endommagée pendant la mise à jour.',
+'Error open' => 'Le fichier téléchargé ne s\'ouvre pas.',
+'Error inject' => 'Le fichier envoyé contient la ficelle défendue. Compressez ce fichier et essayez à nouveau ou contacter à l\'administrateur.',
+'Error usage' => 'File used in %d post(s).',
+
+'Redirect' => 'Options mises à jour. Redirection …',
+'Install info' => 'Préparation de la base de données et du cache pour l\'installation Uploadile.',
+'Install' => 'Installer',
+'Update info' => 'Mise à jour. (valeurs par défauts) <br />',
+'Update' => 'Mis à jour',
+'Uninstall info' => 'Restauration la base de données et mise à jour du cache pour la désinstallation d\'Uploadile.',
+'Uninstall' => 'Désinstaller',
+
+'configuration' => 'Configuration',
+'plugin_desc' => 'Ce plugin permet de configurer les fonctions d\'Uploadile dont vous avez besoin.',
+'legend_2' => 'Choisisser vos options',
+'laws' => 'Types de fichier autorisés. Séparer avec des virgules (,).',
+'thumb' => 'Activer les miniatures',
+'thumb_size' => 'Taille de la miniature: ',
+'quality' => 'Qualité: ',
+'maxsize_member' => 'La taille maximum que les membres peuvent télécharger (MBytes).',
+'limit_member' => 'Espace alloué aux membres (MBytes).',
+'px' => 'Pixel',
+'kbytes' => 'KBytes',
+'pictures' => 'Images',
+'for pictures' => 'Pour une image en poids, c\'est plus',
+'Install quality' => 'Qualité de l\'image:',
+'Size not more' => 'Taille pas plus grande (HxL):',
+'to jpeg' => 'Convertir en jpeg',
+
+'Redirect delete' => 'Fichier(s) supprimé(s) avec succés. Redirection …',
+'Redirect upload' => 'Fichier téléchargé. Redirection …',
+
+'uploadile' => 'Mes téléchargements',
+'titre_2' => 'Télécharger un fichier',
+'titre_4' => 'Mes téléchargements',
+'popup_title' => 'Gestion des fichiers',
+
+'info_2' => '%1$s (max %2$s)',
+'info_4' => 'Espace de stockage utilisé : <span>%s</span> en %s',
+'legend' => 'Fichier',
+'fichier' => 'Sélectionner un fichier',
+
+'th0' => 'Nom',
+'th1' => 'Url du fichier',
+'th2' => 'Prévisualiser',
+'no_preview' => 'Aucune',
+'Member files' => 'Fichiers des membres (nouveaux ci-dessus)',
+
+'legend_1' => 'Conversion',
+'convert' => 'Convertir',
+'mo' => 'Valeur en MB',
+'ko' => 'Valeur en KB',
+'o' => 'Valeur en B',
+'texte' => 'Placer votre texte ici',
+'delete' => 'Supprimer',
+'delete file' => 'Voulez-vous supprimer ce fichier?',
+'insert' => 'Insérer',
+'insert_thumb' => 'Insérer une miniature',
+'update_thumb' => 'Mettre à jour les miniatures',
+
+'upfiles' => 'Téléchargements',
+
+'groups' => 'Le réglage des groupes',
+'group' => 'Groupe',
+
+// Avatar upload stuff
+'Bad type' => 'Ce type de fichier n\'est pas autorisé.',
+'Too large' => 'La taille du fichier dépasse le maximum autorisé',
+'Move failed' => 'Le serveur n\'a pas pu enregistrer le fichier envoyé. Contactez l\'administrateur',
+'Unknown failure' => 'Erreur inconnue. Merci de réessayer.',
+'Upload' => 'Envoyer',
+
+'UPLOAD_ERR_INI_SIZE' => 'La taille du fichier téléchargé excède la valeur de upload_max_filesize, configurée dans le php.ini.',
+'UPLOAD_ERR_FORM_SIZE' => 'La taille du fichier téléchargé excède la valeur de MAX_FILE_SIZE, qui a été spécifiée dans le formulaire HTML.',
+'UPLOAD_ERR_PARTIAL' => 'Le fichier n\'a été que partiellement téléchargé.',
+'UPLOAD_ERR_NO_FILE' => 'Aucun fichier n\'a été téléchargé.',
+'UPLOAD_ERR_NO_TMP_DIR' => 'Un dossier temporaire est manquant.',
+'UPLOAD_ERR_CANT_WRITE' => 'Échec de l\'écriture du fichier sur le disque.',
+'UPLOAD_ERR_EXTENSION' => 'Une extension PHP a arrêté l\'envoi de fichier.',
+'UPLOAD_ERR_UNKNOWN' => 'Erreur de téléchargement inconnue.',
+);
diff --git a/lang/German/upload.php b/lang/German/upload.php
new file mode 100644
index 0000000..2bdf9c6
--- /dev/null
+++ b/lang/German/upload.php
@@ -0,0 +1,92 @@
+<?php
+
+$lang_up = array(
+'No upfiles' => 'Keine Dateien vorhanden.',
+'Error' => '<strong>Fehler</strong> : ',
+'Error DB' => 'Konnte in die Tabelle %s nichts einfügen',
+'Error DB ins-up' => 'Fehler beim Aktualisieren der Datenbank',
+'Error space' => 'Der dir zugewiesene Speicherplatz ist überfüllt. Lösche ein paar Dateien und versuch es dann noch einmal.',
+'Error delete' => 'Fehler während des Löschens der Datei.',
+'Error img' => 'Ungültiges Bildformat. Oder der Server unterstützt keine Bildverarbeitung.',
+'Error no mod img' => 'Das Bild wurde während der Aktualisierung zerstört.',
+'Error open' => 'Die hochgeladene Datei konnte nicht geöffnet werden.',
+'Error inject' => 'Uploaded file contains the forbidden string. Archiviere diese Datei und versuch es noch einmal. Oder sprich mit dem Administrator.',
+'Error usage' => 'File used in %d post(s).',
+
+'Redirect' => 'Optionen aktualisiert. Leite weiter …',
+'Install info' => 'Bereitet die Datenbank und den Cache für den Einsatz von Uploadile vor.',
+'Install' => 'Installieren',
+'Update info' => 'Den Cache aktualisieren. (voreingestellte Werte)',
+'Update' => 'Aktualisieren',
+'Uninstall info' => 'Die Datenbank zurücksetzen und den Zwischenspeicher modifizieren, um Uploadile zu deinstallieren.',
+'Uninstall' => 'Deinstallieren',
+
+'configuration' => 'Konfiguration',
+'plugin_desc' => 'Über dieses Plugin kannst du Uploadile an deine Bedürfnisse anpassen.',
+'legend_2' => 'Wähle deine Optionen',
+'laws' => 'Erlaubte Dateitypen. Mit Kommata (,) trennen.',
+'thumb' => 'Vorschaubilder aktivieren',
+'thumb_size' => 'Größe Vorschaubilder: ',
+'quality' => 'Qualität: ',
+'maxsize_member' => 'Maximale Dateigröße, die von Mitgliedern hochgeladen werden darf (MBytes)',
+'limit_member' => 'Größe des Speicherplatzes für Mitglieder (MBytes)',
+'px' => 'Pixel',
+'kbytes' => 'KBytes',
+'pictures' => 'Bilder',
+'for pictures' => 'Bilder, die größer sind als',
+'Install quality' => 'Konvertierungsqualität:',
+'Size not more' => 'Nicht größer als (BxH):',
+'to jpeg' => 'Ins JPEG-Format konvertieren',
+
+'Redirect delete' => 'Datei(en) gelöscht. Leite weiter …',
+'Redirect upload' => 'Datei hochgeladen. Leite weiter …',
+
+'uploadile' => 'Meine hochgeladenen Dateien',
+'titre_2' => 'Eine Datei hochladen',
+'titre_4' => 'Meine hochgeladenen Dateien',
+'popup_title' => 'Dateiverwaltung',
+
+'info_2' => '%1$s (max %2$s)',
+'info_4' => 'Aktuell belegter Speicherplatz: <span>%s</span> in %s',
+'legend' => 'Datei',
+'fichier' => 'Eine Datei auswählen',
+
+'th0' => 'Mitgliedsname',
+'th1' => 'Dateiname',
+'th2' => 'Vorschau',
+'no_preview' => 'Keine',
+'Member files' => 'Dateien der Mitglieder (neueste zuerst)',
+
+'legend_1' => 'Konvertierung',
+'convert' => 'Konvertieren',
+'mo' => 'Wert in MB',
+'ko' => 'Wert in KB',
+'o' => 'Wert in B',
+'texte' => 'Dein Text hier',
+'delete' => 'Löschen',
+'delete file' => 'Möchten Sie diese Datei löschen?',
+'insert' => 'Einfügen',
+'insert_thumb' => 'Vorschaubild einfügen',
+'update_thumb' => 'Vorschaubild aktualisieren',
+
+'upfiles' => 'Dateien hochladen',
+
+'groups' => 'Anpassung von Gruppen',
+'group' => 'Gruppen',
+
+// Avatar
+'Bad type' => 'Die ausgewählte Datei hat ein falsches Format.',
+'Too large' => 'Die ausgewählte Datei ist größer als maximal erlaubt',
+'Move failed' => 'Der Server konnte die hochgeladene Datei nicht speichern. Bitte kontaktiere den Administrator unter',
+'Unknown failure' => 'Ein unbekannter Fehler ist aufgetreten. Bitte versuche es noch einmal.',
+'Upload' => 'Hochladen',
+
+'UPLOAD_ERR_INI_SIZE' => 'Die hochgeladene Datei überschreitet die in der Anweisung upload_max_filesize in php.ini festgelegte Größe.',
+'UPLOAD_ERR_FORM_SIZE' => 'Die hochgeladene Datei überschreitet die in dem HTML Formular mittels der Anweisung MAX_FILE_SIZE angegebene maximale Dateigröße.',
+'UPLOAD_ERR_PARTIAL' => 'Die Datei wurde nur teilweise hochgeladen.',
+'UPLOAD_ERR_NO_FILE' => 'Es wurde keine Datei hochgeladen.',
+'UPLOAD_ERR_NO_TMP_DIR' => 'Fehlender temporärer Ordner.',
+'UPLOAD_ERR_CANT_WRITE' => 'Speichern der Datei auf die Festplatte ist fehlgeschlagen.',
+'UPLOAD_ERR_EXTENSION' => 'Eine PHP Erweiterung hat den Upload der Datei gestoppt.',
+'UPLOAD_ERR_UNKNOWN' => 'Unbekannter Upload-Fehler.',
+);
diff --git a/lang/Russian/upload.php b/lang/Russian/upload.php
new file mode 100644
index 0000000..316266a
--- /dev/null
+++ b/lang/Russian/upload.php
@@ -0,0 +1,92 @@
+<?php
+
+$lang_up = array(
+'No upfiles' => 'Нет загруженных файлов.',
+'Error' => '<strong>Ошибка</strong> : ',
+'Error DB' => 'Не могу добавить поле в таблицу %s',
+'Error DB ins-up' => 'Ошибка при добавлении/обновлении записи',
+'Error space' => 'Вы превысили лимит отведенного места под ваши файлы.',
+'Error delete' => 'При удалении одного из файлов возникла ошибка.',
+'Error img' => 'Неверный формат картинки. Или сервер не поддерживает обработку картинок.',
+'Error no mod img' => 'Модификация картинки не удалась.',
+'Error open' => 'Загруженный файл не открывается.',
+'Error inject' => 'Загруженный файл содержит запрещенную последовательность символов. Заархивируйте файл и попробуйте снова, или обратитесь к администрации форума.',
+'Error usage' => 'Файл используется в %d сообщении(ях).',
+
+'Redirect' => 'Настройки изменены. Переадресация …',
+'Install info' => 'Плагин внесет нужные изменения в базу форума и обновит кэш.',
+'Install' => 'Установить',
+'Update info' => 'Плагин установит настройки по умолчанию.',
+'Update' => 'Обновить',
+'Uninstall info' => 'Плагин удалит из базы форума изменения и обновит кэш.',
+'Uninstall' => 'Удалить',
+
+'configuration' => 'Настройки',
+'plugin_desc' => 'Этот плагин дает возможность управлять загрузкой файлов.',
+'legend_2' => 'Настройка картинок',
+'laws' => 'Разрешенные типы файлов. Разделяются запятыми (,).',
+'thumb' => 'Использовать превьюшки',
+'thumb_size' => 'Высота превью: ',
+'quality' => 'Качество: ',
+'maxsize_member' => 'Максимальный размер файла для загрузки (Мбайт).',
+'limit_member' => 'Лимит дискового пространства (Мбайт).',
+'px' => 'точек',
+'kbytes' => 'Кбайт',
+'pictures' => 'Картинки',
+'for pictures' => 'Для картинки весом больше',
+'Install quality' => 'Установить качество:',
+'Size not more' => 'Размер не более (ШxВ):',
+'to jpeg' => 'Конвертировать в jpeg',
+
+'Redirect delete' => 'Удаление файла(ов) прошло успешно. Переадресация …',
+'Redirect upload' => 'Файл загружен. Переадресация …',
+
+'uploadile' => 'Мои загрузки',
+'titre_2' => 'Загрузка файла',
+'titre_4' => 'Мои загрузки',
+'popup_title' => 'Управление файлами',
+
+'info_2' => '%1$s (макс. %2$s)',
+'info_4' => 'Использовано: <span>%s</span> из %s',
+'legend' => 'Файл',
+'fichier' => 'Выберите файл',
+
+'th0' => 'Пользователь',
+'th1' => 'Имя файла',
+'th2' => 'Превью',
+'no_preview' => 'нет',
+'Member files' => 'Файлы пользователей (сначала новые)',
+
+'legend_1' => 'Конвертация данных',
+'convert' => 'пересчитать',
+'mo' => 'Величина в Мб',
+'ko' => 'Величина в Кб',
+'o' => 'Величина в байтах',
+'texte' => 'Введите ваш текст',
+'delete' => 'Удалить',
+'delete file' => 'Удалить этот файл?',
+'insert' => 'Вставить',
+'insert_thumb' => 'Вставить превью',
+'update_thumb' => 'Пересоздать превьюшки',
+
+'upfiles' => 'Загрузки',
+
+'groups' => 'Настройка групп',
+'group' => 'Группа',
+
+// Avatar upload stuff
+'Bad type' => 'Загрузка файла с используемым расширением запрещена.',
+'Too large' => 'Выбранный файл больше максимально допустимых размеров',
+'Move failed' => 'Сервер не смог сохранить загруженный файл.',
+'Unknown failure' => 'Произошла неизвестная ошибка.',
+'Upload' => 'Загрузить',
+
+'UPLOAD_ERR_INI_SIZE' => 'Размер принятого файла превысил максимально допустимый размер, который задан директивой upload_max_filesize конфигурационного файла php.ini.',
+'UPLOAD_ERR_FORM_SIZE' => 'Размер загружаемого файла превысил значение MAX_FILE_SIZE, указанное в HTML-форме.',
+'UPLOAD_ERR_PARTIAL' => 'Загружаемый файл был получен только частично.',
+'UPLOAD_ERR_NO_FILE' => 'Файл не был загружен.',
+'UPLOAD_ERR_NO_TMP_DIR' => 'Отсутствует временная папка.',
+'UPLOAD_ERR_CANT_WRITE' => 'Не удалось записать файл на диск.',
+'UPLOAD_ERR_EXTENSION' => 'PHP-расширение остановило загрузку файла.',
+'UPLOAD_ERR_UNKNOWN' => 'Неизвестная ошибка загрузки.',
+);
diff --git a/plugins/AP_Upload.php b/plugins/AP_Upload.php
new file mode 100644
index 0000000..fbf865e
--- /dev/null
+++ b/plugins/AP_Upload.php
@@ -0,0 +1,638 @@
+<?php
+
+/**
+ * Copyright (C) 2011-2020 Visman (mio.visman@yandex.ru)
+ * Copyright (C) 2007 BN (bnmaster@la-bnbox.info)
+ * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
+ */
+
+// Make sure no one attempts to run this script "directly"
+if (! defined('PUN')) {
+ exit;
+}
+
+// Tell admin_loader.php that this is indeed a plugin and that it is loaded
+define('PUN_PLUGIN_LOADED', 1);
+define('PLUGIN_VERSION', '3.0.3');
+define('PLUGIN_URL', pun_htmlspecialchars('admin_loader.php?plugin=' . $plugin));
+define('PLUGIN_EXTS', 'webp,jpg,jpeg,png,gif,mp3,zip,rar,7z');
+define('PLUGIN_NF', 25);
+
+require PUN_ROOT . 'include/upload.php';
+
+// Any action must be confirmed by token
+if (! empty($_POST)) {
+ if (function_exists('csrf_hash')) {
+ confirm_referrer('AP_Upload.php');
+ } else {
+ check_csrf(isset($_POST['csrf_hash']) ? $_POST['csrf_hash'] : null);
+ }
+}
+
+$sconf = [
+ 'thumb' => (true === $upf_class->isResize()) ? 1 : 0,
+ 'thumb_size' => 100,
+ 'thumb_perc' => 75,
+ 'pic_mass' => 300, //килобайт
+ 'pic_perc' => 75,
+ 'pic_w' => 1920,
+ 'pic_h' => 1200,
+];
+
+// обновление до версии 2.3.0
+if (isset($pun_config['o_uploadile_other'])) {
+ if (! isset($pun_config['o_upload_config'])) {
+ $aconf = unserialize($pun_config['o_uploadile_other']);
+ $aconf['pic_mass'] = (int) ($aconf['pic_mass'] / 1024);
+ $pun_config['o_upload_config'] = serialize($aconf);
+
+ $db->query('INSERT INTO ' . $db->prefix . 'config (conf_name, conf_value) VALUES(\'o_upload_config\', \'' . $db->escape($pun_config['o_upload_config']) . '\')') or error($lang_up['Error DB ins-up'], __FILE__, __LINE__, $db->error());
+ }
+
+ $db->query('DELETE FROM ' . $db->prefix . 'config WHERE conf_name=\'o_uploadile_other\'') or error('Unable to remove config entries', __FILE__, __LINE__, $db->error());;
+
+ if (! defined('FORUM_CACHE_FUNCTIONS_LOADED')) {
+ require PUN_ROOT . 'include/cache.php';
+ }
+
+ generate_config_cache();
+
+ $data_grs = [];
+ if (isset($pun_user['g_up_ext'], $pun_user['g_up_limit'], $pun_user['g_up_max'])) {
+ $result = $db->query('SELECT * FROM ' . $db->prefix . 'groups ORDER BY g_id') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error());
+
+ while ($cur_group = $db->fetch_assoc($result)) {
+ if ($cur_group['g_id'] == PUN_GUEST) {
+ continue;
+ }
+ $data_grs[$cur_group['g_id']] = [
+ 'g_up_ext' => $cur_group['g_up_ext'],
+ 'g_up_max' => (int) ($cur_group['g_up_max'] / 10485.76),
+ 'g_up_limit' => (int) ($cur_group['g_up_limit'] / 1048576),
+ ];
+ }
+ }
+
+ $db->drop_field('groups', 'g_up_ext') or error('Unable to drop g_up_ext field', __FILE__, __LINE__, $db->error());
+ $db->drop_field('groups', 'g_up_max') or error('Unable to drop g_up_max field', __FILE__, __LINE__, $db->error());
+ $db->drop_field('groups', 'g_up_limit') or error('Unable to drop g_up_limit field', __FILE__, __LINE__, $db->error());
+
+ $db->add_field('groups', 'g_up_ext', 'VARCHAR(255)', false, PLUGIN_EXTS) or error(sprintf($lang_up['Error DB'], 'groups'), __FILE__, __LINE__, $db->error());
+ $db->add_field('groups', 'g_up_max', 'INT(10)', false, 0) or error(sprintf($lang_up['Error DB'], 'groups'), __FILE__, __LINE__, $db->error());
+ $db->add_field('groups', 'g_up_limit', 'INT(10)', false, 0) or error(sprintf($lang_up['Error DB'], 'groups'), __FILE__, __LINE__, $db->error());
+
+ foreach ($data_grs as $g_id => $cur_group) {
+ $db->query('UPDATE ' . $db->prefix . 'groups SET g_up_ext=\'' . $db->escape($cur_group['g_up_ext']) . '\', g_up_limit=' . $cur_group['g_up_limit'] . ', g_up_max=' . $cur_group['g_up_max'] . ' WHERE g_id=' . $g_id) or error('Unable to update user group list', __FILE__, __LINE__, $db->error());
+ }
+
+ $db->add_field('users', 'upload_size', 'INT(10)', false, 0) or error(sprintf($lang_up['Error DB'], 'users'), __FILE__, __LINE__, $db->error());
+
+ if (isset($pun_user['upload'])) {
+ $db->query('UPDATE ' . $db->prefix . 'users SET upload_size=ROUND(upload/10485.76)') or error('Unable to update upload size of users', __FILE__, __LINE__, $db->error());
+ }
+
+ $db->drop_field('users', 'upload') or error('Unable to drop upload field', __FILE__, __LINE__, $db->error());
+}
+
+// Установка плагина/мода
+if (isset($_POST['installation'])) {
+ $db->add_field('users', 'upload_size', 'INT(10)', false, 0) or error(sprintf($lang_up['Error DB'], 'users'), __FILE__, __LINE__, $db->error());
+ $db->add_field('groups', 'g_up_ext', 'VARCHAR(255)', false, PLUGIN_EXTS) or error(sprintf($lang_up['Error DB'], 'groups'), __FILE__, __LINE__, $db->error());
+ $db->add_field('groups', 'g_up_max', 'INT(10)', false, 0) or error(sprintf($lang_up['Error DB'], 'groups'), __FILE__, __LINE__, $db->error());
+ $db->add_field('groups', 'g_up_limit', 'INT(10)', false, 0) or error(sprintf($lang_up['Error DB'], 'groups'), __FILE__, __LINE__, $db->error());
+
+ $adm_max = (int) (min($upf_class->size(ini_get('upload_max_filesize')), $upf_class->size(ini_get('post_max_size'))) / 10485.76);
+ $db->query('UPDATE ' . $db->prefix . 'groups SET g_up_ext=\'' . $db->escape(PLUGIN_EXTS) . '\', g_up_limit=1024, g_up_max=' . $adm_max . ' WHERE g_id=' . PUN_ADMIN) or error('Unable to update user group list', __FILE__, __LINE__, $db->error());
+
+ $db->query('DELETE FROM ' . $db->prefix . 'config WHERE conf_name=\'o_upload_config\'') or error('Unable to remove config entries', __FILE__, __LINE__, $db->error());;
+ $db->query('INSERT INTO ' . $db->prefix . 'config (conf_name, conf_value) VALUES(\'o_upload_config\', \'' . $db->escape(serialize($sconf)) . '\')') or error($lang_up['Error DB ins-up'], __FILE__, __LINE__, $db->error());
+
+ if (! defined('FORUM_CACHE_FUNCTIONS_LOADED')) {
+ require PUN_ROOT . 'include/cache.php';
+ }
+
+ generate_config_cache();
+
+ redirect(PLUGIN_URL, $lang_up['Redirect']);
+}
+
+// Обновления параметров
+else if (isset($_POST['update'])) {
+ $g_up_ext = isset($_POST['g_up_ext']) ? array_map('pun_trim', $_POST['g_up_ext']) : [];
+ $g_up_max = isset($_POST['g_up_max']) ? array_map('floatval', $_POST['g_up_max']) : [];
+ $g_up_limit = isset($_POST['g_up_limit']) ? array_map('intval', $_POST['g_up_limit']) : [];
+
+ if (empty($g_up_limit)) {
+ $g_up_limit[PUN_ADMIN] = 1024;
+ $g_up_max[PUN_ADMIN] = 1024;
+ }
+
+ $result = $db->query('SELECT g_id FROM ' . $db->prefix . 'groups ORDER BY g_id') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error());
+ while ($cur_group = $db->fetch_assoc($result)) {
+ if ($cur_group['g_id'] == PUN_GUEST) {
+ continue;
+ }
+
+ if (isset($g_up_ext[$cur_group['g_id']])) {
+ $g_ext = str_replace(' ', '', $g_up_ext[$cur_group['g_id']]);
+ $g_ext = preg_replace('%[,]+%u', ',', $g_ext);
+ if (preg_match('%^[0-9a-zA-Z][0-9a-zA-Z,]*[0-9a-zA-Z]$%uD', $g_ext) == 0) {
+ $g_ext = PLUGIN_EXTS;
+ }
+ $g_ext = strtolower($g_ext);
+ } else {
+ $g_ext = PLUGIN_EXTS;
+ }
+
+ $g_max = (! isset($g_up_max[$cur_group['g_id']]) || $g_up_max[$cur_group['g_id']] < 0) ? 0 : $g_up_max[$cur_group['g_id']];
+ $g_max = (int) (100 * min($g_max, $upf_class->size(ini_get('upload_max_filesize')) / 1048576, $upf_class->size(ini_get('post_max_size')) / 1048576));
+ $g_lim = (! isset($g_up_limit[$cur_group['g_id']]) || $g_up_limit[$cur_group['g_id']] < 0) ? 0 : $g_up_limit[$cur_group['g_id']];
+ $g_lim = min($g_lim, 20971520);
+
+ $db->query('UPDATE ' . $db->prefix . 'groups SET g_up_ext=\'' . $db->escape($g_ext) . '\', g_up_limit=' . $g_lim . ', g_up_max=' . $g_max . ' WHERE g_id=' . $cur_group['g_id']) or error('Unable to update user group list', __FILE__, __LINE__, $db->error());
+ }
+
+ if (isset($_POST['thumb'])) {
+ $sconf['thumb'] = $_POST['thumb'] == '1' ? 1 : 0;
+ }
+ if (isset($_POST['thumb_size']) && $_POST['thumb_size'] > 0) {
+ $sconf['thumb_size'] = (int) $_POST['thumb_size'];
+ }
+ if (isset($_POST['thumb_perc']) && $_POST['thumb_perc'] > 0 && $_POST['thumb_perc'] <= 100) {
+ $sconf['thumb_perc'] = (int) $_POST['thumb_perc'];
+ }
+
+ if (isset($_POST['pic_mass']) && $_POST['pic_mass'] >= 0) {
+ $sconf['pic_mass'] = (int) $_POST['pic_mass'];
+ }
+ if (isset($_POST['pic_perc']) && $_POST['pic_perc'] > 0 && $_POST['pic_perc'] <= 100) {
+ $sconf['pic_perc'] = (int) $_POST['pic_perc'];
+ }
+ if (isset($_POST['pic_w']) && $_POST['pic_w'] >= 100) {
+ $sconf['pic_w'] = (int) $_POST['pic_w'];
+ }
+ if (isset($_POST['pic_h']) && $_POST['pic_h'] >= 100) {
+ $sconf['pic_h'] = (int) $_POST['pic_h'];
+ }
+
+ $db->query('DELETE FROM ' . $db->prefix . 'config WHERE conf_name=\'o_upload_config\'') or error('Unable to remove config entries', __FILE__, __LINE__, $db->error());;
+ $db->query('INSERT INTO ' . $db->prefix . 'config (conf_name, conf_value) VALUES(\'o_upload_config\', \'' . $db->escape(serialize($sconf)) . '\')') or error($lang_up['Error DB ins-up'], __FILE__, __LINE__, $db->error());
+
+ if (! defined('FORUM_CACHE_FUNCTIONS_LOADED')) {
+ require PUN_ROOT . 'include/cache.php';
+ }
+
+ generate_config_cache();
+
+ redirect(PLUGIN_URL, $lang_up['Redirect']);
+}
+
+// Удаление мода
+else if (isset($_POST['restore'])) {
+ $db->drop_field('users', 'upload_size') or error('Unable to drop upload field', __FILE__, __LINE__, $db->error());
+ $db->drop_field('groups', 'g_up_ext') or error('Unable to drop g_up_ext field', __FILE__, __LINE__, $db->error());
+ $db->drop_field('groups', 'g_up_max') or error('Unable to drop g_up_max field', __FILE__, __LINE__, $db->error());
+ $db->drop_field('groups', 'g_up_limit') or error('Unable to drop g_up_limit field', __FILE__, __LINE__, $db->error());
+
+ $db->query('DELETE FROM ' . $db->prefix . 'config WHERE conf_name=\'o_upload_config\'') or error('Unable to remove config entries', __FILE__, __LINE__, $db->error());;
+
+ if (! defined('FORUM_CACHE_FUNCTIONS_LOADED')) {
+ require PUN_ROOT . 'include/cache.php';
+ }
+
+ generate_config_cache();
+
+ redirect(PLUGIN_URL, $lang_up['Redirect']);
+}
+
+if (isset($pun_config['o_upload_config'])) {
+ $aconf = unserialize($pun_config['o_upload_config']);
+} else {
+ $aconf = $sconf;
+ $aconf['thumb'] = 0;
+ define('PLUGIN_OFF', 1);
+}
+
+$upf_mem = 'img/members/';
+$upf_regx = '%^img/members/(\d+)/([\w-]+)\.(\w+)$%iD';
+
+// #############################################################################
+
+// Удаление файлов
+if (isset($_POST['delete'], $_POST['delete_f']) && is_array($_POST['delete_f'])) {
+ $error = false;
+
+ if (is_dir(PUN_ROOT . $upf_mem)) {
+ $au = [];
+ foreach ($_POST['delete_f'] as $file) {
+ if (
+ preg_match($upf_regx, $file, $matches)
+ && false === $upf_class->inBlackList($matches[3])
+ && 'mini_' !== substr($matches[2], 0, 5)
+ && is_file(PUN_ROOT . $file)
+ ) {
+ if (unlink(PUN_ROOT . $file)) {
+ $id = (int) $matches[1];
+ $au[$id] = $id;
+ if (is_file(PUN_ROOT . $upf_mem . $matches[1] . '/mini_' . $matches[2] . '.' . $matches[3])) {
+ unlink(PUN_ROOT . $upf_mem . $matches[1] . '/mini_' . $matches[2] . '.' . $matches[3]);
+ }
+ } else {
+ $error = true;
+ }
+ } else {
+ $error = true;
+ }
+ }
+
+ if (! defined('PLUGIN_OFF')) {
+ foreach ($au as $user) {
+ // Считаем общий размер файлов юзера
+ $upload = (int) ($upf_class->dirSize(PUN_ROOT . $upf_mem . $user . '/') / 10485.76);
+ $db->query('UPDATE ' . $db->prefix . 'users SET upload_size=\'' . $upload . '\' WHERE id=' . $user) or error($lang_up['Error DB ins-up'], __FILE__, __LINE__, $db->error());
+ }
+ }
+ }
+
+ $p = empty($_GET['p']) || $_GET['p'] < 1 ? 1 : (int) $_GET['p'];
+
+ if ($error) {
+ if ($pun_config['o_redirect_delay'] < 5) {
+ $pun_config['o_redirect_delay'] = 5;
+ }
+ redirect(PLUGIN_URL . ($p > 1 ? '&amp;p=' . $p : ''), $lang_up['Error'] . $lang_up['Error delete']);
+ } else {
+ redirect(PLUGIN_URL . ($p > 1 ? '&amp;p=' . $p : ''), $lang_up['Redirect delete']);
+ }
+}
+
+if (file_exists(PUN_ROOT . 'style/' . $pun_user['style'] . '/upfiles.css')) {
+ $s = '<link rel="stylesheet" type="text/css" href="style/' . $pun_user['style'] . '/upfiles.css" />';
+} else {
+ $s = '<link rel="stylesheet" type="text/css" href="style/imports/upfiles.css" />';
+}
+$tpl_main = str_replace('</head>', $s . "\n</head>", $tpl_main);
+
+// Display the admin navigation menu
+generate_admin_menu($plugin);
+
+$tabindex = 1;
+$upf_token = function_exists('csrf_hash') ? csrf_hash('AP_Upload.php') : pun_csrf_token();
+
+?>
+ <div id="upf-block" class="plugin blockform">
+ <h2><span>Plugin Upload Files v.<?= PLUGIN_VERSION ?></span></h2>
+ <div class="box">
+ <div class="inbox">
+ <p><?= $lang_up['plugin_desc'] ?></p>
+ <form action="<?= PLUGIN_URL ?>" method="post">
+ <p>
+ <input type="hidden" name="csrf_hash" value="<?= $upf_token ?>" />
+<?php
+
+if (defined('PLUGIN_OFF')) {
+
+?>
+ <input type="submit" name="installation" value="<?= $lang_up['Install'] ?>" />&#160;<?= $lang_up['Install info'] ?><br />
+ </p>
+ </form>
+ </div>
+ </div>
+<?php
+
+} else {
+ $disbl = (true === $upf_class->isResize()) ? '' : '" disabled="disabled';
+ $stthumb = ('' === $disbl && 1 == $aconf['thumb']) ? '' : '" disabled="disabled';
+
+?>
+ <input type="submit" name="update" value="<?= $lang_up['Update'] ?>" />&#160;<?= $lang_up['Update info'] ?><br />
+ <input type="submit" name="restore" value="<?= $lang_up['Uninstall'] ?>" />&#160;<?= $lang_up['Uninstall info'] ?><br /><br />
+ </p>
+ </form>
+ </div>
+ </div>
+ <h2 class="block2"><span><?= $lang_up['configuration'] ?></span></h2>
+ <div class="box">
+ <form method="post" action="<?= PLUGIN_URL ?>">
+ <p class="submittop"><input type="submit" name="update" value="<?= $lang_up['Update'] ?>" tabindex="<?= $tabindex++ ?>" /></p>
+ <div class="inform">
+ <fieldset>
+ <legend><?= $lang_up['legend_2'] ?></legend>
+ <div class="infldset">
+ <table>
+ <tr>
+ <th scope="row"><label><?= $upf_class->getLibName() ?></label></th>
+ <td><?= pun_htmlspecialchars($upf_class->getLibVersion()) ?></td>
+ </tr>
+ <tr>
+ <th scope="row"><label><?= $lang_up['pictures'] ?></label></th>
+ <td>
+ <?= $lang_up['for pictures'] . "\n" ?>
+ <input type="text" name="pic_mass" size="8" maxlength="8" tabindex="<?= $tabindex++ ?>" value="<?= pun_htmlspecialchars($aconf['pic_mass']) . $disbl ?>" />&#160;<?= $lang_up['kbytes'] . ":\n" ?><br />
+ &#160;*&#160;<?= $lang_up['Install quality'] . "\n" ?>
+ <input type="text" name="pic_perc" size="4" maxlength="3" tabindex="<?= $tabindex++ ?>" value="<?= pun_htmlspecialchars($aconf['pic_perc']) . $disbl ?>" />&#160;%<br />
+ &#160;*&#160;<?= $lang_up['Size not more'] . "\n" ?>
+ <input type="text" name="pic_w" size="4" maxlength="4" tabindex="<?= $tabindex++ ?>" value="<?= pun_htmlspecialchars($aconf['pic_w']) . $disbl ?>" />&#160;x
+ <input type="text" name="pic_h" size="4" maxlength="4" tabindex="<?= $tabindex++ ?>" value="<?= pun_htmlspecialchars($aconf['pic_h']) . $disbl ?>" />&#160;<?= $lang_up['px'] . "\n" ?>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row"><label><?= $lang_up['thumb'] ?></label></th>
+ <td>
+ <input type="radio" tabindex="<?= ($tabindex++) . $disbl ?>" name="thumb" value="1"<?= $aconf['thumb'] == 1 ? ' checked="checked"' : '' ?> /> <strong><?= $lang_admin_common['Yes'] ?></strong>
+ &#160;&#160;&#160;
+ <input type="radio" tabindex="<?= ($tabindex++) . $disbl ?>" name="thumb" value="0"<?= $aconf['thumb'] == 0 ? ' checked="checked"' : '' ?> /> <strong><?= $lang_admin_common['No'] ?></strong>
+ <br />
+ &#160;*&#160;<?= $lang_up['thumb_size'] . "\n" ?>
+ <input type="text" name="thumb_size" size="4" maxlength="4" tabindex="<?= $tabindex++ ?>" value="<?= pun_htmlspecialchars($aconf['thumb_size']) . $disbl ?>" />&#160;<?= $lang_up['px'] . "\n" ?><br />
+ &#160;*&#160;<?= $lang_up['quality'] . "\n" ?>
+ <input type="text" name="thumb_perc" size="4" maxlength="3" tabindex="<?= $tabindex++ ?>" value="<?= pun_htmlspecialchars($aconf['thumb_perc']) . $disbl ?>" />&#160;%
+ </td>
+ </tr>
+ </table>
+ </div>
+ </fieldset>
+ </div>
+
+ <div class="inform">
+ <fieldset>
+ <legend><?= $lang_up['groups'] ?></legend>
+ <div class="infldset">
+ <div class="inbox">
+ <p>1* - <?= $lang_up['laws'] ?></p>
+ <p>2* - <?= $lang_up['maxsize_member'] ?></p>
+ <p>3* - <?= $lang_up['limit_member'] ?></p>
+ </div>
+ <table class="aligntop">
+ <thead>
+ <tr>
+ <th class="tcl" scope="col"><?= $lang_up['group'] ?></th>
+ <th class="tc2" scope="col">1*</th>
+ <th class="tcr" scope="col">2*</th>
+ <th class="tcr" scope="col">3*</th>
+ </tr>
+ </thead>
+ <tbody>
+<?php
+
+ $result = $db->query('SELECT * FROM ' . $db->prefix . 'groups ORDER BY g_id') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error());
+
+ while ($cur_group = $db->fetch_assoc($result)) {
+ if ($cur_group['g_id'] != PUN_GUEST) {
+ if (! isset($cur_group['g_up_ext'])) {
+ $cur_group['g_up_max'] = $cur_group['g_up_limit'] = 0;
+ $cur_group['g_up_ext'] = '';
+ }
+
+?>
+ <tr>
+ <td class="tcl"><?= pun_htmlspecialchars($cur_group['g_title']) ?></td>
+ <td class="tc2"><input type="text" name="g_up_ext[<?= $cur_group['g_id'] ?>]" value="<?= pun_htmlspecialchars($cur_group['g_up_ext']) ?>" tabindex="<?= $tabindex++ ?>" size="40" maxlength="255" /></td>
+ <td class="tcr"><input type="text" name="g_up_max[<?= $cur_group['g_id'] ?>]" value="<?= $cur_group['g_up_max'] / 100 ?>" tabindex="<?= $tabindex++ ?>" size="10" maxlength="10" /></td>
+ <td class="tcr"><input type="text" name="g_up_limit[<?= $cur_group['g_id'] ?>]" value="<?= $cur_group['g_up_limit'] ?>" tabindex="<?= $tabindex++ ?>" size="10" maxlength="10" /></td>
+ </tr>
+<?php
+
+ }
+ }
+
+?>
+ </tbody>
+ </table>
+ </div>
+ </fieldset>
+ </div>
+
+ <p class="submitend">
+ <input type="hidden" name="csrf_hash" value="<?= $upf_token ?>" />
+ <input type="submit" name="update" value="<?= $lang_up['Update'] ?>" tabindex="<?= $tabindex++ ?>" />
+ </p>
+ <div class="inform">
+ <fieldset>
+ <legend><?= $lang_up['legend_1'] ?></legend>
+ <div class="infldset">
+ <label for="mo"><?= $lang_up['mo'] ?></label> <input type="text" name="mo" id="mo" size="15" tabindex="<?= $tabindex++ ?>" /> <input type="button" value="<?= $lang_up['convert'] ?>" tabindex="<?= $tabindex++ ?>" onclick="javascript:document.getElementById('ko').value=document.getElementById('mo').value*1024; document.getElementById('o').value=document.getElementById('mo').value*1048576;" />
+ <label for="ko"><?= $lang_up['ko'] ?></label> <input type="text" name="ko" id="ko" size="15" tabindex="<?= $tabindex++ ?>" /> <input type="button" value="<?= $lang_up['convert'] ?>" tabindex="<?= $tabindex++ ?>" onclick="javascript:document.getElementById('mo').value=document.getElementById('ko').value/1024; document.getElementById('o').value=document.getElementById('ko').value*1024;"/>
+ <label for="o"><?= $lang_up['o'] ?></label> <input type="text" name="o" id="o" size="15" tabindex="<?= $tabindex++ ?>" /> <input type="button" value="<?= $lang_up['convert'] ?>" tabindex="<?= $tabindex++ ?>" onclick="javascript:document.getElementById('mo').value=document.getElementById('o').value/1048576; document.getElementById('ko').value=(document.getElementById('o').value*1024)/1048576;"/>
+ </div>
+ </fieldset>
+ </div>
+ </form>
+ </div>
+<?php
+
+}
+
+// #############################################################################
+
+$files = [];
+if (is_dir(PUN_ROOT . $upf_mem)) {
+ $af = [];
+ $ad = scandir(PUN_ROOT . $upf_mem);
+
+ foreach($ad as $f) {
+ if ('.' === $f[0] || ! is_dir(PUN_ROOT . $upf_mem . $f)) {
+ continue;
+ }
+
+ $dir = $upf_mem . $f . '/';
+ $open = opendir(PUN_ROOT . $dir);
+ while (false !== ($file = readdir($open))) {
+ if (
+ '.' === $file[0]
+ || '#' === $file[0]
+ || 'mini_' === substr($file, 0, 5)
+ || true === $upf_class->inBlackList(substr(strrchr($file, '.'), 1))
+ || ! is_file(PUN_ROOT . $dir . $file)
+ ) {
+ continue;
+ }
+
+ $time = filemtime(PUN_ROOT . $dir . $file) . $file . $f;
+ $af[$time] = $dir . $file;
+ }
+ closedir($open);
+ }
+
+ unset($ad);
+
+ if (! empty($af)) {
+ $num_pages = ceil(count($af) / PLUGIN_NF);
+ $p = (empty($_GET['p']) || $_GET['p'] < 1) ? 1 : (int) $_GET['p'];
+ if ($p > $num_pages) {
+ header('Location: ' . PLUGIN_URL . '&p=' . $num_pages . '#gofile');
+ exit;
+ }
+
+ $start_from = PLUGIN_NF * ($p - 1);
+
+ // Generate paging links
+ $paging_links = '<span class="pages-label">' . $lang_common['Pages'] . ' </span>' . paginate($num_pages, $p, PLUGIN_URL);
+ $paging_links = preg_replace('%href="([^">]+)"%', 'href="$1#gofile"', $paging_links);
+
+ krsort($af);
+ $files = array_slice($af, $start_from, PLUGIN_NF);
+ unset($af);
+ }
+}
+
+?>
+ <h2 id="gofile" class="block2"><span><?= $lang_up['Member files'] ?></span></h2>
+ <div class="box">
+<?php
+
+if (empty($files)) {
+
+?>
+ <div class="inbox">
+ <p><?= $lang_up['No upfiles'] ?></p>
+ </div>
+<?php
+
+} else {
+
+?>
+
+ <div class="inbox">
+ <div class="pagepost">
+ <p class="pagelink conl"><?= $paging_links ?></p>
+ </div>
+ </div>
+
+ <form method="post" action="<?= PLUGIN_URL . ($p > 1 ? '&amp;p=' . $p : '') . '#gofile' ?>">
+ <div class="inform">
+ <p class="submittop">
+ <input type="hidden" name="csrf_hash" value="<?= $upf_token ?>" />
+ <input type="submit" name="update_thumb" value="<?= $lang_up['update_thumb'] . $stthumb ?>" />
+ </p>
+ <div class="infldset">
+ <table id="upf-table" class="aligntop">
+ <thead>
+ <tr>
+ <th class="upf-c1" scope="col"><?= $lang_up['th0'] ?></th>
+ <th class="upf-c2" scope="col"><?= $lang_up['th1'] ?></th>
+ <th class="upf-c3" scope="col"><?= $lang_up['th2'] ?></th>
+ <th class="upf-c4" scope="col"><input type="submit" value="<?= $lang_up['delete'] ?>" name="delete" tabindex="<?= $tabindex++ ?>" /></th>
+ </tr>
+ </thead>
+ <tfoot>
+ <tr>
+ <th class="upf-c1"><?= $lang_up['th0'] ?></th>
+ <th class="upf-c2"><?= $lang_up['th1'] ?></th>
+ <th class="upf-c3"><?= $lang_up['th2'] ?></th>
+ <th class="upf-c4"><input type="submit" value="<?= $lang_up['delete'] ?>" name="delete" tabindex="<?= $tabindex++ ?>" /></th>
+ </tr>
+ </tfoot>
+ <tbody>
+<?php
+
+ // данные по юзерам
+ $au = [];
+ foreach ($files as $file) {
+ if (preg_match($upf_regx, $file, $fi)) {
+ $id = (int) $fi[1];
+ $au[$id] = $id;
+ }
+ }
+ $result = $db->query('SELECT id, username, group_id FROM ' . $db->prefix . 'users WHERE id IN(' . implode(',', $au) . ')') or error('Unable to fetch user information', __FILE__, __LINE__, $db->error());
+ $au = $ag = [];
+ while ($u = $db->fetch_assoc($result)) {
+ $au[$u['id']] = $u['username'];
+ $ag[$u['id']] = $u['group_id'];
+ }
+ $db->free_result($result);
+ // данные по группам
+ $extsup = [];
+ $result = $db->query('SELECT * FROM ' . $db->prefix . 'groups') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error());
+ while ($g = $db->fetch_assoc($result)) {
+ if (isset($g['g_up_ext'])) {
+ $extsup[$g['g_id']] = explode(',', $g['g_up_ext'] . ',' . strtoupper($g['g_up_ext']));
+ } else {
+ $extsup[$g['g_id']] = [];
+ }
+ }
+ $db->free_result($result);
+
+ $upf_img_exts = ['jpg', 'jpeg', 'gif', 'png', 'bmp', 'webp'];
+ foreach ($files as $file) {
+ if (! preg_match($upf_regx, $file, $fi)) {
+ continue;
+ }
+
+ $fancybox = in_array(strtolower($fi[3]), $upf_img_exts) ? '" class="fancy_zoom" rel="vi001' : '';
+ $dir = $upf_mem . $fi[1] . '/';
+ $size_file = file_size(filesize(PUN_ROOT . $file));
+ $miniature = $dir . 'mini_' . $fi[2] . '.' . $fi[3];
+
+ if (
+ isset($_POST['update_thumb'])
+ && 1 == $aconf['thumb']
+ && true === $upf_class->loadFile(PUN_ROOT . $file)
+ && true === $upf_class->isImage()
+ && false !== $upf_class->loadImage()
+ ) {
+ $upf_class->setImageQuality($aconf['thumb_perc']);
+ $scaleResize = $upf_class->resizeImage(null, $aconf['thumb_size']);
+
+ if (false !== $scaleResize) {
+ if ($scaleResize < 1) {
+ $upf_class->saveImage(PUN_ROOT . $miniature, true);
+ } else {
+ copy(PUN_ROOT . $file, PUN_ROOT . $miniature);
+ chmod(PUN_ROOT . $miniature, 0644);
+ }
+ }
+ }
+
+?>
+ <tr>
+ <td class="upf-c1"><?= (isset($au[$fi[1]]) ? pun_htmlspecialchars($au[$fi[1]]) : '&#160;') ?></td>
+ <td class="upf-c2"><a href="<?= pun_htmlspecialchars($file) ?>"><?= pun_htmlspecialchars($fi[2]) ?></a> [<?= pun_htmlspecialchars($size_file) ?>].[<?= (isset($ag[$fi[1]]) && in_array($fi[3], $extsup[$ag[$fi[1]]]) ? pun_htmlspecialchars($fi[3]) : '<span style="color: #ff0000"><strong>' . pun_htmlspecialchars($fi[3]) . '</strong></span>') ?>]</td>
+<?php
+
+ if (is_file(PUN_ROOT . $miniature)) {
+
+?>
+ <td class="upf-c3">
+ <a href="<?= pun_htmlspecialchars($file) . $fancybox ?>">
+ <img src="<?= pun_htmlspecialchars($miniature) ?>" alt="<?= pun_htmlspecialchars($fi[2]) ?>" />
+ </a>
+ </td>
+<?php
+
+ } else {
+
+?>
+ <td class="upf-c3"><?= $lang_up['no_preview'] ?></td>
+<?php
+
+ }
+
+?>
+ <td class="upf-c4"><input type="checkbox" name="delete_f[]" value="<?= pun_htmlspecialchars($file) ?>" tabindex="<?= $tabindex++ ?>" /></td>
+ </tr>
+<?php
+
+ } // end foreach
+
+?>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </form>
+
+ <div class="inbox">
+ <div class="pagepost">
+ <p class="pagelink conl"><?= $paging_links ?></p>
+ </div>
+ </div>
+
+<?php
+
+} // end if
+
+?>
+ </div>
+ </div>
+<?php
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..c9e01e2
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,157 @@
+##
+##
+## Mod title: Upload Mod
+##
+## Mod version: 3.0.3
+## Works on FluxBB: 1.5.11
+## Release date: 2020-07-28
+## Review date: YYYY-MM-DD (Leave unedited)
+## Author: Visman (mio.visman@yandex.ru)
+## On a basis "Uploadile" by bagu (https://fluxbb.org/resources/mods/uploadile/)
+##
+## Description: Users can upload files and pictures on a forum at directly in post.
+## Юзеры могут загружать файлы и картинки на форум непосредственно при постинге сообщений.
+##
+## v 1.2.0
+## French is added. Thanks to Bloody.
+## Has added management of the uploaded files in a profile.
+## В профиль добавил возможность загрузки/удаления файлов.
+##
+## v 1.3.0
+## German is added. Thanks to cyberman.
+## For FluxBB v.1.5.0
+## Settings for each group of users.
+## Administration of files is changed.
+##
+## v 1.3.1
+## Fix bug in create thumbnails for .jpg and .jpe files. Thanks to Ian Stanistreet.
+##
+## v 1.3.2
+## For FluxBB v.1.5.1
+## Fix AP_Upload.php
+##
+## v 2.0 beta
+## For FluxBB v.1.5.4
+## Новый вид списка загруженных файлов.
+## New type of the list of the uploaded files.
+##
+## v 2.0.1
+## Fix AP_Upload.php. Thanks to Quy.
+##
+## v 2.2.0 beta
+## New uploader for browsers with FormData support (https://caniuse.com/#search=FormData).
+## Extended blacklist of file types for upload.
+## New .htaccess for img/members/ folder.
+## Automatically add bb-code to the message when uploading a file.
+##
+## v 2.2.1 beta
+## Fix AP_Upload.php for SQLite.
+##
+## v 2.2.2 beta
+## Updated .htaccess for img/members/ folder.
+## A group of administrators can set limits for themselves.
+##
+## v 2.3.0 beta
+## Maximum "Space allocated to members" increased from 2 GiB to 20 TiB. For 32 and 64-bit systems.
+## Maximum "Max size members can upload" remained unchanged and depends on the server/PHP settings and OS bit depth.
+##
+## v 3.0.0 beta
+## Added support for ImageMagick graphics library.
+## The file mentioned in the forum posts cannot be deleted.
+## The search for the mention of the file goes through the search index and further LIKE in the message.
+## Admin can delete files without checks in the admin plugin.
+##
+## v 3.0.1
+## Minor fix: Remove double serialization during automatic reconfiguration of the modification.
+## https://github.com/MioVisman/FluxBB_by_Visman/commit/61fcae2702b5981ecfe277f01792e38d6034214d
+##
+## v 3.0.3
+## Fix for Opera 12.18
+## Fix english language
+##
+##
+##
+## Repository URL: https://fluxbb.org/resources/mods/?s=author&t=Visman&v=all&o=name
+## https://fluxbb.qb7.ru/forum/viewtopic.php?id=3380
+##
+## Affected files: footer.php
+## include/functions.php
+##
+## Affects DB: No (Yes in plugin)
+##
+## Notes: Russian/English/French/German
+## Functions move_uploaded_file(), mkdir(), opendir() and others
+## must be enabled in your Website and this one must accept
+## resizing pictures with GD.
+##
+## DISCLAIMER: Please note that "mods" are not officially supported by
+## FluxBB. Installation of this modification is done at
+## your own risk. Backup your forum database and any and
+## all applicable files before proceeding.
+##
+##
+
+
+#
+#---------[ 1. UPLOAD ]-------------------------------------------------------
+#
+
+upfiles.php to /
+img/ to /img/
+include/ to /include/
+js/ to /js/
+lang/ to /lang/
+plugins/ to /plugins/
+style/ to /style/
+
+#
+#---------[ 2. OPEN ]---------------------------------------------------------
+#
+
+footer.php
+
+#
+#---------[ 3. FIND ]---------------------------------------------------------
+#
+
+ob_start();
+
+#
+#---------[ 4. AFTER, ADD ]---------------------------------------------------
+#
+
+require PUN_ROOT.'include/uploadf.php';
+
+#
+#---------[ 5. SAVE ]---------------------------------------------------------
+#
+
+footer.php
+
+#
+#---------[ 6. OPEN ]---------------------------------------------------------
+#
+
+include/functions.php
+
+#
+#---------[ 7. FIND ]---------------------------------------------------------
+#
+
+ <li<?php if ($page == 'privacy') echo ' class="isactive"'; ?>><a href="profile.php?section=privacy&amp;id=<?php echo $id ?>"><?php echo $lang_profile['Section privacy'] ?></a></li>
+
+#
+#---------[ 8. AFTER, ADD ]---------------------------------------------------
+#
+
+<?php require PUN_ROOT.'include/uploadp.php'; ?>
+
+#
+#---------[ 9. SAVE ]---------------------------------------------------------
+#
+
+include/functions.php
+
+#
+# Adjust this plugin in Administration - Plugins menu - Upload
+#
diff --git a/style/imports/upfiles.css b/style/imports/upfiles.css
new file mode 100644
index 0000000..e3104ba
--- /dev/null
+++ b/style/imports/upfiles.css
@@ -0,0 +1,171 @@
+/* UpFiles
+----------------------------------------------------------------*/
+#brdmain #upf-block .pagepost {
+ overflow: hidden;
+}
+
+#upf-container {
+ overflow: auto;
+ padding: 0;
+}
+
+ul#upf-list {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+
+#upf-list li {
+ display: block;
+ float: left;
+ margin: 3px;
+ padding: 3px;
+ text-align: center;
+ border: 1px solid;
+ position: relative;
+}
+
+.upf-fmess #upf-list-fls {
+ min-width: auto;
+}
+
+.upf-fmess ul#upf-list {
+ white-space: nowrap;
+}
+
+.upf-fmess #upf-list li {
+ display: inline-block;
+ float: none;
+}
+
+.upf-but a, .upf-but a:link, .upf-but a:visited, .upf-but a:hover, .upf-but a:active, .upf-but a:focus {
+ text-decoration: none;
+}
+
+.upf-file img {
+ max-height: 100%;
+ border: none;
+ max-width: 100%;
+}
+
+#upf-list .upf-name {
+ height: 26px;
+ text-align: left;
+ word-wrap: break-word;
+ min-width: 120px;
+}
+
+#upf-list .upf-size {
+ height: 26px;
+}
+
+#upf-list .upf-name span, #upf-list .upf-size span {
+ line-height: 26px;
+}
+
+.upf-delete {
+ position: absolute;
+ top: 0;
+ right: 0;
+}
+
+.upf-insert {
+ position: absolute;
+ bottom: 0;
+ right: 0;
+}
+
+.upf-insert-t {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+}
+
+.upf-delete span {
+ background: url("../../img/upf-x.png") no-repeat scroll 5px 5px;
+ float: right;
+}
+
+.upf-delete .upf-loading span,
+.upf-removal .upf-delete span {
+ background: url("../../img/loading.gif") no-repeat scroll 5px 5px;
+}
+
+.upf-insert span {
+ background: url("../../img/upf-i.png") no-repeat scroll 5px 5px;
+ float: right;
+}
+
+.upf-insert-t span {
+ background: url("../../img/upf-it.png") no-repeat scroll 5px 5px;
+ float: left;
+}
+
+.upf-but a span {
+ height: 26px;
+ width: 26px;
+ opacity: 0.3;
+}
+
+.upf-but a:hover span {
+ opacity: 1;
+ background-color: #999999;
+}
+
+#upf-legend {
+ border: 1px solid #4E642D;
+ width: 100%;
+}
+
+#upf-legend div {
+ border-right: 2px solid #4E642D;
+ background-color: #6C8A3F;
+ text-align: right;
+ width: 100%;
+}
+
+#upf-legend div span {
+ filter: invert(1) grayscale(1) contrast(9);
+}
+
+#upf-table th, #upf-table td {
+ text-align: center;
+ width: auto;
+}
+
+#upf-table .upf-c2 {
+ width: 80%;
+ text-align: left;
+}
+
+#upf-table .upf-c3 img {
+ border: none;
+ max-width: 150px;
+}
+
+#upf-block #upf-table td {
+ vertical-align: middle;
+}
+
+#upf-- .upf-delete,
+#upf-- .upf-insert,
+#upf-- .upf-insert-t {
+ display: none;
+}
+
+#upf-button.upf-uploading {
+ display: none;
+}
+
+#upf-button.upf-uploading + span:before {
+ height: 16px;
+ width: 26px;
+ background: url("../../img/loading.gif") no-repeat scroll left center;
+ display: inline-block;
+ content: " ";
+ vertical-align: middle;
+}
+
+.upf-fmess #upf-- {
+ visibility: hidden;
+}
diff --git a/upfiles.php b/upfiles.php
new file mode 100644
index 0000000..94d615e
--- /dev/null
+++ b/upfiles.php
@@ -0,0 +1,732 @@
+<?php
+
+/**
+ * Copyright (C) 2011-2019 Visman (mio.visman@yandex.ru)
+ * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
+ */
+
+function upf_return_json($data)
+{
+ global $db;
+
+ $db->end_transaction();
+ $db->close();
+
+ if (function_exists('forum_http_headers')) {
+ forum_http_headers('application/json');
+ } else {
+ header('Content-type: application/json; charset=utf-8');
+ header('Cache-Control: no-cache, no-store, must-revalidate');
+ }
+
+ exit(json_encode($data));
+}
+
+function upf_get_pg($key, $default = null)
+{
+ if (isset($_POST[$key])) {
+ return $_POST[$key];
+ } else if (isset($_GET[$key])) {
+ return $_GET[$key];
+ } else {
+ return $default;
+ }
+}
+
+function upf_message($message, $no_back_link = false, $http_status = null)
+{
+ global $upf_ajax;
+
+ if ($upf_ajax) {
+ upf_return_json(['error' => $message]);
+ } else {
+ message($message, $no_back_link, $http_status);
+ }
+}
+
+function upf_redirect($destination_url, $message)
+{
+ global $upf_ajax, $lang_up;
+
+ if ($upf_ajax) {
+ upf_return_json(['error' => $message]);
+ } else {
+ redirect($destination_url, $lang_up['Error'] . $message);
+ }
+}
+
+define('PUN_ROOT', dirname(__FILE__) . '/');
+require PUN_ROOT . 'include/common.php';
+
+define('PLUGIN_REF', pun_htmlspecialchars('upfiles.php'));
+define('PLUGIN_NF', 25);
+
+$upf_ajax = ('1' == upf_get_pg('ajx'));
+$upf_action = upf_get_pg('action');
+$upf_page = (int) upf_get_pg('p', 1);
+
+if ($pun_user['g_read_board'] == '0') {
+ upf_message($lang_common['No view'], false, '403 Forbidden');
+}
+
+if ($pun_user['is_guest'] || empty($pun_user['g_up_ext']) || empty($pun_config['o_upload_config']) || $upf_page < 1) {
+ upf_message($lang_common['Bad request'], false, '404 Not Found');
+}
+
+// Any action must be confirmed by token
+if (null !== $upf_action) {
+ if (function_exists('csrf_hash')) {
+ if ($upf_ajax) {
+ $errors = [];
+ }
+ confirm_referrer(PLUGIN_REF);
+ if ($upf_ajax) {
+ if (! empty($errors)) {
+ upf_return_json(['error' => array_pop($errors)]);
+ }
+ unset($errors);
+ }
+ } else {
+ check_csrf(upf_get_pg('csrf_hash'));
+ }
+}
+
+require PUN_ROOT . 'include/upload.php';
+
+if (! isset($_GET['id'])) {
+ $id = $pun_user['id'];
+
+ define('PUN_HELP', 1);
+ define('PLUGIN_URL', PLUGIN_REF);
+ define('PLUGIN_URLD', PLUGIN_URL.'?');
+ $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_up['popup_title']);
+ $fpr = false;
+ $upf_exts = $pun_user['g_up_ext'];
+ $upf_limit = $pun_user['g_up_limit'];
+ $upf_max_size = $pun_user['g_up_max'];
+ $upf_dir_size = $pun_user['upload_size'];
+} else {
+ $id = intval($_GET['id']);
+ if ($id < 2 || ($pun_user['g_id'] != PUN_ADMIN && $id != $pun_user['id'])) {
+ upf_message($lang_common['Bad request'], false, '404 Not Found');
+ }
+
+ $result = $db->query('SELECT u.username, u.upload_size, g.g_up_ext, g.g_up_max, g.g_up_limit FROM ' . $db->prefix . 'users AS u INNER JOIN '.$db->prefix.'groups AS g ON u.group_id=g.g_id WHERE u.id=' . $id) or error('Unable to fetch user information', __FILE__, __LINE__, $db->error());
+ $user_info = $db->fetch_row($result);
+
+ if (!$user_info) {
+ upf_message($lang_common['Bad request'], false, '404 Not Found');
+ }
+
+ list($usname, $upf_dir_size, $upf_exts, $upf_max_size, $upf_limit) = $user_info;
+
+ define('PLUGIN_URL', PLUGIN_REF . '?id=' . $id);
+ define('PLUGIN_URLD', PLUGIN_URL . '&amp;');
+ $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_common['Profile'], $lang_up['popup_title']);
+ $fpr = true;
+}
+
+$upf_limit *= 1048576;
+$upf_max_size = (int) min(10485.76 * $upf_max_size, $upf_class->size(ini_get('upload_max_filesize')), $upf_class->size(ini_get('post_max_size')));
+$upf_dir_size *= 10485.76;
+
+if ($pun_user['g_id'] != PUN_ADMIN && $upf_limit * $upf_max_size == 0) {
+ upf_message($lang_common['Bad request'], false, '404 Not Found');
+}
+
+$upf_percent = min(100, empty($upf_limit) ? 100 : ceil($upf_dir_size * 100 / $upf_limit));
+
+$upf_dir = 'img/members/' . $id . '/';
+$upf_conf = unserialize($pun_config['o_upload_config']);
+$upf_exts = explode(',', $upf_exts . ',' . strtoupper($upf_exts));
+$upf_new_files = [];
+
+// #############################################################################
+
+// Удаление файла
+if ('delete' === $upf_action) {
+ $error = false;
+
+ if (
+ is_dir(PUN_ROOT . $upf_dir)
+ && preg_match('%^([\w-]+)\.(\w+)$%', pun_trim(upf_get_pg('file')), $matches)
+ && false === $upf_class->inBlackList($matches[2])
+ && 'mini_' !== substr($matches[1], 0, 5)
+ && is_file(PUN_ROOT . $upf_dir . $matches[1] . '.' . $matches[2])
+ ) {
+ include PUN_ROOT . 'include/search_idx.php';
+ $like = '/' . $upf_dir . $matches[1] . '.' . $matches[2];
+ $words = split_words(utf8_strtolower($like), true);
+
+ if (count($words) > 2) {
+ $words = array_diff($words, ['img', 'members']);
+ }
+ if (count($words) > 2) {
+ $words = array_diff($words, ['jpg', 'jpeg', 'png', 'gif', 'zip', 'rar', 'webp']);
+ }
+
+ $count = count($words);
+
+ if ($count > 0) {
+ if (1 == $count) {
+ $query = 'SELECT COUNT(m.post_id) AS numposts FROM ' . $db->prefix . 'search_words AS w INNER JOIN ' . $db->prefix . 'search_matches AS m ON m.word_id = w.id INNER JOIN ' . $db->prefix . 'posts AS p ON p.id=m.post_id WHERE w.word=\'' . $db->escape(array_pop($words)) . '\' AND p.message LIKE \'%' . $db->escape($like) . '%\'';
+ } else {
+ $query = 'SELECT COUNT(p.id) AS numposts FROM ' . $db->prefix . 'posts AS p WHERE p.id IN (SELECT m.post_id FROM ' . $db->prefix . 'search_words AS w INNER JOIN ' . $db->prefix . 'search_matches AS m ON m.word_id = w.id WHERE w.word IN (\'' . implode('\',\'', array_map([$db, 'escape'], $words)) . '\') GROUP BY m.post_id HAVING COUNT(m.post_id)=' . $count . ') AND p.message LIKE \'%' . $db->escape($like) . '%\'';
+ }
+
+ $result = $db->query($query) or error('Unable to fetch search information', __FILE__, __LINE__, $db->error());
+ $count = $db->result($result);
+ }
+
+ if (empty($count) && unlink(PUN_ROOT . $upf_dir . $matches[1] . '.' . $matches[2])) {
+ if (is_file(PUN_ROOT . $upf_dir . 'mini_' . $matches[1] . '.' . $matches[2])) {
+ unlink(PUN_ROOT . $upf_dir . 'mini_' . $matches[1] . '.' . $matches[2]);
+ }
+
+ $upf_dir_size = $upf_class->dirSize(PUN_ROOT . $upf_dir);
+ $upf_percent = min(100, empty($upf_limit) ? 100 : ceil($upf_dir_size * 100 / $upf_limit));
+
+ $db->query('UPDATE ' . $db->prefix . 'users SET upload_size=' . ((int) ($upf_dir_size / 10485.76)) . ' WHERE id=' . $id) or error($lang_up['Error DB ins-up'], __FILE__, __LINE__, $db->error());
+ } else {
+ $error = true;
+ }
+ } else {
+ $error = true;
+ }
+
+ if ($error) {
+ if ($pun_config['o_redirect_delay'] < 5) {
+ $pun_config['o_redirect_delay'] = 5;
+ }
+ $message = empty($count) ? $lang_up['Error delete'] : sprintf($lang_up['Error usage'], $count);
+ upf_redirect(($upf_page < 2 ? PLUGIN_URL : PLUGIN_URLD . 'p=' . $upf_page ) . '#gofile', $message);
+ } else if (! $upf_ajax) {
+ redirect(($upf_page < 2 ? PLUGIN_URL : PLUGIN_URLD . 'p=' . $upf_page ) . '#gofile', $lang_up['Redirect delete']);
+ }
+}
+
+// Загрузка файла
+else if ('upload' === $upf_action && isset($_FILES['upfile']) && $id == $pun_user['id']) {
+ $upf_redir_delay = $pun_config['o_redirect_delay'];
+ if ($upf_redir_delay < 5) {
+ $pun_config['o_redirect_delay'] = 5;
+ }
+
+ // Ошибка при загрузке
+ if (! empty($_FILES['upfile']['error'])) {
+ switch($_FILES['upfile']['error']) {
+ case UPLOAD_ERR_INI_SIZE:
+ upf_redirect(PLUGIN_URL, $lang_up['UPLOAD_ERR_INI_SIZE']);
+ break;
+ case UPLOAD_ERR_FORM_SIZE:
+ upf_redirect(PLUGIN_URL, $lang_up['UPLOAD_ERR_FORM_SIZE']);
+ break;
+ case UPLOAD_ERR_PARTIAL:
+ upf_redirect(PLUGIN_URL, $lang_up['UPLOAD_ERR_PARTIAL']);
+ break;
+ case UPLOAD_ERR_NO_FILE:
+ upf_redirect(PLUGIN_URL, $lang_up['UPLOAD_ERR_NO_FILE']);
+ break;
+ case UPLOAD_ERR_NO_TMP_DIR:
+ upf_redirect(PLUGIN_URL, $lang_up['UPLOAD_ERR_NO_TMP_DIR']);
+ break;
+ case UPLOAD_ERR_CANT_WRITE:
+ upf_redirect(PLUGIN_URL, $lang_up['UPLOAD_ERR_CANT_WRITE']);
+ break;
+ case UPLOAD_ERR_EXTENSION:
+ upf_redirect(PLUGIN_URL, $lang_up['UPLOAD_ERR_EXTENSION']);
+ break;
+ default:
+ upf_redirect(PLUGIN_URL, $lang_up['UPLOAD_ERR_UNKNOWN']);
+ break;
+ }
+ }
+
+ if (false === $upf_class->loadFile($_FILES['upfile']['tmp_name'], $_FILES['upfile']['name'])) {
+ upf_redirect(PLUGIN_URL, $lang_up['Unknown failure'] . ' (' . pun_htmlspecialchars($upf_class->getError()) . ')');
+ }
+
+ // расширение
+ if (! in_array($upf_class->getFileExt(), $upf_exts)) {
+ upf_redirect(PLUGIN_URL, $lang_up['Bad type']);
+ }
+
+ // максимальный размер файла
+ if ($_FILES['upfile']['size'] > $upf_max_size) {
+ upf_redirect(PLUGIN_URL, $lang_up['Too large'] . ' (' . pun_htmlspecialchars(file_size($upf_max_size)) . ').');
+ }
+
+ // допустимое пространство
+ if ($_FILES['upfile']['size'] + $upf_dir_size > $upf_limit) {
+ upf_redirect(PLUGIN_URL, $lang_up['Error space']);
+ }
+
+ // подозрительное содержимое
+ if (false !== $upf_class->isUnsafeContent()) {
+ upf_redirect(PLUGIN_URL, $lang_up['Error inject']);
+ }
+
+ $upf_class->prepFileName();
+
+ if (! is_dir(PUN_ROOT . 'img/members/')) {
+ mkdir(PUN_ROOT . 'img/members', 0755);
+ }
+ if (! is_dir(PUN_ROOT . $upf_dir)) {
+ mkdir(PUN_ROOT . $upf_dir, 0755);
+ }
+
+ $saveImage = false;
+ $fileinfo = false;
+
+ // сохранение картинки
+ if (true === $upf_class->isImage()) {
+ $upf_class->setImageQuality($upf_conf['pic_perc']);
+
+ if (false === $upf_class->loadImage()) {
+ upf_redirect(PLUGIN_URL, $lang_up['Error img'] . ' (' . pun_htmlspecialchars($upf_class->getError()) . ')');
+ }
+
+ if ($_FILES['upfile']['size'] > 1024 * $upf_conf['pic_mass'] && $upf_class->isResize()) {
+ if (false === $upf_class->resizeImage($upf_conf['pic_w'], $upf_conf['pic_h'])) {
+ upf_redirect(PLUGIN_URL, $lang_up['Error no mod img']);
+ }
+
+ $saveImage = true;
+ $fileinfo = $upf_class->saveImage(PUN_ROOT . $upf_dir . $upf_class->getFileName() . '.' . $upf_class->getFileExt(), false);
+
+ if (false === $fileinfo) {
+ upf_redirect(PLUGIN_URL, $lang_up['Move failed'] . ' (' . pun_htmlspecialchars($upf_class->getError()) . ')'); //????
+ }
+
+ // картика стала больше после ресайза
+ if (filesize($fileinfo['path']) > $_FILES['upfile']['size']) {
+ $saveImage = false;
+ unlink($fileinfo['path']);
+ }
+ }
+ }
+
+ // сохранение файла
+ if (false === $saveImage) {
+ if (is_array($fileinfo)) {
+ $fileinfo = $upf_class->saveFile($fileinfo['path'], true);
+ } else {
+ $fileinfo = $upf_class->saveFile(PUN_ROOT . $upf_dir . $upf_class->getFileName() . '.' . $upf_class->getFileExt(), false);
+ }
+
+ if (false === $fileinfo) {
+ upf_redirect(PLUGIN_URL, $lang_up['Move failed'] . ' (' . pun_htmlspecialchars($upf_class->getError()) . ')'); //????
+ }
+ }
+
+ // превью
+ if (true === $upf_class->isImage() && 1 == $upf_conf['thumb'] && $upf_class->isResize()) {
+ $upf_class->setImageQuality($upf_conf['thumb_perc']);
+
+ $scaleResize = $upf_class->resizeImage(null, $upf_conf['thumb_size']);
+ if (false !== $scaleResize) {
+ $path = PUN_ROOT . $upf_dir . 'mini_' . $fileinfo['filename'] . '.' . $fileinfo['extension'];
+
+ if ($scaleResize < 1) {
+ $upf_class->saveImage($path, true);
+ } else {
+ copy($fileinfo['path'], $path);
+ chmod($path, 0644);
+ }
+ }
+ }
+
+ $upf_dir_size = $upf_class->dirSize(PUN_ROOT . $upf_dir);
+ $upf_percent = min(100, empty($upf_limit) ? 100 : ceil($upf_dir_size * 100 / $upf_limit));
+ $db->query('UPDATE ' . $db->prefix . 'users SET upload_size=' . ((int) ($upf_dir_size / 10485.76)) . ' WHERE id=' . $id) or error($lang_up['Error DB ins-up'], __FILE__, __LINE__, $db->error());
+
+ if ($upf_ajax) {
+ $upf_page = 1;
+ $upf_new_files[$fileinfo['filename'] . '.' . $fileinfo['extension']] = true;
+ } else {
+ $pun_config['o_redirect_delay'] = $upf_redir_delay;
+ redirect(PLUGIN_URL, $lang_up['Redirect upload']);
+ }
+}
+
+// Unknown failure
+else if (($upf_ajax && 'view' !== $upf_action) || (! $upf_ajax && ! empty($_POST))) {
+ upf_redirect(PLUGIN_URL, $lang_up['Unknown failure']);
+}
+
+// #############################################################################
+
+$files = [];
+$count = 0;
+$num_pages = 1;
+if (is_dir(PUN_ROOT . $upf_dir)) {
+ $tmp = get_base_url(true) . '/' . $upf_dir;
+ foreach (new DirectoryIterator(PUN_ROOT . $upf_dir) as $file) {
+ if (!$file->isFile() || true === $upf_class->inBlackList($file->getExtension())) {
+ continue;
+ }
+
+ $filename = $file->getFilename();
+ if ('#' === $filename[0] || 'mini_' === substr($filename, 0, 5)) {
+ continue;
+ }
+
+ ++$count;
+ if (empty($upf_new_files) || isset($upf_new_files[$filename])) {
+ $files[$file->getMTime() . $filename] = [
+ 'filename' => $filename,
+ 'ext' => $file->getExtension(),
+ 'alt' => pun_strlen($filename) > 18 ? utf8_substr($filename, 0, 16) . '…' : $filename,
+ 'size' => file_size($file->getSize()),
+ 'url' => $tmp . $filename,
+ 'mini' => is_file(PUN_ROOT . $upf_dir . 'mini_' . $filename) ? $tmp . 'mini_' . $filename : null,
+ ];
+ }
+ }
+ if (! empty($files)) {
+ $num_pages = ceil($count / PLUGIN_NF);
+ if ($upf_page > $num_pages && !$upf_ajax) {
+ header('Location: ' . str_replace('&amp;', '&', PLUGIN_URLD) . 'p=' . $num_pages . '#gofile');
+ exit;
+ }
+
+ krsort($files);
+
+ if (empty($upf_new_files)) {
+ $start_from = PLUGIN_NF * ($upf_page - 1);
+ $files = array_slice($files, $start_from, PLUGIN_NF);
+ }
+ }
+}
+
+if ($upf_ajax) {
+ upf_return_json([
+ 'size' => file_size($upf_dir_size),
+ 'percent' => $upf_percent,
+ 'pages' => $num_pages,
+ 'files' => $files,
+ ]);
+}
+
+if (! isset($page_head)) {
+ $page_head = [];
+}
+
+if (file_exists(PUN_ROOT . 'style/' . $pun_user['style'] . '/upfiles.css')) {
+ $page_head['pmsnewstyle'] = '<link rel="stylesheet" type="text/css" href="style/' . $pun_user['style'] . '/upfiles.css" />';
+} else {
+ $page_head['pmsnewstyle'] = '<link rel="stylesheet" type="text/css" href="style/imports/upfiles.css" />';
+}
+
+define('PUN_ACTIVE_PAGE', 'profile');
+require PUN_ROOT . 'header.php';
+$tpl_main = str_replace('id="punhelp"', 'id="punupfiles"', $tpl_main);
+
+$tabindex = 1;
+
+$upf_token = function_exists('csrf_hash') ? csrf_hash() : pun_csrf_token();
+
+if ($fpr) {
+ // Load the profile.php language file
+ require PUN_ROOT . 'lang/' . $pun_user['language'] . '/profile.php';
+
+ generate_profile_menu('upload');
+}
+
+if ($id == $pun_user['id']) {
+
+?>
+ <div class="blockform">
+ <h2><span><?= $lang_up['titre_2'] ?></span></h2>
+ <div class="box">
+ <form method="post" action="<?= PLUGIN_URL ?>" enctype="multipart/form-data">
+ <div class="inform">
+ <fieldset>
+ <legend><?= $lang_up['legend'] ?></legend>
+ <div class="infldset">
+ <input type="hidden" name="csrf_hash" value="<?= $upf_token ?>" />
+ <input type="hidden" name="action" value="upload" />
+ <input type="hidden" name="MAX_FILE_SIZE" value="<?= $upf_max_size ?>" />
+ <p><?= $lang_up['fichier'] ?></p>
+ <input type="file" id="upfile" name="upfile" tabindex="<?= $tabindex++ ?>" />
+ <p><?= sprintf($lang_up['info_2'], pun_htmlspecialchars(str_replace([' ', ','], ['', ', '], $pun_user['g_up_ext'])), pun_htmlspecialchars(file_size($upf_max_size))) ?></p>
+ </div>
+ </fieldset>
+ </div>
+ <p class="buttons"><input type="submit" name="submit" value="<?= $lang_up['Upload'] ?>" tabindex="<?= $tabindex++ ?>" /></p>
+ </form>
+ </div>
+ </div>
+<?php
+
+ $tit = $lang_up['titre_4'];
+} else {
+ $tit = pun_htmlspecialchars($usname) . ' - ' . $lang_up['upfiles'];
+}
+
+?>
+ <div id="upf-block" class="block">
+ <h2 id="gofile" class="block2"><span><?= $tit ?></span></h2>
+ <div class="box">
+<?php
+
+if (empty($files)) {
+
+?>
+ <div class="inbox"><p><span><?= $lang_up['No upfiles'] ?></span></p></div>
+<?php
+
+} else {
+ // Generate paging links
+ $paging_links = '<span class="pages-label">' . $lang_common['Pages'] . ' </span>' . paginate($num_pages, $upf_page, PLUGIN_URL);
+ $paging_links = str_replace(PLUGIN_REF . '&amp;', PLUGIN_REF . '?', $paging_links);
+ $paging_links = preg_replace('%href="([^">]+)"%', 'href="$1#gofile"', $paging_links);
+
+?>
+ <div class="inbox">
+ <div id="upf-legend">
+ <div style="<?= 'background-color: rgb(' . ceil(($upf_percent > 50 ? 50 : $upf_percent) * 255 / 50) . ', ' . ceil(($upf_percent < 50 ? 50 : 100 - $upf_percent) * 255 / 50) . ', 0); width:' . $upf_percent . '%;' ?>"><span><?= $upf_percent ?>%</span></div>
+ </div>
+ <p id="upf-legend-p"><?= sprintf($lang_up['info_4'], pun_htmlspecialchars(file_size($upf_dir_size)), pun_htmlspecialchars(file_size($upf_limit))) ?></p>
+ </div>
+ <div class="inbox">
+ <div class="pagepost">
+ <p class="pagelink conl"><?= $paging_links ?></p>
+ </div>
+ </div>
+ <div class="inbox">
+ <div id="upf-container">
+ <ul id="upf-list">
+<?php
+
+ $upf_img_exts = ['jpg', 'jpeg', 'gif', 'png', 'bmp', 'webp'];
+ foreach($files as $file) {
+ $fb = in_array($file['ext'], $upf_img_exts) ? '" class="fancy_zoom" rel="vi001' : '';
+
+?>
+ <li>
+ <div class="upf-name" title="<?= pun_htmlspecialchars($file['filename']) ?>"><span><?= pun_htmlspecialchars($file['alt']) ?></span></div>
+ <div class="upf-file" style="height:<?= max(intval($upf_conf['thumb_size']), 100) ?>px;">
+ <a href="<?= pun_htmlspecialchars($file['url']) . $fb ?>">
+<?php if (isset($file['mini'])): ?> <img src="<?= pun_htmlspecialchars($file['mini']) ?>" alt="<?= pun_htmlspecialchars($file['alt']) ?>" />
+<?php else: ?> <span><?= pun_htmlspecialchars($file['alt']) ?></span>
+<?php endif; ?>
+ </a>
+ </div>
+ <div class="upf-size"><span><?= pun_htmlspecialchars($file['size']) ?></span></div>
+ <div class="upf-but upf-delete"><a title="<?= $lang_up['delete'] ?>" href="<?= PLUGIN_URLD . 'csrf_hash=' . $upf_token . ($upf_page < 2 ? '' : '&amp;p=' . $upf_page) . '&amp;action=delete&amp;file=' . pun_htmlspecialchars($file['filename']) ?>" onclick="return FluxBB.upfile.del(this);"><span></span></a></div>
+ </li>
+<?php
+
+ } // end foreach
+
+?>
+ </ul>
+ </div>
+ </div>
+ <div class="inbox">
+ <div class="pagepost">
+ <p class="pagelink conl"><?= $paging_links ?></p>
+ </div>
+ </div>
+<?php
+
+} // end if
+
+?>
+ </div>
+ </div>
+<?php
+
+if ($fpr) {
+
+?>
+ <div class="clearer"></div>
+</div>
+<?php
+
+}
+
+?>
+<script type="text/javascript">
+/* <![CDATA[ */
+if (typeof FluxBB === 'undefined' || !FluxBB) {var FluxBB = {};}
+
+FluxBB.upfile = (function (doc, win) {
+ 'use strict';
+
+ var url, src, par, area;
+
+ function get(elem) {
+ return doc.getElementById(elem);
+ }
+
+ function createElement(elem) {
+ return (doc.createElementNS) ? doc.createElementNS('http://www.w3.org/1999/xhtml', elem) : doc.createElement(elem);
+ }
+
+ function is_img(a) {
+ return /.+\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(a);
+ }
+
+ function get_us(li) {
+ url = '';
+ src = '';
+ var div = li.getElementsByTagName('div')[1];
+ if (!!div) {
+ var a = div.getElementsByTagName('a')[0];
+ if (!!a) {
+ url = a.href;
+ var img = a.getElementsByTagName('img')[0];
+ if (!!img) src = img.src;
+ }
+ }
+ }
+
+ function set_button(li) {
+ get_us(li);
+
+ if (!!url) {
+ var div = createElement('div');
+ div.className = 'upf-but upf-insert';
+ div.innerHTML = '<a title="<?= $lang_up['insert'] ?>" href="#" onclick="return FluxBB.upfile.ins(this);"><span></span></a>';
+ li.appendChild(div);
+
+ if (is_img(src) && src != url) {
+ div = createElement('div');
+ div.className = 'upf-but upf-insert-t';
+ div.innerHTML = '<a title="<?= $lang_up['insert_thumb'] ?>" href="#" onclick="return FluxBB.upfile.ins(this, 1);"><span></span></a>';
+ li.appendChild(div);
+ }
+ }
+ }
+
+ function insr(s, e, t)
+ {
+ area.focus();
+ if ('selectionStart' in area) { // all new
+ var len = area.value.length,
+ sp = Math.min(area.selectionStart, len), // IE bug
+ ep = Math.min(area.selectionEnd, len); // IE bug
+ area.value = area.value.substring(0, sp) + s + (sp == ep ? t : area.value.substring(sp, ep)) + e + area.value.substring(ep);
+ area.selectionStart = ep + e.length + s.length + (sp == ep ? t.length : 0);
+ area.selectionEnd = area.selectionStart;
+ } else if (par.selection && par.selection.createRange) { // IE
+ var sel = par.selection.createRange();
+ sel.text = s + (!sel.text ? t : sel.text) + e;
+ sel.select();
+ }
+ win.focus();
+ }
+
+ function cr_req() {
+ if (win.XMLHttpRequest) {
+ return new XMLHttpRequest();
+ } else {
+ try {
+ return new ActiveXObject('Microsoft.XMLHTTP');
+ } catch (e){}
+ }
+ return !1;
+ }
+
+ function orsc(req, ref) {
+ if (req.readyState == 4) {
+ ref.className = '';
+ var error = true;
+
+ if (req.status == 200) {
+ var data = req.responseText;
+ if (typeof data === 'string') {
+ try {
+ data = JSON.parse(data);
+ } catch (e) {}
+ }
+ if (typeof data === 'string') {
+ if ('{' === data.substr(0, 1) && !/"error"/.test(data)) {
+ error = false;
+ }
+ } else {
+ if ('error' in data) {
+ alert(data.error);
+ } else {
+ error = false;
+ }
+ }
+ }
+
+ if (!error) {
+ ref.parentNode.parentNode.parentNode.removeChild(ref.parentNode.parentNode);
+ if (get('upf-list').getElementsByTagName('li').length == 0) {
+ win.location.reload(true);
+ }
+ }
+ }
+ }
+
+ return {
+
+ del : function (ref) {
+ if (ref.className) return !1;
+ if (!confirm('<?= addslashes($lang_up['delete file']) ?>')) return !1;
+
+ ref.className = 'upf-loading';
+
+ var req = cr_req();
+ if (req) {
+ req.onreadystatechange = function() {
+ orsc(req, ref);
+ };
+ req.open('GET', ref.href + '&ajx=1', true);
+ req.send();
+
+ return !1;
+ } else
+ return !0;
+ },
+
+ ins : function (ref, f) {
+
+ f = f || !1;
+ get_us(ref.parentNode.parentNode);
+
+ if (f && is_img(src) && src != url) {
+ insr('', '[url=' + url + '][img]' + src + '[/img][/url]', '');
+ } else if (is_img(url)) {
+ insr('', '[img]' + url + '[/img]', '');
+ } else {
+ if (f = url.match(/.*\/img\/members\/\d+\/(.+)$/)) f = f[1];
+ else f = '<?= $lang_up['texte'] ?>';
+
+ insr('[url=' + url + ']', '[/url]', f);
+ }
+ return !1;
+ },
+
+ run : function () {
+ if (!win.opener) return;
+
+ par = win.opener.document;
+ area = par.getElementsByName('req_message')[0];
+ if (!area) return;
+
+ var li = get('upf-list').getElementsByTagName('li');
+ for (var i in li) {
+ if (!!li[i].getElementsByTagName) set_button(li[i]);
+ }
+ },
+
+ init : function () {
+ if (!doc.addEventListener) {
+ /in/.test(doc.readyState) ? setTimeout(FluxBB.upfile.init, 100) : FluxBB.upfile.run();
+ } else doc.addEventListener('DOMContentLoaded', FluxBB.upfile.run, false);
+ }
+ };
+}(document, window));
+
+FluxBB.upfile.init();
+/* ]]> */
+</script>
+<?php
+
+require PUN_ROOT . 'footer.php';