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

Show information from a specific plugin in a discussion

JoZ3_69JoZ3_69
edited October 2016 in Vanilla 2.0 - 2.8

Hi, I need get the information from a specific pllugin to show in other place from the discussion, actually with $this->fireEvent('AuthorInfo'); show the role (Role title pluglng) and rank (Yaga - Rank in Meta) and what I want is to take the information of each plugin individually. Thanks

Tagged:

Comments

  • R_JR_J Ex-Fanboy Munich Moderator

    That is quite easy. The information you like is stored in the user table. And every information of the user table is accessible when you have some kind of access to a user object.

    When an event is fired, nearly all the times there are some values passed to that event that you will be able to work with. Start with a basic plugin skeleton (with PluginInfo array and a class definition) and insert something like that:

    public function discussionController_authorInfo_handler($sender, $args)
        // Show all the EventArguments that have been passed.
        print_r(array_keys($sender->EventArguments));
    
        // This is exactly the same and shorter, so I will use that from now on
        // print_r(array_keys($args));
    }
    

    Now when you look at a discussion you will see which EventArguments are available. "Author" is one of them!
    Change the code in the function above into

    print_r(array_keys((array)$args['Author']);
    

    That will give you a list of all available fields you are able to show easily.

    You wanted to see the title? Put that in the function:

    echo '<span class="MItem AuthorTitle">', $args['Author']->Title, '</span>';
    

    But I'm not sure what that should be good for, since it is already shown with the standard theme...


    Getting the Rank is not as easy, since you only have the RankID and what you want is the Rank Name. That's why you have to look up the name.

    Put this in the function:

    echo '<span class="MItem AuthorRank">', (new RankModel())->getByID($args['Author']->RankID)->Name, '</span>';
    


    JoZ3_69whu606hgtonight
  • @R_J thanks mate this helped me understand some things and I will be of useful in the future, but it's not what I'm trying to get. I want to separate the output of Role title and Yaga Rank. I will like know if I can get out of these individually and place them anywhere on the head of the discussion.

    Actually this my output (discussion.php by default):

    And I'm looking for this, without using css:

  • R_JR_J Ex-Fanboy Munich Moderator

    Alright, that isn't much more complicated. By now you might have understood how to access information. On to the next step: how to find out where information can be placed.

    Some remarks on "fireEvent()": whenever you see a call to fireEvent() function in the code, you are able to take influence. you do so by writing a plugin that contains a "public function NameOfTheClassThatContainsTheCall_NameOfTheFiredEvent_handler($sender, $args) {".
    $sender is an object of the class that called the fireEvent.
    $args is an array of all "EventArguments" that have been passed to this event.
    Sometimes you cannot directly see which class contains the event. In such cases look at your forums url where you want to change something. Does it read ".../discussion/123/thisandthat" then it would be "public function discussionController_NameOfEvent_handler($sender, $args) {".
    If it is ".../profile" your function must be named profileController...

    There is a nice plugin which will help you finding the correct events: eventi

    So you would have to find out the correct event name and the name of the controller. Afterwards you can try to find out how to output the information.

    In your case, you want to change how a single discussion looks, so the first start of the function you need to write would be "discussionController_". Look at what Eventi shows you and you will find a name of an event. Sometimes you would need to use CSS nevertheless.

    Afterwards you should take a look at the provided $args. If you are unlucky, you might only have a discussion object, but no user object. In such a case you would have to create a user object based on the discussions InsertUserID.

    But I would suggest you start with what you have by now and if something isn't working as expected or you get stuck, just ask again. In such a case it might be helpful if you could provide the code that you already have.


    hgtonight
  • Hi @R_J sorry for the delay, I was away for the weekend :).

    I've almost accomplished what I seek, with some css, so it looks at the moment:

    But I want to move the badges indicated in the red circle at the head of post. This is the code of the file discussion.php

    <?php
    /**
     * @copyright 2009-2014 Vanilla Forums Inc.
     * @license http://www.opensource.org/licenses/gpl-2.0.php GPLv2
     */
    
    if (!defined('APPLICATION')) {
        exit();
    }
    $UserPhotoFirst = c('Vanilla.Comment.UserPhotoFirst', true);
    
    $Discussion = $this->data('Discussion');
    $Author = Gdn::userModel()->getID($Discussion->InsertUserID); // UserBuilder($Discussion, 'Insert');
    
    // Prep event args.
    $CssClass = CssClass($Discussion, false);
    $this->EventArguments['Discussion'] = &$Discussion;
    $this->EventArguments['Author'] = &$Author;
    $this->EventArguments['CssClass'] = &$CssClass;
    
    // DEPRECATED ARGUMENTS (as of 2.1)
    $this->EventArguments['Object'] = &$Discussion;
    $this->EventArguments['Type'] = 'Discussion';
    
    // Discussion template event
    $this->fireEvent('BeforeDiscussionDisplay');
    ?>
    <div id="<?php echo 'Discussion_'.$Discussion->DiscussionID; ?>" class="<?php echo $CssClass; ?>">
        <div class="Discussion row">
            <div class="col-md-1 Author">
                <?php
                    echo userPhoto($Author);
                    $this->fireEvent('AuthorInfo');
                ?>
            </div>
            <div class="col-md-11 Discussion_Body">
                <div class="Item-Header DiscussionHeader">
                    <div class="AuthorWrap">
                        <div class="Author">
                            <?php
                                $TRole = substr(strstr($CssClass, 'Role_'), 5);
                                echo userAnchor($Author, 'Username').' - <span>'.$TRole.'</span>'; ?>
                        </div>
                    </div>
                    <div class="Meta DiscussionMeta">
                        <span class="MItem DateCreated">
                            <?php echo anchor(Gdn_Format::date($Discussion->DateInserted, 'html'), $Discussion->Url, 'Permalink', array('rel' => 'nofollow')); ?>
                        </span>
                        <?php
                            // Include source if one was set
                            if ($Source = val('Source', $Discussion))
                                echo ' '.Wrap(sprintf(t('via %s'), t($Source.' Source', $Source)), 'span', array('class' => 'MItem MItem-Source')).' ';
                            // Category
                            if (c('Vanilla.Categories.Use')) {
                                echo ' <span class="MItem Category">';
                                echo ' '.t('in').' ';
                                echo anchor(htmlspecialchars($this->data('Discussion.Category')), CategoryUrl($this->data('Discussion.CategoryUrlCode')));
                                echo '</span> ';
                            }
                            $this->fireEvent('DiscussionInfo');
                        ?>
                    </div>
                </div>
                <?php $this->fireEvent('BeforeDiscussionBody'); ?>
                <div class="Item-BodyWrap">
                    <div class="Item-Body">
                        <div class="Message">
                            <?php echo FormatBody($Discussion); ?>
                        </div>
                        <?php
                            $this->fireEvent('AfterDiscussionBody');
                            WriteReactions($Discussion);
                            if (val('Attachments', $Discussion)) {
                                WriteAttachments($Discussion->Attachments);
                            }
                        ?>
                    </div>
                </div>
            </div>
        </div>
    </div>
    

    The $this->fireEvent('AuthorInfo'); show me three items, title role (That I hidde with css), Rank, and the feature badges. I put the title role in the head of the post with the outut from $CssClass check the line 41, but as I said before I want to put the badges next to the title role at the head of the post.

    Is there any way to convert the output of $this->fireEvent('AuthorInfo'); in a string to store it in a variable?

    Thanks for your help :)

  • R_JR_J Ex-Fanboy Munich Moderator

    Sorry, but I would say the question is wrong and the way you do it is wrong.
    But anyway, it is your way and maybe I am the one who is wrong... *sigh*

    Fact is: I do not know what you are trying to achieve. And the answer I gave you above didn't help you to since you are not doing what I was expecting you to do. Are you
    a) trying to get information from Yaga
    b) trying to display any information by the help of events (without changing views)
    c) something completely different

    The answer would always be: depends on what you need. Ask a specific questions


  • I think OP simply wants to move a bit of HTML outputted by YAGA to another place.

    I say simply, but I think you'll have to use Javascript for that (or edit core files).

    Can you provide a link to your forum?

  • Don't worry, maybe all is lost in translation, the English is not my native language. will try to explain what I want to do, step by step:

    1. $this->fireEvent('AuthorInfo') show me the information from three plugins, Roletitle, Yaga Rank and Yaga Feature.
    2. What I want is to take each of these data delivered by > $this->fireEvent('AuthorInfo') and put them in different parts of the post.

    Or is possible can convert $this->fireEvent('AuthorInfo') in a string to store it in a variable?.

    Something like this:

    $this->fireEvent('AuthorInfo') , the ouput is Roletitle|YagaRank|YagaFeature (this ouput is a examble)

    $string = $this->fireEvent('AuthorInfo');
    $information = explode("|", $string);
    
    echo $information[1]; // Roletitle - to show on the top of post
    echo $information[2]; // YagaRank - to show on the left of post
    echo $information[3]; // YagaFeature to show on the top of post
    

    Thanks

  • @Caylus said:
    I think OP simply wants to move a bit of HTML outputted by YAGA to another place.

    I say simply, but I think you'll have to use Javascript for that (or edit core files).

    Can you provide a link to your forum?

    I do not want to use js, I'm editing the file discussion.php. Even I can not share a link, because I'm working from my local server.

  • CaylusCaylus ✭✭
    edited November 2016

    Any particular reason you don't want to use Javascript? Particularly since Vanilla already uses loads of Javascript.

    You'd have to edit quite a bit if you don't want to use javascript, not only discussion.php but also YAGA files etc.

    If YAGA updates, you'll have to edit that update too etc.

    It'll be a lot cleaner and safer to use a few lines of javascript, IMHO.

    EDIT: If you want to see how it could be done with JS, could you post here the HTML source code of the discussion page you see in your browser? Not the php code, the HTML it produces.

  • R_JR_J Ex-Fanboy Munich Moderator

    @JoZ3_69 said:
    1. $this->fireEvent('AuthorInfo') show me the information from three plugins, Roletitle, Yaga Rank and Yaga Feature.

    This is the misunderstanding: $this->fireEvent('AuthorInfo') doesn't show you anything. We are talking about the plugins.

    You would have to look at what they do in their DiscussionController_AuthorInfo_Handler methods and do the same in your file. And since they all hook into the event AuthorInfo, they all have a method called DiscussionController_AuthorInfo_Handler, because that is how you use events.

    Instead of copying that all into your view, you really should considering writing that into at least your own helper functions file so that you can make clean calls in your discussion.php


    @JoZ3_69 said:
    I'm editing the file discussion.php.

    Only edit files if there is no other way to achieve things. You haven't understood the concept of events in Vanilla I guess. Maybe you wouldn't have to to change as much as you most probably do. Your theme stays more compatible with existing plugins if you change only what is needed.


    Using js is only a workaround and no solution. You build a DOM only to destroy it afterwards. That couldn't be efficient.


Sign In or Register to comment.