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.

Annotated Plugin - How to write a Plugin for - how to set guest to view title only and not content?

peregrineperegrine MVP
edited May 2012 in Vanilla 2.0 - 2.8

1. Create the shell and assign the basics of the plugin.

  • all of this goes into default.php
  • the plugin name is GuestRestriction.
  • create a mixed case folder with the name of you plugin under plugins directory
    /vanilla/plugins/GuestRestriction.

  • create a default.php

  • fill in the plugin array with appropriate descriptive info

default.php

 <?php if (!defined('APPLICATION')) exit();


    // Define the plugin:
    // the 'GuestRestriction' is the name of the Plugin folder
    $PluginInfo['GuestRestriction'] = array(
        // just the name to display of the plugin below
        'Name' => 'Guest Restriction',
        // a brief description
        'Description' => 'This plugin prevents guests from viewing discussion, onlty title is viewable.',
        // each time you update plugin update version so you can upload it.
        'Version' => '1.0',
        'Author' => "Peregrine"  // the author
    );

2. add the basic setup

// extend the garden Plugin class and create GuestRestrictionPlugin
// class name is created by adding name of plugin folder "GuestRestriction" + "Plugin"

 class GuestRestrictionPlugin extends Gdn_Plugin {

          // where you put your code logic

     // this allows you to enable and disable plugin
        public function Setup() {

        }

    }

3. Add the logic

          - we want to do things on the individual discussion page for each comment. 
          - How did I find where to put this 
          - I searched for FireEvent  in helper_ functions.php in 
          -  the   /vanilla/applications/vanilla/views/discussion folder.

// this function executes on the discussion page
    public function DiscussionController_BeforeCommentMeta_Handler($Sender) {

    }

4. Add more logic. get the session info and test if user is logged in

public function DiscussionController_BeforeCommentMeta_Handler($Sender) {
       // get current session info
        $Session = Gdn::Session();
        // this tests to see is user is logged in
        if (!($Session->IsValid())) {

        }
    }
    }

5. Add more logic. now we add the .css file that will hide the comments.

 public function DiscussionController_BeforeCommentMeta_Handler($Sender) {
        // get current session info
        $Session = Gdn::Session();
        // this tests to see is user is logged in
        if (!($Session->IsValid())) {
            // if the user is NOT logged in - add this css file which resides 
            // in the /plugins/GuestRestriction design folder
            $Sender->AddCssFile('guestrestriction.css', 'plugins/GuestRestriction');
        }
    }

6. create the css file. it should reside in

                    /vanilla/plugins/GuestRestriction/design
                    we name it 'guestrestriction.css,

/vanilla/plugins/GuestRestriction/design/guestrestriction.css contains

.Comment .Message {
display:none;
}

this isolates any classes of Message that are descendants of class Comment and makes them invisible by setting display to none.
I found this by looking in firebug or chrome developer tools.

7. now we ensure this works when a user is viewing individual categories.

// this function essentially produces the same results
// of Discussion View when viewing Category

public function CategoriesController_BeforeDiscussionMeta_Handler(&$Sender) {
                // the call to discussioncontroller at the BeforeDiscussionMeta event
                // How did I find where to put this - I searched for FireEvent 
                //in helper functions in 
                // the   /vanilla/applications/vanilla/views/discussion folder.
                $this->DiscussionController_BeforeCommentMeta_Handler($Sender);
            }

I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

Adrianr0obert

Best Answer

Answers

  • peregrineperegrine MVP
    edited May 2012

    If you "like" this, download the complete example plugin here.

    http://vanillaforums.org/addon/guestrestriction-plugin

    and now one of "You" can add it to the wiki, if you found it helpful.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

    candymanUnderDogfh111JoZ3_69
  • aeryaery Gtricks Forum in 2.2 :) ✭✭✭
    Accepted Answer

    Thanks @peregrine

    Now I will try to make some plugins based on your skelton :)

    peregrine
  • looking forward to your plugins!

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • fh111fh111 Vanilla Padawan ✭✭
    edited May 2012

    i think i am starting to understand how it works. oh it will be awesome as soon as i totally get it!

    thanks so much @peregrine

    edit: i just wish i had more time on my hands, damn :p

    UnderDog
  • fh111 said:
    i think i am starting to understand how it works. oh it will be awesome as soon as i totally get it!

    thanks so much @peregrine

    edit: i just wish i had more time on my hands, damn :p

    fh111 - Once you get the time looking forward to some new plugins!. I'm happy if this added any more insight in to writing some basic plugins. Once I learned a bit about the naming and syntax of the plugin, it really did become a lot clearer and grepping for Fire to find events gave me a clue as to what events are possible.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

    UnderDogfh111
  • Part 2: Modifying an Existing Plugin.

    Lets say instead of blanking out the message for guests (users who are not logged in), you want to replace the message in the body with a link that directs the user to log-in.

    Steps required to modify the plugin.

    1) In this case i know that the message is added in helper_ functions.php in

            - the /vanilla/applications/vanilla/views/discussion folder.
            - I looked for an event that occurs before the comment is echoed.  
            - this looks good.  
                  $Sender->FireEvent('AfterCommentFormat');  
    

    Go back into default.php

    remove or comment out the two functions

        public function DiscussionController_BeforeCommentMeta_Handler($Sender) {
                   ...
        }
    
        public function CategoriesController_BeforeDiscussionMeta_Handler(&$Sender) {
            ...
        }
    

    2) create the new function

                 - the event to fire on is called 'AfterCommentFormat'
                 - so the new function would be called
    
            public function DiscussionController_AfterCommentFormat_Handler($Sender) {
                               // code here
            }
    

    3) add the logic to replace the message.

    public function DiscussionController_AfterCommentFormat_Handler($Sender) {
    
       // get current session info
            $Session = Gdn::Session();
            // this tests to see is user is logged in
            if (!($Session->IsValid())) {
              // note: put whatever url you want below.
              $Sender->EventArguments['Object']->FormatBody = "<a href=http://localhost/vanilla/entry/signin?Target=discussions> This message can be viewed if you log in</a>";
          }
    }
    

    4) resynch with the category controller

       // this function essentially produces the same results 
        // of Discussion View when viewing Category 
            public function CategoriesController_AfterCommentFormat_Handler(&$Sender) {
                // the call to discussioncontroller at the BeforeDiscussionMeta event
                // How did I find where to put this - I searched for FireEvent 
                //in helper functions in 
                // the   /vanilla/applications/vanilla/views/discussion folder.
                $this->DiscussionController_AfterCommentFormat_Handler($Sender);
            }
    

    5) Now users who are not logged in will see the link "This message can be viewed if you log in" that points to the signin process.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

    leafmonsterfh111UnderDog
  • Nice tutorial @peregrine! I was going to say... hiding restricted content with CSS is not really hiding it. But looks like you changed this function to server-side.

    I just made my first plugin and would love some eyes on it: http://vanillaforums.org/discussion/20373/tag-cloud-plugin

    Next step is to delve into event hooks and whatnot...

    UnderDog
  • peregrineperegrine MVP
    edited May 2012

    @leafmonster
    It was more of an exploratory to try to explain the ins and outs of a simple plugin rather than the virtues of the plugin itself.

    One more plugin developer added to the bunch!

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

    leafmonster
  • whenever i click the redirection link, the page cannot be displayed.

    do i have to change the link to my domain?
    http://localhost/vanilla/entry/signin?Target=discussions

  • pedenskipedenski New
    edited June 2012

    btw! thanks for making my request possible :)

  • whenever i click the redirection link, the page cannot be displayed.

    do i have to change the link to my domain?
    http://localhost/vanilla/entry/signin?Target=discussions

    Yes - unless you have everybody signin at your house or on a keyboard at your physical server location. :)

    on line 6 in step 3 above.
    // note: put whatever url you want below.

    revision of comment, should say
    // note: put whatever url you want below. and obviously you must point it to a valid url**

    just for reference.....
    to point to your own domain for signup. highlight the sigin link on your site and right click and copy the link into this position.

    this annotation is for how-to write a plugin - not how to write php, or css, or how to make a link. It does demand some knowledge of php, css, and a bit of how to write some code logic.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

    Sheila
  • peregrineperegrine MVP
    edited June 2012

    How to put a setting option in your plugin. (there are numerous ways to do this - this technique will add a settings option aside the enable button in the dashboard.

    1 - add the SettingsUrl to the array in default.php

    'SettingsUrl' => '/dashboard/plugin/guestrestiction',

    like so:

    $PluginInfo['GuestRestriction'] = array(
        // just the name to display of the plugin below
        'Name' => 'Guest Restriction - How to Write A Plugin - with message added ',
        // a brief description
        'Description' => 'This plugin prevents replaces comments with signin message for guests.',
        // each time you update plugin update version so you can upload it.
        'Version' => '3.0',
       //  add the option that enables us to have a settings option in the dashboard for the plugin  
       'SettingsUrl' => '/dashboard/plugin/guestrestiction',
        'Author' => "Peregrine"  // the author
    );
    

    2 - add a views directory to your plugin

    vanilla/plugins/GuestRestriction/views

    create a file gr-settings.php

    vanilla/plugins/GuestRestriction/views/gr-settings.php

    <?php if (!defined('APPLICATION')) exit();
    echo $this->Form->Open();
    echo $this->Form->Errors();
    ?>
    
    
    <h1><?php echo Gdn::Translate('Guest Restriction'); ?></h1>
    
    <div class="Info"><?php echo Gdn::Translate('Guest Restriction Options.'); ?></div>
    
    <table class="AltRows">
        <thead>
            <tr>
                <th><?php echo Gdn::Translate('Option'); ?></th>
                <th class="Alt"><?php echo Gdn::Translate('Description'); ?></th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>
                    <?php
                    echo $this->Form->TextBox('Plugins.GuestRestriction.Message');
                    ?>
                </td>
                <td class="Alt">
                    <?php echo Gdn::Translate('Add the name of the guest restriction message'); ?>
                </td>
            </tr>
    
            <tr>
                <td>
                    <?php
                    echo $this->Form->TextBox('Plugins.GuestRestriction.Link');
                    ?>
                </td>
                <td class="Alt">
                    <?php echo Gdn::Translate('Add the LINK to go to when message is clicked'); ?>
                </td>
            </tr>
    
    </table>
    
    <?php echo $this->Form->Close('Save');
    

    3 - modify the default.php to reflect and retrieve the config settings you just created in the view above

    we modify this function so it now retrieves configurations settings form config.php

    public function DiscussionController_AfterCommentFormat_Handler($Sender) {
               // get current session info
            $Session = Gdn::Session();
            // this tests to see is user is logged in
            if (!($Session->IsValid())) {
    
               // these are the 2 config options we provided in gr-settings.php
               // now we retrieve them  the names must match.
                $itemname1 = (C('Plugins.GuestRestriction.Message'));
                $itemlink1 = (C('Plugins.GuestRestriction.Link'));
            //  $Sender->EventArguments['Object']->FormatBody = "<a href=http://localhost/vanilla/entry/signin?Target=discussions> This message can be viewed if you log in  - Click here</a>";
           $Sender->EventArguments['Object']->FormatBody = "<a href=\"" . $itemlink1 . "\">" . $itemname1 . "</a>";
    
    }
    }
    

    4. Add a function to default.php that directs you the view you created above in step 2. Once again make sure the two config option names match.

    public function PluginController_GuestRestriction_Create(&$Sender, $Args = array()) {

        $Sender->Permission('Garden.Settings.Manage');
        $Sender->Form = new Gdn_Form();
        $Validation = new Gdn_Validation();
        $ConfigurationModel = new Gdn_ConfigurationModel($Validation);
    
       // these are the two configuration settings we added that will show up in config.php
    
        $ConfigurationModel->SetField(array(
            'Plugins.GuestRestriction.Message',
            'Plugins.GuestRestriction.Link',
        ));
        $Sender->Form->SetModel($ConfigurationModel);
    
    
        if ($Sender->Form->AuthenticatedPostBack() === FALSE) {
            $Sender->Form->SetData($ConfigurationModel->Data);
        } else {
            $Data = $Sender->Form->FormValues();
    
            if ($Sender->Form->Save() !== FALSE)
                $Sender->StatusMessage = T("Your settings have been saved.");
        }
        // this points to the file in the views folder that we created
        // and is what is shown when you click on settings for the plugin
        $Sender->Render($this->GetView('gr-settings.php'));
    }
    

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • peregrineperegrine MVP
    edited July 2012

    Pt. 3 - add sidemenu to the dashboard for the plugin with a slight change to arguments.

    change this

    public function PluginController_GuestRestriction_Create(&$Sender, $Args = array()) {

    to this (lose the ampersand and the arguments array).

        public function PluginController_GuestRestriction_Create($Sender) {
                $Sender->AddSideMenu('plugin/guestrestriction');
    

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • It may not be perfect - but it might be a start.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

Sign In or Register to comment.