Go Back   vb.org Archive > vBulletin 3 Discussion > vB3 Programming Discussions
FAQ Community Calendar Today's Posts Search

Reply
 
Thread Tools Display Modes
  #1  
Old 04-05-2008, 01:31 PM
KingAdora KingAdora is offline
 
Join Date: Oct 2003
Posts: 31
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default Displaying a random post

Is there a mod which can do this?

So that at the top right of the forum I can have something like this:

"<text from a random post>"
-<username>
-<thread name>

I made one myself, but it instead of the pages loading in less than a second, they took about 2 seconds to load, so I turned it off.

I used the global_start hook as anything else seemed to be processed too late.

Actually, if I post the code maybe someone will be able to help:


PHP Code:
<?php

$Qrs 
$db->query_first('
    SELECT pagetext, username, p.dateline, t.title, p.postid 
    FROM post p
    INNER JOIN thread t on t.threadid = p.threadid
    ORDER BY rand() 
    LIMIT 1
'
);

$Qtext        $Qrs['pagetext'];
$Qusername    $Qrs['username'];
$Qdate        $Qrs['dateline'];
$Qthreadtitle $Qrs['title'];
$QqPostid     $Qrs['postid'];


//setup
$Qurl "http://forum.website.co.uk/showthread.php?p=$QpostID#post$QpostID";
$Qdate date("jS M y"$Qdate);
$Qtext trim($Qtext);


//replacements
$Qtext str_replace('[B}',  '<b>'$Qtext);
$Qtext str_replace('[/B]''</b>'$Qtext);
$Qtext str_replace('[I]',  '<i>'$Qtext);
$Qtext str_replace('[/I]''</i>'$Qtext);
$Qtext str_replace('[U]',  '<u>'$Qtext);
$Qtext str_replace('[/U]''</u>'$Qtext);
$Qtext str_replace('[IMG]''<a href="'$Qtext);
$Qtext str_replace('[/IMG]''">Image</a>'$Qtext);


//remove everything before [/quote] if it exists
$QcutQuote "[/QUOTE]";
$QquotePos stripos($Qtext$QcutQuote);

if(
$QquotePos !== false) {
    
$QstartFrom $QquotePos strlen($QcutQuote);
    
$Qtext substr($Qtext$QstartFrom);
}

//make url
$Qoutput "$Qtext<br/><br/>- $Qusername<br/>\"<a href=\"$Qurl\">$Qthreadtitle</a>\"";

$Qquotes $Qoutput;

?>
$Qquotes is in the top right advert template, and the script is started on global_start
Reply With Quote
  #2  
Old 04-05-2008, 02:37 PM
Opserty Opserty is offline
 
Join Date: Apr 2007
Posts: 4,103
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Maybe use the datastore to store the post then get a scheduled task to select a new post every 5 minutes or so. You may find it quick to select pre-parsed posts from the postparsed table (if you have post caching on).

Instead of doing multple str_replace()s you can put the search and replace values into seperate arrays. E.g.

PHP Code:
$search = array('[B]''[/B]', ....);
$replace = array('<b>''</b>', ....);
str_replace($search$replace$Qtext); 
Reply With Quote
  #3  
Old 04-07-2008, 03:00 PM
KingAdora KingAdora is offline
 
Join Date: Oct 2003
Posts: 31
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Thanks for that! Do you (or others) have any more ideas to make it faster/more efficient?
Reply With Quote
  #4  
Old 04-07-2008, 04:39 PM
Farcaster Farcaster is offline
 
Join Date: Dec 2005
Posts: 386
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

I could think of a couple ways that might make your query faster without caching. By ordering on rand(), you are forcing a table scan of the entire post and thread tables, because that is the only way mySQL can use to determine which row will be ordered first.

So, the first option I see is to limit the posts by the dateline field. After all, do you really want a random post from any time in your board's history? You might limit it instead to a certain number of days in the past.

The second option, is to take advantage of MySQL's super fast row counting on MYISAM tables. You'd use two queries to get your result. The first would do a count of the rows. In PHP, you'd then randomly determine which one you wanted to use. Then execute a second query that used LIMIT $randomRow, 1. That would look something like this:

PHP Code:
// get post count
$posts $vbulletin->db->query_first("SELECT count(*) total_posts FROM ".TABLE_PREFIX."post");

// determine a random offset point.  Offset starts at 0, so subtract 1 from result
$randomRow rand(1,$posts['total_posts']) - 1;

// Retreive the row
$Qrs $db->query_first("
    SELECT pagetext, username, p.dateline, t.title, p.postid 
    FROM "
.TABLE_PREFIX."post p
    INNER JOIN "
.TABLE_PREFIX."thread t on t.threadid = p.threadid
    LIMIT 
$randomRow, 1
"
);

// The rest of your code..... 
(Note I just wrote this up in notepad, I didn't test it. But, I think this should work for you.)
Reply With Quote
  #5  
Old 04-07-2008, 10:04 PM
KingAdora KingAdora is offline
 
Join Date: Oct 2003
Posts: 31
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Wow thanks, that SQL hint really made it faster! Never would have thought 2 queries would better than one!

I also changed this: SELECT count(*) total_posts....
To this: SELECT count(postid) total_posts....

Not sure if using a field rather than * is any 'better'?
If you have any more gems let me know
Reply With Quote
  #6  
Old 04-10-2008, 06:22 PM
KingAdora KingAdora is offline
 
Join Date: Oct 2003
Posts: 31
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

I had a horrible thought just now so I typed some html code <blink>hi</blink> into a post, and set the query just to look at that post...

To my horror it was all parsed as html! So if someone had typed some nasty html into a post and waited (and refreshed for several hours) it quite possibly would have done something?

I assume if I use:
$text = htmlentities($rs['pagetext']);

That will be safe?
Reply With Quote
  #7  
Old 04-10-2008, 08:24 PM
MoT3rror MoT3rror is offline
 
Join Date: Mar 2007
Posts: 423
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Or if you have vbulletin global file already included, you can just use the vbulletin BBcode parser.

https://vborg.vbsupport.ru/showthrea...ghlight=bbcode
Reply With Quote
  #8  
Old 04-10-2008, 10:09 PM
KingAdora KingAdora is offline
 
Join Date: Oct 2003
Posts: 31
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Ahh good tip that, and it means I can get rid of my search replace arrays, because this parser does it all for me!

Keep it simple..
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 05:55 PM.


Powered by vBulletin® Version 3.8.12 by vBS
Copyright ©2000 - 2024, vBulletin Solutions Inc.
X vBulletin 3.8.12 by vBS Debug Information
  • Page Generation 0.09323 seconds
  • Memory Usage 2,255KB
  • Queries Executed 13 (?)
More Information
Template Usage:
  • (1)SHOWTHREAD
  • (1)ad_footer_end
  • (1)ad_footer_start
  • (1)ad_header_end
  • (1)ad_header_logo
  • (1)ad_navbar_below
  • (1)ad_showthread_beforeqr
  • (1)ad_showthread_firstpost
  • (1)ad_showthread_firstpost_sig
  • (1)ad_showthread_firstpost_start
  • (3)bbcode_php
  • (1)footer
  • (1)forumjump
  • (1)forumrules
  • (1)gobutton
  • (1)header
  • (1)headinclude
  • (1)navbar
  • (3)navbar_link
  • (120)option
  • (8)post_thanks_box
  • (8)post_thanks_button
  • (1)post_thanks_javascript
  • (1)post_thanks_navbar_search
  • (8)post_thanks_postbit_info
  • (8)postbit
  • (8)postbit_onlinestatus
  • (8)postbit_wrapper
  • (1)spacer_close
  • (1)spacer_open
  • (1)tagbit_wrapper 

Phrase Groups Available:
  • global
  • inlinemod
  • postbit
  • posting
  • reputationlevel
  • showthread
Included Files:
  • ./showthread.php
  • ./global.php
  • ./includes/init.php
  • ./includes/class_core.php
  • ./includes/config.php
  • ./includes/functions.php
  • ./includes/class_hook.php
  • ./includes/modsystem_functions.php
  • ./includes/functions_bigthree.php
  • ./includes/class_postbit.php
  • ./includes/class_bbcode.php
  • ./includes/functions_reputation.php
  • ./includes/functions_post_thanks.php 

Hooks Called:
  • init_startup
  • init_startup_session_setup_start
  • init_startup_session_setup_complete
  • cache_permissions
  • fetch_postinfo_query
  • fetch_postinfo
  • fetch_threadinfo_query
  • fetch_threadinfo
  • fetch_foruminfo
  • style_fetch
  • cache_templates
  • global_start
  • parse_templates
  • global_setup_complete
  • showthread_start
  • showthread_getinfo
  • forumjump
  • showthread_post_start
  • showthread_query_postids
  • showthread_query
  • bbcode_fetch_tags
  • bbcode_create
  • showthread_postbit_create
  • postbit_factory
  • postbit_display_start
  • post_thanks_function_post_thanks_off_start
  • post_thanks_function_post_thanks_off_end
  • post_thanks_function_fetch_thanks_start
  • post_thanks_function_fetch_thanks_end
  • post_thanks_function_thanked_already_start
  • post_thanks_function_thanked_already_end
  • fetch_musername
  • postbit_imicons
  • bbcode_parse_start
  • bbcode_parse_complete_precache
  • bbcode_parse_complete
  • postbit_display_complete
  • post_thanks_function_can_thank_this_post_start
  • tag_fetchbit_complete
  • forumrules
  • navbits
  • navbits_complete
  • showthread_complete