• This forum has been archived. New threads and replies may not be made. All add-ons/resources that are active should be migrated to the Resource Manager. See this thread for more information.

XF Lightboxed Attachments on Forumhome

calorie

Active member
Well, now that I've finally had a chance to debug this thing, after having to be told that I was missing the <?php on a file (still laughing about that one), I bring to you lightboxed attachments on the forum homepage with no template edits.

forumhome.webp

What it does is it queries for attachments, selects up to twelve of those files, and forms a thumbnail strip for display over the forum list on the forum homepage. The thumbnail strip shows to all visitors, and permissions should be taken into account for larger images that are called when thumbnails are clicked. I say should as this is still new to me and if it barfs, well, I said should, not will, lol.

This add-on adds four queries to the forum homepage: two queries for two templates, and two queries to get something random-like but is not an 'order by rand' clause. As you might know, 'order by rand' is just not all that optimal, especially on large tables.

My first thought was to use the PHP glob function to traverse the attachments directory, but it traverses the whole directory, which after several hundred attachments, would likely produce a noticeable slowdown. Next I thought about using PHP's opendir, readdir, and closedir functions, with some code to 'seek' in order to avoid traversing the whole directory.

Well, there isn't yet a PHP seekdir function, or at least I couldn't find one that'd work, so I then thought about using the PHP shell_exec function with a shell script, but then, oh, the incompatibility issues and so forth. So that lead me to what you see in the code today. There is no 'order by rand' and, although I haven't checked, I doubt you'll find 'order by rand' in the XF code.

Anyway, four good queries in and of themselves are not necessarily a big deal, as most should be optimized in some way. The two queries for the two templates are done with XF's $template->create and of the other two queries, the first one fetches count, min, and max, which might be better handled using a query on a now non-existent summary table handled via a cron job.

Right now though the attachment table is queried for count, min, and max. If it turns out to cause a noticeable slowdown, then I can look into whether a summary table would be a better way to handle it. So that leaves the last of the four queries, which makes use of attachment ID 'between X and Y' so it is keyed, where X and Y are determined using some math,

The downsize to the math is that if there is a large enough gap in the attachment ID sequence, you won't necessarily see Z thumbnails every time the page loads. Alas, the point of this blurb I guess is to talk about what a PITA it is to get something random without it being a total resource hog on bigger boards. So if you have anything to contribute, please feel free to share if you want.

Personally I'm okay with getting less than Z images in the thumbnail strip on occasion if it means that a full table scan is avoided, so at this point, the other improvement that I'd make would be to have a cron job update a summary table and then query said table for count, min, and max to avoid potential slowdowns there.

So how do you handle it when you want something random?

BTW, enjoy the add-on. :)

Edit: Seems I inadvertently wiped out the hover shadow on the thumbnails, oops, so to get it back, in the XML file find <blockquote class="messageText"> and replace with <blockquote class="messageText ugc"> and then import. Also seems like one template query could be removed, but it is not yet clear if the exchange of query for code is worth it, but will try to keep you posted if anything changes. Right now though, sleep is required.
 

Attachments

I love the idea, but there are some things, which could be optimized (i'll check it this weekend)


some quick notes:
two queries for two templates
unneccessary
check the $template->preloadTemplate method;)
You can see it in my invite add-on in action, if you're interessted.


Also maybe a subquery would be better(faster) instead of the 2 queries to fetch the attachments.
 
I love the idea, but there are some things, which could be optimized (i'll check it this weekend)


some quick notes:
unneccessary
check the $template->preloadTemplate method;)
You can see it in my invite add-on in action, if you're interessted.


Also maybe a subquery would be better(faster) instead of the 2 queries to fetch the attachments.

Thanks, but cannot find preloadTemplate in your Invite add-on. Lacking fortitude ATM, maybe I missed it. :(
 
Was this every continued with? Very very interested :) Will this bring back the latest attachments and can it be limited to a certain forum easily enough?
 
Thankyou so much for this .... modified it to bring back latest images from a set forum to replace the random gallery images on ipb ...... VERY VERY welcomed modification that saved me a lot of work
 
Thankyou so much for this .... modified it to bring back latest images from a set forum to replace the random gallery images on ipb ...... VERY VERY welcomed modification that saved me a lot of work

I'm planning on converting one of my IPB forums in the future, if you could share the changed file it would help me a lot with the gallery issue that I'm sure you're familiar with. Thanks. :)
 
OK here are the changes I made. These changes will give you the latest x images rather than random ones, and bring them from a specific forum.

Find in library\LightboxFiles\LightboxStatic.php
PHP:
                $results = $db->fetchAll("
                    SELECT attach.*, data.*, user.username
                    FROM xf_attachment AS attach
                    INNER JOIN xf_attachment_data AS data ON
                        (data.data_id = attach.data_id)
                    LEFT JOIN xf_user AS user ON
                        (user.user_id = data.user_id)
                    WHERE attach.attachment_id BETWEEN " . $start . " AND " . $end . "
                    LIMIT " . $limit . "
                ");

Replace with
PHP:
                $results = $db->fetchAll("
                    SELECT attach.*, data.*, user.username
                    FROM xf_attachment AS attach
                    INNER JOIN xf_attachment_data AS data ON
                        (data.data_id = attach.data_id)
                    INNER JOIN xf_user AS user ON
                        (user.user_id = data.user_id)

                    INNER JOIN xf_post AS tPost ON tPost.Post_id = attach.content_id
                    INNER JOIN xf_thread AS tThread ON tThread.thread_id = tPost.thread_id
                    INNER JOIN xf_node AS tNode ON tNode.node_id = tThread.node_id AND 
                        (tNode.node_id = 49 OR tNode.parent_node_id = 49)
                    WHERE attach.content_type = 'post'
                    ORDER BY attach.attachment_id desc LIMIT " . $limit . "
                ");

NOTE - in this example I have used my gallery forum, which has an ID of 49 (just click on forum and it will give you the number). So you would replace the number 49 in this line "(tNode.node_id = 49 OR tNode.parent_node_id = 49)" to represent the forum you wish to use. This will also include any subforums within that forum, however only down to 1 level.
 
I noticed this line:
PHP:
$can_view = $visitor['permissions']['forum']['viewAttachment'];

Shouldn't that be:
PHP:
$can_view = XenForo_Permission::hasPermission($visitor['permissions'], 'forum', 'viewAttachment');
?
 
I also noticed this:
PHP:
if ($count)
{
shuffle($attachments['attachments']);
$filebits = $template->create('lightbox_files_bits', $attachments)->render();
$contents = $template->create('lightbox_files_list', array('filebits' => $filebits))->render() . $contents;
}
$filebits is a template, you're using the {xen:raw $filebits} to include the template lightbox_files_bits into the lightbox_files_list template? Why not just create the lightbox_files_list template in the PHP and then use <xen:include template="lightbox_files_bits" / >?
 
Also, couldn't you replace your LightboxStaticThumbnailUrl($data) function with getAttachmentThumbnailUrl(array $data) in XenForo_Model_Attachment?

PHP:
XenForo_Model::create('XenForo_Model_Attachment')->getAttachmentThumbnailUrl($data);
 
Quick hack to exclude a specific private forum

PHP:
            $results = $db->fetchAll("
                SELECT attach.*, data.*, user.username
                FROM xf_attachment AS attach
                INNER JOIN xf_attachment_data AS data ON
                    (data.data_id = attach.data_id)
                INNER JOIN xf_user AS user ON
                    (user.user_id = data.user_id)
 
                INNER JOIN xf_post AS post ON
                    (post.post_id = attach.content_id)
 
                INNER JOIN xf_thread AS thread ON
                    (thread.thread_id = post.thread_id)
 
 
                WHERE attach.content_type = 'post' AND thread.node_id != 3
                ORDER BY attach.attachment_id desc LIMIT " . $limit . "
            ");
 
This is really good but I'd like it if I could set it to show most recent attachments and not cycle through attachments randomly.
 
Back
Top Bottom