From adbe6225d8aaaaa785389345e5621c6369636ab3 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 17 Sep 2020 14:36:49 +0200 Subject: added upload-mod 3.0.3 --- img/loading.gif | Bin 0 -> 673 bytes img/members/.gitkeep | 0 img/members/.htaccess | 72 +++++ img/members/nofile.gif | Bin 0 -> 631 bytes img/upf-i.png | Bin 0 -> 649 bytes img/upf-it.png | Bin 0 -> 668 bytes img/upf-x.png | Bin 0 -> 778 bytes include/upload.php | 784 ++++++++++++++++++++++++++++++++++++++++++++++ include/uploadf.php | 116 +++++++ include/uploadp.php | 23 ++ js/upload.js | 407 ++++++++++++++++++++++++ lang/English/upload.php | 92 ++++++ lang/French/upload.php | 92 ++++++ lang/German/upload.php | 92 ++++++ lang/Russian/upload.php | 92 ++++++ plugins/AP_Upload.php | 638 +++++++++++++++++++++++++++++++++++++ readme.txt | 157 ++++++++++ style/imports/upfiles.css | 171 ++++++++++ upfiles.php | 732 +++++++++++++++++++++++++++++++++++++++++++ 19 files changed, 3468 insertions(+) create mode 100644 img/loading.gif create mode 100644 img/members/.gitkeep create mode 100644 img/members/.htaccess create mode 100644 img/members/nofile.gif create mode 100644 img/upf-i.png create mode 100644 img/upf-it.png create mode 100644 img/upf-x.png create mode 100644 include/upload.php create mode 100644 include/uploadf.php create mode 100644 include/uploadp.php create mode 100644 js/upload.js create mode 100644 lang/English/upload.php create mode 100644 lang/French/upload.php create mode 100644 lang/German/upload.php create mode 100644 lang/Russian/upload.php create mode 100644 plugins/AP_Upload.php create mode 100644 readme.txt create mode 100644 style/imports/upfiles.css create mode 100644 upfiles.php diff --git a/img/loading.gif b/img/loading.gif new file mode 100644 index 0000000..f1c77c7 Binary files /dev/null and b/img/loading.gif differ diff --git a/img/members/.gitkeep b/img/members/.gitkeep new file mode 100644 index 0000000..e69de29 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. +#----------------------------------------------------------------------- + + + Options -Indexes + + +# ---------------------------------------------------------------------- +# Disable CGI script execution. +#----------------------------------------------------------------------- + + + Options -ExecCGI + + + Options -ExecCGI + + + Options -ExecCGI + + +# ---------------------------------------------------------------------- +# 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. +#----------------------------------------------------------------------- + + + php_flag engine 0 + + + php_flag engine 0 + + + php_flag engine 0 + + + php_flag engine 0 + + +# ---------------------------------------------------------------------- +# Treat these files as plain text. +# ---------------------------------------------------------------------- + + + 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 + + +# ---------------------------------------------------------------------- +# All files are given through the default handler for static content (Disable script execution). +# ---------------------------------------------------------------------- + +SetHandler default-handler + +# ---------------------------------------------------------------------- +# Show nofile.gif instead of missing files. +# ---------------------------------------------------------------------- + + + 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] + diff --git a/img/members/nofile.gif b/img/members/nofile.gif new file mode 100644 index 0000000..8b4224d Binary files /dev/null and b/img/members/nofile.gif differ diff --git a/img/upf-i.png b/img/upf-i.png new file mode 100644 index 0000000..5d96460 Binary files /dev/null and b/img/upf-i.png differ diff --git a/img/upf-it.png b/img/upf-it.png new file mode 100644 index 0000000..888173a Binary files /dev/null and b/img/upf-it.png differ diff --git a/img/upf-x.png b/img/upf-x.png new file mode 100644 index 0000000..29185fe Binary files /dev/null and b/img/upf-x.png 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 @@ + 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 @@ + 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']) + +?> + + + +
+
+
+ +
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
0%
+
+

+
+
+
+
+ + 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" . '' . $lang_up['upfiles'] . '' . "\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 @@ + 'No upload.', +'Error' => 'Error : ', +'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: %s 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 @@ + 'Pas de téléchargement.', +'Error' => 'Erreur : ', +'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)
', +'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é : %s 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 @@ + 'Keine Dateien vorhanden.', +'Error' => 'Fehler : ', +'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: %s 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 @@ + 'Нет загруженных файлов.', +'Error' => 'Ошибка : ', +'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' => 'Использовано: %s из %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 @@ + (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 ? '&p=' . $p : ''), $lang_up['Error'] . $lang_up['Error delete']); + } else { + redirect(PLUGIN_URL . ($p > 1 ? '&p=' . $p : ''), $lang_up['Redirect delete']); + } +} + +if (file_exists(PUN_ROOT . 'style/' . $pun_user['style'] . '/upfiles.css')) { + $s = ''; +} else { + $s = ''; +} +$tpl_main = str_replace('', $s . "\n", $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(); + +?> +
+

Plugin Upload Files v.

+
+
+

+
+

+ + +  
+

+
+
+
+isResize()) ? '' : '" disabled="disabled'; + $stthumb = ('' === $disbl && 1 == $aconf['thumb']) ? '' : '" disabled="disabled'; + +?> +  
+  

+

+ +
+ +

+
+
+

+
+
+ +
+ + + + + + + + + + + + + +
getLibVersion()) ?>
+ +  
+  *  +  %
+  *  +  x +   +
+ /> +     + /> +
+  *  +  
+  *  +  % +
+
+
+
+ +
+
+ +
+
+

1* -

+

2* -

+

3* -

+
+ + + + + + + + + + +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'] = ''; + } + +?> + + + + + + + + +
1*2*3*
+
+
+
+ +

+ + +

+
+
+ +
+ + + +
+
+
+
+
+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 = '' . $lang_common['Pages'] . ' ' . 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); + } +} + +?> +

+
+ +
+

+
+ + +
+
+ +
+
+ +
+
+

+ + +

+
+ + + + + + + + + + + + + + + + + + +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); + } + } + } + +?> + + + + + + + + + + + + +
[].[' . pun_htmlspecialchars($fi[3]) . '') ?>] + + <?= pun_htmlspecialchars($fi[2]) ?> + +
+
+
+
+ +
+
+ +
+
+ + +
+ +> + +# +#---------[ 8. AFTER, ADD ]--------------------------------------------------- +# + + + +# +#---------[ 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 @@ +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 . '&'); + $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('&', '&', 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'] = ''; +} else { + $page_head['pmsnewstyle'] = ''; +} + +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']) { + +?> +
+

+
+
+
+
+ +
+ + + +

+ +

+
+
+
+

+
+
+
+ +
+

+
+ +

+' . $lang_common['Pages'] . ' ' . paginate($num_pages, $upf_page, PLUGIN_URL); + $paging_links = str_replace(PLUGIN_REF . '&', PLUGIN_REF . '?', $paging_links); + $paging_links = preg_replace('%href="([^">]+)"%', 'href="$1#gofile"', $paging_links); + +?> +
+
+
%
+
+

+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+ + + +