$controllerActions * @param array $nonCacheableControllerActions * @internal */ public static function registerControllerActions(string $extensionName, string $pluginName, array $controllerActions, array $nonCacheableControllerActions): void { if (!is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins'][$pluginName] ?? false)) { $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins'][$pluginName] = []; } foreach ($controllerActions as $controllerClassName => $actionsList) { $controllerAlias = self::resolveControllerAliasFromControllerClassName($controllerClassName); $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins'][$pluginName]['controllers'][$controllerClassName] = [ 'className' => $controllerClassName, 'alias' => $controllerAlias, 'actions' => $actionsList, ]; if (!empty($nonCacheableControllerActions[$controllerClassName])) { $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins'][$pluginName]['controllers'][$controllerClassName]['nonCacheableActions'] = $nonCacheableControllerActions[$controllerClassName]; } } } /** * Register an Extbase PlugIn into backend's list of plugins * FOR USE IN Configuration/TCA/Overrides/tt_content.php * * @param string $extensionName The extension name (in UpperCamelCase) or the extension key (in lower_underscore) * @param string $pluginName must be a unique id for your plugin in UpperCamelCase (the string length of the extension key added to the length of the plugin name should be less than 32!) * @param string $pluginTitle is a speaking title of the plugin that will be displayed in the drop down menu in the backend * @param string|null $pluginIcon is an icon identifier or file path prepended with "EXT:", that will be displayed in the drop down menu in the backend (optional) * @param string $group add this plugin to a plugin group, should be something like "news" or the like, "plugins" as regular * @param string $pluginDescription additional description * @param string $flexForm The flex form (data structure) to be used for the plugin. Either a reference to a flex-form XML file (eg. "FILE:EXT:newloginbox/flexform_ds.xml") or the XML directly. * @throws \InvalidArgumentException */ public static function registerPlugin($extensionName, $pluginName, $pluginTitle, $pluginIcon = null, $group = 'plugins', string $pluginDescription = '', string $flexForm = ''): string { self::checkPluginNameFormat($pluginName); self::checkExtensionNameFormat($extensionName); $extensionName = str_replace(' ', '', ucwords(str_replace('_', ' ', $extensionName))); $pluginSignature = strtolower($extensionName) . '_' . strtolower($pluginName); ExtensionManagementUtility::addPlugin( new SelectItem( 'select', // set pluginName as default pluginTitle $pluginTitle ?: $pluginName, $pluginSignature, $pluginIcon ?? 'content-plugin', $group, $pluginDescription ), $flexForm ); return $pluginSignature; } /** * @internal only used for TYPO3 Core */ public static function resolveControllerAliasFromControllerClassName(string $controllerClassName): string { // This method has been adjusted for TYPO3 10.3 to mitigate the issue that controller aliases // could not longer be calculated from controller classes when calling // \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(). // // The idea for version 11 is to let the user choose a controller alias and to check for its // uniqueness per plugin. That way, the core does no longer rely on the namespace of // controller classes to be in a specific format. // // todo: Change the way plugins are registered and enforce a controller alias to be set by // the user to also free the core from guessing a simple alias by looking at the // class name. This makes it possible to choose controller class names without a // controller suffix. $strLen = strlen('Controller'); if (!str_ends_with($controllerClassName, 'Controller')) { return ''; } $controllerClassNameWithoutControllerSuffix = substr($controllerClassName, 0, -$strLen); if (strrpos($controllerClassNameWithoutControllerSuffix, 'Controller\\') === false) { $positionOfLastSlash = (int)strrpos($controllerClassNameWithoutControllerSuffix, '\\'); $positionOfLastSlash += $positionOfLastSlash === 0 ? 0 : 1; return substr($controllerClassNameWithoutControllerSuffix, $positionOfLastSlash); } $positionOfControllerNamespacePart = (int)strrpos( $controllerClassNameWithoutControllerSuffix, 'Controller\\' ); return substr( $controllerClassNameWithoutControllerSuffix, $positionOfControllerNamespacePart + $strLen + 1 ); } /** * @param array $controllerActions * @return array */ protected static function actionCommaListToArray(array $controllerActions): array { foreach ($controllerActions as $controllerClassName => $actionsList) { if (is_array($actionsList)) { continue; } $actionsListArray = GeneralUtility::trimExplode(',', (string)$actionsList); $controllerActions[$controllerClassName] = $actionsListArray; } return $controllerActions; } /** * Check a given extension name for validity. * * @param string $extensionName The name of the extension * @throws \InvalidArgumentException */ protected static function checkExtensionNameFormat($extensionName) { if (empty($extensionName)) { throw new \InvalidArgumentException('The extension name must not be empty', 1239891990); } } /** * Check a given plugin name for validity. * * @param string $pluginName The name of the plugin * @throws \InvalidArgumentException */ protected static function checkPluginNameFormat($pluginName) { if (empty($pluginName)) { throw new \InvalidArgumentException('The plugin name must not be empty', 1239891988); } } }