Reply to thread

Content:


Hello XenForo Community,


I encountered a bug related to the ButtonManagerController in XenForo 2.3.0, which results in a TypeError. The error occurs when the removeOrphanedButtons method expects an array but receives a string instead. Here’s the detailed error message:


[CODE]

ErrorException: [E_WARNING] foreach() argument must be of type array|object, string given in src/XF/Admin/Controller/ButtonManagerController.php at line 112

XF::handlePhpError() in src/XF/Admin/Controller/ButtonManagerController.php at line 112

XF\Admin\Controller\ButtonManagerController->removeOrphanedButtons() in src/XF/Admin/Controller/ButtonManagerController.php at line 63

XF\Admin\Controller\ButtonManagerController->actionEdit() in src/XF/Mvc/Dispatcher.php at line 362

XF\Mvc\Dispatcher->dispatchClass() in src/XF/Mvc/Dispatcher.php at line 264

XF\Mvc\Dispatcher->dispatchFromMatch() in src/XF/Mvc/Dispatcher.php at line 121

XF\Mvc\Dispatcher->dispatchLoop() in src/XF/Mvc/Dispatcher.php at line 63

XF\Mvc\Dispatcher->run() in src/XF/App.php at line 2777

XF\App->run() in src/XF.php at line 798

XF::runApp() in admin.php at line 15

[/CODE]


The issue arises because the removeOrphanedButtons method processes toolbarButtons and calls the callback with each groupData['buttons'], which might not always be an array.


Steps to Fix:


1. Check the Data Structure: Ensure that toolbarButtons is always an array before passing it to the removeOrphanedButtons method.

2. Modify removeOrphanedButtons Method: Add a type check for toolbarButtons and ensure the callback is called with an array.


Here's the full code with the necessary modifications:


[CODE]

<?php


namespace XF\Admin\Controller;


use XF\Mvc\Dispatcher;

use XF\Mvc\ParameterBag;


class ButtonManagerController extends \XF\Admin\Controller\AbstractController

{

    public function actionEdit(ParameterBag $params)

    {

        $toolbarButtons = $this->getToolbarButtons(); // Ensure this method returns an array

        $availableButtons = $this->getAvailableButtons(); // Ensure this method returns an array


        if (!is_array($toolbarButtons)) {

            $toolbarButtons = []; // Initialize as an empty array if not an array

        }


        $this->removeOrphanedButtons($toolbarButtons, $availableButtons);


        // Continue with the rest of the function

        // ...


        return $this->view('XF:ButtonManager\Edit', 'button_manager_edit', [

            'toolbarButtons' => $toolbarButtons,

            'availableButtons' => $availableButtons

        ]);

    }


    protected function getToolbarButtons()

    {

        // Logic to get toolbar buttons, ensure this returns an array

        // Example:

        return [

            'group1' => [

                'buttons' => ['button1', 'button2']

            ],

            'group2' => [

                'buttons' => ['button3', 'button4']

            ]

        ];

    }


    protected function getAvailableButtons()

    {

        // Logic to get available buttons, ensure this returns an array

        // Example:

        return [

            'button1' => 'Button 1',

            'button2' => 'Button 2',

            'button3' => 'Button 3'

        ];

    }


    protected function removeOrphanedButtons(array &$toolbarButtons, array $availableButtons)

    {

        foreach ($toolbarButtons as $groupId => $group)

        {

            if (!is_array($group) || !isset($group['buttons']) || !is_array($group['buttons'])) {

                continue; // Skip groups that don't have the expected structure

            }


            foreach ($group['buttons'] as $index => $button)

            {

                if (!array_key_exists($button, $availableButtons))

                {

                    unset($toolbarButtons[$groupId]['buttons'][$index]);

                }

            }

        }

    }

}

[/CODE]


Explanation of Changes:

1. Type Check for toolbarButtons: Added a type check for toolbarButtons in actionEdit to ensure it is always an array.

2. Ensuring Array Structure: Added a check to ensure $groupData['buttons'] is an array before processing it in removeOrphanedButtons.


By applying these changes, you can avoid the TypeError and ensure the removeOrphanedButtons method processes the toolbar buttons correctly.


I hope this helps! Feel free to ask any questions or provide further feedback.


Back
Top Bottom