ForumChooser in Options

AndyB

Well-known member
In one of my add-ons I have a need in the Options to be able to select forums. The following code works very well with the exception that nodes besides Forums can be selected. I would like to make it so that nodes which are a Category, Page or LinkForum cannot be selected, only Forums should be able to be selected.

In this example "Community" is a Category:

pic001.webp

Options page code:

pic002.webp

Folder and Files

pic003.webp


ForumChooser.php

PHP:
<?php

abstract class Andy_SimilarThreads_Option_ForumChooser
{
    public static function renderOption(XenForo_View $view, $fieldPrefix, array $preparedOption, $canEdit)
    {
        $value = $preparedOption['option_value'];

        $editLink = $view->createTemplateObject('option_list_option_editlink', array(
            'preparedOption' => $preparedOption,
            'canEditOptionDefinition' => $canEdit
        ));

        $nodeModel = XenForo_Model::create('XenForo_Model_Node');

        $forumOptions = $nodeModel->getNodeOptionsArray($nodeModel->getAllNodes(), $preparedOption['option_value'], '(None)');
     
        return $view->createTemplateObject('andy_option_list_option_select', array(
            'fieldPrefix' => $fieldPrefix,
            'listedFieldName' => $fieldPrefix . '_listed[]',
            'preparedOption' => $preparedOption,
            'formatParams' => $forumOptions,
            'editLink' => $editLink
        ));
    }
}


Admin Template -> andy_option_list_option_select

Code:
<xen:selectunit label="{$preparedOption.title}" name="{$fieldPrefix}[{$preparedOption.option_id}]" value="{xen:raw $preparedOption.option_value}"
hint="{$preparedOption.hint}" size="10" multiple="true">
    <xen:options source="$formatParams" />
    <xen:explain>{xen:raw $preparedOption.explain}</xen:explain>
    <xen:html>
        <input type="hidden" name="{$listedFieldName}" value="{$preparedOption.option_id}" />
        {xen:raw $editLink}
    </xen:html>
</xen:selectunit>
 
Hi batpool52!,

Thank you for the tip.

In the following ForumChooser.php code I simply remove the Category, Page or ForumLink nodes, but this approach is less than ideal because it's nice to be able to see the Categories. Can you tell me how I can make them "disabled" instead.

PHP:
<?php

abstract class Andy_SimilarThreads_Option_ForumChooser
{
    public static function renderOption(XenForo_View $view, $fieldPrefix, array $preparedOption, $canEdit)
    {
        $value = $preparedOption['option_value'];

        $editLink = $view->createTemplateObject('option_list_option_editlink', array(
            'preparedOption' => $preparedOption,
            'canEditOptionDefinition' => $canEdit
        ));

        $nodeModel = XenForo_Model::create('XenForo_Model_Node');

        $forumOptions = $nodeModel->getNodeOptionsArray($nodeModel->getAllNodes(), $preparedOption['option_value'], '(None)');

        // remove nodes which are not forums
        foreach ($forumOptions AS $k => $v)
        {
            foreach ($v AS $k2 => $v2)
            {              
                if ($k2 == 'node_type_id')
                {
                    if ($v2 == 'Category' OR $v2 == 'Page' OR $v2 == 'LinkForum')
                    {                      
                        unset($forumOptions[$k]);
                    }
                }
            }
        }
      
        return $view->createTemplateObject('andy_option_list_option_select', array(
            'fieldPrefix' => $fieldPrefix,
            'listedFieldName' => $fieldPrefix . '_listed[]',
            'preparedOption' => $preparedOption,
            'formatParams' => $forumOptions,
            'editLink' => $editLink
        ));
    }
}
 
When I add a the following code to the ForumChooser.php file:

print_r($forumOptions);

It shows the following:

Code:
(
    [0] => Array
        (
            [value] => 0
            [label] => (None)
            [selected] =>
            [depth] => 0
        )

    [50] => Array
        (
            [value] => 50
            [label] => Community
            [selected] =>
            [depth] => 1
            [node_type_id] => Category
        )

    [5] => Array
        (
            [value] => 5
            [label] => General
            [selected] =>
            [depth] => 2
            [node_type_id] => Forum
        )

    [73] => Array
        (
            [value] => 73
            [label] => Off-Topic
            [selected] =>
            [depth] => 2
            [node_type_id] => Forum
        )

    [127] => Array
        (
            [value] => 127
            [label] => In The News
            [selected] =>
            [depth] => 3
            [node_type_id] => Forum
        )

    [129] => Array
        (
            [value] => 129
            [label] => Music
            [selected] =>
            [depth] => 3
            [node_type_id] => Forum
        )

    [19] => Array
        (
            [value] => 19
            [label] => Pictures
            [selected] =>
            [depth] => 2
            [node_type_id] => Forum
        )

    [4] => Array
        (
            [value] => 4
            [label] => Videos
            [selected] =>
            [depth] => 2
            [node_type_id] => Forum
        )

    [64] => Array
        (
            [value] => 64
            [label] => Dirt Riders
            [selected] =>
            [depth] => 2
            [node_type_id] => Forum
        )

    [178] => Array
        (
            [value] => 178
            [label] => Supercross/Motocross
            [selected] =>
            [depth] => 3
            [node_type_id] => Forum
        )

Do I need to add the following to each array which is not a Forum?

disabled => 1
 
Last edited:
Got it!

ForumChooser.php

PHP:
<?php

abstract class Andy_SimilarThreads_Option_ForumChooser
{
	public static function renderOption(XenForo_View $view, $fieldPrefix, array $preparedOption, $canEdit)
	{
		$value = $preparedOption['option_value'];

		$editLink = $view->createTemplateObject('option_list_option_editlink', array(
			'preparedOption' => $preparedOption,
			'canEditOptionDefinition' => $canEdit
		));

		$nodeModel = XenForo_Model::create('XenForo_Model_Node');

		$forumOptions = $nodeModel->getNodeOptionsArray($nodeModel->getAllNodes(), $preparedOption['option_value'], '(None)');

		// disable nodes which are not forums
		foreach ($forumOptions AS $k => $v)
		{
			foreach ($v AS $k2 => $v2)
			{				
				if ($k2 == 'node_type_id')
				{
					if ($v2 == 'Category' OR $v2 == 'Page' OR $v2 == 'LinkForum')
					{
						$forumOptions[$k] += array(
							'disabled' => 1
						);
					}
				}
			}
		}
	
		return $view->createTemplateObject('andy_option_list_option_select', array(
			'fieldPrefix' => $fieldPrefix,
			'listedFieldName' => $fieldPrefix . '_listed[]',
			'preparedOption' => $preparedOption,
			'formatParams' => $forumOptions,
			'editLink' => $editLink
		));
	}
}
 
Maybe you already know this and I'm missing something, but XenForo includes a built-in NodeChooser callback class for options that is pretty flexible: XenForo_Option_NodeChooser.

The following (from deprecated XenForo_Option_ForumChooser) would only pull forums:
PHP:
$preparedOption['nodeFilter'] = 'Forum';
XenForo_Option_NodeChooser::renderSelect($view, $fieldPrefix, $preparedOption, $canEdit);
 
  • Like
Reactions: HWS
Hi Jeremy P,

I do recall seeing that class, but I don't know how to use it to display a node list in the Options page of an add-on.
 
Ah nevermind. Just realized you need a <select multiple> and the built-in class doesn't support the multiple attribute.

You could extend it with a custom class to do what you need with relative ease, but since you've already got it figured out it's probably fine as-is.
 
The one thing which worries me is this class has been depreciated.

PHP:
<?php

/**
* Deprecated. Use XenForo_Option_NodeChooser::renderSelect
*/
abstract class XenForo_Option_ForumChooser
{
    /**
     * Deprecated
     *
     * @see XenForo_Option_NodeChooser::renderSelect
     */
    public static function renderOption(XenForo_View $view, $fieldPrefix, array $preparedOption, $canEdit)
    {
        $preparedOption['nodeFilter'] = 'Forum';
        return XenForo_Option_NodeChooser::renderSelect($view, $fieldPrefix, $preparedOption, $canEdit);
    }
}

I assume this means that in a future XenForo version this class will remove be removed and any add-on using the class no longer work.
 
Top Bottom