Please upgrade here. These earlier versions are no longer being updated and have security issues.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.
Options

Adding Modules To Discussions

Thank you all for the help in the past few days. Thanks to your help I've been able to figure out how to edit some of the modules and plugins to do what I wanted. I've also learned to make a lot of changes using custom.css.

The one thing I am struggling with and need your help with is how to edit some of these plugins to display in my discussions rather than my profile.

I've tried changing the code for the Karma bank and Friendship add-on where it said ProfileController to make it say DiscussionsController, but that brought me some weird results.

So now I am asking here: how can I add the Karma Bank amount that's displayed in Profile under Discussions, or even add it to the menu header? How can I add the Friendship box that's displays in Profile to display on Discussions panel?

The above is my current Discussions page.

I want to display the Karma Bank amount in menu header, and in the panel to the left where it says My Drafts.
How can I display the friendships box under the All Time Leaders table?

The red rectangle is what I am trying to move from Profile page to Discussions.

Comments

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    First of all: editing files is nearly never the right way! Looking at the source code is always helpful but you should never edit anything.

    So let's start with the Friendship plugin.

    When speaking about a three year old plugin, things might be a little different. In fact it would be the cleanest way to create a copy. The copy uses a few files and in order to use a customized copy, you would have to change several things: file names, class names, plugin description, references to those classes...

    Maybe in this case it would be okay to simply change that plugin sigh

    There is another way, though! Your suggestion could be considered as an enhancement and I could imagine that a pull request will be acccepted. So let's talk about how the code could be changed and then make a pull request!

    A module is attached to the panel with the addModule() call. Friendship attaches the module via base_render_before() so it is accessible on every page. No need to do anything here.

    Modules print out html via their toString() method. When looking at the code, we see that the toString method starts with checking if the module is attached to a profile page. If not, nothing happens. Well, that's bad. So let's change it! This is the code which we have to change:

    public function ToString() {
        if($this->_Sender instanceof ProfileController) {
            if(CheckPermission('Friendships.Friends.View')){
                $ProfileOwnerID = $this->_Sender->User->UserID;
    

    So when we are looking at a profile, we need to get the profile user we are looking at. If we are at a discussion page, we want to see the Friendship module as iff we are looking at our own profile.

    public function ToString() {
        if($this->_Sender instanceof ProfileController) {
            if(CheckPermission('Friendships.Friends.View')){
                $ProfileOwnerID = $this->_Sender->User->UserID;
    

    We do not need that controller check. But we need a ProfileOwnerID and if we are not looking at a profile, we would need the session users id.

    public function ToString() {
        if($this->_Sender instanceof ProfileController) {
            $ProfileOwnerID = $this->_Sender->User->UserID;
        } else {
            $ProfileOwnerID = Gdn::Session()->UserID;
        }
        if(CheckPermission('Friendships.Friends.View')){
            // $ProfileOwnerID = $this->_Sender->User->UserID;
    

    Basically that's all that's needed. You have to take care for one of the last brackets, through. The first if condition is now closed at the top of the file so the former closing bracket in line 137 (of the original file) must be deleted.
    But there is another problem: what should guests see when they look at the page? That requires some more changes. I've mixed up that function in order change it's behavior and created a pull request. If you like to, you can take a look at what I've changed exactly: https://github.com/R-J/Friendships

  • Options

    @R_J Thank you so much for explaining that so well. The way you taught me here will certainly help me modify modules and understand the Garden framework. I could not even imagine a week ago that I'd be able to edit plugins/modules, but with the help of the community it's so much less frustrating than going solo. Thanks a ton as always! Would you suggest I try this same approach on the Karma bank plugin to get the Karma amount to show up in all the pages and not just profile?

    I'd like to try the Karma bank plugin edit myself, but a general direction would be nice.

  • Options

    @R_J Another question: How do I make the friendship box panel go above another plugin's panel? Simply want to change the order in which the modules appear in that panel.

  • Options
    vrijvlindervrijvlinder Papillon-Sauvage MVP
    edited June 2016

    @okhawaja said:
    How do I make the friendship box panel go above another plugin's panel? Simply want to >change the order in which the modules appear in that panel.

    Since the Box is a Module, you would want to Sort the modules. You can try the plugin ModuleSort or you can sort it manually via the config.php .

    Simply add your module in the order you want it to appear on the list of modules.

    // Modules
    $Configuration['Modules']['Vanilla']['Panel'] = array('FriendshipsModule','MeModule', 'UserBoxModule', 'GuestModule', 'NewDiscussionModule', 'DiscussionFilterModule', 'SignedInModule', 'CategoriesModule', 'OnlineNowModule', 'Ads');
    
  • Options
    R_JR_J Ex-Fanboy Munich Admin

    This is the code where the line is created:

       /*
        *   Adds a tab to user profiles linking Karma Bank
        *   Shows current Balance as count
        */
        public function ProfileController_AddProfileTabs_Handler($Sender){
            if(!$this->IsEnabled())
                return;
            $KarmaBank = new KarmaBankModel($Sender->User->UserID);
            $Balance = $KarmaBank->GetBalance();
            $Sender->AddProfileTab('KarmaBank','profile/karmabank/'.$Sender->User->UserID.'/'.rawurlencode($Sender->User->Name),
                            'KarmaBank',T('KarmaBank.KarmaBank','Karma Bank').(isset($Balance->Balance) && is_numeric($Balance->Balance) ? '<span class="Count">'.sprintf(T('KarmaBank.NumberFormat',"%01.2f"),$Balance->Balance).'</span>':''));
        }
    

    The first two lines check if the plugin is enabled. If you want to check if another plugin is enabled, you can write

    if (c('EnabledPlugins.KarmaBank') !== true) {
        return;
    }
    

    If your plugin requires another plugin, you could (and should) specify this already in the plugin info array like that 'RequiredPlugins' => ['KarmaBank' => '>= 0.9.7.3b']. If your plugin contains this in the info array, you wouldn't be able to enable it if not KarmaBank has been enabled beforehand!

    The next line creates an instant of the KarmaBank model and initiates it with the profile user. You do not have a profile user, but you are interested in the session used. Si it would read like that: $karmaBank = new KarmaBankModel(Gdn::session()->UserID);
    The next line stays as it is, but let's split the last line. $Sender->AddProfileTab() is a profileController specific action. We will not use that. Let's focus on building a nice link. Let me reformat what we have above, taking into account what the parameters of the AddProfileTab method are public function addProfileTab($TabName, $TabUrl = '', $CssClass = '', $TabHtml = '') {

    $Sender->AddProfileTab(
        'KarmaBank', // $TabName - no need for any tab.
        'profile/karmabank/'.$Sender->User->UserID.'/'.rawurlencode($Sender->User->Name), // This is the url!
        'KarmaBank', // This is the CssClass
        T('KarmaBank.KarmaBank','Karma Bank'). // First part of the links text
          (isset($Balance->Balance) && is_numeric($Balance->Balance) ? // if there is a balance...
            '<span class="Count">'.sprintf(T('KarmaBank.NumberFormat',"%01.2f"),$Balance->Balance).'</span>' : // add a counter
            '' // add nothing if there is no balance
        )
    );
    

    Now it should be easy. But some things have changed what the html markup is about and we would use some handy functions. Browse through the file functions.render.php to find some. We will use function anchor($Text, $Destination = '', $CssClass = '', $Attributes = array(), $ForceAnchor = false) and function userUrl($User, $Px = '', $Method = '', $Get = null)

    $balance = $karmaBank->getBalance();
    
    $text = t('KarmaBank.KarmaBank','Karma Bank');
    if (isset($balance->Balance) && is_numeric($balance->Balance)) {
        $text .= '<span class="Aside"><span class="Count">';
        $text .= sprintf(t('KarmaBank.NumberFormat',"%01.2f"),$balance->Balance);
        $text .= '</span></span>';
    }
    
    echo anchor(
        // $Text: the link text
        $text,
        // $Destination: the url
        userUrl(
            Gdn::session()->User, // $User
            '', // $Px Ignore this
            'karmabank' // $Method: we want this link to point to /profile/karmabank!
        ),
        'KarmaBank' // $CssClass
    );
    

    The code we have right now will add a link to the karmabank of the currently logged in user and you would be able to use that link anywhere!

    Try this:

    public function discussionController_render_before($sender, $args) {
        // If plugin is not enabled or this is a guest, do nothing.
        if (c('EnabledPlugins.KarmaBank') !== true || !Gdn::session()->isValied()) {
            return;
        }
    
        // Built up link text.
        $karmaBank = new KarmaBankModel(Gdn::session()->UserID);
        $balance = $karmaBank->getBalance();
        $text = t('KarmaBank.KarmaBank','Karma Bank');
        if (isset($balance->Balance) && is_numeric($balance->Balance)) {
            $text .= '<span class="Aside"><span class="Count">';
            $text .= sprintf(t('KarmaBank.NumberFormat',"%01.2f"),$balance->Balance);
            $text .= '</span></span>';
        }
    
        $karmaLink = anchor(
            $text,
            userUrl(
                Gdn::session()->User,
                '',
                'karmabank'
            ),
            'KarmaBank'
        );
    
        echo $karmaLink;
    }
    

    I have not checked the code, but I hope it works. If not, I'm sure you can find the errors I made by yourself until now! :)

    Now you want to add it somewhere else. You should inspect the target where you like to see the link to appear: this is a div.BoxDiscussionFilter. Do a fulltext search for "BoxDiscussionFilter". You will find a file discussionfilter.php which you should take a look at. I've told you that you can add content when you find "fireEvent" anywhere. discussionfilter.php has "AfterDiscussionFilters". So you can create public function base_afterDiscussionFilters_handler($sender) {...} and add the code there.

    Now your link will be shown anywhere, where this menu is shown! WOOHOOO!

    But the html markup is wrong... Look at the html source or the discussions.php file:

            $Controller->fireEvent('AfterDiscussionFilters');
            ?>
        </ul>
    

    We echo our link after a li element and before the closing ul element. So change your code that it echos '

    '.$karmaLink.'' and the markup should be fine.
  • Options

    Just want to add that when you friend someone and then that user gets deleted, the deleted friend remains in your list and gives a page not found when you click on it.

  • Options

    @vrijvlinder your solution about the config was the best.....I don't like that Module Sorter plugin....it somehow reset a lot of my forum's theme settings and disabled some plugins all on its own and it didn't even display all the modules...Thanks for the solution.

  • Options
    RiverRiver MVP
    edited June 2016

    @okhawaja said:
    I don't like that Module Sorter plugin....it somehow reset a lot of my forum's theme settings and disabled some plugins all on its own and it didn't even display all the modules...Thanks for the solution.

    There is nothing in the Module Sort plugin that would reset any theme settings in the downloads area, nor would it disable other plugins. It is best not to blame other plugins for your coding problems that you insert.

    Suggest you restart with a clean vanilla installation without any of your code changes, that are causing your own problems. Until you remove your broken code from plugins, core and themes and start with fresh new copies, you will continue to have problems and may place undue blame on other plugins for your coding mistakes.

    Pragmatism is all I have to offer. Avoiding the sidelines and providing centerline pro-tips.

Sign In or Register to comment.