Breaking: The list, detail and selection events of the plugins are gone 

Description 

The plugins of this extension no longer dispatch four events, and the classes are removed:

  • \FGTCLB\AcademicPersons\Event\ModifyListProfilesEvent , dispatched by the list and list-and-detail plugins after the query,
  • \FGTCLB\AcademicPersons\Event\ModifyDetailProfileEvent , dispatched by the detail and list-and-detail plugins before a profile was rendered,
  • \FGTCLB\AcademicPersons\Event\ModifySelectedProfilesEvent , dispatched by the selected profiles plugin after the query,
  • \FGTCLB\AcademicPersons\Event\ModifySelectedContractsEvent , dispatched by the selected contracts plugin after the query.

Every plugin of this extension, the card plugin included, which had no event of this kind, dispatches \FGTCLB\AcademicBase\Event\ModifyPluginViewEvent of academic_base instead, once each time it renders. It is one event for every academic plugin, so a view variable is added the same way everywhere. See Feature: The plugins dispatch the plugin view event, ModifyPluginViewEvent and the changelog of academic_base.

The new event carries the view and the plugin context, but no data of this extension. What the removed events let a listener change has other places:

Removed Instead
Assigning a view variable, in any of the four events ModifyPluginViewEvent , checking the action name on its context
ModifyListProfilesEvent::setProfileDemand() ModifyProfileDemandEvent , before the query; see below for what follows that demand
ModifyListProfilesEvent::setProfiles() , ModifySelectedProfilesEvent::setProfiles() ModifyProfileQueryEvent or, for the list, ModifyProfileDemandEvent to change which profiles are queried; for the selected profiles and a list without pagination, assigning the view variable profiles in ModifyPluginViewEvent to replace what is rendered. A paginated list renders the items of paginator , which that does not change.
ModifySelectedContractsEvent::setContracts() ModifyContractQueryEvent , or assigning the view variable contracts
ModifyDetailProfileEvent::setProfile() assigning the view variable profile in ModifyPluginViewEvent
ModifyDetailProfileEvent::setDefaultPageTitleFormat() and setSettingsPageTitleFormat() the page title format of the detail content element, the setting plugin.tx_academicpersons.settings.pageTitleFormat for every detail content element that sets none, or ModifyProfileTitlePlaceholderReplacementEvent for the value of a placeholder

A demand a listener of ModifyListProfilesEvent handed back came after the query and drove the rest of the list action: the letters offered, the active letter, the switch that turns the pagination off under a letter, the current page and the order of a manual selection. A demand a listener of ModifyProfileDemandEvent hands back, or changes in place, reaches the repository only, see Important: Demand listeners work on a copy: it decides which profiles are queried and which letters are offered. The active letter, the pagination and the order of a manual selection keep following the demand of the request. A listener that set a letter or a manual selection through the removed event and moves to ModifyProfileDemandEvent narrows the query, which the removed event never did, but the active letter, the pagination and the order of a manual selection do not follow it.

What the action computed from the query keeps using the queried result when a listener of the new event assigns another value to a view variable: the pagination and the letter navigation of the list, and the page title of the detail view.

Impact 

A listener of one of the four events is no longer called. It causes no error: TYPO3 registers the event of a listener as a class name, read from the type of its parameter or from the event argument of the attribute, without loading the class, and PHP checks the type of a parameter only when the method is called. What the listener did silently stops happening.

PHPStan reports the listener, because the class of its parameter does not exist any more:

Parameter $event of method MyVendor\MySitepackage\EventListener\AddOfficeHours::__invoke()
has invalid type FGTCLB\AcademicPersons\Event\ModifyListProfilesEvent.
Copied!

Affected installations 

Installations with an event listener of ModifyListProfilesEvent , ModifyDetailProfileEvent , ModifySelectedProfilesEvent or ModifySelectedContractsEvent , registered with an attribute or in Configuration/Services.yaml. Searching the project code for the four class names finds them.

Migration 

Register the listener for ModifyPluginViewEvent and return early for every plugin and action it is not meant for:

Before
use FGTCLB\AcademicPersons\Event\ModifyDetailProfileEvent;
use TYPO3\CMS\Core\Attribute\AsEventListener;

final class AddOfficeHours
{
    #[AsEventListener]
    public function __invoke(ModifyDetailProfileEvent $event): void
    {
        $event->getView()->assign('officeHoursPageId', 42);
    }
}
Copied!
After
use FGTCLB\AcademicBase\Event\ModifyPluginViewEvent;
use TYPO3\CMS\Core\Attribute\AsEventListener;

final class AddOfficeHours
{
    #[AsEventListener]
    public function __invoke(ModifyPluginViewEvent $event): void
    {
        $context = $event->getPluginControllerActionContext();
        if ($context->getControllerExtensionName() !== 'AcademicPersons'
            || $context->getActionName() !== 'detail'
        ) {
            return;
        }
        $event->getView()->assign('officeHoursPageId', 42);
    }
}
Copied!

The action names are list , detail , card , selectedProfiles and selectedContracts ; the plugin names List , ListAndDetail , Detail , Card , SelectedProfiles and SelectedContracts . The profile the detail view renders is its view variable profile , and the context is typed against the interface of academic_base.