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 --- upfiles.php | 732 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 732 insertions(+) create mode 100644 upfiles.php (limited to 'upfiles.php') 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); + +?> +
+
+
%
+
+

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