Skip to:
Content
Pages
Categories
Search
Top
Bottom

Plugin: bb-Topic-Views

  • bb-Topic-Views keeps track of how many times each topic has been viewed, and then displays the count alongside the title of the topic on the front page, on forums pages, and on tags pages.

    The plugin is written in such a way that it does not double-count views when a visitor browses to a different page in the same topic. If no view count record exists for a specific topic, the plugin will create a record for it. Rather than setting the initial view count to zero, the plugin sets it to the number of posts in the topic, because it has obviously been viewed at least as many times as people have posted in it! This is especially nice for adding the plugin to existing bbpress forums so the view count isn’t zero for every single topic.

    You can download it here: http://blog.wittmania.com/bb-topic-views

    You can see it in action here: http://blog.wittmania.com/bbpress

    By the way, I’ve only tested this plugin in browser environments where cookies were enabled. This plugin doesn’t set any cookies (directly, anyway), but it does use session variables which are usually passed as cookies. So, if anyone runs into any bugs, please let me know!

    I’m also very open to suggestions as to how I could streamline or improve the code. Thanks!

Viewing 25 replies - 1 through 25 (of 25 total)

  • Sam Bauers
    Participant

    @sambauers

    You might want to check and make sure it is compatible (i.e. works along side with my plugin Page links for bbPress. Although it is probably fine, I think we using the same hook to write data to the screen and it would be terrible if we were stepping on each others toes.

    Is there a way to stop it showing next to the topic title and place it wherever I want? I was thinking of making an extra column to add views in to, instead of having them appear in the title link.

    @Sam, I use your excellent Page Links plugin, and I wrote mine specifically to be compatible with yours. In fact, I wouldn’t have known what filter to use if it weren’t for your plugin.

    I set the priority of my filter as 99 (yours is set to 100), so it fires directly before yours. Also, my plugin checks to see if the page_links_add_links function exists, and if it does it automatically drops the page links to a new line below the title in order to make things a little more sightly.

    @smurfdude, I thought about that, too. I initially decided against that route so I could have it function without having to edit any template files. The way it works right now is that it is inserted with a filter that is triggered when (and where) the topic title is fed to the page. If you’re feeling really ambitious, you can go into bb-topic-views.php to see how the mechanics of the plugin work. From there, you could change some things around so you could put the views count in its own column. Eventually I may add that functionality within the plugin, but that’s not a high priority right now.

    Speaking of priorities, the next to-do on my list is to add functionality where a user can add a template tag that will display the top 5 (or 10, or whatever) most viewed posts, either as <li> items so you can use it anywhere, or in a format similar to the way the Latest Discussion area is laid out. Stay tuned…

    Wittmania, it’s a really easy hack – in fact, if you simply take the code that gets the pageviews and seperate it into a different function, you could call that both from the current function you have to automatically append it and use it as a template tag. If you don’t fancy doing it, is it alright if I quickly hack it for Smurf?

    @fel, Hack away… I’d be interested in seeing the code so I could incorporate it in the next version of the plugin. If you’re willing, please e-mail it to me at mike at wittmania dot com.

    Thanks!

    All I did was split display_view_count() into two functions, display_view_count() and get_view_count(). If for example you wanted the views in a seperate column, you’d add the column HTML and then add

    <?php $view_count = get_view_count(); echo $view_count; ?>

    This is what I replaced display_view_count( $title ) with, here for Smurf’s convenience. You’re about to get mail.

    Oh, before I forget – hopefully now that plugins need activation in 1.0-alpha, there’s also an activation hook or the like. That would let you do a lot of preparation first, making the code much easier. :)

    Edit: there is! bb_activate_plugin_XXX. Maybe you can use that – if you want to and figure it out, tell us/make an entry on the wiki. :)

    function display_view_count ($title)
    {
    global $bbdb, $topic;
    $topic_id = $topic->topic_id;

    $view_count = get_view_count( $topic_id );

    //Builds the text to be appended to the title
    $count_display = " <em>($view_count views)</em>"; //This sets the view count var to the existing number of views, if greater than 0
    //Makes this plugin play nice with the Page Links plugin by putting the pages (if they exist) on a new line
    if (function_exists('page_links_add_links')) {
    $count_display .= "n";
    }
    $title .= $count_display;

    return $title;
    }

    function get_view_count( $topic_id )
    {
    $view_count = $bbdb->get_var("SELECT meta_value FROM $bbdb->topicmeta WHERE topic_id = $topic_id AND meta_key='views'");

    if ( $view_count <= 0 ) {
    //If the view count hasn't been initialized...
    if ($topic->topic_posts >= 1) {
    /* Sets the new record to the number of posts that have been made in a topic */
    $view_count = $topic->topic_posts; //sets the view_count number
    } else {
    $view_count = 0; //can't think of a time when this would be necessary (phantom topics???)
    }

    //Adds the record to the DB so it isn't zero any longer
    $bbdb->query("INSERT INTO $bbdb->topicmeta ( meta_id, topic_id, meta_key, meta_value) VALUES ( NULL , $topic_id, 'views', $view_count )");
    }

    return $view_count;
    }

    fel64, thanks for changing it for me. However i get an error when i replace the function with yours, then add <?php $view_count = get_view_count(); echo $view_count; ?>

    The error is:

    Fatal error: Call to a member function on a non-object in bb-topic-views.php

    Actually, adding <?php display_view_cont(); ?> was the very first thing i tried adding earlier. But it didn’t do anything. I have no idea how to write php but am always trying to edit files and see what i can achieve by myself. But in most cases end up getting no where.


    Sam Bauers
    Participant

    @sambauers

    Change:

    function get_view_count( $topic_id )
    {
    $view_count = $bbdb->get_var("SELECT meta_value FROM $bbdb->topicmeta WHERE topic_id = $topic_id AND meta_key='views'");

    To:

    function get_view_count( $topic_id )
    {
    global $bbdb, $topic;

    $view_count = $bbdb->get_var("SELECT meta_value FROM $bbdb->topicmeta WHERE topic_id = $topic_id AND meta_key='views'");

    ????

    I haven’t tested this yet, but it looks like the mods that fel64 and Sam have proposed here should work. So, instead of rushing a new version of the plugin out today, I think I’ll just save these changes (and some other functionality I’m working on) for the next major release. Hopefully I can get a new version of it out in the next couple of weeks.

    Version 1.5 is now available here. Some of the changes:

    • Made major modifications to the internal architecture of how the plugin works, including putting several repeated tasks into functions, based on the hacks listed above.
    • Added separate function calls that makes it possible to show an unformatted view count, a list of most viewed topics, and a table of most viewed topics.
    • Improved documentation to explain how to modify tables on front/forum/tags pages to use the show_view_count() function.

    This plugin will also be available in the plugin browser just as soon as the submission gets approved.


    AphelionZ
    Participant

    @aphelionz

    Thanks for this – I just put it on my site and it works really well. Good job!

    OK… it is now available through the plugin browser!

    One issue with this plugin is that it does a separate SQL call for every single topic on the page…. that’s 30 unnecessary SQL calls per topic list view.

    You might want to take a look at that…

    I’m open to suggestions… since it’s not part of the $topic global, but rather in the topicmeta table, that’s the only way I could think to do it.

    It works as it is, but if you’ve got a better idea as to how it could work better, I’m all ears.

    I suppose you could make the variable static, meaning it’ll be the same every time that function is called, and then check if there’s already something in it before you do the query again. Your query would then be selecting the thirty topics last posted in, of course.

    fel64: I’d think that’s the best way to handle it for normal usage.

    Personally, I moved that functionality into a memcached module… not entirely useful for regular installs.

    Hrmmm, I just installed the plugin, reviewed the steps a few times to make sure I was correct. My view count hasn’t been incrementing at all, stays fixed at the Post count. In fact, today a few View counts have actually decremented from the Post count, weird. Seems like a simple enough plugin, did I miss some setup with the database?


    _ck_
    Participant

    @_ck_

    The topic metadata is returned with every set of topics returned to bbpress.

    In the front page (or any topic page) for example, in the loop it can be found as $topic->views

    There is no need for an extra mysql query. It’s possible to make a function that’s called with $topic if you don’t want to do it as simple as above.


    _ck_
    Participant

    @_ck_

    Here’s a plugin to extend the topic-views plugin and add a “most-views” view page (ie. view.php?view=most-views)

    It does it with a minimum number of mysql calls, just 10 to display an entire page on my setup. You have to hack your views.php template to add the views column, use $topic->views for the view count to use the cached data in memory instead of an extra mysql query for each topic.

    function most_views_views( $views ) {
    global $views;
    $views['most-views'] = 'Topics with the most views';
    return $views;
    }
    add_filter('bb_views', 'most_views_views');

    function most_views( $view ) {
    global $bbdb, $topics, $view_count;
    switch ( $view ) :
    case 'most-views' :
    $limit = bb_get_option('page_topics');
    $where = apply_filters('get_latest_topics_where','');
    $most_views = $bbdb->get_results("SELECT topic_id FROM $bbdb->topicmeta WHERE meta_key='views' ORDER BY cast(meta_value as UNSIGNED) DESC LIMIT $limit");
    foreach (array_keys($most_views) as $i) {$trans[$most_views[$i]->topic_id] =& $most_views[$i];} $ids = join(',', array_keys($trans));
    $topics ="SELECT * FROM $bbdb->topics WHERE topic_id IN ($ids) $where ORDER BY FIELD(topic_id, $ids)";
    $topics = $bbdb->get_results($topics);
    $view_count = count($topics);
    $topics = bb_append_meta( $topics, 'topic' );
    break;
    default :
    do_action( 'bb_custom_view', $view );
    endswitch;
    }
    add_action( 'bb_custom_view', 'most_views' );


    _ck_
    Participant

    @_ck_

    I’ve now come up with an extremely easy/fast way to grab and display the views per forum in the forum list on the front page (or forums with sub-forums.

    Here’s the plugin:

    function forums_views_append($forums) {
    global $bbdb; $sum_meta_value="SUM(meta_value)";
    $forums_views = $bbdb->get_results(" SELECT $sum_meta_value,forum_id FROM $bbdb->topicmeta LEFT JOIN $bbdb->topics ON $bbdb->topicmeta.topic_id = $bbdb->topics.topic_id WHERE $bbdb->topicmeta.meta_key='views' GROUP BY $bbdb->topics.forum_id");
    foreach ($forums_views as $forum_views) {$forums[$forum_views->forum_id]->views=$forum_views->$sum_meta_value; }
    return $forums;
    }
    add_filter('get_forums','forums_views_append');

    To display the views, edit your front-page.php template and insert a views header and views column like so:

    <th><?php _e('Views'); ?></th>
    <th><?php _e('Topics'); ?></th>
    <th><?php _e('Posts'); ?></th>

    .

    <td><?php echo $forum->views; ?></td>
    <td><?php forum_topics(); ?></td>
    <td><?php forum_posts(); ?></td>

    Since there is no clean way to store forum meta data right now in bbpress (apparently an oversight) this will run on every time the forums list is displayed. Maybe not such a good idea for very busy forums, even though it’s a single mysql query (nifty eh?).

    Eventually I’ll figure out a nice way to store this and only update upon new posts or new topics to reduce overhead (or a cron job perhaps).

    this works really well on the front page, although i’m having a slight issue with my dashboard. when this plugin is active, i get the following error text on the right-hand side:

    Recently Moderated

    * Post on

    bbPress database error: [You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘AND meta_key=’views” at line 1]

    SELECT meta_value FROM bb_topicmeta WHERE topic_id = AND meta_key=’views’

    bbPress database error: [You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘ ‘views’, )’ at line 1]

    INSERT INTO bb_topicmeta ( meta_id, topic_id, meta_key, meta_value) VALUES ( NULL , , ‘views’, )

    Welcome to SK6Fans.com by neddi.

    Here is a screenshot

    Any thoughts?

    i got this error too


    _ck_
    Participant

    @_ck_

    Ah I know what it is after studying the code a bit.

    They never planned on $topic_id being null or not set, so it’s being inserted into the query as blank.

    mysql is getting something like

    SELECT meta_value FROM $bbdb->topicmeta WHERE topic_id = AND meta_key='views'

    see the blank before AND? It’s unacceptable to mysql, needs to be a value.

    hack

    function get_view_count ( $topic_id )

    and

    function initialize_view_count( $topic_id )

    and make a new first line for each that says

    if (!$topic_id) return;

    Should be a dirty workaround until the author can take a look.

    :D _CK_ i could not udrestand what should i do you mean i found

    function get_view_count ( $topic_id )

    and

    function initialize_view_count( $topic_id )

    and put this line above them?

    if (!$topic_id) return;


    Macmenddotcom
    Participant

    @macmenddotcom

    hmm is this plugin still available anywhere?

Viewing 25 replies - 1 through 25 (of 25 total)
  • You must be logged in to reply to this topic.
Skip to toolbar