Hide Content - Require Feedback
#1
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,
Reply
#2
  • 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?
Soporte en Español

[Image: signature.png]

Discord at omar.gonzalez (Omar G.#6117); Telegram at @omarugc;
Reply
#3
(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']);
    }
Reply
#4
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
Reply
#5
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?
Soporte en Español

[Image: signature.png]

Discord at omar.gonzalez (Omar G.#6117); Telegram at @omarugc;
Reply
#6
(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']);
    }
Reply
#7
  • 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?
Soporte en Español

[Image: signature.png]

Discord at omar.gonzalez (Omar G.#6117); Telegram at @omarugc;
Reply
#8
(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,
Reply
#9
I meant its visibility. You are hooking at showthread_start so you should be using $visibleonly
Soporte en Español

[Image: signature.png]

Discord at omar.gonzalez (Omar G.#6117); Telegram at @omarugc;
Reply


Forum Jump:


Users browsing this thread: 6 Guest(s)