Deprecation: #107824 - ButtonBar, Menu, and MenuRegistry make* methods deprecated 

See forge#107824

Description 

The factory methods in ButtonBar for creating button instances, in Menu for creating menu item instances, and in MenuRegistry for creating menu instances have been deprecated in favor of using the new ComponentFactory class directly.

The following methods are now deprecated:

  • ButtonBar::makeGenericButton()
  • ButtonBar::makeInputButton()
  • ButtonBar::makeSplitButton()
  • ButtonBar::makeDropDownButton()
  • ButtonBar::makeLinkButton()
  • ButtonBar::makeFullyRenderedButton()
  • ButtonBar::makeShortcutButton()
  • ButtonBar::makeButton()
  • Menu::makeMenuItem()
  • MenuRegistry::makeMenu()

Impact 

Calling any of the deprecated make*() methods on ButtonBar, Menu, or MenuRegistry will trigger a PHP deprecation notice.

The methods continue to work in TYPO3 v14 but will be removed in TYPO3 v15.

Affected installations 

All extensions using ButtonBar::make*() methods to create buttons, Menu::makeMenuItem() to create menu items, or MenuRegistry::makeMenu() to create menus are affected. The extension scanner will report any usages.

Migration 

Inject ComponentFactory in your controller and use its create*() methods instead of ButtonBar::make*().

Before:

public function myAction(): ResponseInterface
{
    $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();

    $linkButton = $buttonBar->makeLinkButton()
        ->setHref($url)
        ->setTitle('My Link')
        ->setIcon($icon);

    $buttonBar->addButton($linkButton);
    // ...
}
Copied!

After:

public function __construct(
    protected readonly ComponentFactory $componentFactory,
) {}

public function myAction(): ResponseInterface
{
    $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();

    $linkButton = $this->componentFactory->createLinkButton()
        ->setHref($url)
        ->setTitle('My Link')
        ->setIcon($icon);

    $buttonBar->addButton($linkButton);
    // ...
}
Copied!

Additionally, consider using the pre-configured button creation methods like createBackButton(), createCloseButton(), createSaveButton(), and createRefreshButton() for common button patterns.

For the low-level makeButton(string $className) method, use GeneralUtility::makeInstance() directly or the appropriate ComponentFactory::create*() method:

// Before:
$button = $buttonBar->makeButton(MyCustomButton::class);

// After (option 1 - direct instantiation):
$button = GeneralUtility::makeInstance(MyCustomButton::class);

// After (option 2 - via factory if it's a standard button):
$button = $this->componentFactory->createLinkButton();
Copied!

For Menu::makeMenuItem(), use ComponentFactory::createMenuItem():

// Before:
$menu = $menuRegistry->makeMenu();
$menuItem = $menu->makeMenuItem()
    ->setTitle('My View')
    ->setHref($url);
$menu->addMenuItem($menuItem);

// After:
public function __construct(
    protected readonly ComponentFactory $componentFactory,
) {}

$menu = $this->componentFactory->createMenu();
$menuItem = $this->componentFactory->createMenuItem()
    ->setTitle('My View')
    ->setHref($url);
$menu->addMenuItem($menuItem);
Copied!

For MenuRegistry::makeMenu(), use ComponentFactory::createMenu():

// Before:
$menuRegistry = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry();
$menu = $menuRegistry->makeMenu();
$menu->setIdentifier('viewSelector')->setLabel('View');

// After:
public function __construct(
    protected readonly ComponentFactory $componentFactory,
) {}

$menuRegistry = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry();
$menu = $this->componentFactory->createMenu();
$menu->setIdentifier('viewSelector')->setLabel('View');
Copied!

Additionally, note that Menu::addMenuItem() now returns static to support fluent interface patterns:

// Now possible with fluent interface:
$menu->addMenuItem($menuItem1)
    ->addMenuItem($menuItem2)
    ->addMenuItem($menuItem3);
Copied!