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 Override xxx_xxx_Create method?

Hay., i'am newbie here and want ask question.
I'am trying make custom theme and need to override this method for custom pagination.

// file in applications/vanilla/settings/class.hooks.php
public function profileController_Comments_Create($Sender, $UserReference = '', $Username = '', $Page = '', $UserID = '') {
// the content
}

I try place it in class theme hooks, not working.,

I try change _Create to _Override, not override.,

Please help, thanks.

Tagged:

Best Answers

  • R_JR_J Ex-Fanboy Munich Admin
    Answer ✓

    You do not have to rewrite a form control that already exists. You just need to use "radioList()".

    Copying complete views and making small changes to them is a bad habit. If you like small modifications, you should do them by changing only the pieces that you do not like. If you look at the view that you try to change, you see that the category selector is only shown if a flag is set ShowCategorySelector. By setting this to false, you can prevent that it will be rendered.

    If the default category dropdown isn't shown, you can render your own form element. And, as I've said before, radioList() already exists:

        public function postController_beforeFormInputs_handler($sender, $args) {
            // This prevents the default category drop down from bein rendered.
            $sender->ShowCategorySelector = false;
    
            // Get all the categories the user is allowed to see.
            $categories = CategoryModel::getByPermission();
    
            // Reduce information to [ID => Name]
            $categories = array_column($categories, 'Name', 'CategoryID');
    
            // Create a radio list.
            echo '<div class="P">';
            echo '<div class="Category">';
            echo $sender->Form->label('Category', 'CategoryID');
            echo $sender->Form->radioList('CategoryID', $categories);
            echo '</div>';
            echo '</div>';
        }
    

    That's all you need (and a little bit of styling)

Answers

  • This a URL redirect?

  • BleistivtBleistivt Moderator

    No, this happens internally. It will be just like if the method was overridden.

  • Thanks, your solution work perfectly. But, what happen if i change "'Internal', false" to "'Internal', true", and what this.

  • BleistivtBleistivt Moderator

    if you change the last parameter, it will persist even after you disable the plugin, because it gets saved to the config.php

  • One more question in this section, hope you can help.

    I'am change select option category in post page to radio button. Working perfect with add new form function in library/core/class.form.php , but i think it not true method.

    This for example:
    public function categoryDropDown($FieldName = 'CategoryID', $Options = false) {
    //...
    }

    I'am add new function below:
    public function categoryDropDownXxx($FieldName = 'CategoryID', $Options = false) {
    //...
    }

    My question,
    How to place public function categoryDropDownXxx to theme or plugins? I try add it in class hooks theme and to plugins, but error.

  • BleistivtBleistivt Moderator

    If you really need to use your own function here put it in a plugin, and override the the post view.

    But I would do this with jQuery since it is just a cosmetic change:

    $('#Form_CategoryID option').each(function() {
        $('<br><input type="radio" name="CategoryID" value="' + $(this).val() + '"> <label for="CategoryID">' + $(this).text()+ '</label>')
            .appendTo('div.Category');
    });
    $('#Form_CategoryID').remove();
    
  • How to make it, "override the the post view", can you help me?

    Solution with jQuery, for me not recomended.

  • BleistivtBleistivt Moderator

    copy applications/vanilla/views/post/discussion.php to themes/YOURTHEME/views/post/discussion.php

  • I already doing it since start custom themes.
    I looking method to override or make new GDN_Form from class.form.php, so i not change core code.

  • I need to override / change this with my own:
    echo $this->Form->CategoryDropDown('CategoryID', array('Value' => val('CategoryID', $this->Category), 'IncludeNull' => TRUE));

    to this,
    echo $this->Form->CategoryDropDownMyOwn('CategoryID', array('Value' => val('CategoryID', $this->Category), 'IncludeNull' => TRUE));

  • BleistivtBleistivt Moderator

    Well, you can always create a subclass that extends Gdn_Form and overwrite the factory:

    public function gdn_dispatcher_appStartup_handler() {
        Gdn::factoryUninstall('Form');
        Gdn::factoryInstall('Form', 'MyCustomFormClass', null, Gdn::FactoryInstance);
    }
    
  • Okay, now i will start to explain with more detail.
    I create custom theme and all views already copy to theme for override.

    Now, in file class.form.php i create new function. This the code:

    // add opsional radio button category picker
        public function categoryDropDownOpsional($FieldName = 'CategoryID', $Options = false) {
            $Value = arrayValueI('Value', $Options); // The selected category id
            $CategoryData = val('CategoryData', $Options);
    
            // Sanity check
            if (is_object($CategoryData)) {
                $CategoryData = (array)$CategoryData;
            } elseif (!is_array($CategoryData)) {
                $CategoryData = array();
            }
    
            $Permission = GetValue('Permission', $Options, 'add');
    
            // Grab the category data.
            if (!$CategoryData) {
                $CategoryData = CategoryModel::GetByPermission(
                    'Discussions.View',
                    $Value,
                    val('Filter', $Options, array('Archived' => 0)),
                    val('PermFilter', $Options, array())
                );
            }
    
            // Respect category permissions (remove categories that the user shouldn't see).
            $SafeCategoryData = array();
            foreach ($CategoryData as $CategoryID => $Category) {
                $Name = $Category['Name'];
    
                if ($Value != $CategoryID) {
                    if ($Category['CategoryID'] <= 0 || !$Category['PermsDiscussionsView']) {
                        continue;
                    }
    
                    if ($Category['Archived']) {
                        continue;
                    }
                }
    
                $SafeCategoryData[$CategoryID] = $Category;
            }
    
            unset($Options['Filter'], $Options['PermFilter']);
    
            // Opening select tag
            $Return = '<div class="SelectCategory"';
            $Return .= $this->_idAttribute($FieldName, $Options);
            $Return .= $this->_nameAttribute($FieldName, $Options);
            $Return .= $this->_attributesToString($Options);
            $Return .= ">\n";
    
            // Get value from attributes
            if ($Value === false) {
                $Value = $this->getValue($FieldName);
            }
            if (!is_array($Value)) {
                $Value = array($Value);
            }
    
            // Prevent default $Value from matching key of zero
            $HasValue = ($Value !== array(false) && $Value !== array('')) ? true : false;
    
            // Show root categories as headings (ie. you can't post in them)?
            $DoHeadings = val('Headings', $Options, C('Vanilla.Categories.DoHeadings'));
    
            // If making headings disabled and there was no default value for
            // selection, make sure to select the first non-disabled value, or the
            // browser will auto-select the first disabled option.
            $ForceCleanSelection = ($DoHeadings && !$HasValue && !$IncludeNull);
    
            // Write out the category options
            if (is_array($SafeCategoryData)) {
                foreach ($SafeCategoryData as $CategoryID => $Category) {
                    $Depth = val('Depth', $Category, 0);
                    $Disabled = (($Depth == 1 && $DoHeadings) || !$Category['AllowDiscussions']);
                    $Selected = in_array($CategoryID, $Value) && $HasValue;
    
                    if ($ForceCleanSelection && $Depth > 1) {
                        $Selected = true;
                        $ForceCleanSelection = false;
                    }
    
                    if ($Category['AllowDiscussions']) {
                        $Disabled &= $Permission == 'add' && !$Category['PermsDiscussionsAdd'];
                    }
    
                    $Return .= '<label class="SelectLabel"><div><input type="radio" for="Form_'.$FieldName.'" name="'.$FieldName.'" value="'.$CategoryID.'"';
                    if ($Disabled) {
                        $Return .= ' disabled="disabled"';
                    } elseif ($Selected) {
                        $Return .= ' checked="checked"'; // only allow selection if NOT disabled
                    }
                    $Name = htmlspecialchars(val('Name', $Category, 'Blank Category Name'));
                    $Description = htmlspecialchars(val('Description', $Category, 'Blank Category Name'));
                    if ($Depth > 1) {
                        $Name = str_repeat('&#160;', 4 * ($Depth - 1)).$Name;
    //               $Name = str_replace(' ', '&#160;', $Name);
                    }
    
                    $Return .= '/><span>'.$Name.'</span><p>'.$Description.'</p></div></label>';
                }
            }
            return $Return.'</div>';
        }
    

    And I modified select option category to radio button /ThemeName/views/post/discussion.php, change this
    echo $this->Form->CategoryDropDown('CategoryID', array('Value' => val('CategoryID', $this->Category), 'IncludeNull' => TRUE));

    to this

    echo $this->Form->CategoryDropDownOpsional('CategoryID', array('Value' => val('CategoryID', $this->Category), 'IncludeNull' => TRUE));

    My question, how to place
    public function categoryDropDownOpsional($FieldName = 'CategoryID', $Options = false) {
    //conten
    }

    to plugins / theme hooks.

  • R_JR_J Ex-Fanboy Munich Admin
    Answer ✓

    You do not have to rewrite a form control that already exists. You just need to use "radioList()".

    Copying complete views and making small changes to them is a bad habit. If you like small modifications, you should do them by changing only the pieces that you do not like. If you look at the view that you try to change, you see that the category selector is only shown if a flag is set ShowCategorySelector. By setting this to false, you can prevent that it will be rendered.

    If the default category dropdown isn't shown, you can render your own form element. And, as I've said before, radioList() already exists:

        public function postController_beforeFormInputs_handler($sender, $args) {
            // This prevents the default category drop down from bein rendered.
            $sender->ShowCategorySelector = false;
    
            // Get all the categories the user is allowed to see.
            $categories = CategoryModel::getByPermission();
    
            // Reduce information to [ID => Name]
            $categories = array_column($categories, 'Name', 'CategoryID');
    
            // Create a radio list.
            echo '<div class="P">';
            echo '<div class="Category">';
            echo $sender->Form->label('Category', 'CategoryID');
            echo $sender->Form->radioList('CategoryID', $categories);
            echo '</div>';
            echo '</div>';
        }
    

    That's all you need (and a little bit of styling)

  • idlamalifidlamalif New
    edited June 2016

    thanks @R_J , you'r solution give me inspitration.

Sign In or Register to comment.