5 Add new types of restrictions
Benjamin edited this page 2026-07-27 15:28:48 +00:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This page explains how you can add new types of restrictions for your reactions.

To do this, you need to be comfortable with the different ways to extend a XenForo add-on. (Class Extensions, Code Events, Template Modifications)

Youll need to implement the behavior of your new restriction type in four different places:

  • The admin form for adding restrictions.
  • The cache storage for allowed reactions.
  • The reaction validation logic.
  • The front-end reaction list.

You can also extend the functionality to control which context value is saved when restrictions are updated.

Extend the admin form

To extend the form for saving reaction restrictions, you can use a modification template.

You can extend the bencm_reactions_restrictions_admin_form template and search for the comment <!-- [BenCM-Reaction-Restrictions--End-Restrictions] --> to replace it.

You can then add your fields. Be sure to prepare your data first by extending XF\Admin\Controller\ReactionController if the data is dynamic.

Next, for each option, the option name must be as follows: restrictions[{$contextType}][{$primaryContextValue}] with value=“{$secondaryContextValue}”. Where $contextType corresponds to the context (e.g., node, content_type, ...) and $contextValue corresponds to the context value (e.g., node_id, post, profile_post_comment, ...)

If you are not using a tree or complex structures, you can leave value=“1”.

These fields will be automatically saved with $primaryContextValue taken into account. If you need to use $secondaryContextValue or perform additional processing, you must enable an event listener for bencm_reactions_update_restrictions_context_value. Full details about this event are available when you register the event listener.

Add the context type to the cache

Whenever changes are made to restrictions, the add-on refreshes its cache used for public templates.

By default, your context type will be present, but only with the values you have added; all other default values will be missing.

You must therefore add the default values—such as unrestricted reaction IDs—to your context type.

To do this, you must use the bencm_reactions_cache_setup event hook. Details are available when you register the listener.

Example using node as the context type (built-in):

        if( !isset( $byContextType['node'] ) ){
            $byContextType['node'] = [];
        }

        foreach( $this->getAvailableNodes() as $nodeId )
        {
            if( !isset( $byContextType['node'][strval($nodeId)] ) ){
                $byContextType['node'][strval($nodeId)] = $nonRestrictedReactionsIds;
            }
        }

Add the context type validation logic

To add validation logic for your contextType, you can use the code eventbencm_reactions_is_allowed, which will provide you with the reaction and the entity associated with the reaction. Be sure to use the event hint (which is the entity's content type) to avoid conflicting with other declarations.

Remove restricted reactions from the public reactions list

XenForo loads the list of reactions on all pages. To remove restricted reactions for the specific content type in question, you must edit the content template—using template modifications—to add the data-reactions-restrictions attribute, which should contain a comma-separated string of all the reaction IDs allowed for that content.

To do this, you can use the BenjaminCM\ReactionsRestriction\Template\ReactionRestriction class, which provides methods for this purpose; you can use <xf:callback> to call it in the appropriate location. You can also extend it via class extensions.

Here is an example of the template modification for forum posts, along with the callback.

<!-- public:post_macros, find: "data-content="post-{$post.post_id}"" -->
$0
data-reactions-restrictions="<xf:callback class="BenjaminCM\ReactionsRestriction\Template\ReactionRestriction" method="getReactionIdsRestrictionsForPost" params="[$post.Thread.node_id]"></xf:callback>"
    /**
     * @param $contents
     * @param array $params
     * @param \XF\Template\Templater $templater
     *
     * @return string
     */
    public static function getReactionIdsRestrictionsForPost($contents, array $params, \XF\Template\Templater $templater)
    {
        $node_id = $params[0] ?? null;

        $array = static::getAllowedReactionIds('content_type', 'post' );
        if( $node_id ){
            $array = array_values(array_unique([...$array, ...static::getAllowedReactionIds('node', intval($node_id) ) ] ) ) ;
        }
        return static::renderHtmlArray($array);
    }