How to make image attachments visible to guests?
A topic to publish my solution, maybe I'll create a modification soon.
Open Sources/display.php and:
# STEP 1
// Fetch attachments.
if (!empty($modSettings['attachmentEnable']) && allowedTo('view_attachments'))
{
$request = $smcFunc['db_query']('', '
SELECT
a.id_attach, a.id_folder, a.id_msg, a.filename, a.file_hash, IFNULL(a.size, 0) AS filesize, a.downloads, a.approved,
a.width, a.height' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : ',
IFNULL(thumb.id_attach, 0) AS id_thumb, thumb.width AS thumb_width, thumb.height AS thumb_height') . '
FROM {db_prefix}attachments AS a' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : '
LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = a.id_thumb)') . '
WHERE a.id_msg IN ({array_int:message_list})
AND a.attachment_type = {int:attachment_type}',
array(
'message_list' => $messages,
'attachment_type' => 0,
'is_approved' => 1,
)
);
$temp = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
{
if (!$row['approved'] && $modSettings['postmod_active'] && !allowedTo('approve_posts') && (!isset($all_posters[$row['id_msg']]) || $all_posters[$row['id_msg']] != $user_info['id']))
continue;
$temp[$row['id_attach']] = $row;
if (!isset($attachments[$row['id_msg']]))
$attachments[$row['id_msg']] = array();
}
$smcFunc['db_free_result']($request);
// This is better than sorting it with the query...
ksort($temp);
foreach ($temp as $row)
$attachments[$row['id_msg']][] = $row;
}
This snippet will only load image attachments for guest. According to tests, this allows you to display the image from the attachment in the post if it is placed. However, I recommend that you also use step two.
// Fetch attachments.
if (!empty($modSettings['attachmentEnable']))
{
if (allowedTo('view_attachments'))
{
$request = $smcFunc['db_query']('', '
SELECT
a.id_attach, a.id_folder, a.id_msg, a.filename, a.file_hash, IFNULL(a.size, 0) AS filesize, a.downloads, a.approved,
a.width, a.height' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : ',
IFNULL(thumb.id_attach, 0) AS id_thumb, thumb.width AS thumb_width, thumb.height AS thumb_height') . '
FROM {db_prefix}attachments AS a' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : '
LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = a.id_thumb)') . '
WHERE a.id_msg IN ({array_int:message_list})
AND a.attachment_type = {int:attachment_type}',
array(
'message_list' => $messages,
'attachment_type' => 0,
'is_approved' => 1,
)
);
$temp = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
{
if (!$row['approved'] && $modSettings['postmod_active'] && !allowedTo('approve_posts') && (!isset($all_posters[$row['id_msg']]) || $all_posters[$row['id_msg']] != $user_info['id']))
continue;
$temp[$row['id_attach']] = $row;
if (!isset($attachments[$row['id_msg']]))
$attachments[$row['id_msg']] = array();
}
$smcFunc['db_free_result']($request);
// This is better than sorting it with the query...
ksort($temp);
foreach ($temp as $row)
$attachments[$row['id_msg']][] = $row;
}
else
{
$request = $smcFunc['db_query']('', '
SELECT
a.id_attach, a.id_folder, a.id_msg, a.filename, a.fileext, a.file_hash, IFNULL(a.size, 0) AS filesize, a.downloads, a.approved,
a.width, a.height' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : ',
IFNULL(thumb.id_attach, 0) AS id_thumb, thumb.width AS thumb_width, thumb.height AS thumb_height') . '
FROM {db_prefix}attachments AS a' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : '
LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = a.id_thumb)') . '
WHERE a.id_msg IN ({array_int:message_list})
AND a.fileext IN ("jpg", "gif", "jpeg", "x-ms-bmp", "png", "psd", "tiff", "iff")
AND a.attachment_type = {int:attachment_type}',
array(
'message_list' => $messages,
'attachment_type' => 0,
'is_approved' => 1,
)
);
$temp = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
{
if (!$row['approved'] && $modSettings['postmod_active'] && !allowedTo('approve_posts') && (!isset($all_posters[$row['id_msg']]) || $all_posters[$row['id_msg']] != $user_info['id']))
continue;
$temp[$row['id_attach']] = $row;
if (!isset($attachments[$row['id_msg']]))
$attachments[$row['id_msg']] = array();
}
$smcFunc['db_free_result']($request);
// This is better than sorting it with the query...
ksort($temp);
foreach ($temp as $row)
$attachments[$row['id_msg']][] = $row;
}
}
# STEP 2
// This checks only the current board for $board/$topic's permissions.
isAllowedTo('view_attachments');
// Make sure this attachment is on this board.
// NOTE: We must verify that $topic is the attachment's topic, or else the permission check above is broken.
$request = $smcFunc['db_query']('', '
SELECT a.id_folder, a.filename, a.file_hash, a.fileext, a.id_attach, a.attachment_type, a.mime_type, a.approved, m.id_member
FROM {db_prefix}attachments AS a
INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg AND m.id_topic = {int:current_topic})
INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board AND {query_see_board})
WHERE a.id_attach = {int:attach}
LIMIT 1',
array(
'attach' => $_REQUEST['attach'],
'current_topic' => $topic,
)
);
}
if ($smcFunc['db_num_rows']($request) == 0)
fatal_lang_error('no_access', false);
This snippet will display the attachment and allow you to download it.
// Make sure this attachment is on this board.
// NOTE: We must verify that $topic is the attachment's topic, or else the permission check above is broken.
if (allowedTo('view_attachments'))
{
$request = $smcFunc['db_query']('', '
SELECT a.id_folder, a.filename, a.file_hash, a.fileext, a.id_attach, a.attachment_type, a.mime_type, a.approved, m.id_member
FROM {db_prefix}attachments AS a
INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg AND m.id_topic = {int:current_topic})
INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board AND {query_see_board})
WHERE a.id_attach = {int:attach}
LIMIT 1',
array(
'attach' => $_REQUEST['attach'],
'current_topic' => $topic,
)
);
}
else
{
$request = $smcFunc['db_query']('', '
SELECT a.id_folder, a.filename, a.file_hash, a.fileext, a.id_attach, a.attachment_type, a.mime_type, a.approved, m.id_member
FROM {db_prefix}attachments AS a
INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg AND m.id_topic = {int:current_topic})
INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board AND {query_see_board})
WHERE a.id_attach = {int:attach}
AND a.fileext IN ("jpg", "gif", "jpeg", "x-ms-bmp", "png", "psd", "tiff", "iff")
LIMIT 1',
array(
'attach' => $_REQUEST['attach'],
'current_topic' => $topic,
)
);
}
}
if ($smcFunc['db_num_rows']($request) == 0)
{
// This checks only the current board for $board/$topic's permissions.
isAllowedTo('view_attachments');
fatal_lang_error('no_access', false);
}
To the coders, will his tip work the way it's written for what he wants it to do (allow only image attachments to guests)?
Yes it works. Just needs to add a note somewhere indicating that this tip is for SMF 2.0.x.
Also, you don't need to replace and duplicate that much code, just move the condition to the query, as a ternary.
#1
// Fetch attachments.
if (!empty($modSettings['attachmentEnable']))
{
$request = $smcFunc['db_query']('', '
SELECT
a.id_attach, a.id_folder, a.id_msg, a.filename, a.fileext, a.file_hash, IFNULL(a.size, 0) AS filesize, a.downloads, a.approved,
a.width, a.height' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : ',
IFNULL(thumb.id_attach, 0) AS id_thumb, thumb.width AS thumb_width, thumb.height AS thumb_height') . '
FROM {db_prefix}attachments AS a' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : '
LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = a.id_thumb)') . '
WHERE a.id_msg IN ({array_int:message_list})' . (allowedTo('view_attachments') ? '' : '
AND a.fileext IN ({array_string:image_extensions})') . '
AND a.attachment_type = {int:attachment_type}',
array(
'message_list' => $messages,
'attachment_type' => 0,
'is_approved' => 1,
'image_extensions' => array('jpg', 'gif', 'jpeg', 'x-ms-bmp', 'png', 'psd', 'tiff', 'iff'),
)
);
#2
// This is just a regular attachment...
else
{
// Make sure this attachment is on this board.
// NOTE: We must verify that $topic is the attachment's topic, or else the permission check above is broken.
$request = $smcFunc['db_query']('', '
SELECT a.id_folder, a.filename, a.file_hash, a.fileext, a.id_attach, a.attachment_type, a.mime_type, a.approved, m.id_member
FROM {db_prefix}attachments AS a
INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg AND m.id_topic = {int:current_topic})
INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board AND {query_see_board})
WHERE a.id_attach = {int:attach}' . (allowedTo('view_attachments') ? '' : '
AND a.fileext IN ({array_string:image_extensions})') . '
LIMIT 1',
array(
'attach' => $_REQUEST['attach'],
'current_topic' => $topic,
'image_extensions' => array('jpg', 'gif', 'jpeg', 'x-ms-bmp', 'png', 'psd', 'tiff', 'iff'),
)
);
}
if ($smcFunc['db_num_rows']($request) == 0)
{
// This checks only the current board for $board/$topic's permissions.
isAllowedTo('view_attachments');
fatal_lang_error('no_access', false);
}
It makes sense to follow this lead, I don't know if it should not also be added for "SELECT --> a.fileext"
Because purely theoretically, a large number of files and a subsequent query in the database gives more calculations than one query in a php script.
Mby also for "'image_extensions' => array('jpg', 'gif', 'jpeg', 'x-ms-bmp', 'png', 'psd', 'tiff', 'iff'),"
In this case 3x allowedTo('view_attachments') > 1 x allowedTo('view_attachments')
Code length doesn't always equate to performance.
And yes can add image_extensions in array:
'image_extensions' => array('jpg', 'gif', 'jpeg', 'x-ms-bmp', 'png', 'psd', 'tiff', 'iff'),
provided that the user would like to edit this part of the code, otherwise it probably doesn't affect anything.
This is a good step to create a modification with the option of selecting an attachment extension that can be displayed to the guest in the event of blocking attachments in permissions.
Topic cleaned up.