HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

testing new plugin

jackmaessenjackmaessen ✭✭✭
edited December 2014 in General Banter

I am testing with a new plugin (based on what Bleistivt made one of these days for JoinedDate).
I created this:

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

$PluginInfo['MarkV'] = array(
    'Name' => 'MarkV',
    'Version' => '1',
    'Author' => 'jackmaessen'
    );

    class MarkVPlugin extends Gdn_Plugin {

       public function DiscussionController_CommentInfo_Handler($Sender) {$this->AddMarkV($Sender);}
       public function DiscussionController_DiscussionInfo_Handler($Sender) {$this->AddMarkV($Sender);}

       protected function AddMarkV($Sender) {

       echo '<img src="http://www.webprofis.nl/images/markwhite.png" class="img-swap" />';

       echo ' <script>
        $(function () {
            $(".img-swap").live("click", function () {
                if ($(this).attr("class") == "img-swap") {
                    this.src = this.src.replace("markwhite", "markgreen");
                } else {
                    this.src = this.src.replace("markgreen", "markwhite");
                }
                $(this).toggleClass("on");
            });
        });
     </script>';

       } // end protected function
    }

The "V" appears in the meta tag of the discussion and when click on it it becomes green color. That works fine, only when 1 V is in a discussion.
Look here: http://forum.webprofis.nl/discussion/301/test-plugin-mark-ok-with-no-comment#latest
When someone posts a comment, there are 2 V's which you can click but the change does not work anymore
Look here: http://forum.webprofis.nl/discussion/302/test-plugin-mark-ok-with-1-comment

What do i have to do to make this work for all the comments that are following in a topic?
(Ofcourse, the first V should not appear in the topic start but the idea is that with 2 V the change does not work anymore)

«1

Comments

  • Spit the markup out as you are doing it, and add the JS as an asset.

    Then make your JS work on classes.

    The issue you are having is two functions are being called on click. If My intuition is correct, adding a third comment should make them all change on the same time with your current code.

    Sample JS file:

    jQuery(document).ready(function($) {
      $(".img-swap").click(function() {
        $(this).toggleClass('on');
      });
    });
    

    Sample Plugin file:

    <?php if (!defined('APPLICATION')) exit();
    $PluginInfo['MarkV'] = array(
      'Name' => 'MarkV',
      'Version' => '1',
      'Author' => 'jackmaessen'
    );
    
    class MarkVPlugin extends Gdn_Plugin {
    
      public function DiscussionController_CommentInfo_Handler($Sender) {$this->AddMarkV($Sender);}
    
      public function DiscussionController_DiscussionInfo_Handler($Sender) {$this->AddMarkV($Sender);}
    
      protected function AddMarkV($Sender) {
        echo '<div class="img-swap" />&#10004;</div>';
      }
    
      public function DiscussionController_Render_Before($Sender) {
        $Sender->AddJsFile($this->GetResource('js/markv.js', FALSE, FALSE));
        $Sender->AddCssFile($this->GetResource('design/markv.css', FALSE, FALSE));
      }
    }
    

    Then just add styles to your CSS file:

    .img-swap {
       background: url('http://www.webprofis.nl/images/markwhite.png');
    }
    
    .img-swap.on {
       background: url('http://www.webprofis.nl/images/markgreen.png');
    }
    

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • i tested it but the same result. Only if 1 Mark is in the topic, it changes background.

    http://forum.webprofis.nl/discussion/301/test-plugin-mark-ok-with-no-comment#latest

    http://forum.webprofis.nl/discussion/302/test-plugin-mark-ok-with-1-comment#latest

    Anothe rproblem is the js and the css file are not loaded. so i put the css lines in my general style.css and i echoed the script after the div tag. Maybe DiscussionController_Render_Before is not the right one?

  • if you put a description in your plugin we would know what you are trying to achieve by reading the description.

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

  • @jackmaessen said:
    i tested it but the same result. Only if 1 Mark is in the topic, it changes background.

    http://forum.webprofis.nl/discussion/301/test-plugin-mark-ok-with-no-comment#latest

    http://forum.webprofis.nl/discussion/302/test-plugin-mark-ok-with-1-comment#latest

    Anothe rproblem is the js and the css file are not loaded. so i put the css lines in my general style.css and i echoed the script after the div tag. Maybe DiscussionController_Render_Before is not the right one?

    Outputting the JS in the middle of the page will do the exact same thing as won't work. This will call a toggle on the class "on" once for every time the script is output.

    The JS needs to be added once not every time. Is the JS file located in /plugins/MarkV/js/markv.js? Is the CSS file located in /plugins/MarkV/design/markv.css?

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • jackmaessenjackmaessen ✭✭✭
    edited December 2014

    What i am trying to achieve is actually the same as what you can see in stackoverflow forum. When someone clicks on the mark "V" it becomes green; means: this answer is accepted as the right answer or the best answer on my question.

    Probably you are going to say now: but we already have such an option, it's called Q&A plugin?
    That's right, but Q&A is very advanced and the way it works is not usefull for me because:

    1. It makes a distinction between discussions and questions. For me everything posted is a topic, whether it is a discussion or a question. I make no distinction between them.

    2. When someone accepts an answer, Q&A drops the comment immediately on the top of the discussion. ( In my case this is not necessary.

    3. Q&A doesn't load geshi highlighting anymore when moving a comment.

    So that's the reason i am experimenting with a very simple solution to make a comment as "best answer" by just clicking on the grey V mark which becomes a green V.
    This grey V should be in every meta tag of a comment. Users can click on it and it must become green.

    And i thought (with my little experience) i could make this myself but.... :s i don't succeed in it

  • jackmaessenjackmaessen ✭✭✭
    edited December 2014

    @hgtonight:
    yes; the css code is in /plugins/MarkV/design/markv.css

    the js code is in /plugins/MarkV/js/markv.js

    When i look into the browserconsole and click on the element, i can not see the css belonging to it at the right side; so it is not loaded

    BTW: this is a type failure i think?

    `echo '<div class="img-swap" />&#10004;</div>';`
    

    should be:

    `echo '<div class="img-swap">&#10004;</div>';`
    
  • post a zip attachment of your complete plugin. if you want some testing and help.

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

  • So... this was just a fun little project that was pretty easy, so I made the plugin myself.

    Please read the source of the plugin I posted. Then ask any questions you have. My goal is for you to learn. :)

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • @jackmaessen said:
    What i am trying to achieve is actually the same as what you can see in stackoverflow forum. When someone clicks on the mark "V" it becomes green; means: this answer is accepted as the right answer or the best answer on my question.

    Probably you are going to say now: but we already have such an option, it's called Q&A plugin?
    That's right, but Q&A is very advanced and the way it works is not usefull for me because:

    1. It makes a distinction between discussions and questions. For me everything posted is a topic, whether it is a discussion or a question. I make no distinction between them.

    2. When someone accepts an answer, Q&A drops the comment immediately on the top of the discussion. ( In my case this is not necessary.

    3. Q&A doesn't load geshi highlighting anymore when moving a comment.

    So that's the reason i am experimenting with a very simple solution to make a comment as "best answer" by just clicking on the grey V mark which becomes a green V.
    This grey V should be in every meta tag of a comment. Users can click on it and it must become green.

    And i thought (with my little experience) i could make this myself but.... :s i don't succeed in it

    Using a single character as something a user has to click is a bad user experience. You should consider using a button using a link with class button is also better, because you have to communicate users choice to the server and that should be done by calling your own function. Here is some messy code how I would try to achieve that.

    public function structure() {
    $Structure = Gdn::Structure;
    
    $Structure->Table('Comment')
    ->Column(BestAnswer, 'bool')
    ->Set();
    
    /* 
    use that only if you want to show answered/unanswered state outside the dicussion itself
    $Structure->Table('Discussion')
    ->Column('Answered', 'bool') // you must use short int for that
    ->Set();
    */
    }
    
    public function setup() {
    $this->structure();
    }
    
    // this is copied from hgtonight (believe him, it is the right hook for the call)
    public function DiscussionController_Render_Before($Sender) {
    $Sender->AddJsFile($this->GetResource('js/markv.js', FALSE, FALSE));
    $Sender->AddCssFile($this->GetResource('design/markv.css', FALSE, FALSE));
    }
    /*
     create a js file with following content (also taken from hgtonight)
        jQuery(document).ready(function($) {
        $(".MarkV").click(function() {
        $(this).toggleClass('Answer');
        });
        });
    */
    
    public function discussionController_commentInfo_handler ($Sender) {
    $CommentID = $Sender->EventArguments['CommentID'];
    echo '<a href="', Url('plugin/markv/'.$CommentID), '"  class="MarkV SmallButton Popup" title="', T('Best Answer'), ">', T('✔'), '</a>';
    }
    
    public function pluginController_markv_create ($Sender, $Args) {
    $Comment = CommentModel::Get($Args[0]);
    
    /*
    1. check if session user is discussion author 
    2. check if session user != comment author
    3. if !$CommentID->BestAnswer, Gdn::SQL()->Update('Comment')
    ->Set('BestAnswer', false)
    ->Where('DiscussionID', $Comment->DiscussionID)
    ->Where('BestAnswer', true);
    4. Gdn::SQL()->Update('Comment')
    ->Set('BestAnswer', !$Comment->BestAnswer)
    ->Where('CommentID', $Comment->CommentID;
    */
    }
    
    

    Now do some kick ass styling and it should be okay

  • peregrineperegrine MVP
    edited December 2014

    @hgtonight said:
    So... this was just a fun little project that was pretty easy, so I made the plugin myself.

    Please read the source of the plugin I posted. Then ask any questions you have. My goal is for you to learn. :)

    @hgtonight - what was the reasoning for this...

    $Sender->Render('Blank', 'Utility', 'Dashboard');

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

  • hgtonighthgtonight MVP
    edited December 2014

    @peregrine said:

    hgtonight - what was the reasoning for this...

    $Sender->Render('Blank', 'Utility', 'Dashboard');
    

    That is a blank view that I specified the controller and application to find it in. This way, the standard Render method is executed.

    I went through the Render method so the InformMessages I set on the controller would be sent back and parsed by global.js. The real magic is adding the class "Hijack" to the anchor element. This tells Garden it should load that link via AJAX and parse the response automatically. You can set set targets to do things or pass inform messages which will be shown to the user.

    EDIT - I actually just realized that I don't need to have any custom JS at all if I used some well placed JsonTargets.

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • hgtonighthgtonight MVP
    edited December 2014

    Woo leveraging the power of the framework! Here is the updated plugin file contents:

    <?php if (!defined('APPLICATION')) exit();
    /* Copyright 2014 Zachary Doll */
    $PluginInfo['MarkV'] = array(
        'Name' => 'Mark V',
        'Description' => 'Allows user to mark a comment as a V.',
        'Version' => '0.2',
        'MobileFriendly' => TRUE,
        'Author' => 'Zachary Doll',
        'AuthorEmail' => 'hgtonight@daklutz.com',
        'AuthorUrl' => 'http://www.daklutz.com',
        'License' => 'GPLv3'
    );
    
    class MarkVPlugin extends Gdn_Plugin {
    
      public function DiscussionController_CommentInfo_Handler($Sender) {
        $Discussion = $Sender->EventArguments['Discussion'];
        $Session = Gdn::Session();
        $Comment = $Sender->EventArguments['Comment'];
        if ($Session->UserID == $Discussion->InsertUserID || $Session->CheckPermission('Garden.Moderation.Manage')) {
          echo $this->RenderMarkVToggle($Comment->CommentID, $Comment->MarkV);
        } else {
          echo $this->RenderMarkV($Comment->MarkV);
        }
      }
    
      private function RenderMarkV($State) {
        $Class = 'img-swap';
        if ($State) {
          $Class .= ' on';
        }
        return Wrap("&#10004;", 'div', array('class' => $Class));
      }
    
      private function RenderMarkVToggle($ID, $State) {
        $Class = 'Hijack img-swap';
        if ($State) {
          $Class .= ' on';
        }
        return Anchor("&#10004;", 'discussion/markv/' . $ID, $Class);
      }
    
      public function DiscussionController_Render_Before($Sender) {
        $Sender->AddCssFile($this->GetResource('design/markv.css', FALSE, FALSE));
      }
    
      public function DiscussionController_MarkV_Create($Sender, $Args) {
        // Make sure the user is allowed to mark this comment
        $Comment = $Sender->CommentModel->GetID($Args[0]);
        $Discussion = $Sender->DiscussionModel->GetID($Comment->DiscussionID);
        $Session = Gdn::Session();
        if ($Session->UserID == $Discussion->InsertUserID || $Session->CheckPermission('Garden.Moderation.Manage')) {
          $Sender->CommentModel->SetField($Comment->CommentID, 'MarkV', !$Comment->MarkV);
    
          if (!$Sender->Request->IsPostBack()) {
            Redirect('/discussion/' . $Comment->DiscussionID);
          } else {
            $Sender->InformMessage('Mark Updated');
            $Sender->JsonTarget('#Comment_' . $Comment->CommentID . ' .img-swap', $this->RenderMarkVToggle($Comment->CommentID, !$Comment->MarkV), 'ReplaceWith');
            // Don't render anything
            $Sender->Render('Blank', 'Utility', 'Dashboard');
          }
        }
      }
    
      public function Structure() {
        $Structure = Gdn::Structure();
        $Structure->Table('Comment')
                ->Column('MarkV', 'tinyint', 0)
                ->Set();
      }
    
      public function Setup() {
        $this->Structure();
      }
    
    }
    

    Then you can delete the JS folder in the plugin package.

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • jackmaessenjackmaessen ✭✭✭
    edited December 2014

    This is very strange! I still can not see belonging css ( the backgrounds) for the mark sign and
    i still do not understand why the css is not loaded!
    The example plugin is exactly the same as what i have.

    Console:

    http://www.webprofis.nl/images/console.png

    My MarkV plugin:

    http://www.webprofis.nl/images/markv.zip

    Please look into the browserconsole and admit that the belonging css (img-swap backgrounds) are not loaded: http://forum.webprofis.nl/discussion/301/test-plugin-mark-ok-with-no-comment#latest

  • peregrineperegrine MVP
    edited December 2014

    @jackmaessen said:
    This is very strange! I still can not see belonging css ( the backgrounds) for the mark sign and
    i still do not understand why the css is not loaded!
    The example plugin is exactly the same as what i have.

    Console:

    http://www.webprofis.nl/images/console.png

    My MarkV plugin:

    http://www.webprofis.nl/images/markv.zip

    Please look into the browserconsole and admit that the belonging css (img-swap backgrounds) are not loaded: http://forum.webprofis.nl/discussion/301/test-plugin-mark-ok-with-no-comment#latest

    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 WORKS!!! :) You were absolutely right @peregrine : it was almost the same but not exactly ;)

    Does it make sense if you name the .php file class.markv.plugin.php or class.markvplugin.php ( 1 dot less)

    Thank you very much for making this; @hgtonight, @R_J and @peregrine

    Much much appreciated!

  • peregrineperegrine MVP
    edited December 2014

    You were absolutely right @peregrine

    that's a given, isn't it :wink:

    yes people often say it s exactly the same, when they mean the same but different, which leads to different results B) because it is inexactly the same and just plain different.

    I would change the css to this

    .img-swap {
      background: url('images/markwhite.png');
      width: 40px;
      height: 31px;
      display: inline-block;
      font-size: 0.1px;
      text-indent: 9999px;
    }
    .img-swap.on {
      background: url('images/markgreen.png');
    }
    

    and put the two .png files

    in

    plugins/MarkV/design/images

    instead of hardcoding images to your site

    anyone who download hgtonight's zip will be retrieving images from your site, if they run the plugin :)

    three cheers for your idea, and hgtonight's masterful reworking.

    kind of a cool plugin.

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

  • yes; i already put those images local in the images folder. That's the way it should be ;)

  • One more question about this plugin:
    Everybody who is logged in can mark one of the comments. It should be this:

    Only the topic starter can mark the comments of his own topic. Other members should not been able to mark this.

    I think i have to put a new condition into this piece of code:

      if($Session->UserID == $Discussion->InsertUserID or $Session->CheckPermission('Garden.Moderation.Manage')) {
          $Sender->CommentModel->SetField($Comment->CommentID, 'MarkV', !$Comment->MarkV);
    
  • That check should be sufficient. Make sure you are testing with a user without the moderation permission.

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • jackmaessenjackmaessen ✭✭✭
    edited December 2014

    I agree. My fault. I was testing with a moderator account. For normal users it works perfect!

Sign In or Register to comment.