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.

How to add/remove a predetermined discussion prefix right from the discussion list

rbrahmsonrbrahmson "You may say I'm a dreamer / But I'm not the only one"NY ✭✭✭

I'd like to add a button/image on the discussion list so that users with permission will be able to click on it and in doing so assign a prefix to a discussion.

I'm thinking that I need a new plugin that pre-requisites the PrefixDiscussion plugin. I looked at the PrefixDiscussion plugin and I can see that a new column (d.Prefix) holds the prefix value. Assuming that there is a way to set the value from the discussion list I think I will need to find a way to pick the correct discussion id from the clicked button, set a value, and save.

Would appreciate some help/advice on how to do it.
Happy New Year!

Comments

  • R_JR_J Ex-Fanboy Munich Admin

    You could either write a plugin that requires PrefixDiscussion or extend it. Sources are n GitHub and I think what you are talking about would make a great extension!

    I would check for the right to manage prefixes and show the option according to that:

    public function discussionsController_discussionOptions_handler($sender, $args) {
        if (!Gdn::session()->checkPermission('Vanilla.PrefixDiscussion.Manage')) {
            return;
        }
        $sender->Options .= '<li>'.anchor(t('Prefix'), '/plugin/prefixdiscussion/'.$sender->DiscussionID, 'PrefixDiscussion Popup Hijack').'</li>';
    }
    

    You would have to create a public function pluginController_prefixdiscussion_create($sender, $args) that displays a simple form showing all prefixes and you are nearly finished. Don't forget to check the permission for PrefixDiscussion.Manage and for accessing the given discussionID before the prefix is changed/added

  • rbrahmsonrbrahmson "You may say I'm a dreamer / But I'm not the only one" NY ✭✭✭

    So in full disclosure I'm also in the midst of writing another plugin related to Prefix Discussion and got most of it working - it's a Filter Discussion with a custom view that filters the discussion to those that have a specific prefix. So since I'm already writing a plugin that prereqs Prefix Discussion I will do the same here.

    And of course when I'm done with both, I'll post them to the community.

    Re:your note about the form, I wanted to set a predetermined prefix, not offering a list.

    Not sure on the process of saving the discussion... Will have to play with these.

  • R_JR_J Ex-Fanboy Munich Admin
    edited December 2015
  • rbrahmsonrbrahmson "You may say I'm a dreamer / But I'm not the only one" NY ✭✭✭

    Thanks R_J. I will definitely try that. I'll start the plugin (probably tomorrow) after I finish testing the Prefix Filter plugin I mentioned above (and then uploading it for the community).

    Happy New Year!

  • rbrahmsonrbrahmson "You may say I'm a dreamer / But I'm not the only one" NY ✭✭✭
    edited December 2015

    So I started with the new plugin and I am able to place text with a link in the meta data for each discussion on the list where the text and link depend on the content of a specially reserved prefix.

    What I want to do is to control and change the value of the reserved prefix value when the user clicks on the link. With @R_J 's help above I even know how to save the changed value once I get control.

    Alas, what I don't know is how to set the link in the button to invoke my plugin passing the discussion id.

  • R_JR_J Ex-Fanboy Munich Admin
  • rbrahmsonrbrahmson "You may say I'm a dreamer / But I'm not the only one" NY ✭✭✭

    @R_J - I finally figured out what was wrong and why the discussion id was not passed to the plugin: the DiscussionID needs to be passed through the Discussion. I changed the code as follows:

    public function discussionsController_discussionOptions_handler($sender, $args) {
        if (!Gdn::session()->checkPermission('Vanilla.PrefixDiscussion.Manage')) {
            return;
        }
        $Discussion = $sender->EventArguments['Discussion']; //New Line. Also note change in the following line
        $sender->Options .= '<li>'.anchor(t('Prefix'), '/plugin/prefixdiscussion/'.$Discussion->DiscussionID, 'PrefixDiscussion Popup Hijack').'</li>';
    }
    

    With the above changes the the discussion id is passed in the link as intended.

    I do not understand the meaning and purpose of 'PrefixDiscussion Popup Hijack'.

  • R_JR_J Ex-Fanboy Munich Admin

    Look at the anchor function:
    function anchor($Text, $Destination = '', $CssClass = '', $Attributes = array(), $ForceAnchor = false)
    So those three are the css classes of the link that the anchor function generates. "PrefixDiscussion" is just the name I've chosen because I thought of extending the plugin PrefixDiscussion and I want to make it possible to be styled.

    "Popup" and "Hijack" are some Vanilla magic classes which are defined in global.js. Try omitting the Popup and you will see that your link opens in a new page. If you give any link the class "Popup" it is loaded as a popup! That's a really handy feature.
    To be true: I'm not sure about "Hijack". But it has been explained here. I haven't really understood it, anyway - I simply always use "Popup Hijack" in conjunction :mrgreen:

  • rbrahmsonrbrahmson "You may say I'm a dreamer / But I'm not the only one" NY ✭✭✭

    Thanks again @R_J. This is helpful. I made further progress and I am able to change the value of the "Reserved" prefix when the button is clicked and reassign it again when it is clicked again ("toggle"). I am using the "Gdn::sql()->update" function as suggested and I am able to verify that the updates take place. The new stumbling block is that after the update takes place the Discussions List screen is not refreshed.
    I took a peak at your "Preview" plugin and saw few lines that were promising:

    //retrieve and render discussion view
    $Sender->SetData('Discussion', $Discussion);
    require_once $Sender->FetchViewLocation('helper_functions', 'Discussion', 'Vanilla');
    $Sender->Render($Sender->FetchViewLocation('discussion', 'Discussion', 'Vanilla'));
    

    But these don't seem to help - the discussion list is not refreshed.

    Any hints on how to force the screen refresh?

  • R_JR_J Ex-Fanboy Munich Admin

    Use javascript for that, otherwise you would have to reload the page
    I'm not fluent in js and not in the near of my computer, so I cannot help you...

  • rbrahmsonrbrahmson "You may say I'm a dreamer / But I'm not the only one" NY ✭✭✭
    edited December 2015

    NP @R_J I'm playing with it. I don't have Java experience at all (and as you can tell, very little PHP too...). Thanks anyway.

  • hgtonighthgtonight ∞ · New Moderator

    I would suggest using a json target on the controller. That will automatically be handled by the global js file and doesn't require too specific of knowledge of JS.

    Check out this post for more information: http://vanillaforums.org/discussion/comment/236342#Comment_236342

    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.

  • rbrahmsonrbrahmson "You may say I'm a dreamer / But I'm not the only one" NY ✭✭✭

    Thank you @hgtonight , I saw that in another comment and I figured out that the function I need is a refresh. But what I get leads me to a suspicion that there is more complexity to it. Allow me to elaborate:

    The plugin inserts the following html into the meta area of each discussion on the discussion list:

    <div id="Alert"><a href="/Vanilla/dashboard/plugin/DiscussionAlert/582" class="DiscussionAlertOn Hijack Popup ">Remove Alert</a></div>

    The plugin gets control in the function "PluginController_DiscussionAlert_Create". At the end of that function I added:

    $Sender->jsonTarget("#Alert", "<ВR>", "Refresh")

    The plugin function logic is to alter a value in the discussion table and save it in the database. All of that works fine. At this point I was hoping to re-display the discussion list with the value refreshed in the discussion list.

    The attempt to auto-refresh did not work. The updated values only appear when I manually perform a browser refresh. I suspect that either my use of jsonTarget is wrong, or the problem is that the plugin is called with the new URL that changes the state of affairs for refresh requests.

    I did various tests which may shed some light on the problem. Here is what I see:

    1. When the HTML in the meta area has a style that includes "Hijack Popup" then a popup screen displays a test text I echo in the PluginController_DiscussionAlert_Create function.

    2. When these links only have the "Hijack" term included (no Popup) then I am returned to the non-refreshed discussion list screen with the echoed text shown as an inform message.

    3. When the links have neither "Hijack" nor "Popup" I get the echoed text displayed on a blank screen (the URL is intranet-forum/Vanilla/dashboard/plugin/DiscussionAlert/585).

    I conducted these three tests with and without jsonTarget and saw no difference.

  • hgtonighthgtonight ∞ · New Moderator

    Traditionally, you modify the current markup to make it look like a refresh. This makes the change appear almost immediately and doesn't require a full page refresh.

    So you re-render the discussion into a string and use a json target replace method. Or you pick the markup you want to remove via a selector and use a json target remove method.

    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.

  • rbrahmsonrbrahmson "You may say I'm a dreamer / But I'm not the only one" NY ✭✭✭
    edited January 2016

    Thanks. I understand that but am wondering whether my speculation earlier (that a refresh is not possible because the "current" screen is a new one) is true.

    I will try your suggestion but I'm not crazy about it because it would be my plugin that would change the value (by playing with the output) rather than PrefixDiscussion that would display the altered value from the database. What I am saying is that doing refresh, with all it's overhead, ensures that all the code that ensures integrity of information will be executed. Just hiding/showing/replacing value on the screen won't.

    So I appreciate the support, guidance and advice, but I'd like to try both approaches. Any ideas about the refresh will be appreciated.

    On that second approach (the Refresh) I managed to pass the current url as a parameter to the linked/clicked item. That gives "PluginController_DiscussionAlert_Create" a chance to route to that screen (albeit not necessarily the same position... so this is not a working solution either).

  • rbrahmsonrbrahmson "You may say I'm a dreamer / But I'm not the only one" NY ✭✭✭

    Just reporting on my further progress - I was successful in changing the button using the jsontarget technique (hijack is cool!). I am still stomped on the refresh technique which I prefer (as I described above). Welcoming hints/insights...

  • hgtonighthgtonight ∞ · New Moderator

    Have you tried $sender->jsonTarget('', '', 'Refresh');

    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.

  • rbrahmsonrbrahmson "You may say I'm a dreamer / But I'm not the only one" NY ✭✭✭

    I think I did, will retry later and report my results.

  • rbrahmsonrbrahmson "You may say I'm a dreamer / But I'm not the only one" NY ✭✭✭

    Hi @hgtonight , thanks for keeping up with me. I am afraid to report that I did test the $sender->jsonTarget('', '', 'Refresh'); and that it did not work.

    So to summarize what worked and what did not:

    1. The Hijack technique replacing the CSS works like a charm, but in my experience is also requires $Sender->Render('Blank', 'Utility', 'Dashboard');
    2. Short of doing what I described in #1 above I was not able to return back (with refresh) to the discussion list (in the same browser positioning).

    With that it became impractical to keep piggybacking onto the PrefixDiscussion plugin with a reserved keyword in order to implement a special discussion state. To be honest, it was never a good idea to have a variable that has different meanings just because I was in a rush.

    So instead I detached the functionality from PrefixDiscussion and wrote an entire new Plugin, tested it and it now works like a charm. I think it has general usefulness so I am going to upload it to the community and you and everyone else can take a look, improve, and comment on my miserable coding skills;-). I guess further discussions about these issues (if at all) will be under that new plugin.

    While it is pure academic, I am still curious as to why I was unable to get the refresh functionality.

    And last but not least - tons of thanks to you and @R_J who brought me to the point of being able to write simple plugins. This community is great!

Sign In or Register to comment.