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

Reading/Writing form settings in admin dashboard

mikhomikho New
edited August 2015 in Vanilla 2.0 - 2.8

Hello fellow community members!

Recently decided to get back into coding (going from Windows applications to websites) and needed a "real" project to work with and a friend of mine suggested to make a vanilla forums plugin that he needed. So I dived in head first, reading this community and studying other addons/plugins and my first plugin is now almost finished. Only one thing missing :) Saving the settings in the admin interface that I created.

I'll give a short description on what I'm trying to accomplish:
I have created a trigger to Fire on BeforeSaveDiscussion as I want certain things to happen depending on the Category the discussion is posted.

My settings in the dashboard is really simple, I read the available categories and their CategoryID and list them with checkboxes.
I then read from the config file with the excellent function C() an array with the CategoryID of chosen Categories.
My issue here is that I'm probably doing it the wrong way ;)

This is from my class file

public function Controller_Index($Sender) {
        // Prevent non-admins from accessing this page
        $Sender->Permission($this->GetPluginKey('SettingsPermission'));
        $Sender->SetData('PluginDescription',$this->GetPluginKey('Description'));
        $Validation = new Gdn_Validation();
        $ConfigurationModel = new Gdn_ConfigurationModel($Validation);
        $ConfigurationModel->SetField(array('Plugins.AutoCategory.Categories')); 

        // Set the model on the form.
        $Sender->Form->SetModel($ConfigurationModel);

        // If seeing the form for the first time...
        if ($Sender->Form->AuthenticatedPostBack() === FALSE) {
            // Apply the config settings to the form.
            $Sender->Form->SetData($ConfigurationModel->Data);
        } else {
             $Saved = $Sender->Form->Save();
            if ($Saved) {
                $Sender->StatusMessage = T("Your changes have been saved.");
            }
        }
      // GetView() looks for files inside plugins/PluginFolderName/views/ and returns their full path. Useful!
      $Sender->Render($this->GetView('autocategory.php'));
   }

and this is from my autocategory.php file:

$arrayAutoCategoryCategories = C('Plugins.AutoCategory.Categories');

$CategoryModel = new CategoryModel();
    $UnprocessedCategories = CategoryModel::Categories();
    foreach ($UnprocessedCategories as $Category) {
        if ($Category["CategoryID"] != -1) {
            echo  $this->Form->Checkbox($Category["CategoryID"], 
                                        $Category["Name"] . " ID: " . $Category["CategoryID"], 
                                        ( in_array($Category["CategoryID"],
                                                   $arrayAutoCategoryCategories)) ? array('checked' => "checked") : array('checked'));
            // echo $this->Form->Checkbox()
        } 
    }

This is (I know) not the correct way to do it. Could anyone please guide me or at least point me in the right direction as I've looked at this code so many times that I can't get out of the hamster wheel......

thanks in advance!

Best Answers

Answers

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    Building a setting screen is really easy! There are a lot of helpers you can use. For a category specific example look here: https://github.com/R-J/EventCalendar/blob/master/class.eventcalendar.plugin.php#L121-L139
    For a general overview, look at that: https://github.com/R-J/HowToSettings/blob/master/class.howtosettings.plugin.php

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    And, if I remember it right, you can also add $sender->setData('Description', t('Whatever')); from Vanilla 2.2 onwards, but you would have to test that...

  • Options

    @R_J said:
    And, if I remember it right, you can also add $sender->setData('Description', t('Whatever')); from Vanilla 2.2 onwards, but you would have to test that...

    This part is what is confusing me at this moment, I think I've done the setting correct:

    $ConfigurationModel = new Gdn_ConfigurationModel($Validation);
            // $AutosinkinCategoryCategories = C('Plugins.AutosinkinCategory.Categories',"");
            $ConfigurationModel->SetField(array(
                'Plugins.AutosinkinCategory.Categories'
            )); 
            // Set the model on the form.
            $Sender->Form->SetModel($ConfigurationModel);
    
            // If seeing the form for the first time...
            if ($Sender->Form->AuthenticatedPostBack() === FALSE) {
                // Apply the config settings to the form.
    
                $Sender->Form->SetData($ConfigurationModel->Data);
    

    But how do I create one checkbox for each category that I have and assign the value from $ConfigurationModel->Data ?

    a print_r of Plugins.AutosinkinCategory.Categories looks like this: Array ( [0] => 5 [1] => 6 )

    that means that Categories with ID 5 and 6 should have their checkboxes checked.
    When I hit the Save button it should save the data to the config file again.

    Hope this makes it clearer with what I'm trying to accomplish.

    And THANK YOU for taking the time to read and trying to help me, really appriciate it.

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    And if you are beginning writing plugins for Vanilla, take a look at the coding standards: https://github.com/vanilla/addons/tree/master/standards/Vanilla

    Moreover I have changed Plugins.AutosinkinCategory.Categories to AutosinkinCategory.Categories. I guess it was @hgtonight who told me that the Plugins prefix will not be used in future times, but I'm not really sure about that.

  • Options

    Haven't read your replies properly yet but are you saying that all I need is those few lines of code?
    And then any admin can set which categories they want from the dashboard?

    If that is true then I was really in the wrong place.. I will read the links about coding standards and try your suggestions tonigh when I get home from work.

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    Yes, the configuration module is made exactly for that: all you need are a very few lines of code to present a beautiful settings screen!

    Try the snippet I posted above to see its magic :)

  • Options
    hgtonighthgtonight ∞ · New Moderator

    @R_J said:

    Moreover I have changed Plugins.AutosinkinCategory.Categories to AutosinkinCategory.Categories. I guess it was hgtonight who told me that the Plugins prefix will not be used in future times, but I'm not really sure about that.

    http://vanillaforums.org/discussion/27858/plugins-namespace

    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.

  • Options

    Hello again!
    sorry for the late follow up.

    Had some time late last night and tried the code pasted by @R_J and got this wierd json_encode recursive error?

    The error occurred on or near: /public_html/library/core/class.controller.php
    674:                  (isset($this->ReflectArgs['Sender']) && $this->ReflectArgs['Sender'] instanceof Gdn_Pluggable)
    675:                ))
    676:             $ReflectArgs = json_encode(array_slice($this->ReflectArgs, 1));
    677:          else
    678:             $ReflectArgs = json_encode($this->ReflectArgs);
    679:          
    680:          $this->_Definitions['ResolvedArgs'] = $ReflectArgs;
    681:       }
    682: 
    

    row 678 is highlighted in red if that helps.

    One thing I noticed is that I tried to create a plugin using the "guide" here http://docs.vanillaforums.com/developers/plugins/quickstart/

    the code above says: public function settingsController_autoCategory_create($sender) {
    but my original code had: public function PluginController_autoCategory_create($Sender) {

    Is the docs outdated or have I misunderstood something with the code above?

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    Have you really copy and pasted it only? The error message has a capitalized "$Sender" while I was only using "$sender". Has that been part of your question? Since $sender is the variable name I define in my local scope, I can choose which spelling I like and $sender adheres to the new naming conventions. In Vanilla 2.1 you'll only find $Sender, though. It's completely up to you.

    But I guess your question has something to do with the first part of the function name: settingsController vs. PluginController. It is just a matter of taste. There is nothing in the settingsController that you need for your plugin. So you could use the much leaner pluginsController.
    The controller you extend determines the address that you have to call to reach your function. If you extend the pluginController, the address would be yourforum.com/plugin/autocat, if you extend settingsController it would be yourforum.com/settings/autocat and that's why I prefer the settingsController. But if you compare pluginController and settingsController you see that settingsController is bloated (but it is the boards settings, so who cares? THat's at least my opinion)

    If you look at the pluginController, you see that it is nothing more than the dashboard controller. So you could theoretically use public function dashboardController_autoCategory_create($sender) {... and reach your settings screen with yourforum.com/dashboard/autocat.

    Just do what you like and what "feels" best to you. But remember that you have to give the corresponding address in the PluginInfo: 'SettingsUrl' => '/controllerNameYouHaveChosen/autoCategory',

  • Options
    mikhomikho New
    edited August 2015

    I did copy/paste it as you posted but noticed the difference in upper/lowecase in $sender so I "updated" it to be same case (lower) everywhere in my files.

    Your answer did help! I am using Vanilla 2.1.11 so when I changed EVERY $sender to $Sender it works!

    Now I only need to look at the BeforeSaveDiscussion_handler since I need to read the config values from another place then where I did before.

    THANK YOU SO MUCH!

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    How you write $sender isn't really important as long as you stay consistent.
    If you have public function settingsController_autoCat_create($sender), the $sender is an instance(? Sorry, I'm not fluent with OOP wordings) of the settingsController. So you could as well write
    public function settingsController_autoCat_create($settingsController)
    public function settingsController_autoCat_create($s)
    ... or whatever. You simply have to use the same variable everywhere you use it. ($sender, $args) is just Vanilla convention meaning $sender = the controller that has fired the event, $args = arguments (if any) passed together with the hook.

  • Options

    I was consistent in my original code using $Sender :)
    When I pasted your code I changed it to $sender everywhere in my code which gave me the recursive error. So I changed every $sender instance to $Sender as the error message said

    (isset($this->ReflectArgs['Sender']) && $this->ReflectArgs['Sender'] instanceof Gdn_Pluggable)

    with a Capital S. that cleared the error and I could continue. ;)

Sign In or Register to comment.