From 1ceec6acaba7b24295ea230a36a38e7284127a83 Mon Sep 17 00:00:00 2001 From: Yury Pikhtarev Date: Thu, 19 Jun 2025 16:03:50 +0400 Subject: [PATCH] WIP: feat(attachments): implement attachment handling in viewtopic and render_attachments function POSTPONED UNTIL ATTACHMENT MOD DEPRECATION. - Add logic to handle post attachments in viewtopic.php, including user authorization checks and guest notices for first posts. - Implement render_attachments function to generate HTML for displaying attachments, including support for images, thumbnails, and download links. - Enhance error logging for debugging attachment loading and rendering processes. - Remove legacy display_post_attachments function calls to streamline attachment handling. --- library/attach_mod/displaying.php | 237 +++++++++++++++--- .../attach_mod/includes/functions_attach.php | 16 +- viewtopic.php | 42 +++- 3 files changed, 245 insertions(+), 50 deletions(-) diff --git a/library/attach_mod/displaying.php b/library/attach_mod/displaying.php index 9f6ee8394..3163ae1f5 100644 --- a/library/attach_mod/displaying.php +++ b/library/attach_mod/displaying.php @@ -43,48 +43,215 @@ function init_complete_extensions_data() } /** - * Writing Data into plain Template Vars + * Render attachments HTML for a post */ -function init_display_template($template_var, $replacement, $filename = 'viewtopic_attach.tpl') +function render_attachments($post_id) { - global $template; + global $template, $upload_dir, $userdata, $allowed_extensions, $display_categories, $download_modes, $lang, $attachments, $upload_icons, $attach_config; + + // Debug: Check if required globals are available + error_log("render_attachments: upload_dir=" . ($upload_dir ?? 'null') . ", attach_config=" . (isset($attach_config) ? 'set' : 'null') . ", template=" . (isset($template) ? 'set' : 'null')); + + // If attachments global is empty, try to load data directly + if (empty($attachments['_' . $post_id])) { + if (function_exists('get_attachments_from_post')) { + $attachment_data = get_attachments_from_post([$post_id]); + if (!empty($attachment_data)) { + $attachments['_' . $post_id] = $attachment_data; + error_log("render_attachments: Loaded " . count($attachment_data) . " attachments for post $post_id"); + + // Also ensure we have required globals initialized + if (empty($allowed_extensions) && function_exists('init_complete_extensions_data')) { + init_complete_extensions_data(); + } + } else { + error_log("render_attachments: get_attachments_from_post returned empty for post $post_id"); + } + } else { + error_log("render_attachments: get_attachments_from_post function not found"); + } + } else { + error_log("render_attachments: Found existing attachment data for post $post_id"); + } + + $num_attachments = @count($attachments['_' . $post_id]); + + if ($num_attachments == 0) { + // Debug: Show what attachments we have + $debug_keys = array_keys($attachments); + return ''; + } + + // Create a new template instance just for rendering attachments + $template_root = $template ? $template->root : TEMPLATES_DIR . '/default'; + $attach_template = \TorrentPier\Template\Template::getInstance($template_root); + $attach_template->set_filenames(['body' => 'viewtopic_attach.tpl']); + + // Pass necessary variables to the attachment template + if ($template) { + $attach_template->assign_vars($template->vars); + } + $attach_template->lang =& $lang; + + // Start building attachment blocks + $attach_template->assign_block_vars('attach', []); + + for ($i = 0; $i < $num_attachments; $i++) { + $filename = $upload_dir . '/' . basename($attachments['_' . $post_id][$i]['physical_filename']); - // This function is adapted from the old template class - // I wish i had the functions from the 3.x one. :D (This class rocks, can't await to use it in Mods) - - // Handle Attachment Informations - if (!isset($template->uncompiled_code[$template_var]) && empty($template->uncompiled_code[$template_var])) { - // If we don't have a file assigned to this handle, die. - if (!isset($template->files[$template_var])) { - die("Template->loadfile(): No file specified for handle $template_var"); + $upload_image = ''; + if ($attach_config['upload_img'] && empty($upload_icons[$attachments['_' . $post_id][$i]['extension']])) { + $upload_image = ''; + } elseif (trim($upload_icons[$attachments['_' . $post_id][$i]['extension']]) != '') { + $upload_image = ''; } - $filename_2 = $template->files[$template_var]; + $filesize = humn_size($attachments['_' . $post_id][$i]['filesize']); - $str = file_get_contents($filename_2); - if (empty($str)) { - die("Template->loadfile(): File $filename_2 for handle $template_var is empty"); + $display_name = htmlspecialchars($attachments['_' . $post_id][$i]['real_filename']); + $comment = htmlspecialchars($attachments['_' . $post_id][$i]['comment']); + $comment = str_replace("\n", '
', $comment); + + $denied = false; + + // Admin is allowed to view forbidden Attachments, but the error-message is displayed too to inform the Admin + if (!in_array($attachments['_' . $post_id][$i]['extension'], $allowed_extensions)) { + $denied = true; + + $attach_template->assign_block_vars('attach.denyrow', ['L_DENIED' => sprintf($lang['EXTENSION_DISABLED_AFTER_POSTING'], $attachments['_' . $post_id][$i]['extension'])]); } - $template->uncompiled_code[$template_var] = $str; - } + if (!$denied || IS_ADMIN) { + // define category + $image = false; + $thumbnail = false; + $link = false; - $complete_filename = $filename; - if ($complete_filename[0] != '/') { - $complete_filename = $template->root . '/' . $complete_filename; - } + // Shows the images in topic + if (@(int)$display_categories[$attachments['_' . $post_id][$i]['extension']] == IMAGE_CAT && (int)$attach_config['img_display_inlined']) { + if ((int)$attach_config['img_link_width'] != 0 || (int)$attach_config['img_link_height'] != 0) { + // Get image sizes + [$width, $height] = getimagesize($filename); - if (!file_exists($complete_filename)) { - die("Template->make_filename(): Error - file $complete_filename does not exist"); - } + // Check if image sizes is allowed + if ($width == 0 && $height == 0) { + $image = true; + } else { + if ($width <= (int)$attach_config['img_link_width'] && $height <= (int)$attach_config['img_link_height']) { + $image = true; + } + } + } else { + $image = true; + } + } - $content = file_get_contents($complete_filename); - if (empty($content)) { - die('Template->loadfile(): File ' . $complete_filename . ' is empty'); - } + // Checks if image is thumbnail + if (@(int)$display_categories[$attachments['_' . $post_id][$i]['extension']] == IMAGE_CAT && $attachments['_' . $post_id][$i]['thumbnail'] == 1) { + $thumbnail = true; + $image = false; + } - // replace $replacement with uncompiled code in $filename - $template->uncompiled_code[$template_var] = str_replace($replacement, $content, $template->uncompiled_code[$template_var]); + // Checks whether the image should be displayed as a link + if (!$image && !$thumbnail) { + $link = true; + } + + if ($image) { + // Images + if ($attach_config['upload_dir'][0] == '/' || ($attach_config['upload_dir'][0] != '/' && $attach_config['upload_dir'][1] == ':')) { + $img_source = BB_ROOT . DL_URL . $attachments['_' . $post_id][$i]['attach_id']; + $download_link = true; + } else { + $img_source = $filename; + $download_link = false; + } + + $attach_template->assign_block_vars('attach.cat_images', [ + 'DOWNLOAD_NAME' => $display_name, + 'S_UPLOAD_IMAGE' => $upload_image, + 'IMG_SRC' => $img_source, + 'FILESIZE' => $filesize, + 'COMMENT' => $comment + ]); + + // Directly Viewed Image ... update the download count + if (!$download_link) { + $sql = 'UPDATE ' . BB_ATTACHMENTS_DESC . ' + SET download_count = download_count + 1 + WHERE attach_id = ' . (int)$attachments['_' . $post_id][$i]['attach_id']; + + if (!(DB()->sql_query($sql))) { + bb_die('Could not update attachment download count'); + } + } + } + + if ($thumbnail) { + // Images, but display Thumbnail + if ($attach_config['upload_dir'][0] == '/' || ($attach_config['upload_dir'][0] != '/' && $attach_config['upload_dir'][1] == ':')) { + $thumb_source = BB_ROOT . DL_URL . $attachments['_' . $post_id][$i]['attach_id'] . '&thumb=1'; + } else { + // Get the thumbnail image + $thumbnail_filename = $upload_dir . '/' . THUMB_DIR . '/t_' . basename($attachments['_' . $post_id][$i]['physical_filename']); + + // Checks the thumbnail existence + if (!is_file($thumbnail_filename)) { + continue; + } + + $thumb_source = $thumbnail_filename; + } + + $attach_template->assign_block_vars('attach.cat_thumb_images', [ + 'DOWNLOAD_NAME' => $display_name, + 'S_UPLOAD_IMAGE' => $upload_image, + 'IMG_SRC' => BB_ROOT . DL_URL . $attachments['_' . $post_id][$i]['attach_id'], + 'IMG_THUMB_SRC' => $thumb_source, + 'FILESIZE' => $filesize, + 'COMMENT' => $comment, + 'DOWNLOAD_COUNT' => declension((int)$attachments['_' . $post_id][$i]['download_count'], 'times'), + ]); + } + + // bt + if ($link && ($attachments['_' . $post_id][$i]['extension'] === TORRENT_EXT)) { + // For torrents, we need special handling + // Temporarily swap the global template variable + $saved_global_template = $template; + $template = $attach_template; + + // Include the torrent display file (it will use the swapped template) + if (file_exists(ATTACH_DIR . '/displaying_torrent.php')) { + include ATTACH_DIR . '/displaying_torrent.php'; + } + + // Restore the original template + $template = $saved_global_template; + } elseif ($link) { + $target_blank = ((@(int)$display_categories[$attachments['_' . $post_id][$i]['extension']] == IMAGE_CAT)) ? 'target="_blank"' : ''; + + // display attachment + $attach_template->assign_block_vars('attach.attachrow', [ + 'U_DOWNLOAD_LINK' => BB_ROOT . DL_URL . $attachments['_' . $post_id][$i]['attach_id'], + 'S_UPLOAD_IMAGE' => $upload_image, + 'DOWNLOAD_NAME' => $display_name, + 'FILESIZE' => $filesize, + 'COMMENT' => $comment, + 'TARGET_BLANK' => $target_blank, + 'IS_IMAGE' => (bool)$target_blank, + 'DOWNLOAD_COUNT' => declension((int)$attachments['_' . $post_id][$i]['download_count'], 'times') + ]); + } + } + } + + // Capture output + ob_start(); + $attach_template->pparse('body'); + $html = ob_get_clean(); + + return $html; } /** @@ -109,13 +276,15 @@ function display_post_attachments($post_id, $switch_attachment) function init_display_post_attachments($switch_attachment) { global $attach_config, $is_auth, $template, $lang, $postrow, $total_posts, $attachments, $forum_row, $t_data; + + // Debug: Log that this function is called + error_log("init_display_post_attachments called with switch_attachment: $switch_attachment"); if (empty($t_data) && !empty($forum_row)) { $switch_attachment = $forum_row['topic_attachment']; } - if ((int)$switch_attachment == 0 || (int)$attach_config['disable_mod'] || (!($is_auth['auth_download'] && $is_auth['auth_view']))) { - init_display_template('body', '{postrow.ATTACHMENTS}', 'viewtopic_attach_guest.tpl'); + if ((int)$switch_attachment == 0 || (int)$attach_config['disable_mod']) { return; } @@ -128,6 +297,8 @@ function init_display_post_attachments($switch_attachment) } if (count($post_id_array) == 0) { + // Debug: Log when no posts have attachments + error_log("init_display_post_attachments: No posts with attachments found. Total posts: $total_posts"); return; } @@ -152,8 +323,6 @@ function init_display_post_attachments($switch_attachment) //bt end } - init_display_template('body', '{postrow.ATTACHMENTS}'); - init_complete_extensions_data(); } diff --git a/library/attach_mod/includes/functions_attach.php b/library/attach_mod/includes/functions_attach.php index e2d7bc67a..5658276cf 100644 --- a/library/attach_mod/includes/functions_attach.php +++ b/library/attach_mod/includes/functions_attach.php @@ -236,19 +236,13 @@ function get_attachments_from_post($post_id_array) AND a.attach_id = d.attach_id ORDER BY d.filetime $display_order"; - if (!($result = DB()->sql_query($sql))) { - bb_die('Could not get attachment informations for post number ' . $post_id_array); - } - - $num_rows = DB()->num_rows($result); - $attachments = DB()->sql_fetchrowset($result); - DB()->sql_freeresult($result); - - if ($num_rows == 0) { + try { + $attachments = DB()->fetch_rowset($sql); + return $attachments ?: []; + } catch (Exception $e) { + error_log('get_attachments_from_post error: ' . $e->getMessage()); return []; } - - return $attachments; } /** diff --git a/viewtopic.php b/viewtopic.php index 806327ded..277b5abc6 100644 --- a/viewtopic.php +++ b/viewtopic.php @@ -678,6 +678,40 @@ for ($i = 0; $i < $total_posts; $i++) { $page_cfg['meta_description'] = str_short(strip_tags($message_meta), 220); } + // Handle attachments + $attachments_html = ''; + if (isset($postrow[$i]['post_attachment']) && $postrow[$i]['post_attachment']) { + $attachments_html = ''; + if ($is_auth['auth_download'] && $is_auth['auth_view']) { + $attachments_html .= ''; + if (function_exists('render_attachments')) { + $attachments_html .= ''; + $render_result = render_attachments($post_id); + $attachments_html .= $render_result; + $attachments_html .= ''; + } else { + $attachments_html .= ''; + } + } elseif ($is_first_post) { + $attachments_html .= ''; + // Show guest attachment notice only for first post + $guest_template = \TorrentPier\Template\Template::getInstance($template->root); + $guest_template->set_filenames(['body' => 'viewtopic_attach_guest.tpl']); + $guest_template->assign_vars($template->vars); + $guest_template->lang =& $lang; + $guest_template->assign_block_vars('postrow', ['IS_FIRST_POST' => true]); + ob_start(); + $guest_template->pparse('body'); + $guest_result = ob_get_clean(); + $attachments_html .= $guest_result; + $attachments_html .= ''; + } else { + $attachments_html .= ''; + } + } else { + $attachments_html = ''; + } + $template->assign_block_vars('postrow', [ 'ROW_CLASS' => !($i % 2) ? 'row1' : 'row2', 'POST_ID' => $post_id, @@ -729,7 +763,9 @@ for ($i = 0; $i < $total_posts; $i++) { 'RG_URL' => GROUP_URL . $rg_id, 'RG_FIND_URL' => 'tracker.php?srg=' . $rg_id, 'RG_SIG' => $rg_signature, - 'RG_SIG_ATTACH' => $postrow[$i]['attach_rg_sig'] + 'RG_SIG_ATTACH' => $postrow[$i]['attach_rg_sig'], + + 'ATTACHMENTS' => $attachments_html . '' ]); // Ban information @@ -740,10 +776,6 @@ for ($i = 0; $i < $total_posts; $i++) { ]); } - if (isset($postrow[$i]['post_attachment']) && $is_auth['auth_download'] && function_exists('display_post_attachments')) { - display_post_attachments($post_id, $postrow[$i]['post_attachment']); - } - if ($moderation && !defined('SPLIT_FORM_START') && ($start || $post_id == $t_data['topic_first_post_id'])) { define('SPLIT_FORM_START', true); }