MyBB Community Forums

Full Version: Hide Content - Require Feedback
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi all,

I'm new to coding MyBB plugins and have formed an addon which hides content when using the following BBCode:

[hide]Hidden content here...[/hide]

What does it do?
We have 2 settings in the admin control panel:
  • Ignore usergroups
  • Minimum posts 

When a user uses the above BBCode:

Guests will see the following message:
Quote:Please login or register to view hidden content.


A user who doesn't meet the required minimum posts will see:
Quote:Please make 5 posts to view hidden content.


A user who does meet the required minimum posts but has not replied to the topic will see:
Quote:Please reply to this topic to view hidden content.


An admin (and other ignored usergroups) would see the hidden content no matter what.

Here's my code:

<?php
    /**
     * Jordan Francis
     * Oct 8, 2015
     * Copyright 2015, All Rights Reserved
     * Website:
     */

    if(!defined('IN_MYBB')) die('This file cannot be accessed directly.');

    // Hooks
    $plugins->add_hook('showthread_start', 'hidecontent_showthread_start');
    $plugins->add_hook('parse_message', 'hidecontent_parse_message');
    $plugins->add_hook('parse_quoted_message', 'hidecontent_quoted_message');

    function hidecontent_info()
    {
        return array(
            'name'          => 'Hide Content',
            'description'   => 'Hides content from guests and users without no. of posts/replying to the thread.',
            'website'       => 'http://mybb.com',
            'author'        => 'Jordan F',
            'authorsite'    => 'http://mybb.com',
            'version'       => '1.0',
            'compatibility' => '18*',
            'guid'          =>    ''
        );
    }

    function hidecontent_activate()
    {
        global $db;

        $group = array(
            'name'          => 'hidecontent',
            'title'         => 'Hide Content',
            'description'   => 'Settings relating to the hide content plugin.',
            'isdefault'     => 0
        );

        $db->insert_query('settinggroups', $group);
        $gid = $db->insert_id();

        $settings = array(
            array(
                'name'          => 'hidecontent_ignoregroups',
                'title'         => 'Ignore Usergroups',
                'description'   => 'Usergroups to ignore? Their usergroup ID comma seperated without spaces.',
                'optionscode'   => 'groupselect',
                'value'         => '4',
                'disporder'     => 1,
                'gid'           => intval($gid)
            ),
            array(
                'name'          => 'hidecontent_minposts',
                'title'         => 'Post Requirement',
                'description'   => 'The standard amount of posts to view hidden content?',
                'optionscode'   => 'numeric',
                'value'         => '5',
                'disporder'     => 2,
                'gid'           => intval($gid)
            )
        );

        foreach($settings as $setting)
        {
            $db->insert_query('settings', $setting);
        }

        rebuild_settings();
    }

    // Delete relevant settings from database
    function hidecontent_deactivate()
    {
        global $db;

        $db->delete_query('settinggroups',"name = 'hidecontent'");
        $db->delete_query('settings',"name LIKE 'hidecontent_%'");
        rebuild_settings();
    }

    function hidecontent_showthread_start()
    {
        global $db, $thread, $mybb, $replied;
        $query = $db->simple_select('posts', 'pid', "tid='{$thread['tid']}' AND uid='{$mybb->user['uid']}' AND visible='{$thread['visible']}'", array('limit' => 1));
        $replied = $db->num_rows($query);
    }

    function hidecontent_parse_message($message)
    {
        global $mybb, $post, $replied;

        // User should be able to see their own hidden content
        if($mybb->user['uid'] != $post['uid'])
        {
            // Ignore if user is within an ignored usergroup
            if (!is_member($mybb->settings['hidecontent_ignoregroups'], $mybb->user))
            {
                $replace = '<div class="hide_box">';

                // Guest?
                if ($mybb->user['usergroup'] == 1)
                {
                    $lock = true;
                    $replace .= 'Please <a href="member.php?action=login">login</a> or <a href="member.php?action=register">register</a> to view hidden content.';
                }
                else
                {
                    // Does the user meet the minimum post requirement?
                    if ($mybb->user['postnum'] < intval($mybb->settings['hidecontent_minposts']))
                    {
                        $lock = true;
                        $replace .= "Users require at least {$mybb->settings['hidecontent_minposts']} posts to view hidden content.";
                    }
                    elseif ($replied == 0)
                    {
                        // The user has NOT replied to this thread
                        $lock = true;
                        $replace .= "Please reply to this thread to view hidden content.";
                    }
                }

                $replace .= '</div>';
            }
        }

        // Replace hidden content with user friendly message
        if($lock)
            $message = preg_replace('~\[hide\](.*?)\[/hide\]~s', $replace, $message);
        // When unlocked, remove the hide BBCode
        else
            $message = preg_replace("~\[hide\](.*?)\[/hide\]~s", "$1", $message);

        return $message;
    }

    // For when a user quotes hidden content
    function hidecontent_quoted_message(&$quoted_post)
    {
        $quoted_post['message'] = preg_replace('~\[hide\](.*?)\[/hide\]~s', '[b][color=#FF9C9C]Hidden content...[/color][/b]', $quoted_post['message']);
    }

Any feedback?  Angel

Regards,
  • Make use of is_member() core function.
  • $query = $db->query("SELECT pid FROM ".TABLE_PREFIX."posts WHERE tid='".intval($tid)."' AND uid ='".intval($uid)."'");

    You may want to check if the reply is visible (not unapproved or soft deleted).
  • Your code is not optimized, this will make plenty of queries per thread page. You will need to get all the poster of X threads at, lets say, showthread_start, cache them and use that instead of a query per message.

    Check the postbit hook as well.
  •         else
            {
                $message = str_replace('[hide]', '', $message);
                $message = str_replace('[/hide]', '', $message);
            }

    I would assume unclosed/unopened tags shouldn't simply be replaced?
(2015-10-15, 05:44 PM)Omar G. Wrote: [ -> ]
  • Make use of is_member() core function.
  • $query = $db->query("SELECT pid FROM ".TABLE_PREFIX."posts WHERE tid='".intval($tid)."' AND uid ='".intval($uid)."'");

    You may want to check if the reply is visible (not unapproved or soft deleted).
  • Your code is not optimized, this will make plenty of queries per thread page. You will need to get all the poster of X threads at, lets say, showthread_start, cache them and use that instead of a query per message.

    Check the postbit hook as well.
  •         else
            {
                $message = str_replace('[hide]', '', $message);
                $message = str_replace('[/hide]', '', $message);
            }

    I would assume unclosed/unopened tags shouldn't simply be replaced?

Ah yes, I see exactly what you mean, Omar.

Quote:Check the postbit hook as well.
[*]
        else
        {
            $message = str_replace('[hide]', '', $message);
            $message = str_replace('[/hide]', '', $message);
        }

I would assume unclosed/unopened tags shouldn't simply be replaced?

This is for when they are able to see the hidden content, otherwise they see:

Quote:[hide]The answer is 5![/hide]

Opposed to:

Quote:The answer is 5!

Newer version thus far:

<?php
    /**
    * Jordan Francis
    * Oct 8, 2015
    * Copyright 2015, All Rights Reserved
    * Website:
    */

    if(!defined('IN_MYBB')) die('This file cannot be accessed directly.');

    // Hooks
    $plugins->add_hook('showthread_start', 'hidecontent_hasreplied');
    $plugins->add_hook('parse_message', 'hidecontent_parse');
    $plugins->add_hook('parse_quoted_message', 'hidecontent_quote');

    function hidecontent_info()
    {
        return array(
            'name' => 'Hide Content',
            'description' => 'Hides content from guests and users without no. of posts/replying to the thread.',
            'website' => 'http://mybb.com',
            'author' => 'Jordan F',
            'authorsite' => 'http://mybb.com',
            'version' => '1.0',
            'compatibility' => '18*',
            'guid' => ''
        );
    }

    function hidecontent_activate()
    {
        global $db;

        $group = array(
            'name' => 'hidecontent',
            'title' => 'Hide Content',
            'description' => 'Settings relating to the hide content plugin.',
            'isdefault' => 0
        );

        $db->insert_query('settinggroups', $group);
        $gid = $db->insert_id();

        $settings = array(
            array(
                'name' => 'hidecontent_ignoregroups',
                'title' => 'Ignore Usergroups',
                'description' => 'Usergroups to ignore? Their usergroup ID comma seperated without spaces.',
                'optionscode' => 'groupselect',
                'value' => '4',
                'disporder' => 1,
                'gid' => intval($gid)
            ),
            array(
                'name' => 'hidecontent_minposts',
                'title' => 'Post Requirement',
                'description' => 'The standard amount of posts to view hidden content?',
                'optionscode' => 'text',
                'value' => '5',
                'disporder' => 2,
                'gid' => intval($gid)
            )
        );

        foreach($settings as $setting) $db->insert_query('settings', $setting);

        rebuild_settings();
    }

    // Delete relevant settings from database
    function hidecontent_deactivate()
    {
        global $db;

        $db->delete_query('settinggroups',"name = 'hidecontent'");
        $db->delete_query('settings',"name LIKE 'hidecontent_%'");

        rebuild_settings();
    }

    // Work out usergroups to be ignored configured in admin cp
    function hidecontent_ignoregroup()
    {
        global $mybb;

        // All usergroups ignored
        if($mybb->settings['hidecontent_ignoregroups'] == '-1') return true;

        if($mybb->settings['hidecontent_ignoregroups'])
        {
            $usergroups = explode(",", $mybb->settings['hidecontent_ignoregroups']);
            if(in_array($mybb->user['usergroup'], $usergroups)) return true;
        }
    }

    function hidecontent_hasreplied()
    {
        /*
         * Select ? from posts where tid = $tid and uid = $poster
         * Set $replied = number of rows from query
         */

        global $thread, $mybb, $replied, $db;
        $query = $db->simple_select('posts', 'pid', "tid='{$thread['tid']}' AND uid ='{$mybb->user['uid']}'");
        $replied = $db->num_rows($query);
    }

    function hidecontent_parse($message)
    {
        global $mybb, $post, $replied;

        // User should be able to see their own hidden content
        if($mybb->user['uid'] != $post['uid'])
        {
            // Ignore if user is within an ignored usergroup
            if (!hidecontent_ignoregroup()) {
                $replace = '<div class="hide_box">';

                // Guest?
                if ($mybb->user['usergroup'] == 1)
                {
                    $lock = true;
                    $replace .= 'Please <a href="member.php?action=login">login</a> or <a href="member.php?action=register">register</a> to view hidden content.';
                }
                else
                {
                    // Does the user meet the minimum post requirement?
                    if ($mybb->user['postnum'] < $mybb->settings['hidecontent_minposts'])
                    {
                        $lock = true;
                        $replace .= "Users require at least {$mybb->settings['hidecontent_minposts']} posts to view hidden content.";
                    }
                    elseif ($replied == 0)
                    {
                        // The user has NOT replied to this thread
                        $lock = true;
                        $replace .= "Please reply to this thread to view hidden content.";
                    }
                }

                $replace .= '</div>';
            }
        }

        // Disable plugin in printhread.php
        if(THIS_SCRIPT == "printthread.php") $lock = true;

        if($lock)
        {
            $message = preg_replace('~\[hide\](.*?)\[/hide\]~s', $replace, $message);
        }
        else
        {
            $message = str_replace('[hide]', '', $message);
            $message = str_replace('[/hide]', '', $message);
        }

        return $message;
    }

    // For when a user quotes hidden content
    function hidecontent_quote(&$quoted_post)
    {
        $quoted_post['message'] = preg_replace('~\[hide\](.*?)\[/hide\]~s', '[b][color=#FF9C9C]Hidden content...[/color][/b]', $quoted_post['message']);
    }
Few things:
1. Why are you selecting all posts made by user in that thread? That's not optimal. You only need to get their single reply (use limit = 1 as 4th argument). http://dev.mysql.com/doc/refman/5.6/en/l...ation.html
2. hidecontent_minposts could be a numeric type setting. And/or $mybb->settings['hidecontent_minposts'] casted to int just in case.
3. Templates and language strings could be used.
4. As Omar said, is_member() should be rather used (why would you write another function that does a similar thing but doesn't consider additional groups?) and post status checked for unapproved/soft-deleted replies.
5. I'm quite sure you don't cover all cases, for example:
- your printthread solution isn't good, it hides everything for everyone without any message
- archive has its own way of displaying posts, also requires other hooks: https://github.com/mybb/mybb/blob/featur...x.php#L120
- same applies to portal announcements: https://github.com/mybb/mybb/blob/featur...l.php#L585
- and also other things like quoting a post in newreply.php, editing someone's post with editpost.php or quick edit (when you're a mod)
- own hidden content within quotes won't be seen

EDIT: and here a similar 1.8 plugin which covers most of these things, but not all (+ other things I forgot, like RSS): https://github.com/WhiteNeo/Hide-Content...hideip.php
Quote:This is for when they are able to see the hidden content, otherwise they see:

I probably didn't explain myself. Try:
[hide]Content[/hide][/hide]

Surely the last [/hide] should be displayed because it was never opened to being with?
(2015-10-17, 12:43 AM)Destroy666 Wrote: [ -> ]Few things:
1. Why are you selecting all posts made by user in that thread? That's not optimal. You only need to get their single reply (use limit = 1 as 4th argument). http://dev.mysql.com/doc/refman/5.6/en/l...ation.html
2. hidecontent_minposts could be a numeric type setting. And/or $mybb->settings['hidecontent_minposts'] casted to int just in case.
3. Templates and language strings could be used.
4. As Omar said, is_member() should be rather used (why would you write another function that does a similar thing but doesn't consider additional groups?) and post status checked for unapproved/soft-deleted replies.
5. I'm quite sure you don't cover all cases, for example:
- your printthread solution isn't good, it hides everything for everyone without any message
- archive has its own way of displaying posts, also requires other hooks: https://github.com/mybb/mybb/blob/featur...x.php#L120
- same applies to portal announcements: https://github.com/mybb/mybb/blob/featur...l.php#L585
- and also other things like quoting a post in newreply.php, editing someone's post with editpost.php or quick edit (when you're a mod)
- own hidden content within quotes won't be seen

EDIT: and here a similar 1.8 plugin which covers most of these things, but not all (+ other things I forgot, like RSS): https://github.com/WhiteNeo/Hide-Content...hideip.php

(2015-10-17, 06:23 AM)Omar G. Wrote: [ -> ]
Quote:This is for when they are able to see the hidden content, otherwise they see:

I probably didn't explain myself. Try:
[hide]Content[/hide][/hide]

Surely the last [/hide] should be displayed because it was never opened to being with?

Thank you guys very much for your feedback - it's helpful! I've tried to cover all your points (apart from caching and Destroy666's #5 which I need to do!). This plugin is my first and more a learning experience than anything.

Here's the new code (will update thread):

Edit: For some reason I forgot to include the showthread_start hook update in my last post:

<?php
    /**
     * Jordan Francis
     * Oct 8, 2015
     * Copyright 2015, All Rights Reserved
     * Website:
     */

    if(!defined('IN_MYBB')) die('This file cannot be accessed directly.');

    // Hooks
    $plugins->add_hook('showthread_start', 'hidecontent_showthread_start');
    $plugins->add_hook('parse_message', 'hidecontent_parse_message');
    $plugins->add_hook('parse_quoted_message', 'hidecontent_quoted_message');

    function hidecontent_info()
    {
        return array(
            'name'          => 'Hide Content',
            'description'   => 'Hides content from guests and users without no. of posts/replying to the thread.',
            'website'       => 'http://mybb.com',
            'author'        => 'Jordan F',
            'authorsite'    => 'http://mybb.com',
            'version'       => '1.0',
            'compatibility' => '18*',
            'guid'          =>    ''
        );
    }

    function hidecontent_activate()
    {
        global $db;

        $group = array(
            'name'          => 'hidecontent',
            'title'         => 'Hide Content',
            'description'   => 'Settings relating to the hide content plugin.',
            'isdefault'     => 0
        );

        $db->insert_query('settinggroups', $group);
        $gid = $db->insert_id();

        $settings = array(
            array(
                'name'          => 'hidecontent_ignoregroups',
                'title'         => 'Ignore Usergroups',
                'description'   => 'Usergroups to ignore? Their usergroup ID comma seperated without spaces.',
                'optionscode'   => 'groupselect',
                'value'         => '4',
                'disporder'     => 1,
                'gid'           => intval($gid)
            ),
            array(
                'name'          => 'hidecontent_minposts',
                'title'         => 'Post Requirement',
                'description'   => 'The standard amount of posts to view hidden content?',
                'optionscode'   => 'numeric',
                'value'         => '5',
                'disporder'     => 2,
                'gid'           => intval($gid)
            )
        );

        foreach($settings as $setting)
        {
            $db->insert_query('settings', $setting);
        }

        rebuild_settings();
    }

    // Delete relevant settings from database
    function hidecontent_deactivate()
    {
        global $db;

        $db->delete_query('settinggroups',"name = 'hidecontent'");
        $db->delete_query('settings',"name LIKE 'hidecontent_%'");
        rebuild_settings();
    }

    function hidecontent_showthread_start()
    {
        global $db, $thread, $mybb, $replied;
        $query = $db->simple_select('posts', 'pid', "tid='{$thread['tid']}' AND uid='{$mybb->user['uid']}' AND visible='{$thread['visible']}'", array('limit' => 1));
        $replied = $db->num_rows($query);
    }

    function hidecontent_parse_message($message)
    {
        global $mybb, $post, $replied;

        // User should be able to see their own hidden content
        if($mybb->user['uid'] != $post['uid'])
        {
            // Ignore if user is within an ignored usergroup
            if (!is_member($mybb->settings['hidecontent_ignoregroups'], $mybb->user))
            {
                $replace = '<div class="hide_box">';

                // Guest?
                if ($mybb->user['usergroup'] == 1)
                {
                    $lock = true;
                    $replace .= 'Please <a href="member.php?action=login">login</a> or <a href="member.php?action=register">register</a> to view hidden content.';
                }
                else
                {
                    // Does the user meet the minimum post requirement?
                    if ($mybb->user['postnum'] < intval($mybb->settings['hidecontent_minposts']))
                    {
                        $lock = true;
                        $replace .= "Users require at least {$mybb->settings['hidecontent_minposts']} posts to view hidden content.";
                    }
                    elseif ($replied == 0)
                    {
                        // The user has NOT replied to this thread
                        $lock = true;
                        $replace .= "Please reply to this thread to view hidden content.";
                    }
                }

                $replace .= '</div>';
            }
        }

        // Replace hidden content with user friendly message
        if($lock)
            $message = preg_replace('~\[hide\](.*?)\[/hide\]~s', $replace, $message);
        // When unlocked, remove the hide BBCode
        else
            $message = preg_replace("~\[hide\](.*?)\[/hide\]~s", "$1", $message);

        return $message;
    }

    // For when a user quotes hidden content
    function hidecontent_quoted_message(&$quoted_post)
    {
        $quoted_post['message'] = preg_replace('~\[hide\](.*?)\[/hide\]~s', '[b][color=#FF9C9C]Hidden content...[/color][/b]', $quoted_post['message']);
    }
  • I would like to be able to disable the plugin without it deleting my previous settings for it. Note the differences between disabling/uninstalling.
  • $query = $db->simple_select('posts', 'pid', "tid='{$thread['tid']}' AND uid='{$mybb->user['uid']}' AND visible='{$thread['visible']}'", array('limit' => 1));
    I think you got this wrong.
  • $quoted_post['message'] = preg_replace('~\[hide\](.*?)\[/hide\]~s', '[b][color=#FF9C9C]Hidden content...[/color][/b]', $quoted_post['message']);
    It may be a matter of preferences but why would you add -formatted- content? Shouldn't it just be stripped away?
(2015-10-22, 04:13 AM)Omar G. Wrote: [ -> ]
  • I would like to be able to disable the plugin without it deleting my previous settings for it. Note the differences between disabling/uninstalling.
  • $query = $db->simple_select('posts', 'pid', "tid='{$thread['tid']}' AND uid='{$mybb->user['uid']}' AND visible='{$thread['visible']}'", array('limit' => 1));
    I think you got this wrong.
  • $quoted_post['message'] = preg_replace('~\[hide\](.*?)\[/hide\]~s', '[b][color=#FF9C9C]Hidden content...[/color][/b]', $quoted_post['message']);
    It may be a matter of preferences but why would you add -formatted- content? Shouldn't it just be stripped away?

Sure, disabling is easy. Smile
I don't think I got it wrong? If the logged in user has posted on the visiting thread it will return 1 row therefore true?
Sure, it's a preference - I suppose I could strip it award.

Thanks,
I meant its visibility. You are hooking at showthread_start so you should be using $visibleonly