diff --git a/includes/functions_content.php b/includes/functions_content.php index 1d87f8df..985641cb 100644 --- a/includes/functions_content.php +++ b/includes/functions_content.php @@ -1079,12 +1079,17 @@ function smiley_text($text, $force_option = false) */ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_ary, $preview = false) { - if (!count($attachments)) + preg_match_all('#\d+(?:_(?P\d+))?) \-\->(?P.*?)#', $message, $matches, PREG_PATTERN_ORDER); + + if (!count($attachments) && !count($matches)) { return; } - global $template, $cache, $user, $phpbb_dispatcher; + /** @var \phpbb\auth\auth $auth */ + /** @var \phpbb\db\driver\driver_interface $db */ + /** @var \phpbb\user $user */ + global $auth, $db, $template, $cache, $user, $phpbb_dispatcher; global $extensions, $config, $phpbb_root_path, $phpEx; // @@ -1116,8 +1121,6 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a // Grab attachments (security precaution) if (count($attach_ids)) { - global $db; - $new_attachment_data = array(); $sql = 'SELECT * @@ -1146,10 +1149,66 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a unset($new_attachment_data); } - // Make sure attachments are properly ordered - ksort($attachments); + if ($auth->acl_get($forum_id ? 'u_download' : 'u_pm_download')) + { + $post_msg_ids = array_filter($matches['post_msg_id'], function ($id) { return !empty($id); }); + if (count($post_msg_ids)) + { + $sql = [ + 'SELECT' => 'a.*', + 'FROM' => [ ATTACHMENTS_TABLE => 'a' ], + 'WHERE' => + $db->sql_in_set('post_msg_id', $post_msg_ids) . + ' AND in_message = ' . ($forum_id ? 0 : 1), + 'ORDER' => 'post_msg_id ASC, attach_id DESC', + ]; + + if ($forum_id) + { + $sql['SELECT'] .= ', p.forum_id'; + $sql['FROM'][POSTS_TABLE] = 'p'; + $sql['WHERE'] .= ' AND a.post_msg_id = p.post_id'; + } + else + { + $sql['FROM'][PRIVMSGS_TABLE] = 'p'; + $sql['WHERE'] .= ' AND a.post_msg_id = p.msg_id'; + if (!$auth->acl_get('m_report')) + { + $sql['FROM'][PRIVMSGS_TO_TABLE] = 't'; + $sql['WHERE'] .= ' AND p.msg_id = t.msg_id'; + $sql['WHERE'] .= ' AND t.user_id = ' . $user->data['user_id']; + } + } + + $result = $db->sql_query($db->sql_build_query('SELECT', $sql)); + for ($post_msg_id = 0, $index = 0; ($row = $db->sql_fetchrow($result)); ++$index) + { + if ($forum_id && !$auth->acl_get('f_download', (int) $row['forum_id'])) + { + continue; + } + + if ($row['post_msg_id'] != $post_msg_id) + { + $post_msg_id = $row['post_msg_id']; + $index = 0; + } + + $key = "{$index}_{$post_msg_id}"; - foreach ($attachments as $attachment) + if (in_array($key, $matches['key'])) + { + unset($row['forum_id']); + $row['in_quote'] = true; + $attachments[$key] = $row; + } + } + $db->sql_freeresult($result); + } + } + + foreach ($attachments as $key => $attachment) { if (!count($attachment)) { @@ -1159,7 +1218,11 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a // We need to reset/empty the _file block var, because this function might be called more than once $template->destroy_block_vars('_file'); - $block_array = array(); + $in_quote = !empty($row['in_quote']); + + $block_array = array( + 'IN_QUOTE' => $in_quote, + ); // Some basics... $attachment['extension'] = strtolower(trim($attachment['extension'])); @@ -1266,7 +1329,10 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a 'U_INLINE_LINK' => $inline_link, ); - $update_count_ary[] = $attachment['attach_id']; + if (!$in_quote) + { + $update_count_ary[] = $attachment['attach_id']; + } break; // Images, but display Thumbnail @@ -1279,7 +1345,10 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a 'THUMB_IMAGE' => $thumbnail_link, ); - $update_count_ary[] = $attachment['attach_id']; + if (!$in_quote) + { + $update_count_ary[] = $attachment['attach_id']; + } break; // Macromedia Flash Files @@ -1294,7 +1363,10 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a ); // Viewed/Heared File ... update the download count - $update_count_ary[] = $attachment['attach_id']; + if (!$in_quote) + { + $update_count_ary[] = $attachment['attach_id']; + } break; default: @@ -1350,7 +1422,7 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a $template->assign_block_vars('_file', $block_array); - $compiled_attachments[] = $template->assign_display('attachment_tpl'); + $compiled_attachments[$key] = $template->assign_display('attachment_tpl'); } $attachments = $compiled_attachments; @@ -1358,17 +1430,15 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a $unset_tpl = array(); - preg_match_all('#(.*?)#', $message, $matches, PREG_PATTERN_ORDER); - $replace = array(); foreach ($matches[0] as $num => $capture) { - $index = $matches[1][$num]; + $key = $matches['key'][$num]; $replace['from'][] = $matches[0][$num]; - $replace['to'][] = (isset($attachments[$index])) ? $attachments[$index] : sprintf($user->lang['MISSING_INLINE_ATTACHMENT'], $matches[2][array_search($index, $matches[1])]); + $replace['to'][] = (isset($attachments[$key])) ? $attachments[$key] : $user->lang('MISSING_INLINE_ATTACHMENT', $matches['filename'][$num]); - $unset_tpl[] = $index; + $unset_tpl[] = $key; } if (isset($replace['from'])) diff --git a/includes/functions_posting.php b/includes/functions_posting.php index 1956f656..7de04681 100644 --- a/includes/functions_posting.php +++ b/includes/functions_posting.php @@ -1127,10 +1127,12 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id $parse_flags |= ($row['enable_smilies'] ? OPTION_FLAG_SMILIES : 0); $message = generate_text_for_display($row['post_text'], $row['bbcode_uid'], $row['bbcode_bitfield'], $parse_flags, true); - if (!empty($attachments[$row['post_id']])) + $update_count = array(); + $post_attachments = $attachments[$row['post_id']] ?? []; + parse_attachments($forum_id, $message, $post_attachments, $update_count); + if (isset($attachments[$row['post_id']])) { - $update_count = array(); - parse_attachments($forum_id, $message, $attachments[$row['post_id']], $update_count); + $attachments[$row['post_id']] = $post_attachments; } $post_subject = censor_text($post_subject); diff --git a/includes/mcp/mcp_pm_reports.php b/includes/mcp/mcp_pm_reports.php index eecfe9cb..6244701c 100644 --- a/includes/mcp/mcp_pm_reports.php +++ b/includes/mcp/mcp_pm_reports.php @@ -141,11 +141,8 @@ class mcp_pm_reports } $db->sql_freeresult($result); - if (count($attachments)) - { - $update_count = array(); - parse_attachments(0, $message, $attachments, $update_count); - } + $update_count = array(); + parse_attachments(false, $message, $attachments, $update_count); // Display not already displayed Attachments for this post, we already parsed them. ;) if (!empty($attachments)) diff --git a/includes/mcp/mcp_post.php b/includes/mcp/mcp_post.php index 8d278079..ad2acc44 100644 --- a/includes/mcp/mcp_post.php +++ b/includes/mcp/mcp_post.php @@ -165,12 +165,9 @@ function mcp_post_details($id, $mode, $action) } $db->sql_freeresult($result); - if (count($attachments)) - { - $user->add_lang('viewtopic'); - $update_count = array(); - parse_attachments($post_info['forum_id'], $message, $attachments, $update_count); - } + $user->add_lang('viewtopic'); + $update_count = array(); + parse_attachments($post_info['forum_id'], $message, $attachments, $update_count); // Display not already displayed Attachments for this post, we already parsed them. ;) if (!empty($attachments)) diff --git a/includes/mcp/mcp_queue.php b/includes/mcp/mcp_queue.php index a29900ad..381f6335 100644 --- a/includes/mcp/mcp_queue.php +++ b/includes/mcp/mcp_queue.php @@ -231,11 +231,8 @@ class mcp_queue } $db->sql_freeresult($result); - if (count($attachments)) - { - $update_count = array(); - parse_attachments($post_info['forum_id'], $message, $attachments, $update_count); - } + $update_count = array(); + parse_attachments($post_info['forum_id'], $message, $attachments, $update_count); // Display not already displayed Attachments for this post, we already parsed them. ;) if (!empty($attachments)) diff --git a/includes/mcp/mcp_reports.php b/includes/mcp/mcp_reports.php index 46002573..d0f43185 100644 --- a/includes/mcp/mcp_reports.php +++ b/includes/mcp/mcp_reports.php @@ -222,11 +222,8 @@ class mcp_reports } $db->sql_freeresult($result); - if (count($attachments)) - { - $update_count = array(); - parse_attachments($post_info['forum_id'], $message, $attachments, $update_count); - } + $update_count = array(); + parse_attachments($post_info['forum_id'], $message, $attachments, $update_count); // Display not already displayed Attachments for this post, we already parsed them. ;) if (!empty($attachments)) diff --git a/includes/mcp/mcp_topic.php b/includes/mcp/mcp_topic.php index 5d1ecc08..3155696e 100644 --- a/includes/mcp/mcp_topic.php +++ b/includes/mcp/mcp_topic.php @@ -250,10 +250,12 @@ function mcp_topic_view($id, $mode, $action) $parse_flags = ($row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES; $message = generate_text_for_display($message, $row['bbcode_uid'], $row['bbcode_bitfield'], $parse_flags, false); - if (!empty($attachments[$row['post_id']])) + $update_count = array(); + $post_attachments = $attachments[$row['post_id']] ?? []; + parse_attachments($topic_info['forum_id'], $message, $post_attachments, $update_count); + if (isset($attachments[$row['post_id']])) { - $update_count = array(); - parse_attachments($topic_info['forum_id'], $message, $attachments[$row['post_id']], $update_count); + $attachments[$row['post_id']] = $post_attachments; } if ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) diff --git a/includes/ucp/ucp_pm_compose.php b/includes/ucp/ucp_pm_compose.php index 4b376896..de02097e 100644 --- a/includes/ucp/ucp_pm_compose.php +++ b/includes/ucp/ucp_pm_compose.php @@ -936,23 +936,22 @@ function compose_pm($id, $mode, $action, $user_folders = array()) } // Attachment Preview - if (count($message_parser->attachment_data)) + $update_count = array(); + $attachment_data = $message_parser->attachment_data; + parse_attachments(false, $preview_message, $attachment_data, $update_count, true); + + if (count($attachment_data)) { $template->assign_var('S_HAS_ATTACHMENTS', true); - $update_count = array(); - $attachment_data = $message_parser->attachment_data; - - parse_attachments(false, $preview_message, $attachment_data, $update_count, true); - foreach ($attachment_data as $i => $attachment) { $template->assign_block_vars('attachment', array( 'DISPLAY_ATTACHMENT' => $attachment) ); } - unset($attachment_data); } + unset($attachment_data); $preview_subject = censor_text($subject); diff --git a/includes/ucp/ucp_pm_viewmessage.php b/includes/ucp/ucp_pm_viewmessage.php index 7c0091ef..fce11055 100644 --- a/includes/ucp/ucp_pm_viewmessage.php +++ b/includes/ucp/ucp_pm_viewmessage.php @@ -128,19 +128,16 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) } // Assign inline attachments - if (!empty($attachments)) - { - $update_count = array(); - parse_attachments(false, $message, $attachments, $update_count); + $update_count = array(); + parse_attachments(false, $message, $attachments, $update_count); - // Update the attachment download counts - if (count($update_count)) - { - $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' - SET download_count = download_count + 1 - WHERE ' . $db->sql_in_set('attach_id', array_unique($update_count)); - $db->sql_query($sql); - } + // Update the attachment download counts + if (count($update_count)) + { + $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' + SET download_count = download_count + 1 + WHERE ' . $db->sql_in_set('attach_id', array_unique($update_count)); + $db->sql_query($sql); } $user_info['sig'] = ''; diff --git a/phpbb/feed/helper.php b/phpbb/feed/helper.php index 7d50b7ce..4901cf67 100644 --- a/phpbb/feed/helper.php +++ b/phpbb/feed/helper.php @@ -152,15 +152,12 @@ class helper $content = preg_replace( '#<(script|iframe)([^[]+)\1>#siU', ' $1 ', $content); // Parse inline images to display with the feed - if (!empty($post_attachments)) - { - $update_count = array(); - parse_attachments($forum_id, $content, $post_attachments, $update_count); - $content .= implode('
', $post_attachments); + $update_count = array(); + parse_attachments($forum_id, $content, $post_attachments, $update_count); + $content .= implode('
', $post_attachments); - // Convert attachments' relative path to absolute path - $content = str_replace($this->path_helper->get_web_root_path() . 'download/file.' . $this->path_helper->get_php_ext(), $this->get_board_url() . '/download/file.' . $this->path_helper->get_php_ext(), $content); - } + // Convert attachments' relative path to absolute path + $content = str_replace($this->path_helper->get_web_root_path() . 'download/file.' . $this->path_helper->get_php_ext(), $this->get_board_url() . '/download/file.' . $this->path_helper->get_php_ext(), $content); // Remove Comments from inline attachments [ia] $content = preg_replace('#
(.*?)
#','',$content); diff --git a/phpbb/textformatter/s9e/factory.php b/phpbb/textformatter/s9e/factory.php index f82c7b07..551dbc79 100644 --- a/phpbb/textformatter/s9e/factory.php +++ b/phpbb/textformatter/s9e/factory.php @@ -614,7 +614,24 @@ class factory implements \phpbb\textformatter\cache_interface // The [attachment] BBCode uses the inline_attachment template to output a comment that // is post-processed by parse_attachments() - $templates['attachment'] = $fragments['inline_attachment_open'] . ' ia ia ' . $fragments['inline_attachment_close']; + $templates['attachment'] = $fragments['inline_attachment_open'] . ' + + ia_ ia_ + + + ' . $fragments['inline_attachment_close']; // Add fragments as templates foreach ($fragments as $fragment_name => $fragment) diff --git a/posting.php b/posting.php index c7437204..4e416a45 100644 --- a/posting.php +++ b/posting.php @@ -1640,23 +1640,22 @@ if (!count($error) && $preview) } // Attachment Preview - if (count($message_parser->attachment_data)) + $update_count = array(); + $attachment_data = $message_parser->attachment_data; + parse_attachments($forum_id, $preview_message, $attachment_data, $update_count, true); + + if (count($attachment_data)) { $template->assign_var('S_HAS_ATTACHMENTS', true); - $update_count = array(); - $attachment_data = $message_parser->attachment_data; - - parse_attachments($forum_id, $preview_message, $attachment_data, $update_count, true); - foreach ($attachment_data as $i => $attachment) { $template->assign_block_vars('attachment', array( 'DISPLAY_ATTACHMENT' => $attachment) ); } - unset($attachment_data); } + unset($attachment_data); if (!count($error)) { @@ -1686,9 +1685,6 @@ $message_parser->decode_message($post_data['bbcode_uid']); if ($generate_quote) { - // Remove attachment bbcode tags from the quoted message to avoid mixing with the new post attachments if any - $message_parser->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#uis', '\\2', $message_parser->message); - $quote_attributes = array( 'author' => $post_data['quote_username'], 'post_id' => $post_data['post_id'], diff --git a/search.php b/search.php index 64790713..293e9627 100644 --- a/search.php +++ b/search.php @@ -1174,13 +1174,11 @@ if ($keywords || $author || $author_id || $search_id || $submit) $parse_flags = ($row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES; $row['post_text'] = generate_text_for_display($row['post_text'], $row['bbcode_uid'], $row['bbcode_bitfield'], $parse_flags, false); - if (!empty($attachments[$row['post_id']])) - { - parse_attachments($forum_id, $row['post_text'], $attachments[$row['post_id']], $update_count); + $post_attachments = $attachments[$row['post_id']] ?? []; + parse_attachments($forum_id, $row['post_text'], $post_attachments, $update_count); - // we only display inline attachments - unset($attachments[$row['post_id']]); - } + // we only display inline attachments + unset($post_attachments, $attachments[$row['post_id']]); } if ($hilit) diff --git a/viewtopic.php b/viewtopic.php index 4e502538..4b113ae7 100644 --- a/viewtopic.php +++ b/viewtopic.php @@ -1763,9 +1763,11 @@ for ($i = 0, $end = count($post_list); $i < $end; ++$i) $parse_flags = ($row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES; $message = generate_text_for_display($row['post_text'], $row['bbcode_uid'], $row['bbcode_bitfield'], $parse_flags, true); - if (!empty($attachments[$row['post_id']])) + $post_attachments = $attachments[$row['post_id']] ?? []; + parse_attachments($forum_id, $message, $post_attachments, $update_count); + if (isset($attachments[$row['post_id']])) { - parse_attachments($forum_id, $message, $attachments[$row['post_id']], $update_count); + $attachments[$row['post_id']] = $post_attachments; } // Replace naughty words such as farty pants